pax_global_header00006660000000000000000000000064151671200400014506gustar00rootroot0000000000000052 comment=2e33d86d6ce85ebe023775fa8750ef698d8d9ddb boca-1.0.7+git20260412.690d4ffe+dfsg/000077500000000000000000000000001516712004000161645ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/.gitattributes000066400000000000000000000000101516712004000210460ustar00rootroot00000000000000* -text boca-1.0.7+git20260412.690d4ffe+dfsg/.github/000077500000000000000000000000001516712004000175245ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/.github/workflows/000077500000000000000000000000001516712004000215615ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/.github/workflows/verify-build.yml000066400000000000000000000047601516712004000247140ustar00rootroot00000000000000name: "Verify build" on: push: pull_request: schedule: - cron: '0 6 * * 1' jobs: build: strategy: matrix: include: - os: ubuntu-latest cc: gcc cxx: g++ - os: ubuntu-latest cc: clang cxx: clang++ - os: macos-latest cc: clang cxx: clang++ runs-on: ${{ matrix.os }} steps: - name: Install smooth dependencies if: ${{ runner.os == 'Linux' }} run: | sudo apt update sudo apt install -y libbz2-dev libcurl4-openssl-dev libfribidi-dev libgtk-3-dev libjpeg-dev libxml2-dev - name: Checkout smooth uses: actions/checkout@v6 with: repository: enzo1982/smooth path: smooth - name: Build smooth env: CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} run: | cd smooth make -j$(nproc) sudo make install prefix=/usr/local cd .. - name: Install dependencies if: ${{ runner.os == 'Linux' }} run: | sudo apt update sudo apt install -y libcdio-dev libcdio-paranoia-dev libexpat1-dev liburiparser-dev libpulse-dev - name: Install dependencies macOS if: ${{ runner.os == 'macOS' }} run: | wget https://ftp.gnu.org/gnu/libcdio/libcdio-2.1.0.tar.bz2 tar xfj libcdio-2.1.0.tar.bz2 cd libcdio-2.1.0 ./configure --prefix=/usr/local && make -j$(nproc) && sudo make install cd .. wget https://ftp.gnu.org/gnu/libcdio/libcdio-paranoia-10.2+2.0.1.tar.bz2 tar xfj libcdio-paranoia-10.2+2.0.1.tar.bz2 cd libcdio-paranoia-10.2+2.0.1 sed -i -e "s/-Wl,--version-script=.*\.la\.ver//" lib/*/Makefile.in ./configure --prefix=/usr/local && make -j$(nproc) && sudo make install cd .. - name: Checkout repository uses: actions/checkout@v6 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} - name: Build env: CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} run: | make -j$(nproc) boca-1.0.7+git20260412.690d4ffe+dfsg/.gitignore000066400000000000000000000003621516712004000201550ustar00rootroot00000000000000# Ignore artifacts created during build. bin/* bin64/* components/**/*.[oa] lib/* lib64/* include/smooth.h include/smooth/* msvc/**/.vs/* msvc/**/Debug/* msvc/**/Release/* msvc/**/*.VC.* msvc/**/*.vcxproj.user runtime/**/*.[oa] boca-1.0.7+git20260412.690d4ffe+dfsg/COPYING000066400000000000000000000431241516712004000172230ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. boca-1.0.7+git20260412.690d4ffe+dfsg/Makefile000077500000000000000000000020351516712004000176270ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = . include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options all: mkdir -p $(BOCA_PATH)/$(BINDIR) $(BOCA_PATH)/$(LIBDIR) + $(call makein,runtime) + $(call makein,components) codesign: all signtool sign -fd sha1 -tr http://timestamp.digicert.com -td sha1 $(BOCA_PATH)/$(BINDIR)/*.dll $(BOCA_PATH)/$(BINDIR)/*.exe signtool sign -fd sha256 -tr http://timestamp.digicert.com -td sha256 -as $(BOCA_PATH)/$(BINDIR)/*.dll $(BOCA_PATH)/$(BINDIR)/*.exe clean: + $(call cleanin,runtime) + $(call cleanin,components) ifneq ("$(SRCDIR)","$(CURDIR)") rmdir $(BOCA_PATH)/$(BINDIR) $(BOCA_PATH)/$(LIBDIR) || true endif install: ifneq ($(BUILD_WIN32),True) $(call makein,include,install) $(call makein,runtime,install) $(call makein,scripts,install) $(call makein,components,install) endif uninstall: ifneq ($(BUILD_WIN32),True) $(call makein,include,uninstall) $(call makein,runtime,uninstall) $(call makein,scripts,uninstall) $(call makein,components,uninstall) endif boca-1.0.7+git20260412.690d4ffe+dfsg/Makefile-commands000077500000000000000000000040531516712004000214300ustar00rootroot00000000000000########## BoCA commands makefile ########## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options CCOPTS = -fvisibility=hidden -DBOCA_COMPONENT_BUILD $(DEFINE) -I"$(SRCDIR)"/$(BOCA_PATH)/include LDOPTS = -L$(BOCA_PATH)/$(LIBDIR) -L"$(SRCDIR)"/$(BOCA_PATH)/$(LIBDIR) $(LIBS) ifeq ($(BUILD_WIN32),True) LDOPTS += -lsmooth -lboca -Wl,--dynamicbase,--nxcompat,--enable-auto-import else CCOPTS += -fPIC ifneq ($(BUILD_SOLARIS),True) ifneq ($(BUILD_HAIKU),True) CCOPTS += -pthread ifneq ($(BUILD_OSX),True) ifeq ($(BUILD_NETBSD),True) CCOPTS += -I/usr/pkg/include else CCOPTS += -I/usr/local/include endif endif endif endif LDOPTS += -L$(prefix)/lib -lsmooth-$(SMOOTHVER) -lboca-$(VERSION) ifeq ($(BUILD_OSX),True) LDOPTS += -Wl,-headerpad,80 else ifeq ($(BUILD_NETBSD),True) LDOPTS += -Wl,-rpath,/usr/pkg/lib -L/usr/pkg/lib else ifneq ($(BUILD_LINUX),True) ifneq ($(BUILD_SOLARIS),True) LDOPTS += -L/usr/local/lib endif endif endif endif all: allcmds $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET).$(VERSION)$(SHARED) allcmds: + $(ALLCMD1) + $(ALLCMD2) $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET).$(VERSION)$(SHARED) : $(OBJECTS) mkdir -p $(BOCA_PATH)/$(BINDIR) ifneq ($(BUILD_OSX),True) $(LD) --shared -o $@ $(OBJECTS) $(LDOPTS) $(LDFLAGS) else $(LD) -dynamiclib -o $@ $(OBJECTS) $(LDOPTS) $(LDFLAGS) endif clean: rm -f $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET).$(VERSION)$(SHARED) $(OBJECTS) $(CLEANCMD1) $(CLEANCMD2) install: all ifneq ($(BUILD_WIN32),True) $(INSTALL) -d "$(DESTDIR)"$(libdir)/boca $(INSTALL_DATA) $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET).$(VERSION)$(SHARED) "$(DESTDIR)"$(libdir)/boca endif $(INSTCMD1) $(INSTCMD2) uninstall: ifneq ($(BUILD_WIN32),True) rm -f "$(DESTDIR)"$(libdir)/boca/boca_$(TYPE)_$(TARGET).$(VERSION)$(SHARED) endif $(UINSTCMD1) $(UINSTCMD2) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ .cpp.o: $(CXX) $(CCOPTS) $(CXXFLAGS) -c $< -o $@ .m.o: $(OBJC) $(CCOPTS) $(OBJCFLAGS) -c $< -o $@ .mm.o: $(OBJCXX) $(CCOPTS) $(OBJCXXFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/Makefile-options000066400000000000000000000224371516712004000213250ustar00rootroot00000000000000########## BoCA options makefile ########## SMOOTHVER = 0.9 # Find source folder and set vpath SRCDIR = $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) vpath %.c "$(SRCDIR)" vpath %.cc "$(SRCDIR)" vpath %.cpp "$(SRCDIR)" vpath %.m "$(SRCDIR)" vpath %.mm "$(SRCDIR)" # Define makein and cleanin macros ifeq ("$(SRCDIR)","$(CURDIR)") makein = cd $(1) && $(MAKE) $(2) && cd .. cleanin = cd $(1) && $(MAKE) clean && cd .. else makein = mkdir -p $(1) && cd $(1) && $(MAKE) -f "$(SRCDIR)"/$(1)/Makefile $(2) && cd .. cleanin = mkdir -p $(1) && cd $(1) && $(MAKE) -f "$(SRCDIR)"/$(1)/Makefile clean && cd .. && (rmdir $(1) || true) endif # Find architecture and system UNAME = $(shell uname) MACHINE = $(shell $(CC) -dumpmachine) ifneq ($(findstring arm,$(MACHINE)),) ifneq ($(BUILD_ARM),False) BUILD_ARM = True endif else ifneq ($(findstring aarch64,$(MACHINE)),) ifneq ($(BUILD_ARM64),False) BUILD_ARM64 = True endif else ifneq ($(findstring mips,$(MACHINE)),) ifneq ($(BUILD_MIPS),False) BUILD_MIPS = True endif else ifneq ($(findstring powerpc64,$(MACHINE)),) ifneq ($(BUILD_PPC64),False) BUILD_PPC64 = True endif else ifneq ($(findstring powerpc,$(MACHINE)),) ifneq ($(BUILD_PPC),False) BUILD_PPC = True endif else ifneq ($(findstring riscv64,$(MACHINE)),) ifneq ($(BUILD_RISCV64),False) BUILD_RISCV64 = True endif else ifneq ($(findstring x86_64,$(MACHINE)),) ifneq ($(BUILD_ARM64),True) ifneq ($(BUILD_X86),True) ifneq ($(BUILD_X86_64),False) BUILD_X86_64 = True endif endif endif else ifneq ($(findstring amd64,$(MACHINE)),) ifneq ($(BUILD_ARM64),True) ifneq ($(BUILD_X86),True) ifneq ($(BUILD_X86_64),False) BUILD_X86_64 = True endif endif endif else ifneq ($(findstring i586,$(MACHINE))$(findstring i686,$(MACHINE)),) ifneq ($(BUILD_ARM64),True) ifneq ($(BUILD_X86),False) ifneq ($(BUILD_X86_64),True) BUILD_X86 = True endif endif endif endif # Treat MSYS and MinGW the same ifneq ($(findstring MSYS,$(UNAME)),) UNAME = MINGW endif ifneq ($(findstring MINGW,$(UNAME)),) # Set executable and shared object extensions EXECUTABLE = .exe SHARED = .dll # Build on Win32 BUILD_WIN32 = True else # Set executable and shared object extensions EXECUTABLE = SHARED = .so BUILD_UNIX = True ifeq ($(UNAME),Linux) BUILD_LINUX = True else ifeq ($(UNAME),FreeBSD) BUILD_FREEBSD = True else ifeq ($(UNAME),OpenBSD) BUILD_OPENBSD = True else ifeq ($(UNAME),NetBSD) BUILD_NETBSD = True else ifeq ($(UNAME),SunOS) BUILD_SOLARIS = True else ifeq ($(UNAME),Haiku) BUILD_HAIKU = True else ifeq ($(UNAME),GNU) BUILD_GNU = True else ifeq ($(UNAME),Darwin) # Set shared object extension SHARED = .dylib BUILD_OSX = True endif endif # Set default commands ifndef OBJC OBJC = $(CC) endif ifndef OBJCXX OBJCXX = $(CXX) endif ifeq ($(LD),ld) LD = $(CXX) endif LDCONFIG = /sbin/ldconfig INSTALL = install ifeq ($(BUILD_SOLARIS),True) INSTALL = ginstall endif INSTALL_PROGRAM = $(INSTALL) INSTALL_DATA = $(INSTALL) -m 644 # Set output folders BINDIR = bin LIBDIR = lib ifeq ($(BUILD_WIN32),True) ifeq ($(BUILD_X86_64),True) BINDIR = bin64 LIBDIR = lib64 endif endif # Set install folders ifndef prefix prefix = /usr/local ifeq ($(BUILD_HAIKU),True) prefix = /system/non-packaged endif endif bindir = $(prefix)/bin libdir = $(prefix)/lib includedir = $(prefix)/include datadir = $(prefix)/share ifeq ($(BUILD_HAIKU),True) includedir = $(prefix)/develop/headers datadir = $(prefix)/data endif # Decide which libraries to use ifeq ($(findstring bundledlibexpat,$(config)),bundledlibexpat) USE_BUNDLED_LIBEXPAT = True else ifeq ($(findstring systemlibexpat,$(config)),systemlibexpat) USE_BUNDLED_LIBEXPAT = False else ifeq ($(BUILD_WIN32),True) USE_BUNDLED_LIBEXPAT = True endif endif ifeq ($(findstring bundledliburiparser,$(config)),bundledliburiparser) USE_BUNDLED_LIBURIPARSER = True else ifeq ($(findstring systemliburiparser,$(config)),systemliburiparser) USE_BUNDLED_LIBURIPARSER = False else ifeq ($(BUILD_OSX),True) USE_BUNDLED_LIBURIPARSER = True else ifeq ($(BUILD_SOLARIS),True) USE_BUNDLED_LIBURIPARSER = True else ifeq ($(BUILD_WIN32),True) USE_BUNDLED_LIBURIPARSER = True endif endif ifeq ($(findstring bundledlibxspf,$(config)),bundledlibxspf) USE_BUNDLED_LIBXSPF = True else ifeq ($(findstring systemlibxspf,$(config)),systemlibxspf) USE_BUNDLED_LIBXSPF = False else USE_BUNDLED_LIBXSPF = True endif ifeq ($(findstring bundledzlib,$(config)),bundledzlib) USE_BUNDLED_ZLIB = True else ifeq ($(findstring systemzlib,$(config)),systemzlib) USE_BUNDLED_ZLIB = False else ifeq ($(BUILD_OSX),True) USE_BUNDLED_ZLIB = True else ifeq ($(BUILD_WIN32),True) USE_BUNDLED_ZLIB = True endif endif # Decide whether to build using Wine ifneq ($(BUILD_OSX),True) ifneq ($(BUILD_WIN32),True) ifeq ($(shell type winegcc 1> /dev/null 2> /dev/null; echo $$?),0) USE_WINE = True endif endif endif # Set release specific options ifeq ($(findstring release,$(config)),release) ifeq ($(BUILD_FREEBSD),True) override CC = clang override CXX = clang++ override OBJC = clang override OBJCXX = clang++ override LD = clang++ else ifeq ($(BUILD_OSX),True) override CC = gcc override CXX = g++ override OBJC = gcc override OBJCXX = g++ override LD = g++ endif override CFLAGS = -pipe -g0 -Wall -Os override CXXFLAGS = override OBJCFLAGS = override OBJCXXFLAGS = override LDFLAGS = -pipe ifneq ($(RTTI),True) ifneq ($(BUILD_HAIKU),True) override CXXFLAGS += -fno-rtti override OBJCXXFLAGS += -fno-rtti endif endif ifneq ($(EXCEPTION),True) override CXXFLAGS += -fno-exceptions override OBJCXXFLAGS += -fno-exceptions endif ifeq ($(BUILD_OSX),True) # Find macOS and Xcode version XCODEVERSION = $(shell xcodebuild -version | head -n1) MACOSVERSION = $(MACOSX_DEPLOYMENT_TARGET) ifeq ($(MACOSVERSION),) MACOSVERSION = $(shell sw_vers | awk '$$1 == "ProductVersion:" { print $$2 }') endif XCODE_LE3 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -le 3 ]; then echo True; fi") XCODE_LE9 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -le 9 ]; then echo True; fi") XCODE_EQ12 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -eq 12 ]; then echo True; fi") XCODE_GE13 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -ge 13 ]; then echo True; fi") XCODE_N_GE2 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#*.}; if [ \$${v%%.*} -ge 2 ]; then echo True; fi") MACOS_GE11 = $(shell bash -c "v='$(MACOSVERSION)'; if [ \$${v%%.*} -ge 11 ]; then echo True; fi") # Build universal binaries ifneq ($(BUILD_X86_64),False) BUILD_X86_64 = True endif ifeq ($(XCODE_LE9),True) ifneq ($(BUILD_X86),False) BUILD_X86 = True endif ifeq ($(XCODE_LE3),True) ifneq ($(BUILD_PPC),False) BUILD_PPC = True endif endif else ifeq ($(XCODE_EQ12),True) ifeq ($(XCODE_N_GE2),True) ifeq ($(MACOS_GE11),True) ifneq ($(BUILD_ARM64),False) BUILD_ARM64 = True endif endif endif else ifeq ($(XCODE_GE13),True) ifeq ($(MACOS_GE11),True) ifneq ($(BUILD_ARM64),False) BUILD_ARM64 = True endif endif endif # Set build flags override LDFLAGS += -Wl,-x ifeq ($(BUILD_X86),True) override CFLAGS += -arch i386 -Xarch_i386 -march=prescott override LDFLAGS += -arch i386 endif ifeq ($(BUILD_X86_64),True) ifeq ($(MACOS_GE11),True) override CFLAGS += -arch x86_64 -Xarch_x86_64 -march=haswell else override CFLAGS += -arch x86_64 -Xarch_x86_64 -march=core2 endif override LDFLAGS += -arch x86_64 endif ifeq ($(BUILD_PPC),True) override CFLAGS += -arch ppc -Xarch_ppc -mcpu=G4 override LDFLAGS += -arch ppc endif ifeq ($(BUILD_PPC64),True) override CFLAGS += -arch ppc64 -Xarch_ppc64 -mcpu=G5 override LDFLAGS += -arch ppc64 endif ifeq ($(BUILD_ARM64),True) override CFLAGS += -arch arm64 override LDFLAGS += -arch arm64 endif else override LDFLAGS += -s ifeq ($(BUILD_X86),True) override CFLAGS += -m32 override LDFLAGS += -m32 else ifeq ($(BUILD_X86_64),True) override CFLAGS += -m64 override LDFLAGS += -m64 endif endif override CXXFLAGS += $(CFLAGS) override OBJCFLAGS += $(CFLAGS) override OBJCXXFLAGS += $(CFLAGS) ifneq ($(BUILD_WIN32),True) ifneq ($(BUILD_OSX),True) override LDFLAGS += -Wl,-rpath,. endif endif endif # Set debug specific options ifeq ($(findstring debug,$(config)),debug) override CFLAGS = -pipe -g -Wall -DDEBUG override CXXFLAGS = override OBJCFLAGS = override OBJCXXFLAGS = override LDFLAGS = -pipe ifneq ($(RTTI),True) ifneq ($(BUILD_HAIKU),True) override CXXFLAGS += -fno-rtti override OBJCXXFLAGS += -fno-rtti endif endif ifneq ($(EXCEPTION),True) override CXXFLAGS += -fno-exceptions override OBJCXXFLAGS += -fno-exceptions endif override CXXFLAGS += $(CFLAGS) override OBJCFLAGS += $(CFLAGS) override OBJCXXFLAGS += $(CFLAGS) ifneq ($(BUILD_WIN32),True) ifneq ($(BUILD_OSX),True) override LDFLAGS += -Wl,-rpath,. endif endif endif # Flags needed for Windows ARM64 toolchain ifeq ($(BUILD_WIN32),True) ifeq ($(BUILD_ARM64),True) override CFLAGS += -target aarch64-w64-mingw32 override LDFLAGS += -target aarch64-w64-mingw32 endif endif # Clear config variable config = boca-1.0.7+git20260412.690d4ffe+dfsg/Readme.md000066400000000000000000000037331516712004000177110ustar00rootroot00000000000000BoCA - fre:ac Component Architecture ==================================================================================================== [![Build Status](https://img.shields.io/github/actions/workflow/status/enzo1982/BoCA/verify-build.yml?branch=master)](https://github.com/enzo1982/BoCA/actions?query=workflow%3A%22Verify+build%22+branch%3Amaster) [![Last commit](https://img.shields.io/github/last-commit/enzo1982/BoCA.svg)](https://github.com/enzo1982/BoCA/commits/master) [![License](https://img.shields.io/github/license/enzo1982/BoCA.svg)](https://github.com/enzo1982/BoCA/blob/master/COPYING) BoCA is the component framework behind the fre:ac audio converter. It provides unified interfaces for components like encoders, decoders, taggers and extensions as well as code to support communication between the application and its components. Contents -------- The code for the main library can be found in the `runtime` directory with headers in the `include` folder. The `components` directory contains various components of different types that can be used with audio software like fre:ac and also serve as examples on how to implement BoCA components. The `scripts` directory contains XML scripts that are interpreted by BoCA in order to use various external command line encoders and decoders. Installation ------------ The following packages must be installed in order to compile BoCA: - the _smooth_ Class Library - libpulse development package (Linux only) - libcdio and libcdio-paranoia development packages (except OpenBSD) - libcdparanoia development package (OpenBSD only) - libexpat development package - liburiparser development package When all prerequisites are met, run `make` followed by `sudo make install` to compile and install BoCA. ---------------------------------------------------------------------------------------------------- The official fre:ac homepage: https://www.freac.org/ robert.kausch@freac.org,
Robert Kausch boca-1.0.7+git20260412.690d4ffe+dfsg/components/000077500000000000000000000000001516712004000203515ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/Makefile000077500000000000000000000013671516712004000220230ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = .. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = decoder deviceinfo dsp encoder extension other output playlist tagger verifier .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/000077500000000000000000000000001516712004000217565ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/Makefile000077500000000000000000000017751516712004000234330ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = alac cuesheet faad2 fdkaac flac mac mpg123 opus sndfile speex vorbis ifeq ($(BUILD_UNIX),True) ifneq ($(BUILD_HAIKU),True) ifneq ($(BUILD_OPENBSD),True) FOLDERS += cdio else FOLDERS += cdparanoia endif endif else ifeq ($(BUILD_WIN32),True) FOLDERS += cdrip mediafoundation wma ifeq ($(BUILD_X86),True) FOLDERS += winamp endif endif .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/aiff/000077500000000000000000000000001516712004000226635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/aiff/Makefile000077500000000000000000000011201516712004000243200ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = aiff TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = aiff.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/aiff/aiff.cpp000066400000000000000000000140771516712004000243050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "aiff.h" using namespace smooth::IO; const String &BoCA::DecoderAIFF::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Apple Audio File Decoder \ 1.0 \ aiff-dec \ decoder \ \ Apple Audio Files \ true \ aif \ aiff \ aifc \ ID3v2 \ .TOC.plist \ \ \ \ "; return componentSpecs; } Bool BoCA::DecoderAIFF::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) != "FORM") return False; in.RelSeek(4); String fileType = in.InputString(4); if (fileType == "AIFF") return True; else if (fileType != "AIFC") return False; String chunk; while (chunk != "COMM") { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt32 cSize = in.InputNumberRaw(4); if (chunk == "COMM") { in.RelSeek(18); /* Parse AIFF-C compression type. */ String compression = in.InputString(4); if (compression == "NONE" || compression == "sowt") return True; /* Skip rest of chunk. */ if (!in.RelSeek(cSize - 22 + cSize % 2)) break; } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) break; } } return False; } Error BoCA::DecoderAIFF::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); track.fileSize = in.Size(); /* Read FORM chunk. */ if (in.InputString(4) != "FORM") { errorState = True; errorString = "Unknown file type"; } in.RelSeek(4); String fileType = in.InputString(4); if (fileType != "AIFF" && fileType != "AIFC") { errorState = True; errorString = "Unknown file type"; } String chunk; while (!errorState) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt32 cSize = in.InputNumberRaw(4); if (chunk == "COMM") { Int cStart = in.GetPos(); Format format = track.GetFormat(); format.channels = (unsigned short) in.InputNumberRaw(2); track.length = (unsigned long) in.InputNumberRaw(4); format.order = BYTE_RAW; format.bits = (unsigned short) in.InputNumberRaw(2); /* Read sample rate as 80 bit float. */ int16_t exp = (in.InputNumberRaw(2) & 0x7FFF) - 16383 - 63; uint64_t man = 0; for (int i = 0; i < 8; i++) man = (man << 8) | in.InputNumberRaw(1); format.rate = ldexp((double) man, exp); /* Parse AIFF-C compression type. */ if (fileType == "AIFC") { String compression = in.InputString(4); if (compression == "NONE") format.order = BYTE_RAW; else if (compression == "sowt") format.order = BYTE_INTEL; else { errorState = True; errorString = "Unsupported audio format"; } } track.SetFormat(format); /* Skip rest of chunk. */ in.Seek(cStart + cSize + cSize % 2); } else if (chunk == "AUTH" || chunk == "NAME" || chunk == "ANNO") { Info info = track.GetInfo(); if (chunk == "AUTH") info.artist = in.InputString(cSize); else if (chunk == "NAME") info.title = in.InputString(cSize); else if (chunk == "ANNO") info.comment = in.InputString(cSize); track.SetInfo(info); /* Skip rest of chunk. */ in.RelSeek(cSize % 2); } else if (chunk == "ID3 ") { Buffer buffer(cSize); in.InputData(buffer, cSize); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(buffer, track); boca.DeleteComponent(tagger); } /* Skip rest of chunk. */ in.RelSeek(cSize % 2); } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) { errorState = True; errorString = "Invalid file format"; } } } /* Read .TOC.plist if it exists. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("tocplist-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } if (errorState) return Error(); else return Success(); } BoCA::DecoderAIFF::DecoderAIFF() { dataOffset = 0; } BoCA::DecoderAIFF::~DecoderAIFF() { } Bool BoCA::DecoderAIFF::Activate() { InStream in(STREAM_DRIVER, driver); in.Seek(12); String chunk; do { /* Read next chunk */ chunk = in.InputString(4); UnsignedInt32 cSize = in.InputNumberRaw(4); if (chunk != "SSND") { if (!in.RelSeek(cSize + cSize % 2)) return False; } } while (chunk != "SSND"); dataOffset = in.GetPos() + 8; driver->Seek(dataOffset); return True; } Bool BoCA::DecoderAIFF::Seek(Int64 samplePosition) { const Format &format = track.GetFormat(); driver->Seek(dataOffset + samplePosition * format.channels * (format.bits / 8)); return True; } Int BoCA::DecoderAIFF::ReadData(Buffer &data) { if (driver->GetPos() == driver->GetSize()) return -1; return driver->ReadData(data, data.Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/aiff/aiff.h000066400000000000000000000021261516712004000237420ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DecoderAIFF) namespace BoCA { class DecoderAIFF : public CS::DecoderComponent { private: Int dataOffset; public: static const String &GetComponentSpecs(); DecoderAIFF(); ~DecoderAIFF(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderAIFF) BoCA_END_COMPONENT(DecoderAIFF) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/000077500000000000000000000000001516712004000226565ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/Makefile000066400000000000000000000014721516712004000243220ustar00rootroot00000000000000########## BoCA component makefile ########## .NOTPARALLEL: # Change these variables to fit your project: TARGET = alac TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = dllinterface.o alac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)" -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -Wno-multichar # Enter additional library dependencies here: LIBS = alac/libalac.a # Enter addition commands for targets all and clean here: ALLCMD1 = $(call makein,alac) ALLCMD2 = CLEANCMD1 = $(call cleanin,alac) CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac.cpp000066400000000000000000000236721516712004000242740ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef __WIN32__ # define WIN32_LEAN_AND_MEAN #endif #include #include #include "alac.h" #include "alac/ALACBitUtilities.h" using namespace smooth::IO; const String &BoCA::DecoderALAC::GetComponentSpecs() { static String componentSpecs; if (mp4v2dll != NIL) { componentSpecs = " \ \ \ \ Apple Lossless Decoder \ 1.0 \ alac-dec \ decoder \ alac-decoder-dec \ ffmpeg-alac-dec \ \ Apple Lossless Files \ true \ m4a \ m4b \ mp4 \ MP4 Metadata \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_read(void *, void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, MP4IO_read, NIL, NIL }; }; Bool BoCA::DecoderALAC::CanOpenStream(const String &streamURI) { Bool isValidFile = False; InStream in(STREAM_FILE, streamURI, IS_READ); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) != 'ftyp') return False; MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4HaveTrackAtom(mp4File, mp4Track, "mdia.minf.stbl.stsd.alac") && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) isValidFile = True; ex_MP4Close(mp4File, 0); return isValidFile; } Error BoCA::DecoderALAC::GetStreamInfo(const String &streamURI, Track &track) { Format format = track.GetFormat(); InStream in(STREAM_FILE, streamURI, IS_READ); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) != 'ftyp') return Error(); track.fileSize = File(streamURI).GetFileSize(); track.length = -1; MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) { /* Get codec configuration. */ unsigned char *ascBuffer = NIL; unsigned int ascBufferSize = 0; ex_MP4GetTrackBytesProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.alac.alac.decoderConfig", (uint8_t **) &ascBuffer, (uint32_t *) &ascBufferSize); /* Work around a bug in MP4v2 that ignores the version * and flags bytes at the start of the alac atom. */ Int offset = 0; if (ascBufferSize == 28 || ascBufferSize == 52) offset = 4; /* Init decoder to get format info. */ if (decoder.Init(ascBuffer + offset, ascBufferSize - offset) == ALAC_noErr) { format.rate = decoder.mConfig.sampleRate; format.channels = decoder.mConfig.numChannels; track.length = ex_MP4GetTrackDuration(mp4File, mp4Track); format.bits = decoder.mConfig.bitDepth; } else { errorState = True; errorString = "Unsupported audio format"; } ex_MP4Free(ascBuffer); track.SetFormat(format); /* Read gapless information. */ Int delay = 0, padding = 0; Int64 length = 0; if (ReadGaplessInfo(mp4File, delay, padding, length) && delay == 0 && padding + length == Int64(ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track)) * decoder.mConfig.frameLength) { track.length = length; } } ex_MP4Close(mp4File, 0); /* Read MP4 metadata. */ if (!errorState) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } track.SetFormat(format); if (!errorState) return Success(); else return Error(); } BoCA::DecoderALAC::DecoderALAC() { mp4File = NIL; mp4Track = MP4_INVALID_TRACK_ID; sampleId = 1; skipSamples = 0; samplesLeft = 0; } BoCA::DecoderALAC::~DecoderALAC() { } Bool BoCA::DecoderALAC::Activate() { InStream in(STREAM_DRIVER, driver); mp4File = ex_MP4ReadCallbacks(&mp4Callbacks, driver); mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track == MP4_INVALID_TRACK_ID) { ex_MP4Close(mp4File, 0); return False; } samplesLeft = track.length; /* Get codec configuration. */ unsigned char *ascBuffer = NIL; unsigned int ascBufferSize = 0; ex_MP4GetTrackBytesProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.alac.alac.decoderConfig", (uint8_t **) &ascBuffer, (uint32_t *) &ascBufferSize); /* Work around a bug in MP4v2 that ignores the version * and flags bytes at the start of the alac atom. */ Int offset = 0; if (ascBufferSize == 28 || ascBufferSize == 52) offset = 4; /* Init decoder. */ if (decoder.Init(ascBuffer + offset, ascBufferSize - offset) != ALAC_noErr) errorState = True; ex_MP4Free(ascBuffer); return !errorState; } Bool BoCA::DecoderALAC::Deactivate() { /* Close MP4 file. */ ex_MP4Close(mp4File, 0); return True; } Bool BoCA::DecoderALAC::Seek(Int64 samplePosition) { MP4Timestamp time = Math::Round(Float(samplePosition) / track.GetFormat().rate * ex_MP4GetTrackTimeScale(mp4File, mp4Track)); sampleId = ex_MP4GetSampleIdFromTime(mp4File, mp4Track, time, true); skipSamples = time - ex_MP4GetSampleTime(mp4File, mp4Track, sampleId); samplesLeft = track.sampleOffset + track.length - samplePosition; return True; } Int BoCA::DecoderALAC::ReadData(Buffer &data) { const Format &format = track.GetFormat(); /* Read MP4 sample. * * Allocate 4 extra bytes for the buffer as the ALAC decoder always reads * 32 bits ahead, even at the end of the sample buffer. The extra bytes * prevent this from crossing page boundaries, causing access violations. */ unsigned int bufferSize = ex_MP4GetSampleSize(mp4File, mp4Track, sampleId); dataBuffer.Resize(bufferSize + 4); unsigned char *buffer = dataBuffer; if (!ex_MP4ReadSample(mp4File, mp4Track, sampleId++, (uint8_t **) &buffer, (uint32_t *) &bufferSize, NIL, NIL, NIL, NIL) || bufferSize == 0) return -1; /* Fill ALAC decoder bit buffer. */ BitBuffer bits; BitBufferInit(&bits, buffer, bufferSize); /* Prepare output buffer and decode samples. */ Int bytesPerSample = format.channels * (format.bits / 8); uint32_t samplesRead = 0; data.Resize(decoder.mConfig.frameLength * bytesPerSample); if (decoder.Decode(&bits, data, decoder.mConfig.frameLength, format.channels, &samplesRead) != ALAC_noErr) return -1; /* Adjust buffer for samples to skip. */ if (skipSamples > 0) { Int samplesToSkip = Math::Min(samplesRead, skipSamples); memcpy(data, data + samplesToSkip * bytesPerSample, (samplesRead - samplesToSkip) * bytesPerSample); data.Resize((samplesRead - samplesToSkip) * bytesPerSample); skipSamples -= samplesToSkip; } /* Cut data buffer on last frame. */ data.Resize(Math::Min(data.Size(), samplesLeft * bytesPerSample)); samplesLeft -= data.Size() / bytesPerSample; /* Change to default channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::AAC_3_0, Channel::Default_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::AAC_5_0, Channel::Default_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::AAC_5_1, Channel::Default_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::AAC_6_1, Channel::Default_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::AAC_7_1, Channel::Default_7_1); return data.Size(); } Bool BoCA::DecoderALAC::ReadGaplessInfo(MP4FileHandle mp4File, Int &delay, Int &padding, Int64 &length) const { Bool result = False; /* Look for iTunes metadata with gapless information. */ MP4ItmfItemList *items = ex_MP4ItmfGetItemsByMeaning(mp4File, "com.apple.iTunes", "iTunSMPB"); if (items != NIL) { if (items->size == 1) { /* Read value as string. */ Buffer value(items->elements[0].dataList.elements[0].valueSize + 1); memset(value, 0, items->elements[0].dataList.elements[0].valueSize + 1); memcpy(value, items->elements[0].dataList.elements[0].value, items->elements[0].dataList.elements[0].valueSize); /* Parse value string. */ const Array &values = String(value).Trim().Explode(" "); delay = (Int64) Number::FromHexString(values.GetNth(1)); padding = (Int64) Number::FromHexString(values.GetNth(2)); length = (Int64) Number::FromHexString(values.GetNth(3)); result = True; } ex_MP4ItmfItemListFree(items); } return result; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_read(void *handle, void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->ReadData((UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac.h000066400000000000000000000026551516712004000237370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" #include "alac/ALACDecoder.h" BoCA_BEGIN_COMPONENT(DecoderALAC) namespace BoCA { class DecoderALAC : public CS::DecoderComponent { private: MP4FileHandle mp4File; ALACDecoder decoder; MP4TrackId mp4Track; MP4SampleId sampleId; UnsignedInt skipSamples; UnsignedInt64 samplesLeft; Buffer dataBuffer; Bool ReadGaplessInfo(MP4FileHandle, Int &, Int &, Int64 &) const; public: static const String &GetComponentSpecs(); DecoderALAC(); ~DecoderALAC(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderALAC) BoCA_END_COMPONENT(DecoderALAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/000077500000000000000000000000001516712004000235565ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ALACAudioTypes.h000066400000000000000000000125001516712004000264340ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: ALACAudioTypes.h */ #ifndef ALACAUDIOTYPES_H #define ALACAUDIOTYPES_H #if PRAGMA_ONCE #pragma once #endif #ifdef __cplusplus extern "C" { #endif #if PRAGMA_STRUCT_ALIGN #pragma options align=mac68k #elif PRAGMA_STRUCT_PACKPUSH #pragma pack(push, 2) #elif PRAGMA_STRUCT_PACK #pragma pack(2) #endif #include #if defined(__ppc__) #define TARGET_RT_BIG_ENDIAN 1 #elif defined(__ppc64__) #define TARGET_RT_BIG_ENDIAN 1 #endif #define kChannelAtomSize 12 enum { kALAC_UnimplementedError = -4, kALAC_FileNotFoundError = -43, kALAC_ParamError = -50, kALAC_MemFullError = -108 }; enum { kALACFormatAppleLossless = 'alac', kALACFormatLinearPCM = 'lpcm' }; enum { kALACMaxChannels = 8, kALACMaxEscapeHeaderBytes = 8, kALACMaxSearches = 16, kALACMaxCoefs = 16, kALACDefaultFramesPerPacket = 4096 }; typedef uint32_t ALACChannelLayoutTag; enum { kALACFormatFlagIsFloat = (1 << 0), // 0x1 kALACFormatFlagIsBigEndian = (1 << 1), // 0x2 kALACFormatFlagIsSignedInteger = (1 << 2), // 0x4 kALACFormatFlagIsPacked = (1 << 3), // 0x8 kALACFormatFlagIsAlignedHigh = (1 << 4), // 0x10 }; enum { #if TARGET_RT_BIG_ENDIAN kALACFormatFlagsNativeEndian = kALACFormatFlagIsBigEndian #else kALACFormatFlagsNativeEndian = 0 #endif }; // this is required to be an IEEE 64bit float typedef double alac_float64_t; // These are the Channel Layout Tags used in the Channel Layout Info portion of the ALAC magic cookie enum { kALACChannelLayoutTag_Mono = (100<<16) | 1, // C kALACChannelLayoutTag_Stereo = (101<<16) | 2, // L R kALACChannelLayoutTag_MPEG_3_0_B = (113<<16) | 3, // C L R kALACChannelLayoutTag_MPEG_4_0_B = (116<<16) | 4, // C L R Cs kALACChannelLayoutTag_MPEG_5_0_D = (120<<16) | 5, // C L R Ls Rs kALACChannelLayoutTag_MPEG_5_1_D = (124<<16) | 6, // C L R Ls Rs LFE kALACChannelLayoutTag_AAC_6_1 = (142<<16) | 7, // C L R Ls Rs Cs LFE kALACChannelLayoutTag_MPEG_7_1_B = (127<<16) | 8 // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC) }; // ALAC currently only utilizes these channels layouts. There is a one for one correspondance between a // given number of channels and one of these layout tags static const ALACChannelLayoutTag ALACChannelLayoutTags[kALACMaxChannels] = { kALACChannelLayoutTag_Mono, // C kALACChannelLayoutTag_Stereo, // L R kALACChannelLayoutTag_MPEG_3_0_B, // C L R kALACChannelLayoutTag_MPEG_4_0_B, // C L R Cs kALACChannelLayoutTag_MPEG_5_0_D, // C L R Ls Rs kALACChannelLayoutTag_MPEG_5_1_D, // C L R Ls Rs LFE kALACChannelLayoutTag_AAC_6_1, // C L R Ls Rs Cs LFE kALACChannelLayoutTag_MPEG_7_1_B // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC) }; // AudioChannelLayout from CoreAudioTypes.h. We never need the AudioChannelDescription so we remove it struct ALACAudioChannelLayout { ALACChannelLayoutTag mChannelLayoutTag; uint32_t mChannelBitmap; uint32_t mNumberChannelDescriptions; }; typedef struct ALACAudioChannelLayout ALACAudioChannelLayout; struct AudioFormatDescription { alac_float64_t mSampleRate; uint32_t mFormatID; uint32_t mFormatFlags; uint32_t mBytesPerPacket; uint32_t mFramesPerPacket; uint32_t mBytesPerFrame; uint32_t mChannelsPerFrame; uint32_t mBitsPerChannel; uint32_t mReserved; }; typedef struct AudioFormatDescription AudioFormatDescription; /* Lossless Definitions */ enum { kALACCodecFormat = 'alac', kALACVersion = 0, kALACCompatibleVersion = kALACVersion, kALACDefaultFrameSize = 4096 }; // note: this struct is wrapped in an 'alac' atom in the sample description extension area // note: in QT movies, it will be further wrapped in a 'wave' atom surrounded by 'frma' and 'term' atoms typedef struct ALACSpecificConfig { uint32_t frameLength; uint8_t compatibleVersion; uint8_t bitDepth; // max 32 uint8_t pb; // 0 <= pb <= 255 uint8_t mb; uint8_t kb; uint8_t numChannels; uint16_t maxRun; uint32_t maxFrameBytes; uint32_t avgBitRate; uint32_t sampleRate; } ALACSpecificConfig; // The AudioChannelLayout atom type is not exposed yet so define it here enum { AudioChannelLayoutAID = 'chan' }; #if PRAGMA_STRUCT_ALIGN #pragma options align=reset #elif PRAGMA_STRUCT_PACKPUSH #pragma pack(pop) #elif PRAGMA_STRUCT_PACK #pragma pack() #endif #ifdef __cplusplus } #endif #endif /* ALACAUDIOTYPES_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ALACBitUtilities.c000066400000000000000000000131551516712004000267620ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * Portions Copyright (c) 2011-2015 Peter Pawlowski. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /*============================================================================= File: ALACBitUtilities.c $NoKeywords: $ =============================================================================*/ #include #include "ALACBitUtilities.h" // BitBufferInit // void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize ) { bits->cur = buffer; bits->end = bits->cur + byteSize; bits->bitIndex = 0; bits->byteSize = byteSize; } // BitBufferRemaining // uint32_t BitBufferRemaining( BitBuffer * bits ) { return (uint32_t)(bits->end - bits->cur) * 8 - bits->bitIndex; } // BitBufferRead // uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ) { uint32_t returnBits; //Assert( numBits <= 16 ); returnBits = ((uint32_t)bits->cur[0] << 16) | ((uint32_t)bits->cur[1] << 8) | ((uint32_t)bits->cur[2]); returnBits = returnBits << bits->bitIndex; returnBits &= 0x00FFFFFF; bits->bitIndex += numBits; returnBits = returnBits >> (24 - numBits); bits->cur += (bits->bitIndex >> 3); bits->bitIndex &= 7; //Assert( bits->cur <= bits->end ); return returnBits; } // BitBufferReadSmall // // Reads up to 8 bits uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits ) { uint16_t returnBits; //Assert( numBits <= 8 ); returnBits = (bits->cur[0] << 8) | bits->cur[1]; returnBits = returnBits << bits->bitIndex; bits->bitIndex += numBits; returnBits = returnBits >> (16 - numBits); bits->cur += (bits->bitIndex >> 3); bits->bitIndex &= 7; //Assert( bits->cur <= bits->end ); return (uint8_t)returnBits; } // BitBufferReadOne // // Reads one byte uint8_t BitBufferReadOne( BitBuffer * bits ) { uint8_t returnBits; returnBits = (bits->cur[0] >> (7 - bits->bitIndex)) & 1; bits->bitIndex++; bits->cur += (bits->bitIndex >> 3); bits->bitIndex &= 7; //Assert( bits->cur <= bits->end ); return returnBits; } // BitBufferPeek // uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits ) { return ((((((uint32_t) bits->cur[0] << 16) | ((uint32_t) bits->cur[1] << 8) | ((uint32_t) bits->cur[2])) << bits->bitIndex) & 0x00FFFFFF) >> (24 - numBits)); } // BitBufferPeekOne // uint32_t BitBufferPeekOne( BitBuffer * bits ) { return ((bits->cur[0] >> (7 - bits->bitIndex)) & 1); } // BitBufferUnpackBERSize // uint32_t BitBufferUnpackBERSize( BitBuffer * bits ) { uint32_t size; uint8_t tmp; for ( size = 0, tmp = 0x80u; tmp &= 0x80u; size = (size << 7u) | (tmp & 0x7fu) ) tmp = (uint8_t) BitBufferReadSmall( bits, 8 ); return size; } // BitBufferGetPosition // uint32_t BitBufferGetPosition( BitBuffer * bits ) { uint8_t * begin; begin = bits->end - bits->byteSize; return ((uint32_t)(bits->cur - begin) * 8) + bits->bitIndex; } // BitBufferByteAlign // void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros ) { // align bit buffer to next byte boundary, writing zeros if requested if ( bits->bitIndex == 0 ) return; if ( addZeros ) BitBufferWrite( bits, 0, 8 - bits->bitIndex ); else BitBufferAdvance( bits, 8 - bits->bitIndex ); } // BitBufferAdvance // void BitBufferAdvance( BitBuffer * bits, uint32_t numBits ) { if ( numBits ) { bits->bitIndex += numBits; bits->cur += (bits->bitIndex >> 3); bits->bitIndex &= 7; } } // BitBufferRewind // void BitBufferRewind( BitBuffer * bits, uint32_t numBits ) { uint32_t numBytes; if ( numBits == 0 ) return; if ( bits->bitIndex >= numBits ) { bits->bitIndex -= numBits; return; } numBits -= bits->bitIndex; bits->bitIndex = 0; numBytes = numBits / 8; numBits = numBits % 8; bits->cur -= numBytes; if ( numBits > 0 ) { bits->bitIndex = 8 - numBits; bits->cur--; } if ( bits->cur < (bits->end - bits->byteSize) ) { //DebugCMsg("BitBufferRewind: Rewound too far."); bits->cur = (bits->end - bits->byteSize); bits->bitIndex = 0; } } // BitBufferWrite // void BitBufferWrite( BitBuffer * bits, uint32_t bitValues, uint32_t numBits ) { uint32_t invBitIndex; RequireAction( bits != nil, return; ); RequireActionSilent( numBits > 0, return; ); invBitIndex = 8 - bits->bitIndex; while ( numBits > 0 ) { uint32_t tmp; uint8_t shift; uint8_t mask; uint32_t curNum; curNum = MIN( invBitIndex, numBits ); tmp = bitValues >> (numBits - curNum); shift = (uint8_t)(invBitIndex - curNum); mask = 0xffu >> (8 - curNum); // must be done in two steps to avoid compiler sequencing ambiguity mask <<= shift; bits->cur[0] = (bits->cur[0] & ~mask) | (((uint8_t) tmp << shift) & mask); numBits -= curNum; // increment to next byte if need be invBitIndex -= curNum; if ( invBitIndex == 0 ) { invBitIndex = 8; bits->cur++; } } bits->bitIndex = 8 - invBitIndex; } void BitBufferReset( BitBuffer * bits ) //void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize ) { bits->cur = bits->end - bits->byteSize; bits->bitIndex = 0; } #if PRAGMA_MARK #pragma mark - #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ALACBitUtilities.h000066400000000000000000000060421516712004000267640ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * Portions Copyright (c) 2011-2015 Peter Pawlowski. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /*============================================================================= File: ALACBitUtilities.h $NoKeywords: $ =============================================================================*/ #ifndef __ALACBITUTILITIES_H #define __ALACBITUTILITIES_H #include #ifndef MIN #define MIN(x, y) ( (x)<(y) ?(x) :(y) ) #endif //MIN #ifndef MAX #define MAX(x, y) ( (x)>(y) ?(x): (y) ) #endif //MAX #ifndef nil #define nil NULL #endif #define RequireAction(condition, action) if (!(condition)) { action } #define RequireActionSilent(condition, action) if (!(condition)) { action } #define RequireNoErr(condition, action) if ((condition)) { action } #ifdef __cplusplus extern "C" { #endif enum { ALAC_noErr = 0 }; typedef enum { ID_SCE = 0, /* Single Channel Element */ ID_CPE = 1, /* Channel Pair Element */ ID_CCE = 2, /* Coupling Channel Element */ ID_LFE = 3, /* LFE Channel Element */ ID_DSE = 4, /* not yet supported */ ID_PCE = 5, ID_FIL = 6, ID_END = 7 } CHANNEL_ELEMENT_TYPE; // types typedef struct BitBuffer { uint8_t * cur; uint8_t * end; uint32_t bitIndex; uint32_t byteSize; } BitBuffer; /* BitBuffer routines - these routines take a fixed size buffer and read/write to it - bounds checking must be done by the client */ void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize ); uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time uint32_t BitBufferRemaining( BitBuffer * bits ); uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits ); uint8_t BitBufferReadOne( BitBuffer * bits ); uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time uint32_t BitBufferPeekOne( BitBuffer * bits ); uint32_t BitBufferUnpackBERSize( BitBuffer * bits ); uint32_t BitBufferGetPosition( BitBuffer * bits ); void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros ); void BitBufferAdvance( BitBuffer * bits, uint32_t numBits ); void BitBufferRewind( BitBuffer * bits, uint32_t numBits ); void BitBufferWrite( BitBuffer * bits, uint32_t value, uint32_t numBits ); void BitBufferReset( BitBuffer * bits); #ifdef __cplusplus } #endif #endif /* __BITUTILITIES_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ALACDecoder.cpp000066400000000000000000000545451516712004000262650ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * Portions Copyright (c) 2011 Peter Pawlowski. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: ALACDecoder.cpp */ #include #include #include "ALACDecoder.h" #include "dplib.h" #include "aglib.h" #include "matrixlib.h" #include "ALACBitUtilities.h" #include "EndianPortable.h" // constants/data const uint32_t kMinBitDepth = 16; // min allowed bit depth is 16 const uint32_t kMaxBitDepth = 32; // max allowed bit depth is 32 // prototypes static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride ); static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride ); static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride ); /* Constructor */ ALACDecoder::ALACDecoder() : mActiveElements( 0 ), mMixBufferU( nil ), mMixBufferV( nil ), mPredictor( nil ), mShiftBuffer( nil ) { memset( &mConfig, 0, sizeof(mConfig) ); } /* Destructor */ ALACDecoder::~ALACDecoder() { // delete the matrix mixing buffers free(mMixBufferU); free(mMixBufferV); // delete the dynamic predictor's "corrector" buffer // - note: mShiftBuffer shares memory with this buffer free(mPredictor); } /* Init() - initialize the decoder with the given configuration */ int32_t ALACDecoder::Init( void * inMagicCookie, uint32_t inMagicCookieSize ) { ALACSpecificConfig theConfig; uint8_t * theActualCookie = (uint8_t *)inMagicCookie; uint32_t theCookieBytesRemaining = inMagicCookieSize; // For historical reasons the decoder needs to be resilient to magic cookies vended by older encoders. // As specified in the ALACMagicCookieDescription.txt document, there may be additional data encapsulating // the ALACSpecificConfig. This would consist of format ('frma') and 'alac' atoms which precede the // ALACSpecificConfig. // See ALACMagicCookieDescription.txt for additional documentation concerning the 'magic cookie' if (theCookieBytesRemaining < 12) return kALAC_ParamError; // skip format ('frma') atom if present if (theActualCookie[4] == 'f' && theActualCookie[5] == 'r' && theActualCookie[6] == 'm' && theActualCookie[7] == 'a') { theActualCookie += 12; theCookieBytesRemaining -= 12; } if (theCookieBytesRemaining < 12) return kALAC_ParamError; // skip 'alac' atom header if present if (theActualCookie[4] == 'a' && theActualCookie[5] == 'l' && theActualCookie[6] == 'a' && theActualCookie[7] == 'c') { theActualCookie += 12; theCookieBytesRemaining -= 12; } // read the ALACSpecificConfig if (theCookieBytesRemaining < sizeof(ALACSpecificConfig)) return kALAC_ParamError; theConfig.frameLength = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->frameLength); // frame length is 4096 by default, some claim 16384 is max allowed by standard decoders // fail early with nonsensical values, don't allocate extreme amounts of memory if (theConfig.frameLength == 0 || theConfig.frameLength > 1024 * 1024) return kALAC_ParamError; theConfig.compatibleVersion = ((ALACSpecificConfig *)theActualCookie)->compatibleVersion; theConfig.bitDepth = ((ALACSpecificConfig *)theActualCookie)->bitDepth; if (theConfig.bitDepth < kMinBitDepth || theConfig.bitDepth > kMaxBitDepth) return kALAC_ParamError; theConfig.pb = ((ALACSpecificConfig *)theActualCookie)->pb; theConfig.mb = ((ALACSpecificConfig *)theActualCookie)->mb; theConfig.kb = ((ALACSpecificConfig *)theActualCookie)->kb; theConfig.numChannels = ((ALACSpecificConfig *)theActualCookie)->numChannels; theConfig.maxRun = Swap16BtoN(((ALACSpecificConfig *)theActualCookie)->maxRun); theConfig.maxFrameBytes = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->maxFrameBytes); theConfig.avgBitRate = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->avgBitRate); theConfig.sampleRate = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->sampleRate); mConfig = theConfig; RequireAction( mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError; ); // allocate mix buffers mMixBufferU = (int32_t *) calloc( mConfig.frameLength, sizeof(int32_t) ); mMixBufferV = (int32_t *) calloc( mConfig.frameLength, sizeof(int32_t) ); // allocate dynamic predictor buffer mPredictor = (int32_t *) calloc( mConfig.frameLength, sizeof(int32_t) ); // "shift off" buffer shares memory with predictor buffer mShiftBuffer = (uint16_t *) mPredictor; RequireAction( (mMixBufferU != nil) && (mMixBufferV != nil) && (mPredictor != nil), return kALAC_MemFullError; ); // channel bookkeeping if (mConfig.numChannels < 1 || mConfig.numChannels > kALACMaxChannels) return kALAC_MemFullError; // skip to Channel Layout Info // theActualCookie += sizeof(ALACSpecificConfig); // Currently, the Channel Layout Info portion of the magic cookie (as defined in the // ALACMagicCookieDescription.txt document) is unused by the decoder. return ALAC_noErr; } /* Decode() - the decoded samples are interleaved into the output buffer in the order they arrive in the bitstream */ int32_t ALACDecoder::Decode( BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples ) { BitBuffer shiftBits; uint32_t bits1, bits2; uint8_t tag; uint8_t elementInstanceTag; AGParamRec agParams; uint32_t channelIndex; int16_t coefsU[32]; // max possible size is 32 although NUMCOEPAIRS is the current limit int16_t coefsV[32]; uint8_t numU, numV; uint8_t mixBits; int8_t mixRes; uint16_t unusedHeader; uint8_t escapeFlag; uint32_t chanBits; uint8_t bytesShifted; uint32_t shift; uint8_t modeU, modeV; uint32_t denShiftU, denShiftV; uint16_t pbFactorU, pbFactorV; uint16_t pb; int16_t * out16; uint8_t * out20; uint8_t * out24; int32_t * out32; uint8_t headerByte; uint8_t partialFrame; uint32_t extraBits; int32_t val; uint32_t i, j; int32_t status; RequireAction( (bits != nil) && (sampleBuffer != nil) && (outNumSamples != nil), return kALAC_ParamError; ); RequireAction( numChannels > 0, return kALAC_ParamError; ); mActiveElements = 0; channelIndex = 0; status = ALAC_noErr; *outNumSamples = numSamples; while ( status == ALAC_noErr ) { // bail if we ran off the end of the buffer RequireAction( bits->cur < bits->end, status = kALAC_ParamError; goto Exit; ); // copy global decode params for this element pb = mConfig.pb; // read element tag tag = BitBufferReadSmall( bits, 3 ); switch ( tag ) { case ID_SCE: case ID_LFE: { // mono/LFE channel if ( (channelIndex + 1) > numChannels ) goto NoMoreChannels; elementInstanceTag = BitBufferReadSmall( bits, 4 ); mActiveElements |= (1u << elementInstanceTag); // read the 12 unused header bits unusedHeader = (uint16_t) BitBufferRead( bits, 12 ); RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; ); // read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag headerByte = (uint8_t) BitBufferRead( bits, 4 ); partialFrame = headerByte >> 3; bytesShifted = (headerByte >> 1) & 0x3u; RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; ); shift = bytesShifted * 8; escapeFlag = headerByte & 0x1; chanBits = mConfig.bitDepth - (bytesShifted * 8); // check for partial frame to override requested numSamples if ( partialFrame != 0 ) { uint32_t numPartial; numPartial = BitBufferRead( bits, 16 ) << 16; numPartial |= BitBufferRead( bits, 16 ); RequireAction( numPartial <= numSamples, status = kALAC_ParamError; goto Exit; ); numSamples = numPartial; } if ( escapeFlag == 0 ) { // compressed frame, read rest of parameters mixBits = (uint8_t) BitBufferRead( bits, 8 ); mixRes = (int8_t) BitBufferRead( bits, 8 ); //Assert( (mixBits == 0) && (mixRes == 0) ); // no mixing for mono headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeU = headerByte >> 4; denShiftU = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorU = headerByte >> 5; numU = headerByte & 0x1fu; for ( i = 0; i < numU; i++ ) coefsU[i] = (int16_t) BitBufferRead( bits, 16 ); // if shift active, skip the the shift buffer but remember where it starts if ( bytesShifted != 0 ) { shiftBits = *bits; BitBufferAdvance( bits, (bytesShifted * 8) * numSamples ); } // decompress set_ag_params( &agParams, mConfig.mb, (pb * pbFactorU) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits1 ); RequireNoErr( status, goto Exit; ); if ( modeU == 0 ) { unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } } else { //Assert( bytesShifted == 0 ); // uncompressed frame, copy data into the mix buffer to use common output code shift = 32 - chanBits; RequireAction(BitBufferRemaining(bits) >= chanBits * numSamples, status = kALAC_ParamError; goto Exit; ); if ( chanBits <= 16 ) { for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferU[i] = val; } } else { // BitBufferRead() can't read more than 16 bits at a time so break up the reads extraBits = chanBits - 16; for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t) extraBits ); } } mixBits = mixRes = 0; bits1 = chanBits * numSamples; bytesShifted = 0; } // now read the shifted values into the shift buffer if ( bytesShifted != 0 ) { shift = bytesShifted * 8; //Assert( shift <= 16 ); for ( i = 0; i < numSamples; i++ ) mShiftBuffer[i] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); } // convert 32-bit integers into output buffer switch ( mConfig.bitDepth ) { case 16: out16 = &((int16_t *)sampleBuffer)[channelIndex]; for ( i = 0, j = 0; i < numSamples; i++, j += numChannels ) out16[j] = (int16_t) mMixBufferU[i]; break; case 20: out20 = (uint8_t *)sampleBuffer + (channelIndex * 3); copyPredictorTo20( mMixBufferU, out20, numChannels, numSamples ); break; case 24: out24 = (uint8_t *)sampleBuffer + (channelIndex * 3); if ( bytesShifted != 0 ) copyPredictorTo24Shift( mMixBufferU, mShiftBuffer, out24, numChannels, numSamples, bytesShifted ); else copyPredictorTo24( mMixBufferU, out24, numChannels, numSamples ); break; case 32: out32 = &((int32_t *)sampleBuffer)[channelIndex]; if ( bytesShifted != 0 ) copyPredictorTo32Shift( mMixBufferU, mShiftBuffer, out32, numChannels, numSamples, bytesShifted ); else copyPredictorTo32( mMixBufferU, out32, numChannels, numSamples); break; } channelIndex += 1; *outNumSamples = numSamples; break; } case ID_CPE: { // if decoding this pair would take us over the max channels limit, bail if ( (channelIndex + 2) > numChannels ) goto NoMoreChannels; // stereo channel pair elementInstanceTag = BitBufferReadSmall( bits, 4 ); mActiveElements |= (1u << elementInstanceTag); // read the 12 unused header bits unusedHeader = (uint16_t) BitBufferRead( bits, 12 ); RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; ); // read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag headerByte = (uint8_t) BitBufferRead( bits, 4 ); partialFrame = headerByte >> 3; bytesShifted = (headerByte >> 1) & 0x3u; RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; ); shift = bytesShifted * 8; escapeFlag = headerByte & 0x1; chanBits = mConfig.bitDepth - (bytesShifted * 8) + 1; // check for partial frame length to override requested numSamples if ( partialFrame != 0 ) { uint32_t numPartial; numPartial = BitBufferRead( bits, 16 ) << 16; numPartial |= BitBufferRead( bits, 16 ); RequireAction( numPartial <= numSamples, status = kALAC_ParamError; goto Exit; ); numSamples = numPartial; } if ( escapeFlag == 0 ) { // compressed frame, read rest of parameters mixBits = (uint8_t) BitBufferRead( bits, 8 ); mixRes = (int8_t) BitBufferRead( bits, 8 ); headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeU = headerByte >> 4; denShiftU = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorU = headerByte >> 5; numU = headerByte & 0x1fu; for ( i = 0; i < numU; i++ ) coefsU[i] = (int16_t) BitBufferRead( bits, 16 ); headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeV = headerByte >> 4; denShiftV = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorV = headerByte >> 5; numV = headerByte & 0x1fu; for ( i = 0; i < numV; i++ ) coefsV[i] = (int16_t) BitBufferRead( bits, 16 ); // if shift active, skip the interleaved shifted values but remember where they start if ( bytesShifted != 0 ) { shiftBits = *bits; BitBufferAdvance( bits, (bytesShifted * 8) * 2 * numSamples ); } // decompress and run predictor for "left" channel set_ag_params( &agParams, mConfig.mb, (pb * pbFactorU) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits1 ); RequireNoErr( status, goto Exit; ); if ( modeU == 0 ) { unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } // decompress and run predictor for "right" channel set_ag_params( &agParams, mConfig.mb, (pb * pbFactorV) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits2 ); RequireNoErr( status, goto Exit; ); if ( modeV == 0 ) { unpc_block( mPredictor, mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV ); } } else { //Assert( bytesShifted == 0 ); // uncompressed frame, copy data into the mix buffers to use common output code chanBits = mConfig.bitDepth; shift = 32 - chanBits; RequireAction(BitBufferRemaining(bits) >= 2 * chanBits * numSamples, status = kALAC_ParamError; goto Exit; ); if ( chanBits <= 16 ) { for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferU[i] = val; val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferV[i] = val; } } else { // BitBufferRead() can't read more than 16 bits at a time so break up the reads extraBits = chanBits - 16; for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t)extraBits ); val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferV[i] = val | BitBufferRead( bits, (uint8_t)extraBits ); } } bits1 = chanBits * numSamples; bits2 = chanBits * numSamples; mixBits = mixRes = 0; bytesShifted = 0; } // now read the shifted values into the shift buffer if ( bytesShifted != 0 ) { shift = bytesShifted * 8; //Assert( shift <= 16 ); for ( i = 0; i < (numSamples * 2); i += 2 ) { mShiftBuffer[i + 0] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); mShiftBuffer[i + 1] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); } } // un-mix the data and convert to output format // - note that mixRes = 0 means just interleave so we use that path for uncompressed frames switch ( mConfig.bitDepth ) { case 16: out16 = &((int16_t *)sampleBuffer)[channelIndex]; unmix16( mMixBufferU, mMixBufferV, out16, numChannels, numSamples, mixBits, mixRes ); break; case 20: out20 = (uint8_t *)sampleBuffer + (channelIndex * 3); unmix20( mMixBufferU, mMixBufferV, out20, numChannels, numSamples, mixBits, mixRes ); break; case 24: out24 = (uint8_t *)sampleBuffer + (channelIndex * 3); unmix24( mMixBufferU, mMixBufferV, out24, numChannels, numSamples, mixBits, mixRes, mShiftBuffer, bytesShifted ); break; case 32: out32 = &((int32_t *)sampleBuffer)[channelIndex]; unmix32( mMixBufferU, mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes, mShiftBuffer, bytesShifted ); break; } channelIndex += 2; *outNumSamples = numSamples; break; } case ID_CCE: case ID_PCE: { // unsupported element, bail //AssertNoErr( tag ); status = kALAC_ParamError; break; } case ID_DSE: { // data stream element -- parse but ignore status = this->DataStreamElement( bits ); break; } case ID_FIL: { // fill element -- parse but ignore status = this->FillElement( bits ); break; } case ID_END: { // frame end, all done so byte align the frame and check for overruns BitBufferByteAlign( bits, false ); //Assert( bits->cur == bits->end ); goto Exit; } } #if ! DEBUG // if we've decoded all of our channels, bail (but not in debug b/c we want to know if we're seeing bad bits) // - this also protects us if the config does not match the bitstream or crap data bits follow the audio bits if ( channelIndex >= numChannels ) break; #endif } NoMoreChannels: // if we get here and haven't decoded all of the requested channels, fill the remaining channels with zeros for ( ; channelIndex < numChannels; channelIndex++ ) { switch ( mConfig.bitDepth ) { case 16: { int16_t * fill16 = &((int16_t *)sampleBuffer)[channelIndex]; Zero16( fill16, numSamples, numChannels ); break; } case 20: case 24: { uint8_t * fill24 = (uint8_t *)sampleBuffer + (channelIndex * 3); Zero24( fill24, numSamples, numChannels ); break; } case 32: { int32_t * fill32 = &((int32_t *)sampleBuffer)[channelIndex]; Zero32( fill32, numSamples, numChannels ); break; } } } Exit: return status; } #if PRAGMA_MARK #pragma mark - #endif /* FillElement() - they're just filler so we don't need 'em */ int32_t ALACDecoder::FillElement( BitBuffer * bits ) { int16_t count; // 4-bit count or (4-bit + 8-bit count) if 4-bit count == 15 // - plus this weird -1 thing I still don't fully understand count = BitBufferReadSmall( bits, 4 ); if ( count == 15 ) count += (int16_t) BitBufferReadSmall( bits, 8 ) - 1; BitBufferAdvance( bits, count * 8 ); RequireAction( bits->cur <= bits->end, return kALAC_ParamError; ); return ALAC_noErr; } /* DataStreamElement() - we don't care about data stream elements so just skip them */ int32_t ALACDecoder::DataStreamElement( BitBuffer * bits ) { uint8_t element_instance_tag; int32_t data_byte_align_flag; uint16_t count; // the tag associates this data stream element with a given audio element element_instance_tag = BitBufferReadSmall( bits, 4 ); data_byte_align_flag = BitBufferReadOne( bits ); // 8-bit count or (8-bit + 8-bit count) if 8-bit count == 255 count = BitBufferReadSmall( bits, 8 ); if ( count == 255 ) count += BitBufferReadSmall( bits, 8 ); // the align flag means the bitstream should be byte-aligned before reading the following data bytes if ( data_byte_align_flag ) BitBufferByteAlign( bits, false ); // skip the data bytes BitBufferAdvance( bits, count * 8 ); RequireAction( bits->cur <= bits->end, return kALAC_ParamError; ); return ALAC_noErr; } /* ZeroN() - helper routines to clear out output channel buffers when decoding fewer channels than requested */ static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * sizeof(int16_t) ); } else { for ( uint32_t index = 0; index < (numItems * stride); index += stride ) buffer[index] = 0; } } static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * 3 ); } else { for ( uint32_t index = 0; index < (numItems * stride * 3); index += (stride * 3) ) { buffer[index + 0] = 0; buffer[index + 1] = 0; buffer[index + 2] = 0; } } } static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * sizeof(int32_t) ); } else { for ( uint32_t index = 0; index < (numItems * stride); index += stride ) buffer[index] = 0; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ALACDecoder.h000066400000000000000000000032361516712004000257210ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: ALACDecoder.h */ #ifndef _ALACDECODER_H #define _ALACDECODER_H #if PRAGMA_ONCE #pragma once #endif #include #include "ALACAudioTypes.h" struct BitBuffer; class ALACDecoder { public: ALACDecoder(); ~ALACDecoder(); int32_t Init( void * inMagicCookie, uint32_t inMagicCookieSize ); int32_t Decode( struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples ); public: // decoding parameters (public for use in the analyzer) ALACSpecificConfig mConfig; protected: int32_t FillElement( struct BitBuffer * bits ); int32_t DataStreamElement( struct BitBuffer * bits ); uint16_t mActiveElements; // decoding buffers int32_t * mMixBufferU; int32_t * mMixBufferV; int32_t * mPredictor; uint16_t * mShiftBuffer; // note: this points to mPredictor's memory but different // variable for clarity and type difference }; #endif /* _ALACDECODER_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/APPLE_LICENSE.txt000066400000000000000000000472141516712004000263320ustar00rootroot00000000000000APPLE PUBLIC SOURCE LICENSE Version 2.0 - August 6, 2003 Please read this License carefully before downloading this software. By downloading or using this software, you are agreeing to be bound by the terms of this License. If you do not or cannot agree to the terms of this License, please do not download or use the software. Apple Note: In January 2007, Apple changed its corporate name from "Apple Computer, Inc." to "Apple Inc." This change has been reflected below and copyright years updated, but no other changes have been made to the APSL 2.0. 1. General; Definitions. This License applies to any program or other work which Apple Inc. ("Apple") makes publicly available and which contains a notice placed by Apple identifying such program or work as "Original Code" and stating that it is subject to the terms of this Apple Public Source License version 2.0 ("License"). As used in this License: 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to Apple and (ii) that cover subject matter contained in the Original Code, but only to the extent necessary to use, reproduce and/or distribute the Original Code without infringement; and (b) in the case where You are the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to You and (ii) that cover subject matter in Your Modifications, taken alone or in combination with Original Code. 1.2 "Contributor" means any person or entity that creates or contributes to the creation of Modifications. 1.3 "Covered Code" means the Original Code, Modifications, the combination of Original Code and any Modifications, and/or any respective portions thereof. 1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise make Covered Code available, directly or indirectly, to anyone other than You; and/or (b) to use Covered Code, alone or as part of a Larger Work, in any way to provide a service, including but not limited to delivery of content, through electronic communication with a client other than You. 1.5 "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.6 "Modifications" mean any addition to, deletion from, and/or change to, the substance and/or structure of the Original Code, any previous Modifications, the combination of Original Code and any previous Modifications, and/or any respective portions thereof. When code is released as a series of files, a Modification is: (a) any addition to or deletion from the contents of a file containing Covered Code; and/or (b) any new file or other representation of computer program statements that contains any part of Covered Code. 1.7 "Original Code" means (a) the Source Code of a program or other work as originally made available by Apple under this License, including the Source Code of any updates or upgrades to such programs or works made available by Apple under this License, and that has been expressly identified by Apple as such in the header file(s) of such work; and (b) the object code compiled from such Source Code and originally made available by Apple under this License 1.8 "Source Code" means the human readable form of a program or other work that is suitable for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an executable (object code). 1.9 "You" or "Your" means an individual or a legal entity exercising rights under this License. For legal entities, "You" or "Your" includes any entity which controls, is controlled by, or is under common control with, You, where "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity. 2. Permitted Uses; Conditions & Restrictions. Subject to the terms and conditions of this License, Apple hereby grants You, effective on the date You accept this License and download the Original Code, a world-wide, royalty-free, non-exclusive license, to the extent of Apple's Applicable Patent Rights and copyrights covering the Original Code, to do the following: 2.1 Unmodified Code. You may use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy verbatim, unmodified copies of the Original Code, for commercial or non-commercial purposes, provided that in each instance: (a) You must retain and reproduce in all copies of Original Code the copyright and other proprietary notices and disclaimers of Apple as they appear in the Original Code, and keep intact all notices in the Original Code that refer to this License; and (b) You must include a copy of this License with every copy of Source Code of Covered Code and documentation You distribute or Externally Deploy, and You may not offer or impose any terms on such Source Code that alter or restrict this License or the recipients' rights hereunder, except as permitted under Section 6. 2.2 Modified Code. You may modify Covered Code and use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy Your Modifications and Covered Code, for commercial or non-commercial purposes, provided that in each instance You also meet all of these conditions: (a) You must satisfy all the conditions of Section 2.1 with respect to the Source Code of the Covered Code; (b) You must duplicate, to the extent it does not already exist, the notice in Exhibit A in each file of the Source Code of all Your Modifications, and cause the modified files to carry prominent notices stating that You changed the files and the date of any change; and (c) If You Externally Deploy Your Modifications, You must make Source Code of all Your Externally Deployed Modifications either available to those to whom You have Externally Deployed Your Modifications, or publicly available. Source Code of Your Externally Deployed Modifications must be released under the terms set forth in this License, including the license grants set forth in Section 3 below, for as long as you Externally Deploy the Covered Code or twelve (12) months from the date of initial External Deployment, whichever is longer. You should preferably distribute the Source Code of Your Externally Deployed Modifications electronically (e.g. download from a web site). 2.3 Distribution of Executable Versions. In addition, if You Externally Deploy Covered Code (Original Code and/or Modifications) in object code, executable form only, You must include a prominent notice, in the code itself as well as in related documentation, stating that Source Code of the Covered Code is available under the terms of this License with information on how and where to obtain such Source Code. 2.4 Third Party Rights. You expressly acknowledge and agree that although Apple and each Contributor grants the licenses to their respective portions of the Covered Code set forth herein, no assurances are provided by Apple or any Contributor that the Covered Code does not infringe the patent or other intellectual property rights of any other entity. Apple and each Contributor disclaim any liability to You for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, You hereby assume sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow You to distribute the Covered Code, it is Your responsibility to acquire that license before distributing the Covered Code. 3. Your Grants. In consideration of, and as a condition to, the licenses granted to You under this License, You hereby grant to any person or entity receiving or distributing Covered Code under this License a non-exclusive, royalty-free, perpetual, irrevocable license, under Your Applicable Patent Rights and other intellectual property rights (other than patent) owned or controlled by You, to use, reproduce, display, perform, modify, sublicense, distribute and Externally Deploy Your Modifications of the same scope and extent as Apple's licenses under Sections 2.1 and 2.2 above. 4. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In each such instance, You must make sure the requirements of this License are fulfilled for the Covered Code or any portion thereof. 5. Limitations on Patent License. Except as expressly stated in Section 2, no other patent rights, express or implied, are granted by Apple herein. Modifications and/or Larger Works may require additional patent licenses from Apple which Apple may grant in its sole discretion. 6. Additional Terms. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the scope of the license granted herein ("Additional Terms") to one or more recipients of Covered Code. However, You may do so only on Your own behalf and as Your sole responsibility, and not on behalf of Apple or any Contributor. You must obtain the recipient's agreement that any such Additional Terms are offered by You alone, and You hereby agree to indemnify, defend and hold Apple and every Contributor harmless for any liability incurred by or claims asserted against Apple or such Contributor by reason of any such Additional Terms. 7. Versions of the License. Apple may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Once Original Code has been published under a particular version of this License, You may continue to use it under the terms of that version. You may also choose to use such Original Code under the terms of any subsequent version of this License published by Apple. No one other than Apple has the right to modify the terms applicable to Covered Code created under this License. 8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in part pre-release, untested, or not fully tested works. The Covered Code may contain errors that could cause failures or loss of data, and may be incomplete or contain inaccuracies. You expressly acknowledge and agree that use of the Covered Code, or any portion thereof, is at Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. You acknowledge that the Covered Code is not intended for use in the operation of nuclear facilities, aircraft navigation, communication systems, or air traffic control machines in which case the failure of the Covered Code could lead to death, personal injury, or severe physical or environmental damage. 9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event shall Apple's total liability to You for all damages (other than as may be required by applicable law) under this License exceed the amount of fifty dollars ($50.00). 10. Trademarks. This License does not grant any rights to use the trademarks or trade names "Apple", "Mac", "Mac OS", "QuickTime", "QuickTime Streaming Server" or any other trademarks, service marks, logos or trade names belonging to Apple (collectively "Apple Marks") or to any trademark, service mark, logo or trade name belonging to any Contributor. You agree not to use any Apple Marks in or as part of the name of products derived from the Original Code or to endorse or promote products derived from the Original Code other than as expressly permitted by and in strict compliance at all times with Apple's third party trademark usage guidelines which are posted at http://www.apple.com/legal/guidelinesfor3rdparties.html. 11. Ownership. Subject to the licenses granted under this License, each Contributor retains all rights, title and interest in and to any Modifications made by such Contributor. Apple retains all rights, title and interest in and to the Original Code and any Modifications made by or on behalf of Apple ("Apple Modifications"), and such Apple Modifications will not be automatically subject to this License. Apple may, at its sole discretion, choose to license such Apple Modifications under this License, or on different terms from those contained in this License or may choose not to license them at all. 12. Termination. 12.1 Termination. This License and the rights granted hereunder will terminate: (a) automatically without notice from Apple if You fail to comply with any term(s) of this License and fail to cure such breach within 30 days of becoming aware of such breach; (b) immediately in the event of the circumstances described in Section 13.5(b); or (c) automatically without notice from Apple if You, at any time during the term of this License, commence an action for patent infringement against Apple; provided that Apple did not first commence an action for patent infringement against You in that instance. 12.2 Effect of Termination. Upon termination, You agree to immediately stop any further use, reproduction, modification, sublicensing and distribution of the Covered Code. All sublicenses to the Covered Code which have been properly granted prior to termination shall survive any termination of this License. Provisions which, by their nature, should remain in effect beyond the termination of this License shall survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other for compensation, indemnity or damages of any sort solely as a result of terminating this License in accordance with its terms, and termination of this License will be without prejudice to any other right or remedy of any party. 13. Miscellaneous. 13.1 Government End Users. The Covered Code is a "commercial item" as defined in FAR 2.101. Government software and technical data rights in the Covered Code include only those rights customarily provided to the public as defined in this License. This customary commercial license in technical data and software is provided in accordance with FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 (Rights in Commercial Computer Software or Computer Software Documentation). Accordingly, all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 13.2 Relationship of Parties. This License will not be construed as creating an agency, partnership, joint venture or any other form of legal association between or among You, Apple or any Contributor, and You will not represent to the contrary, whether expressly, by implication, appearance or otherwise. 13.3 Independent Development. Nothing in this License will impair Apple's right to acquire, license, develop, have others develop for it, market and/or distribute technology or products that perform the same or similar functions as, or otherwise compete with, Modifications, Larger Works, technology or products that You may develop, produce, market or distribute. 13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce any provision of this License will not be deemed a waiver of future enforcement of that or any other provision. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this License. 13.5 Severability. (a) If for any reason a court of competent jurisdiction finds any provision of this License, or portion thereof, to be unenforceable, that provision of the License will be enforced to the maximum extent permissible so as to effect the economic benefits and intent of the parties, and the remainder of this License will continue in full force and effect. (b) Notwithstanding the foregoing, if applicable law prohibits or restricts You from fully and/or specifically complying with Sections 2 and/or 3 or prevents the enforceability of either of those Sections, this License will immediately terminate and You must immediately discontinue any use of the Covered Code and destroy all copies of it that are in your possession or control. 13.6 Dispute Resolution. Any litigation or other dispute resolution between You and Apple relating to this License shall take place in the Northern District of California, and You and Apple hereby consent to the personal jurisdiction of, and venue in, the state and federal courts within that District with respect to this License. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. 13.7 Entire Agreement; Governing Law. This License constitutes the entire agreement between the parties with respect to the subject matter hereof. This License shall be governed by the laws of the United States and the State of California, except that body of California law concerning conflicts of law. Where You are located in the province of Quebec, Canada, the following clause applies: The parties hereby confirm that they have requested that this License and all related documents be drafted in English. Les parties ont exigé que le présent contrat et tous les documents connexes soient rédigés en anglais. EXHIBIT A. "Portions Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. This file contains Original Code and/or Modifications of Original Code as defined in and that are subject to the Apple Public Source License Version 2.0 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.opensource.apple.com/apsl/ and read it before using this file. The Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License." boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/EndianPortable.c000066400000000000000000000073111516712004000266130ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ // // EndianPortable.c // // Copyright 2011 Apple Inc. All rights reserved. // #include #include "EndianPortable.h" #define BSWAP16(x) (((x << 8) | ((x >> 8) & 0x00ff))) #define BSWAP32(x) (((x << 24) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff))) #define BSWAP64(x) ((((int64_t)x << 56) | (((int64_t)x << 40) & 0x00ff000000000000LL) | \ (((int64_t)x << 24) & 0x0000ff0000000000LL) | (((int64_t)x << 8) & 0x000000ff00000000LL) | \ (((int64_t)x >> 8) & 0x00000000ff000000LL) | (((int64_t)x >> 24) & 0x0000000000ff0000LL) | \ (((int64_t)x >> 40) & 0x000000000000ff00LL) | (((int64_t)x >> 56) & 0x00000000000000ffLL))) #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) # define TARGET_RT_LITTLE_ENDIAN 1 #elif defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM) || defined(_M_ARM64) # define TARGET_RT_LITTLE_ENDIAN 1 #elif defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) # define TARGET_RT_LITTLE_ENDIAN 1 #elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) # define TARGET_RT_LITTLE_ENDIAN 0 #else # error "Unknown byte order!" #endif uint16_t Swap16NtoB(uint16_t inUInt16) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP16(inUInt16); #else return inUInt16; #endif } uint16_t Swap16BtoN(uint16_t inUInt16) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP16(inUInt16); #else return inUInt16; #endif } uint32_t Swap32NtoB(uint32_t inUInt32) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP32(inUInt32); #else return inUInt32; #endif } uint32_t Swap32BtoN(uint32_t inUInt32) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP32(inUInt32); #else return inUInt32; #endif } uint64_t Swap64BtoN(uint64_t inUInt64) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP64(inUInt64); #else return inUInt64; #endif } uint64_t Swap64NtoB(uint64_t inUInt64) { #if TARGET_RT_LITTLE_ENDIAN return BSWAP64(inUInt64); #else return inUInt64; #endif } float SwapFloat32BtoN(float in) { #if TARGET_RT_LITTLE_ENDIAN union { float f; int32_t i; } x; x.f = in; x.i = BSWAP32(x.i); return x.f; #else return in; #endif } float SwapFloat32NtoB(float in) { #if TARGET_RT_LITTLE_ENDIAN union { float f; int32_t i; } x; x.f = in; x.i = BSWAP32(x.i); return x.f; #else return in; #endif } double SwapFloat64BtoN(double in) { #if TARGET_RT_LITTLE_ENDIAN union { double f; int64_t i; } x; x.f = in; x.i = BSWAP64(x.i); return x.f; #else return in; #endif } double SwapFloat64NtoB(double in) { #if TARGET_RT_LITTLE_ENDIAN union { double f; int64_t i; } x; x.f = in; x.i = BSWAP64(x.i); return x.f; #else return in; #endif } void Swap16(uint16_t * inUInt16) { *inUInt16 = BSWAP16(*inUInt16); } void Swap24(uint8_t * inUInt24) { uint8_t tempVal = inUInt24[0]; inUInt24[0] = inUInt24[2]; inUInt24[2] = tempVal; } void Swap32(uint32_t * inUInt32) { *inUInt32 = BSWAP32(*inUInt32); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/EndianPortable.h000066400000000000000000000026151516712004000266220ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ // // EndianPortable.h // // Copyright 2011 Apple Inc. All rights reserved. // #ifndef _EndianPortable_h #define _EndianPortable_h #include #ifdef __cplusplus extern "C" { #endif uint16_t Swap16NtoB(uint16_t inUInt16); uint16_t Swap16BtoN(uint16_t inUInt16); uint32_t Swap32NtoB(uint32_t inUInt32); uint32_t Swap32BtoN(uint32_t inUInt32); uint64_t Swap64BtoN(uint64_t inUInt64); uint64_t Swap64NtoB(uint64_t inUInt64); float SwapFloat32BtoN(float in); float SwapFloat32NtoB(float in); double SwapFloat64BtoN(double in); double SwapFloat64NtoB(double in); void Swap16(uint16_t * inUInt16); void Swap24(uint8_t * inUInt24); void Swap32(uint32_t * inUInt32); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/Makefile000066400000000000000000000010361516712004000252160ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = ag_dec.o ALACBitUtilities.o ALACDecoder.o dp_dec.o EndianPortable.o matrix_dec.o TARGET = libalac.a CCOPTS = -Wno-multichar AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif OFLAGS = -O3 -funroll-loops all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) $(OFLAGS) -c $< -o $@ .cpp.o: $(CXX) $(CCOPTS) $(CXXFLAGS) $(OFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/ag_dec.c000066400000000000000000000207231516712004000251300ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * Portions Copyright (c) 2011-2015 Peter Pawlowski. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: ag_dec.c Contains: Adaptive Golomb decode routines. Copyright: (c) 2001-2011 Apple, Inc. Portions Copyright (c) 2011-2015 Peter Pawlowski. */ #include "aglib.h" #include "ALACBitUtilities.h" #include "ALACAudioTypes.h" #include #include #include #include #if defined(_MSC_VER) #include #endif #define CODE_TO_LONG_MAXBITS 32 #define N_MAX_MEAN_CLAMP 0xffff #define N_MEAN_CLAMP_VAL 0xffff #define REPORT_VAL 40 #if __GNUC__ #define ALWAYS_INLINE __attribute__((always_inline)) #else #define ALWAYS_INLINE #endif /* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this to help the compiler out. In many cases this required manual inlining or a macro. Sorry if it is ugly but the performance gains are well worth it. - WSK 5/19/04 */ void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth) { /* Use fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data, but use fullwidth = full image width, sectorwidth = sector (patch) width for such as image (2-dim.) data. */ set_ag_params( params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT ); } void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun) { params->mb = params->mb0 = m; params->pb = p; params->kb = k; params->wb = (1u<kb)-1; params->qb = QB-params->pb; params->fw = f; params->sw = s; params->maxrun = maxrun; } #if PRAGMA_MARK #pragma mark - #endif #if defined(_MSC_VER) static int32_t lead(int32_t m) { unsigned long index = 0; _BitScanReverse(&index, m); return 31 - index; } #elif defined(__llvm__) || defined(__GNUC__) static inline int32_t lead(int32_t m) { return __builtin_clz(m); } #else // note: implementing this with some kind of "count leading zeros" assembly is a big performance win static inline int32_t lead( int32_t m ) { int32_t j; uint32_t c = (1ul << 31); for(j=0; j < 32; j++) { if((c & (uint32_t) m) != 0) break; c >>= 1; } return (j); } #endif #define arithmin(a, b) ((a) < (b) ? (a) : (b)) static inline int32_t ALWAYS_INLINE lg3a( int32_t x) { int32_t result; x += 3; result = lead(x); return 31 - result; } static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer ) { // embedded CPUs typically can't read unaligned 32-bit words so just read the bytes uint32_t value; value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | ((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3]; return value; } #if PRAGMA_MARK #pragma mark - #endif #define get_next_fromlong(inlong, suff) ((inlong) >> (32 - (suff))) static inline uint32_t ALWAYS_INLINE getstreambits( uint8_t *in, int32_t bitoffset, int32_t numbits ) { uint32_t load1, load2; uint32_t byteoffset = bitoffset / 8; uint32_t result; //Assert( numbits <= 32 ); load1 = read32bit( in + byteoffset ); if ( (numbits + (bitoffset & 0x7)) > 32) { int32_t load2shift; result = load1 << (bitoffset & 0x7); load2 = (uint32_t) in[byteoffset+4]; load2shift = (8-(numbits + (bitoffset & 0x7)-32)); load2 >>= load2shift; result >>= (32-numbits); result |= load2; } else { result = load1 >> (32-numbits-(bitoffset & 7)); } // a shift of >= "the number of bits in the type of the value being shifted" results in undefined // behavior so don't try to shift by 32 if ( numbits != (sizeof(result) * 8) ) result &= ~(0xfffffffful << numbits); return result; } static inline int32_t dyn_get(unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k) { uint32_t tempbits = *bitPos; uint32_t result; uint32_t pre = 0, v; uint32_t streamlong; streamlong = read32bit( in + (tempbits >> 3) ); streamlong <<= (tempbits & 7); /* find the number of bits in the prefix */ { uint32_t notI = ~streamlong; pre = lead( notI); } if(pre >= MAX_PREFIX_16) { pre = MAX_PREFIX_16; tempbits += pre; streamlong <<= pre; result = get_next_fromlong(streamlong,MAX_DATATYPE_BITS_16); tempbits += MAX_DATATYPE_BITS_16; } else { // all of the bits must fit within the long we have loaded //Assert(pre+1+k <= 32); tempbits += pre; tempbits += 1; streamlong <<= pre+1; v = get_next_fromlong(streamlong, k); tempbits += k; result = pre*m + v-1; if(v<2) { result -= (v-1); tempbits -= 1; } } *bitPos = tempbits; return result; } static inline int32_t dyn_get_32bit( uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits ) { uint32_t tempbits = *bitPos; uint32_t v; uint32_t streamlong; uint32_t result; streamlong = read32bit( in + (tempbits >> 3) ); streamlong <<= (tempbits & 7); /* find the number of bits in the prefix */ { uint32_t notI = ~streamlong; result = lead( notI); } if(result >= MAX_PREFIX_32) { result = getstreambits(in, tempbits+MAX_PREFIX_32, maxbits); tempbits += MAX_PREFIX_32 + maxbits; } else { /* all of the bits must fit within the long we have loaded*/ //Assert(k<=14); //Assert(result=2) { result += (v-1); tempbits += 1; } } } *bitPos = tempbits; return result; } int32_t dyn_decomp( AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, uint32_t numSamples, int32_t maxSize, uint32_t * outNumBits ) { uint8_t *in; int32_t *outPtr = pc; uint32_t bitPos, startPos, maxPos; uint32_t j, m, k, n, c, mz; int32_t del, zmode; uint32_t mb; uint32_t pb_local = params->pb; uint32_t kb_local = params->kb; uint32_t wb_local = params->wb; int32_t status; RequireAction( (bitstream != nil) && (pc != nil) && (outNumBits != nil), return kALAC_ParamError; ); *outNumBits = 0; in = bitstream->cur; startPos = bitstream->bitIndex; maxPos = bitstream->byteSize * 8; bitPos = startPos; mb = params->mb0; zmode = 0; c = 0; status = ALAC_noErr; while (c < numSamples) { // bail if we've run off the end of the buffer RequireAction( bitPos < maxPos, status = kALAC_ParamError; goto Exit; ); m = (mb)>>QBSHIFT; k = lg3a(m); k = arithmin(k, kb_local); m = (1<> 1) * (multiplier); } *outPtr++ = del; c++; mb = pb_local*(n+zmode) + mb - ((pb_local*mb)>>QBSHIFT); // update mean tracking if (n > N_MAX_MEAN_CLAMP) mb = N_MEAN_CLAMP_VAL; zmode = 0; if (((mb << MMULSHIFT) < QB) && (c < numSamples)) { zmode = 1; k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT); mz = ((1<= 65535) zmode = 0; mb = 0; } } Exit: *outNumBits = (bitPos - startPos); BitBufferAdvance( bitstream, *outNumBits ); RequireAction( bitstream->cur <= bitstream->end, status = kALAC_ParamError; ); return status; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/aglib.h000066400000000000000000000037471516712004000250200ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: aglib.h Copyright: (C) 2001-2011 Apple, Inc. */ #ifndef AGLIB_H #define AGLIB_H #include #ifdef __cplusplus extern "C" { #endif #define QBSHIFT 9 #define QB (1< #if __GNUC__ #define ALWAYS_INLINE __attribute__((always_inline)) #else #define ALWAYS_INLINE #endif #if TARGET_CPU_PPC && (__MWERKS__ >= 0x3200) // align loops to a 16 byte boundary to make the G5 happy #pragma function_align 16 #define LOOP_ALIGN asm { align 16 } #else #define LOOP_ALIGN #endif static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i ) { return (0 < i) - (i < 0); } void unpc_block( int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift ) { register int16_t a0, a1, a2, a3; register int32_t b0, b1, b2, b3; int32_t j, k, lim; int32_t sum1, sg, sgn, top, dd; int32_t * pout; int32_t del, del0; uint32_t chanshift = 32 - chanbits; int32_t denhalf = 1<<(denshift-1); out[0] = pc1[0]; if ( numactive == 0 ) { // just copy if numactive == 0 (but don't bother if in/out pointers the same) if ( (num > 1) && (pc1 != out) ) memcpy( &out[1], &pc1[1], (num - 1) * sizeof(int32_t) ); return; } if ( numactive == 31 ) { // short-circuit if numactive == 31 int32_t prev; /* this code is written such that the in/out buffers can be the same to conserve buffer space on embedded devices like the iPod (original code) for ( j = 1; j < num; j++ ) del = pc1[j] + out[j-1]; out[j] = (del << chanshift) >> chanshift; */ prev = out[0]; for ( j = 1; j < num; j++ ) { del = pc1[j] + prev; prev = (del << chanshift) >> chanshift; out[j] = prev; } return; } for ( j = 1; j <= numactive; j++ ) { del = pc1[j] + out[j-1]; out[j] = (del << chanshift) >> chanshift; } lim = numactive + 1; if ( numactive == 4 ) { // optimization for numactive == 4 register int16_t a0, a1, a2, a3; register int32_t b0, b1, b2, b3; a0 = coefs[0]; a1 = coefs[1]; a2 = coefs[2]; a3 = coefs[3]; for ( j = lim; j < num; j++ ) { LOOP_ALIGN top = out[j - lim]; pout = out + j - 1; b0 = top - pout[0]; b1 = top - pout[-1]; b2 = top - pout[-2]; b3 = top - pout[-3]; sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3) >> denshift; del = pc1[j]; del0 = del; sg = sign_of_int(del); del += top + sum1; out[j] = (del << chanshift) >> chanshift; if ( sg > 0 ) { sgn = sign_of_int( b3 ); a3 -= sgn; del0 -= (4 - 3) * ((sgn * b3) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b2 ); a2 -= sgn; del0 -= (4 - 2) * ((sgn * b2) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b1 ); a1 -= sgn; del0 -= (4 - 1) * ((sgn * b1) >> denshift); if ( del0 <= 0 ) continue; a0 -= sign_of_int( b0 ); } else if ( sg < 0 ) { // note: to avoid unnecessary negations, we flip the value of "sgn" sgn = -sign_of_int( b3 ); a3 -= sgn; del0 -= (4 - 3) * ((sgn * b3) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b2 ); a2 -= sgn; del0 -= (4 - 2) * ((sgn * b2) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b1 ); a1 -= sgn; del0 -= (4 - 1) * ((sgn * b1) >> denshift); if ( del0 >= 0 ) continue; a0 += sign_of_int( b0 ); } } coefs[0] = a0; coefs[1] = a1; coefs[2] = a2; coefs[3] = a3; } else if ( numactive == 8 ) { register int16_t a4, a5, a6, a7; register int32_t b4, b5, b6, b7; // optimization for numactive == 8 a0 = coefs[0]; a1 = coefs[1]; a2 = coefs[2]; a3 = coefs[3]; a4 = coefs[4]; a5 = coefs[5]; a6 = coefs[6]; a7 = coefs[7]; for ( j = lim; j < num; j++ ) { LOOP_ALIGN top = out[j - lim]; pout = out + j - 1; b0 = top - (*pout--); b1 = top - (*pout--); b2 = top - (*pout--); b3 = top - (*pout--); b4 = top - (*pout--); b5 = top - (*pout--); b6 = top - (*pout--); b7 = top - (*pout); pout += 8; sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3 - a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift; del = pc1[j]; del0 = del; sg = sign_of_int(del); del += top + sum1; out[j] = (del << chanshift) >> chanshift; if ( sg > 0 ) { sgn = sign_of_int( b7 ); a7 -= sgn; del0 -= 1 * ((sgn * b7) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b6 ); a6 -= sgn; del0 -= 2 * ((sgn * b6) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b5 ); a5 -= sgn; del0 -= 3 * ((sgn * b5) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b4 ); a4 -= sgn; del0 -= 4 * ((sgn * b4) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b3 ); a3 -= sgn; del0 -= 5 * ((sgn * b3) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b2 ); a2 -= sgn; del0 -= 6 * ((sgn * b2) >> denshift); if ( del0 <= 0 ) continue; sgn = sign_of_int( b1 ); a1 -= sgn; del0 -= 7 * ((sgn * b1) >> denshift); if ( del0 <= 0 ) continue; a0 -= sign_of_int( b0 ); } else if ( sg < 0 ) { // note: to avoid unnecessary negations, we flip the value of "sgn" sgn = -sign_of_int( b7 ); a7 -= sgn; del0 -= 1 * ((sgn * b7) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b6 ); a6 -= sgn; del0 -= 2 * ((sgn * b6) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b5 ); a5 -= sgn; del0 -= 3 * ((sgn * b5) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b4 ); a4 -= sgn; del0 -= 4 * ((sgn * b4) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b3 ); a3 -= sgn; del0 -= 5 * ((sgn * b3) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b2 ); a2 -= sgn; del0 -= 6 * ((sgn * b2) >> denshift); if ( del0 >= 0 ) continue; sgn = -sign_of_int( b1 ); a1 -= sgn; del0 -= 7 * ((sgn * b1) >> denshift); if ( del0 >= 0 ) continue; a0 += sign_of_int( b0 ); } } coefs[0] = a0; coefs[1] = a1; coefs[2] = a2; coefs[3] = a3; coefs[4] = a4; coefs[5] = a5; coefs[6] = a6; coefs[7] = a7; } else { // general case for ( j = lim; j < num; j++ ) { LOOP_ALIGN sum1 = 0; pout = out + j - 1; top = out[j-lim]; for ( k = 0; k < numactive; k++ ) sum1 += coefs[k] * (pout[-k] - top); del = pc1[j]; del0 = del; sg = sign_of_int( del ); del += top + ((sum1 + denhalf) >> denshift); out[j] = (del << chanshift) >> chanshift; if ( sg > 0 ) { for ( k = (numactive - 1); k >= 0; k-- ) { dd = top - pout[-k]; sgn = sign_of_int( dd ); coefs[k] -= sgn; del0 -= (numactive - k) * ((sgn * dd) >> denshift); if ( del0 <= 0 ) break; } } else if ( sg < 0 ) { for ( k = (numactive - 1); k >= 0; k-- ) { dd = top - pout[-k]; sgn = sign_of_int( dd ); coefs[k] += sgn; del0 -= (numactive - k) * ((-sgn * dd) >> denshift); if ( del0 >= 0 ) break; } } } } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/dplib.h000066400000000000000000000031701516712004000250220ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: dplib.h Contains: Dynamic Predictor routines Copyright: Copyright (C) 2001-2011 Apple, Inc. */ #ifndef __DPLIB_H__ #define __DPLIB_H__ #include #ifdef __cplusplus extern "C" { #endif // defines #define DENSHIFT_MAX 15 #define DENSHIFT_DEFAULT 9 #define AINIT 38 #define BINIT (-29) #define CINIT (-2) #define NUMCOEPAIRS 16 // prototypes void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs ); void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs ); // NOTE: these routines read at least "numactive" samples so the i/o buffers must be at least that big void pc_block( int32_t * in, int32_t * pc, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift ); void unpc_block( int32_t * pc, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift ); #ifdef __cplusplus } #endif #endif /* __DPLIB_H__ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/matrix_dec.c000066400000000000000000000224251516712004000260460ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: matrix_dec.c Contains: ALAC mixing/matrixing decode routines. Copyright: (c) 2004-2011 Apple, Inc. */ #include "matrixlib.h" #include "ALACAudioTypes.h" // up to 24-bit "offset" macros for the individual bytes of a 20/24-bit word #if TARGET_RT_BIG_ENDIAN #define LBYTE 2 #define MBYTE 1 #define HBYTE 0 #else #define LBYTE 0 #define MBYTE 1 #define HBYTE 2 #endif /* There is no plain middle-side option; instead there are various mixing modes including middle-side, each lossless, as embodied in the mix() and unmix() functions. These functions exploit a generalized middle-side transformation: u := [(rL + (m-r)R)/m]; v := L - R; where [ ] denotes integer floor. The (lossless) inverse is L = u + v - [rV/m]; R = L - v; */ // 16-bit routines void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres ) { int16_t * op = out; int32_t j; if ( mixres != 0 ) { /* matrixed stereo */ for ( j = 0; j < numSamples; j++ ) { int32_t l, r; l = u[j] + v[j] - ((mixres * v[j]) >> mixbits); r = l - v[j]; op[0] = (int16_t) l; op[1] = (int16_t) r; op += stride; } } else { /* Conventional separated stereo. */ for ( j = 0; j < numSamples; j++ ) { op[0] = (int16_t) u[j]; op[1] = (int16_t) v[j]; op += stride; } } } // 20-bit routines // - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres ) { uint8_t * op = out; int32_t j; if ( mixres != 0 ) { /* matrixed stereo */ for ( j = 0; j < numSamples; j++ ) { int32_t l, r; l = u[j] + v[j] - ((mixres * v[j]) >> mixbits); r = l - v[j]; l <<= 4; r <<= 4; op[HBYTE] = (uint8_t)((l >> 16) & 0xffu); op[MBYTE] = (uint8_t)((l >> 8) & 0xffu); op[LBYTE] = (uint8_t)((l >> 0) & 0xffu); op += 3; op[HBYTE] = (uint8_t)((r >> 16) & 0xffu); op[MBYTE] = (uint8_t)((r >> 8) & 0xffu); op[LBYTE] = (uint8_t)((r >> 0) & 0xffu); op += (stride - 1) * 3; } } else { /* Conventional separated stereo. */ for ( j = 0; j < numSamples; j++ ) { int32_t val; val = u[j] << 4; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += 3; val = v[j] << 4; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += (stride - 1) * 3; } } } // 24-bit routines // - the 24 bits of data are right-justified in the input/output predictor buffers void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ) { uint8_t * op = out; int32_t shift = bytesShifted * 8; int32_t l, r; int32_t j, k; if ( mixres != 0 ) { /* matrixed stereo */ if ( bytesShifted != 0 ) { for ( j = 0, k = 0; j < numSamples; j++, k += 2 ) { l = u[j] + v[j] - ((mixres * v[j]) >> mixbits); r = l - v[j]; l = (l << shift) | (uint32_t) shiftUV[k + 0]; r = (r << shift) | (uint32_t) shiftUV[k + 1]; op[HBYTE] = (uint8_t)((l >> 16) & 0xffu); op[MBYTE] = (uint8_t)((l >> 8) & 0xffu); op[LBYTE] = (uint8_t)((l >> 0) & 0xffu); op += 3; op[HBYTE] = (uint8_t)((r >> 16) & 0xffu); op[MBYTE] = (uint8_t)((r >> 8) & 0xffu); op[LBYTE] = (uint8_t)((r >> 0) & 0xffu); op += (stride - 1) * 3; } } else { for ( j = 0; j < numSamples; j++ ) { l = u[j] + v[j] - ((mixres * v[j]) >> mixbits); r = l - v[j]; op[HBYTE] = (uint8_t)((l >> 16) & 0xffu); op[MBYTE] = (uint8_t)((l >> 8) & 0xffu); op[LBYTE] = (uint8_t)((l >> 0) & 0xffu); op += 3; op[HBYTE] = (uint8_t)((r >> 16) & 0xffu); op[MBYTE] = (uint8_t)((r >> 8) & 0xffu); op[LBYTE] = (uint8_t)((r >> 0) & 0xffu); op += (stride - 1) * 3; } } } else { /* Conventional separated stereo. */ if ( bytesShifted != 0 ) { for ( j = 0, k = 0; j < numSamples; j++, k += 2 ) { l = u[j]; r = v[j]; l = (l << shift) | (uint32_t) shiftUV[k + 0]; r = (r << shift) | (uint32_t) shiftUV[k + 1]; op[HBYTE] = (uint8_t)((l >> 16) & 0xffu); op[MBYTE] = (uint8_t)((l >> 8) & 0xffu); op[LBYTE] = (uint8_t)((l >> 0) & 0xffu); op += 3; op[HBYTE] = (uint8_t)((r >> 16) & 0xffu); op[MBYTE] = (uint8_t)((r >> 8) & 0xffu); op[LBYTE] = (uint8_t)((r >> 0) & 0xffu); op += (stride - 1) * 3; } } else { for ( j = 0; j < numSamples; j++ ) { int32_t val; val = u[j]; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += 3; val = v[j]; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += (stride - 1) * 3; } } } } // 32-bit routines // - note that these really expect the internal data width to be < 32 but the arrays are 32-bit // - otherwise, the calculations might overflow into the 33rd bit and be lost // - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ) { int32_t * op = out; int32_t shift = bytesShifted * 8; int32_t l, r; int32_t j, k; if ( mixres != 0 ) { //Assert( bytesShifted != 0 ); /* matrixed stereo with shift */ for ( j = 0, k = 0; j < numSamples; j++, k += 2 ) { int32_t lt, rt; lt = u[j]; rt = v[j]; l = lt + rt - ((mixres * rt) >> mixbits); r = l - rt; op[0] = (l << shift) | (uint32_t) shiftUV[k + 0]; op[1] = (r << shift) | (uint32_t) shiftUV[k + 1]; op += stride; } } else { if ( bytesShifted == 0 ) { /* interleaving w/o shift */ for ( j = 0; j < numSamples; j++ ) { op[0] = u[j]; op[1] = v[j]; op += stride; } } else { /* interleaving with shift */ for ( j = 0, k = 0; j < numSamples; j++, k += 2 ) { op[0] = (u[j] << shift) | (uint32_t) shiftUV[k + 0]; op[1] = (v[j] << shift) | (uint32_t) shiftUV[k + 1]; op += stride; } } } } // 20/24-bit <-> 32-bit helper routines (not really matrixing but convenient to put here) void copyPredictorTo24( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples ) { uint8_t * op = out; int32_t j; for ( j = 0; j < numSamples; j++ ) { int32_t val = in[j]; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += (stride * 3); } } void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted ) { uint8_t * op = out; int32_t shiftVal = bytesShifted * 8; int32_t j; //Assert( bytesShifted != 0 ); for ( j = 0; j < numSamples; j++ ) { int32_t val = in[j]; val = (val << shiftVal) | (uint32_t) shift[j]; op[HBYTE] = (uint8_t)((val >> 16) & 0xffu); op[MBYTE] = (uint8_t)((val >> 8) & 0xffu); op[LBYTE] = (uint8_t)((val >> 0) & 0xffu); op += (stride * 3); } } void copyPredictorTo20( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples ) { uint8_t * op = out; int32_t j; // 32-bit predictor values are right-aligned but 20-bit output values should be left-aligned // in the 24-bit output buffer for ( j = 0; j < numSamples; j++ ) { int32_t val = in[j]; op[HBYTE] = (uint8_t)((val >> 12) & 0xffu); op[MBYTE] = (uint8_t)((val >> 4) & 0xffu); op[LBYTE] = (uint8_t)((val << 4) & 0xffu); op += (stride * 3); } } void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples ) { int32_t i, j; // this is only a subroutine to abstract the "iPod can only output 16-bit data" problem for ( i = 0, j = 0; i < numSamples; i++, j += stride ) out[j] = in[i]; } void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted ) { int32_t * op = out; uint32_t shiftVal = bytesShifted * 8; int32_t j; //Assert( bytesShifted != 0 ); // this is only a subroutine to abstract the "iPod can only output 16-bit data" problem for ( j = 0; j < numSamples; j++ ) { op[0] = (in[j] << shiftVal) | (uint32_t) shift[j]; op += stride; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/alac/matrixlib.h000066400000000000000000000070171516712004000257270ustar00rootroot00000000000000/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: matrixlib.h Contains: ALAC mixing/matrixing routines to/from 32-bit predictor buffers. Copyright: Copyright (C) 2004 to 2011 Apple, Inc. */ #ifndef __MATRIXLIB_H #define __MATRIXLIB_H #pragma once #include #ifdef __cplusplus extern "C" { #endif // 16-bit routines void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres ); void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres ); // 20-bit routines void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres ); void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres ); // 24-bit routines // - 24-bit data sometimes compresses better by shifting off the bottom byte so these routines deal with // the specified "unused lower bytes" in the combined "shift" buffer void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ); void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ); // 32-bit routines // - note that these really expect the internal data width to be < 32-bit but the arrays are 32-bit // - otherwise, the calculations might overflow into the 33rd bit and be lost // - therefore, these routines deal with the specified "unused lower" bytes in the combined "shift" buffer void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ); void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted ); // 20/24/32-bit <-> 32-bit helper routines (not really matrixing but convenient to put here) void copy20ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples ); void copy24ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples ); void copyPredictorTo24( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples ); void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted ); void copyPredictorTo20( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples ); void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples ); void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted ); #ifdef __cplusplus } #endif #endif /* __MATRIXLIB_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/dllinterface.cpp000066400000000000000000000073311516712004000260220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" MP4READ ex_MP4Read = NIL; MP4READCALLBACKS ex_MP4ReadCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4FREE ex_MP4Free = NIL; MP4FINDTRACKID ex_MP4FindTrackId = NIL; MP4GETTRACKDURATION ex_MP4GetTrackDuration = NIL; MP4HAVETRACKATOM ex_MP4HaveTrackAtom = NIL; MP4GETTRACKBYTESPROPERTY ex_MP4GetTrackBytesProperty = NIL; MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale = NIL; MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples = NIL; MP4GETSAMPLETIME ex_MP4GetSampleTime = NIL; MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime = NIL; MP4GETSAMPLESIZE ex_MP4GetSampleSize = NIL; MP4READSAMPLE ex_MP4ReadSample = NIL; MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning = NIL; MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Read = (MP4READ) mp4v2dll->GetFunctionAddress("MP4Read"); ex_MP4ReadCallbacks = (MP4READCALLBACKS) mp4v2dll->GetFunctionAddress("MP4ReadCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Free = (MP4FREE) mp4v2dll->GetFunctionAddress("MP4Free"); ex_MP4FindTrackId = (MP4FINDTRACKID) mp4v2dll->GetFunctionAddress("MP4FindTrackId"); ex_MP4GetTrackDuration = (MP4GETTRACKDURATION) mp4v2dll->GetFunctionAddress("MP4GetTrackDuration"); ex_MP4HaveTrackAtom = (MP4HAVETRACKATOM) mp4v2dll->GetFunctionAddress("MP4HaveTrackAtom"); ex_MP4GetTrackBytesProperty = (MP4GETTRACKBYTESPROPERTY) mp4v2dll->GetFunctionAddress("MP4GetTrackBytesProperty"); ex_MP4GetTrackTimeScale = (MP4GETTRACKTIMESCALE) mp4v2dll->GetFunctionAddress("MP4GetTrackTimeScale"); ex_MP4GetTrackNumberOfSamples = (MP4GETTRACKNUMBEROFSAMPLES) mp4v2dll->GetFunctionAddress("MP4GetTrackNumberOfSamples"); ex_MP4GetSampleTime = (MP4GETSAMPLETIME) mp4v2dll->GetFunctionAddress("MP4GetSampleTime"); ex_MP4GetSampleIdFromTime = (MP4GETSAMPLEIDFROMTIME) mp4v2dll->GetFunctionAddress("MP4GetSampleIdFromTime"); ex_MP4GetSampleSize = (MP4GETSAMPLESIZE) mp4v2dll->GetFunctionAddress("MP4GetSampleSize"); ex_MP4ReadSample = (MP4READSAMPLE) mp4v2dll->GetFunctionAddress("MP4ReadSample"); ex_MP4ItmfGetItemsByMeaning = (MP4ITMFGETITEMSBYMEANING) mp4v2dll->GetFunctionAddress("MP4ItmfGetItemsByMeaning"); ex_MP4ItmfItemListFree = (MP4ITMFITEMLISTFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemListFree"); if (ex_MP4Read == NIL || ex_MP4ReadCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Free == NIL || ex_MP4FindTrackId == NIL || ex_MP4GetTrackDuration == NIL || ex_MP4HaveTrackAtom == NIL || ex_MP4GetTrackBytesProperty == NIL || ex_MP4GetTrackTimeScale == NIL || ex_MP4GetTrackNumberOfSamples == NIL || ex_MP4GetSampleTime == NIL || ex_MP4GetSampleIdFromTime == NIL || ex_MP4GetSampleSize == NIL || ex_MP4ReadSample == NIL || ex_MP4ItmfGetItemsByMeaning == NIL || ex_MP4ItmfItemListFree == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/alac/dllinterface.h000066400000000000000000000055421516712004000254710ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *mp4v2dll; Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef MP4FileHandle (*MP4READ) (const char *); typedef MP4FileHandle (*MP4READCALLBACKS) (const MP4IOCallbacks *, void *); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef void (*MP4FREE) (void *); typedef MP4TrackId (*MP4FINDTRACKID) (MP4FileHandle, uint16_t, const char *, uint8_t); typedef MP4Duration (*MP4GETTRACKDURATION) (MP4FileHandle, MP4TrackId); typedef bool (*MP4HAVETRACKATOM) (MP4FileHandle, MP4TrackId, const char *); typedef bool (*MP4GETTRACKBYTESPROPERTY) (MP4FileHandle, MP4TrackId, const char *, uint8_t **, uint32_t *); typedef uint32_t (*MP4GETTRACKTIMESCALE) (MP4FileHandle, MP4TrackId); typedef MP4SampleId (*MP4GETTRACKNUMBEROFSAMPLES) (MP4FileHandle, MP4TrackId); typedef MP4Timestamp (*MP4GETSAMPLETIME) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef MP4SampleId (*MP4GETSAMPLEIDFROMTIME) (MP4FileHandle, MP4TrackId, MP4Timestamp, bool); typedef uint32_t (*MP4GETSAMPLESIZE) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef bool (*MP4READSAMPLE) (MP4FileHandle, MP4TrackId, MP4SampleId, uint8_t **, uint32_t *, MP4Timestamp *, MP4Duration *, MP4Duration *, bool *); typedef MP4ItmfItemList * (*MP4ITMFGETITEMSBYMEANING) (MP4FileHandle, const char *, const char *); typedef void (*MP4ITMFITEMLISTFREE) (MP4ItmfItemList *); extern MP4READ ex_MP4Read; extern MP4READCALLBACKS ex_MP4ReadCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4FREE ex_MP4Free; extern MP4FINDTRACKID ex_MP4FindTrackId; extern MP4GETTRACKDURATION ex_MP4GetTrackDuration; extern MP4HAVETRACKATOM ex_MP4HaveTrackAtom; extern MP4GETTRACKBYTESPROPERTY ex_MP4GetTrackBytesProperty; extern MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale; extern MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples; extern MP4GETSAMPLETIME ex_MP4GetSampleTime; extern MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime; extern MP4GETSAMPLESIZE ex_MP4GetSampleSize; extern MP4READSAMPLE ex_MP4ReadSample; extern MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning; extern MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/au/000077500000000000000000000000001516712004000223635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/au/Makefile000077500000000000000000000011141516712004000240230ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = au TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = au.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/au/au.cpp000066400000000000000000000056501516712004000235020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "au.h" using namespace smooth::IO; const String &BoCA::DecoderSunAu::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Sun Audio File Decoder \ 1.0 \ au-dec \ decoder \ \ Sun Audio Files \ true \ au \ snd \ \ \ \ "; return componentSpecs; } Bool BoCA::DecoderSunAu::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) == ".snd") return True; return False; } Error BoCA::DecoderSunAu::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); Format format = track.GetFormat(); track.fileSize = in.Size(); format.order = BYTE_RAW; /* Skip magic number and data offset. */ in.RelSeek(8); track.length = UnsignedInt32(in.InputNumberRaw(4)); format.bits = UnsignedInt32(in.InputNumberRaw(4)); if (format.bits == 2) format.bits = 8; else if (format.bits == 3) format.bits = 16; else if (format.bits == 4) format.bits = 24; else if (format.bits == 5) format.bits = 32; else { errorState = True; errorString = "Unsupported audio format"; } if (!errorState) { format.rate = UnsignedInt32(in.InputNumberRaw(4)); format.channels = UnsignedInt32(in.InputNumberRaw(4)); track.length = track.length / format.channels / (format.bits / 8); } track.SetFormat(format); if (errorState) return Error(); else return Success(); } BoCA::DecoderSunAu::DecoderSunAu() { dataOffset = 0; } BoCA::DecoderSunAu::~DecoderSunAu() { } Bool BoCA::DecoderSunAu::Activate() { InStream in(STREAM_DRIVER, driver); /* Read magic number. */ in.InputNumber(4); dataOffset = in.InputNumberRaw(4); driver->Seek(dataOffset); return True; } Bool BoCA::DecoderSunAu::Seek(Int64 samplePosition) { const Format &format = track.GetFormat(); driver->Seek(dataOffset + samplePosition * format.channels * (format.bits / 8)); return True; } Int BoCA::DecoderSunAu::ReadData(Buffer &data) { if (driver->GetPos() == driver->GetSize()) return -1; return driver->ReadData(data, data.Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/au/au.h000066400000000000000000000021341516712004000231410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DecoderSunAu) namespace BoCA { class DecoderSunAu : public CS::DecoderComponent { private: Int dataOffset; public: static const String &GetComponentSpecs(); DecoderSunAu(); ~DecoderSunAu(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderSunAu) BoCA_END_COMPONENT(DecoderSunAu) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/000077500000000000000000000000001516712004000227075ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/Makefile000077500000000000000000000012121516712004000243460ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = bonk TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = bonk.o dllinterface.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/bonk.cpp000066400000000000000000000075321516712004000243530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "bonk.h" using namespace smooth::IO; const String &BoCA::DecoderBonk::GetComponentSpecs() { static String componentSpecs; if (bonkdll != NIL) { componentSpecs = " \ \ \ \ Bonk Audio Decoder %VERSION% \ 1.0 \ bonk-dec \ decoder \ \ Bonk Audio Files \ bonk \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(ex_bonk_get_version_string())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadBonkDLL(); } Void smooth::DetachDLL() { FreeBonkDLL(); } Bool BoCA::DecoderBonk::CanOpenStream(const String &streamURI) { return streamURI.ToLower().EndsWith(".bonk"); } Error BoCA::DecoderBonk::GetStreamInfo(const String &streamURI, Track &track) { InStream *in = new InStream(STREAM_FILE, streamURI, IS_READ); unsigned int length = 0; unsigned int rate = 0; int channels = 0; void *decoder = ex_bonk_decoder_create(); Format format = track.GetFormat(); Buffer data(Math::Min(in->Size(), (Int64) 524288)); in->InputData(data, data.Size()); ex_bonk_decoder_init(decoder, data, data.Size(), &length, &rate, &channels); format.rate = rate; format.channels = channels; format.bits = 16; track.SetFormat(format); track.length = length / format.channels; track.fileSize = in->Size(); bool lossless = False; bool mid_side = False; ex_bonk_decoder_get_stream_info(decoder, &lossless, &mid_side); track.lossless = lossless; unsigned char *id3tag = NIL; int id3tag_size = 0; ex_bonk_decoder_get_id3_data(decoder, &id3tag, &id3tag_size); if (id3tag_size > 0) { Buffer buffer(id3tag_size); memcpy(buffer, id3tag, id3tag_size); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(buffer, track); boca.DeleteComponent(tagger); } } ex_bonk_decoder_close(decoder); delete in; return Success(); } BoCA::DecoderBonk::DecoderBonk() { decoder = NIL; } BoCA::DecoderBonk::~DecoderBonk() { } Bool BoCA::DecoderBonk::Activate() { unsigned int length = 0; unsigned int rate = 0; int channels = 0; decoder = ex_bonk_decoder_create(); Buffer data(Math::Min(driver->GetSize(), (Int64) 524288)); driver->ReadData(data, data.Size()); ex_bonk_decoder_init(decoder, data, data.Size(), &length, &rate, &channels); return True; } Bool BoCA::DecoderBonk::Deactivate() { ex_bonk_decoder_finish(decoder); ex_bonk_decoder_close(decoder); return True; } Int BoCA::DecoderBonk::ReadData(Buffer &data) { Int size = driver->ReadData(data, data.Size()); data.Resize(Math::Max(data.Size(), 131072)); Int nSamples = ex_bonk_decoder_decode_packet(decoder, data, Math::Max(0, size), (signed short *) (UnsignedByte *) data, data.Size()); if (nSamples == -1) return -1; data.Resize(nSamples * (track.GetFormat().bits / 8)); return data.Size(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/bonk.h000066400000000000000000000021561516712004000240150ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderBonk) namespace BoCA { class DecoderBonk : public CS::DecoderComponent { private: void *decoder; public: static const String &GetComponentSpecs(); DecoderBonk(); ~DecoderBonk(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderBonk) BoCA_END_COMPONENT(DecoderBonk) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/dllinterface.cpp000077500000000000000000000056671516712004000260700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; BONKDECODERCREATE ex_bonk_decoder_create = NIL; BONKDECODERINIT ex_bonk_decoder_init = NIL; BONKDECODERDECODEPACKET ex_bonk_decoder_decode_packet = NIL; BONKDECODERFINISH ex_bonk_decoder_finish = NIL; BONKDECODERCLOSE ex_bonk_decoder_close = NIL; BONKDECODERGETSTREAMINFO ex_bonk_decoder_get_stream_info = NIL; BONKDECODERGETID3DATA ex_bonk_decoder_get_id3_data = NIL; BONKDECODERINITSEEKTABLE ex_bonk_decoder_init_seektable = NIL; BONKDECODERSEEKTO ex_bonk_decoder_seek_to = NIL; BONKGETVERSIONSTRING ex_bonk_get_version_string = NIL; DynamicLoader *bonkdll = NIL; Bool LoadBonkDLL() { bonkdll = BoCA::Utilities::LoadCodecDLL("bonk"); if (bonkdll == NIL) return False; ex_bonk_decoder_create = (BONKDECODERCREATE) bonkdll->GetFunctionAddress("bonk_decoder_create"); ex_bonk_decoder_init = (BONKDECODERINIT) bonkdll->GetFunctionAddress("bonk_decoder_init"); ex_bonk_decoder_decode_packet = (BONKDECODERDECODEPACKET) bonkdll->GetFunctionAddress("bonk_decoder_decode_packet"); ex_bonk_decoder_finish = (BONKDECODERFINISH) bonkdll->GetFunctionAddress("bonk_decoder_finish"); ex_bonk_decoder_close = (BONKDECODERCLOSE) bonkdll->GetFunctionAddress("bonk_decoder_close"); ex_bonk_decoder_get_stream_info = (BONKDECODERGETSTREAMINFO) bonkdll->GetFunctionAddress("bonk_decoder_get_stream_info"); ex_bonk_decoder_get_id3_data = (BONKDECODERGETID3DATA) bonkdll->GetFunctionAddress("bonk_decoder_get_id3_data"); ex_bonk_decoder_init_seektable = (BONKDECODERINITSEEKTABLE) bonkdll->GetFunctionAddress("bonk_decoder_init_seektable"); ex_bonk_decoder_seek_to = (BONKDECODERSEEKTO) bonkdll->GetFunctionAddress("bonk_decoder_seek_to"); ex_bonk_get_version_string = (BONKGETVERSIONSTRING) bonkdll->GetFunctionAddress("bonk_get_version_string"); if (ex_bonk_decoder_create == NIL || ex_bonk_decoder_init == NIL || ex_bonk_decoder_decode_packet == NIL || ex_bonk_decoder_finish == NIL || ex_bonk_decoder_close == NIL || ex_bonk_decoder_get_stream_info == NIL || ex_bonk_decoder_get_id3_data == NIL || ex_bonk_decoder_init_seektable == NIL || ex_bonk_decoder_seek_to == NIL || ex_bonk_get_version_string == NIL) { FreeBonkDLL(); return False; } return True; } Void FreeBonkDLL() { BoCA::Utilities::FreeCodecDLL(bonkdll); bonkdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/bonk/dllinterface.h000077500000000000000000000040611516712004000255200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *bonkdll; Bool LoadBonkDLL(); Void FreeBonkDLL(); typedef void * (BONKCONV *BONKDECODERCREATE) (); typedef bool (BONKCONV *BONKDECODERINIT) (void *, unsigned char *, int, unsigned int *, unsigned int *, int *); typedef int (BONKCONV *BONKDECODERDECODEPACKET) (void *, unsigned char *, int, signed short *, int); typedef int (BONKCONV *BONKDECODERFINISH) (void *); typedef bool (BONKCONV *BONKDECODERCLOSE) (void *); typedef bool (BONKCONV *BONKDECODERGETSTREAMINFO) (void *, bool *, bool *); typedef bool (BONKCONV *BONKDECODERGETID3DATA) (void *, unsigned char **, int *); typedef bool (BONKCONV *BONKDECODERINITSEEKTABLE) (void *, unsigned char *, int); typedef bool (BONKCONV *BONKDECODERSEEKTO) (void *, int); typedef const char * (BONKCONV *BONKGETVERSIONSTRING) (); extern BONKDECODERCREATE ex_bonk_decoder_create; extern BONKDECODERINIT ex_bonk_decoder_init; extern BONKDECODERDECODEPACKET ex_bonk_decoder_decode_packet; extern BONKDECODERFINISH ex_bonk_decoder_finish; extern BONKDECODERCLOSE ex_bonk_decoder_close; extern BONKDECODERGETSTREAMINFO ex_bonk_decoder_get_stream_info; extern BONKDECODERGETID3DATA ex_bonk_decoder_get_id3_data; extern BONKDECODERINITSEEKTABLE ex_bonk_decoder_init_seektable; extern BONKDECODERSEEKTO ex_bonk_decoder_seek_to; extern BONKGETVERSIONSTRING ex_bonk_get_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/000077500000000000000000000000001516712004000226745ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/Makefile000066400000000000000000000016551516712004000243430ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdio TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = cdio.o config.o info/cdinfo.o info/cdtext.o # Enter additional defines here: ifeq ($(wildcard /usr/include/cdio/paranoia/paranoia.h),) ifneq ($(wildcard /usr/include/cdio/paranoia.h),) DEFINE = -DHAVE_OLD_PARANOIA_INCLUDE=1 endif endif # Enter additional library dependencies here: LIBS = -lcdio -lcdio_cdda -lcdio_paranoia ifeq ($(BUILD_WIN32),True) LIBS += -lwinmm endif # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/cdio.cpp000066400000000000000000000374261516712004000243320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #if LIBCDIO_VERSION_NUM < 93 # include # define cdio_free(p) free(p) #endif #if HAVE_OLD_PARANOIA_INCLUDE # include #else # include #endif #include "cdio.h" #include "config.h" #ifndef PARANOIA_CB_CACHEERR # define PARANOIA_CB_CACHEERR 13 #endif using namespace smooth::IO; using namespace smooth::GUI::Dialogs; const String &BoCA::DecoderCDIO::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ CDIO Ripper Component %VERSION% \ 1.0 \ cdio-dec \ decoder \ cdio-info \ cdparanoia-dec \ \ Windows CD Audio Track \ true \ cda \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(String(cdio_version_string).Head(String(cdio_version_string).Find(" ")))); return componentSpecs; } namespace BoCA { void paranoiaCallback(long int offset, paranoia_cb_mode_t state) { if (state == PARANOIA_CB_CACHEERR) DecoderCDIO::readDecoder->numCacheErrors++; } }; BoCA::CDText BoCA::DecoderCDIO::cdText; UnsignedInt32 BoCA::DecoderCDIO::cdTextDiscID = 0; Array BoCA::DecoderCDIO::lastRead; Threads::Mutex BoCA::DecoderCDIO::readMutex; BoCA::DecoderCDIO *BoCA::DecoderCDIO::readDecoder = NIL; Bool BoCA::DecoderCDIO::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.StartsWith("device://cdda:") || lcURI.EndsWith(".cda"); } Error BoCA::DecoderCDIO::GetStreamInfo(const String &streamURI, Track &track) { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (component == NIL) return Error(); const Config *config = GetConfiguration(); track.isCDTrack = True; Format format; format.channels = 2; format.rate = 44100; format.bits = 16; format.order = BYTE_INTEL; track.SetFormat(format); Int trackNumber = -1; Int trackLength = 0; Int audiodrive = 0; if (streamURI.StartsWith("device://cdda:")) { audiodrive = streamURI.SubString(14, 1).ToInt(); trackNumber = streamURI.SubString(16, streamURI.Length() - 16).ToInt(); } else if (streamURI.EndsWith(".cda")) { /* Find track number and length. */ { InStream in(STREAM_FILE, streamURI, IS_READ); in.Seek(22); trackNumber = in.InputNumber(2); in.Seek(32); trackLength = in.InputNumber(4); } for (audiodrive = 0; audiodrive < component->GetNumberOfDevices(); audiodrive++) { Bool done = False; const MCDI &mcdi = component->GetNthDeviceMCDI(audiodrive); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) != ENTRY_AUDIO) continue; Int length = mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i); if (length == trackLength && mcdi.GetNthEntryTrackNumber(i) == trackNumber) { done = True; break; } } if (done) break; } } if (trackNumber == -1) return Error(); /* Fill MCDI data. */ Info info; info.mcdi = component->GetNthDeviceMCDI(audiodrive); Int entryNumber = -1; if (trackNumber == 0) { if (info.mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { entryNumber = 0; trackLength = info.mcdi.GetNthEntryOffset(0); } } else { for (Int i = 0; i < info.mcdi.GetNumberOfEntries(); i++) { if (info.mcdi.GetNthEntryType(i) == ENTRY_AUDIO && info.mcdi.GetNthEntryTrackNumber(i) == trackNumber) { entryNumber = i; trackLength = info.mcdi.GetNthEntryTrackLength(i); break; } } } if (entryNumber == -1) return Error(); track.length = trackLength * samplesPerSector; track.fileSize = trackLength * bytesPerSector; track.cdTrack = trackNumber; track.drive = audiodrive; track.outputFile = NIL; info.track = trackNumber; info.numTracks = info.mcdi.GetNumberOfAudioTracks(); info.SetOtherInfo(INFO_MEDIATYPE, I18n::Get()->TranslateString("CD", "Media types")); /* Read CD-Text. */ UnsignedInt32 discid = ComputeDiscID(info.mcdi); if (config->GetIntValue(ConfigureCDIO::ConfigID, "ReadCDText", True) && cdTextDiscID != discid) { cdText.ReadCDText(component->GetNthDeviceInfo(track.drive).path); cdTextDiscID = discid; } if (config->GetIntValue(ConfigureCDIO::ConfigID, "ReadCDText", True) && cdText.GetCDInfo().GetTrackTitle(trackNumber) != NIL) { const CDInfo &cdInfo = cdText.GetCDInfo(); info.SetOtherInfo(INFO_ALBUMARTIST, cdInfo.GetArtist()); info.title = cdInfo.GetTrackTitle(trackNumber); info.album = cdInfo.GetTitle(); info.genre = cdInfo.GetGenre(); if (cdInfo.GetTrackArtist(trackNumber) != NIL) info.artist = cdInfo.GetTrackArtist(trackNumber); else info.artist = cdInfo.GetArtist(); if (cdInfo.GetTrackComment(trackNumber) != NIL) info.comment = cdInfo.GetTrackComment(trackNumber); else info.comment = cdInfo.GetComment(); if (cdInfo.GetTrackSongwriter(trackNumber) != NIL) info.SetOtherInfo(INFO_LYRICIST, cdInfo.GetTrackSongwriter(trackNumber)); else if (cdInfo.GetSongwriter() != NIL) info.SetOtherInfo(INFO_LYRICIST, cdInfo.GetSongwriter()); if (cdInfo.GetTrackComposer(trackNumber) != NIL) info.SetOtherInfo(INFO_COMPOSER, cdInfo.GetTrackComposer(trackNumber)); else if (cdInfo.GetComposer() != NIL) info.SetOtherInfo(INFO_COMPOSER, cdInfo.GetComposer()); if (cdInfo.GetTrackArranger(trackNumber) != NIL) info.SetOtherInfo(INFO_ARRANGER, cdInfo.GetTrackArranger(trackNumber)); else if (cdInfo.GetArranger() != NIL) info.SetOtherInfo(INFO_ARRANGER, cdInfo.GetArranger()); if (cdInfo.GetCatalog() != NIL) info.SetOtherInfo(INFO_CATALOGNUMBER, cdInfo.GetCatalog()); if (cdInfo.GetBarcode() != NIL) info.SetOtherInfo(INFO_BARCODE, cdInfo.GetBarcode()); if (Info::IsISRC(cdInfo.GetTrackISRC(trackNumber))) info.isrc = cdInfo.GetTrackISRC(trackNumber); } /* Read ISRC if requested. */ if (config->GetIntValue(ConfigureCDIO::ConfigID, "ReadISRC", 0)) { CdIo_t *cd = cdio_open(component->GetNthDeviceInfo(track.drive).path, DRIVER_UNKNOWN); if (cd != NIL) { char *isrc = cdio_get_track_isrc(cd, track.cdTrack); if (isrc != NIL) { /* Check if the ISRC is valid. */ if (Info::IsISRC(isrc)) info.isrc = isrc; cdio_free(isrc); } cdio_destroy(cd); } } track.SetInfo(info); /* Delete DeviceInfo component. */ boca.DeleteComponent(component); return Success(); } BoCA::DecoderCDIO::DecoderCDIO() { configLayer = NIL; cd = NIL; drive = NIL; paranoia = NIL; nextSector = 0; sectorsLeft = 0; readOffset = 0; skipSamples = 0; prependSamples = 0; appendSamples = 0; numCacheErrors = 0; lastRead.EnableLocking(); } BoCA::DecoderCDIO::~DecoderCDIO() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderCDIO::Activate() { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (info != NIL) { if (lastRead.Length() == 0) for (Int i = 0; i < info->GetNumberOfDevices(); i++) lastRead.Add(0); cd = cdio_open(info->GetNthDeviceInfo(track.drive).path, DRIVER_UNKNOWN); boca.DeleteComponent(info); } if (cd == NIL) return False; /* Set ripping speed. */ const Config *config = GetConfiguration(); Int speed = config->GetIntValue(ConfigureCDIO::ConfigID, String("RippingSpeedDrive-").Append(GetDriveID()), 0); if (speed > 0) cdio_set_speed(cd, speed); else cdio_set_speed(cd, -1); /* Enable paranoia mode. */ paranoia = NIL; if (config->GetIntValue(ConfigureCDIO::ConfigID, "CDParanoia", False)) { int paranoiaMode = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP; switch (config->GetIntValue(ConfigureCDIO::ConfigID, "CDParanoiaMode", 3)) { case 0: paranoiaMode = PARANOIA_MODE_OVERLAP; break; case 1: paranoiaMode &= ~PARANOIA_MODE_VERIFY; break; case 2: paranoiaMode &= ~(PARANOIA_MODE_SCRATCH | PARANOIA_MODE_REPAIR); break; } drive = cdio_cddap_identify_cdio(cd, CDDA_MESSAGE_FORGETIT, NIL); cdio_cddap_open(drive); paranoia = cdio_paranoia_init(drive); cdio_paranoia_modeset(paranoia, paranoiaMode); } /* Call seek to initialize ripper to start of track. */ if (!Seek(0)) return False; return True; } Bool BoCA::DecoderCDIO::Deactivate() { if (cd == NIL) return False; /* Check for drive cache errors. */ if (numCacheErrors > 0) { Config *config = Config::Get(); Bool noCacheWarning = config->GetIntValue(ConfigureCDIO::ConfigID, "NoCacheWarning", False); if (!noCacheWarning) { MessageDlg *msgBox = new MessageDlg("The CD-ROM drive appears to be seeking impossibly quickly.\n" "This could be due to timer bugs, a drive that really is improbably fast,\n" "or, most likely, a bug in cdparanoia's cache modelling.\n\n" "Please consider using another drive for ripping audio CDs and send a bug\n" "report to support@freac.org to assist developers in correcting the problem.", "Warning", Message::Buttons::Ok, Message::Icon::Warning, "Do not display this warning again", &noCacheWarning); msgBox->ShowDialog(); config->SetIntValue(ConfigureCDIO::ConfigID, "NoCacheWarning", noCacheWarning); config->SaveSettings(); Object::DeleteObject(msgBox); } } if (paranoia != NIL) { cdio_paranoia_free(paranoia); cdio_cddap_close_no_free_cdio(drive); } cdio_destroy(cd); return True; } Bool BoCA::DecoderCDIO::Seek(Int64 samplePosition) { const Config *config = GetConfiguration(); Int startSector = 0; Int endSector = 0; Bool lastTrack = False; if (!GetTrackSectors(startSector, endSector, lastTrack)) return False; startSector += samplePosition / samplesPerSector; /* Calculate offset values. */ readOffset = config->GetIntValue(ConfigureCDIO::ConfigID, String("UseOffsetDrive-").Append(GetDriveID()), 0) ? config->GetIntValue(ConfigureCDIO::ConfigID, String("ReadOffsetDrive-").Append(GetDriveID()), 0) : 0; startSector += readOffset / Int(samplesPerSector); endSector += readOffset / Int(samplesPerSector); if (readOffset % Int(samplesPerSector) < 0) { startSector--; skipSamples = samplesPerSector + readOffset % Int(samplesPerSector); } else if (readOffset % Int(samplesPerSector) > 0) { if (!lastTrack) endSector++; skipSamples = readOffset % Int(samplesPerSector); } if (startSector < 0) { prependSamples = -startSector * samplesPerSector; startSector = 0; } if (lastTrack && readOffset > 0) { appendSamples = readOffset; endSector -= readOffset / samplesPerSector; } skipSamples += samplePosition % samplesPerSector; /* Set nextSector and sectors left to be read. */ nextSector = startSector; sectorsLeft = endSector - startSector + 1; /* Open ripper. */ if (paranoia != NIL) cdio_paranoia_seek(paranoia, startSector, SEEK_SET); inBytes = 4 * samplePosition; /* Wait for drive to spin up if requested. */ Int spinUpTime = config->GetIntValue(ConfigureCDIO::ConfigID, String("SpinUpTimeDrive-").Append(GetDriveID()), 0); UnsignedInt64 startTime = S::System::System::Clock(); while (spinUpTime > 0 && startTime - lastRead.GetNth(track.drive) > 2500 && S::System::System::Clock() - startTime < (UnsignedInt64) Math::Abs(spinUpTime * 1000)) { if (paranoia != NIL) { readMutex.Lock(); readDecoder = this; cdio_paranoia_read(paranoia, ¶noiaCallback); readMutex.Release(); cdio_paranoia_seek(paranoia, startSector, SEEK_SET); } else { Buffer buffer(bytesPerSector); cdio_read_audio_sectors(cd, buffer, nextSector, 1); } } return True; } Int BoCA::DecoderCDIO::ReadData(Buffer &data) { if (inBytes >= track.fileSize) return -1; /* Set up buffer respecting empty samples to prepend. */ Int sectors = Math::Min(sectorsLeft, paranoia == NIL ? 26 : 1); Int prependBytes = 4 * prependSamples; Int appendBytes = 4 * appendSamples; Int skipBytes = 4 * skipSamples; prependSamples = 0; skipSamples = 0; data.Resize(sectors * bytesPerSector + prependBytes); if (prependBytes > 0) data.Zero(); /* Append offset bytes to last track. */ if (sectors == 0) { data.Resize(prependBytes + appendBytes - skipBytes); data.Zero(); inBytes += data.Size(); return data.Size(); } /* Rip chunk. */ if (paranoia != NIL) { readMutex.Lock(); readDecoder = this; int16_t *audio = cdio_paranoia_read(paranoia, ¶noiaCallback); readMutex.Release(); if (audio == NIL) return -1; memcpy(data + prependBytes, audio, sectors * bytesPerSector); } else { driver_return_code_t error = cdio_read_audio_sectors(cd, data + prependBytes, nextSector, sectors); if (error != DRIVER_OP_SUCCESS) return -1; } nextSector += sectors; sectorsLeft -= sectors; lastRead.SetNth(track.drive, S::System::System::Clock()); /* Strip samples to skip from the beginning. */ Int dataBytes = Math::Min(track.fileSize - inBytes, (Int64) sectors * bytesPerSector + prependBytes - skipBytes); if (skipBytes > 0) memmove(data, data + skipBytes, dataBytes); inBytes += dataBytes; return dataBytes; } Bool BoCA::DecoderCDIO::GetTrackSectors(Int &startSector, Int &endSector, Bool &lastTrack) const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (component == NIL) return False; MCDI mcdi = component->GetNthDeviceMCDI(track.drive); boca.DeleteComponent(component); if (track.cdTrack == 0) { /* Special handling for hidden track one audio. */ if (mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { startSector = 0; endSector = mcdi.GetNthEntryOffset(0) - 1; lastTrack = False; return True; } } else { /* Handle regular tracks. */ for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryTrackNumber(i) == track.cdTrack) { startSector = mcdi.GetNthEntryOffset(i); endSector = startSector + mcdi.GetNthEntryTrackLength(i) - 1; if (mcdi.GetNthEntryType(i + 1) == ENTRY_AUDIO) lastTrack = False; else lastTrack = True; return True; } } } return False; } ConfigLayer *BoCA::DecoderCDIO::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureCDIO(); return configLayer; } String BoCA::DecoderCDIO::GetDriveID() const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (info == NIL) return NIL; const Device &device = info->GetNthDeviceInfo(track.drive); boca.DeleteComponent(info); return device.GetID(); } static int cddb_sum(int n) { int ret = 0; while (n > 0) { ret = ret + (n % 10); n = n / 10; } return ret; } UnsignedInt32 BoCA::DecoderCDIO::ComputeDiscID(const MCDI &mcdi) const { Int numTocEntries = mcdi.GetNumberOfEntries(); Int n = 0; for (Int i = 0; i < numTocEntries; i++) { Int offset = mcdi.GetNthEntryOffset(i) + 150; n += cddb_sum(offset / 75); } Int t = mcdi.GetNthEntryOffset(numTocEntries) / 75 - mcdi.GetNthEntryOffset(0) / 75; return ((n % 0xff) << 24 | t << 8 | numTocEntries); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/cdio.h000066400000000000000000000041261516712004000237660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #if HAVE_OLD_PARANOIA_INCLUDE # include #else # include #endif #include "info/cdtext.h" BoCA_BEGIN_COMPONENT(DecoderCDIO) namespace BoCA { class DecoderCDIO : public CS::DecoderComponent { friend void paranoiaCallback(long int, paranoia_cb_mode_t); constants: static const UnsignedInt bytesPerSector = 2352; static const UnsignedInt samplesPerSector = 588; private: static Threads::Mutex readMutex; static DecoderCDIO *readDecoder; static CDText cdText; static UnsignedInt32 cdTextDiscID; static Array lastRead; ConfigLayer *configLayer; CdIo_t *cd; cdrom_drive_t *drive; cdrom_paranoia_t *paranoia; Int nextSector; Int sectorsLeft; Int readOffset; Int skipSamples; Int prependSamples; Int appendSamples; Int numCacheErrors; String GetDriveID() const; UnsignedInt32 ComputeDiscID(const MCDI &) const; Bool GetTrackSectors(Int &, Int &, Bool &) const; public: static const String &GetComponentSpecs(); DecoderCDIO(); ~DecoderCDIO(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderCDIO) BoCA_END_COMPONENT(DecoderCDIO) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/config.cpp000066400000000000000000000325331516712004000246530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureCDIO::ConfigID = "Ripper"; BoCA::ConfigureCDIO::ConfigureCDIO() { const Config *config = Config::Get(); Bool notificationAvailable = config->GetIntValue("Internal", "NotificationAvailable", False); autoRead = notificationAvailable && config->GetIntValue(ConfigID, "AutoReadContents", True); autoRip = notificationAvailable && config->GetIntValue(ConfigID, "AutoRip", False); autoEject = config->GetIntValue(ConfigID, "EjectAfterRipping", False); readCDText = config->GetIntValue(ConfigID, "ReadCDText", True); readISRC = config->GetIntValue(ConfigID, "ReadISRC", False); cdparanoia = config->GetIntValue(ConfigID, "CDParanoia", False); I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); group_drive = new GroupBox(i18n->TranslateString("Active CD-ROM drive"), Point(7, 11), Size(354, 121)); combo_drive = new ComboBox(Point(10, 12), Size(334, 0)); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (info != NIL) { if (info->GetNumberOfDevices() == 0) group_drive->Deactivate(); for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); combo_drive->AddEntry(device.GetName()); driveOffsetUsed.Add(config->GetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), 0)); driveOffsets.Add(config->GetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), 0)); driveSpeeds.Add(config->GetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), 0)); driveSpinUpTimes.Add(config->GetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), -5)); } boca.DeleteComponent(info); } combo_drive->SelectNthEntry(config->GetIntValue(ConfigID, "ActiveDrive", 0)); combo_drive->onSelectEntry.Connect(&ConfigureCDIO::SelectDrive, this); useoffset = driveOffsetUsed.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); spinup = driveSpinUpTimes.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)) > 0; setspeed = driveSpeeds.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); check_speed = new CheckBox(i18n->AddColon(i18n->TranslateString("Set drive speed limit")), Point(10, 40), Size(162, 0), &setspeed); check_speed->onAction.Connect(&ConfigureCDIO::ToggleSetSpeed, this); check_spinup = new CheckBox(i18n->AddColon(i18n->TranslateString("Spin up before ripping")), Point(10, 67), Size(162, 0), &spinup); check_spinup->onAction.Connect(&ConfigureCDIO::ToggleSpinUp, this); check_offset = new CheckBox(i18n->AddColon(i18n->TranslateString("Use read offset")), Point(10, 94), Size(162, 0), &useoffset); check_offset->onAction.Connect(&ConfigureCDIO::ToggleUseOffset, this); Int maxTextSize = Math::Max(Math::Max(check_speed->GetUnscaledTextWidth(), check_spinup->GetUnscaledTextWidth()), check_offset->GetUnscaledTextWidth()); check_speed->SetWidth(maxTextSize + 21); check_spinup->SetWidth(maxTextSize + 21); check_offset->SetWidth(maxTextSize + 21); combo_speed = new ComboBox(Point(39 + maxTextSize, 39), Size(305 - maxTextSize, 0)); combo_speed->onSelectEntry.Connect(&ConfigureCDIO::SelectSpeed, this); for (Int i = 48; i > 0; i -= 4) combo_speed->AddEntry(String::FromInt(i).Append("x")); text_spinup_seconds = new Text(i18n->TranslateString("%1 seconds").Replace("%1", "00"), Point(275, 69)); text_spinup_seconds->SetX(343 - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup = new Slider(Point(39 + maxTextSize, 67), Size(86, 0), OR_HORZ, NIL, 1, 30); slider_spinup->SetWidth(335 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup->onValueChange.Connect(&ConfigureCDIO::ChangeSpinUpTime, this); edit_offset = new EditBox(Point(39 + maxTextSize, 93), Size(36, 0), 5); edit_offset->SetFlags(EDB_NUMERIC); edit_offset->onInput.Connect(&ConfigureCDIO::ChangeOffset, this); text_offset_samples = new Text(i18n->TranslateString("samples"), Point(edit_offset->GetX() + edit_offset->GetWidth() + 8, 96)); SelectDrive(); group_drive->Add(combo_drive); group_drive->Add(check_speed); group_drive->Add(combo_speed); group_drive->Add(check_spinup); group_drive->Add(slider_spinup); group_drive->Add(text_spinup_seconds); group_drive->Add(check_offset); group_drive->Add(edit_offset); group_drive->Add(text_offset_samples); group_cdinfo = new GroupBox(i18n->TranslateString("CD information"), Point(7, 144), Size(354, 65)); check_readCDText = new CheckBox(i18n->TranslateString("Read CD-Text"), Point(10, 11), Size(162, 0), &readCDText); check_readISRC = new CheckBox(i18n->TranslateString("Read ISRC when adding tracks to joblist"), Point(10, 37), Size(333, 0), &readISRC); check_readCDText->SetWidth(Math::Max(162, check_readCDText->GetUnscaledTextWidth() + 21)); check_readISRC->SetWidth(Math::Max(333, check_readISRC->GetUnscaledTextWidth() + 21)); group_cdinfo->SetWidth(Math::Max(check_readCDText->GetWidth(), check_readISRC->GetWidth()) + 20); group_cdinfo->Add(check_readCDText); group_cdinfo->Add(check_readISRC); group_ripping = new GroupBox(i18n->TranslateString("Ripper settings"), Point(7, 221), Size(354, 42)); check_paranoia = new CheckBox(i18n->AddColon(i18n->TranslateString("Activate cdparanoia mode")), Point(10, 14), Size(162, 0), &cdparanoia); check_paranoia->onAction.Connect(&ConfigureCDIO::ToggleParanoia, this); combo_paranoia_mode = new ComboBox(Point(181, 13), Size(162, 0)); combo_paranoia_mode->AddEntry(i18n->TranslateString("Overlap only")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No verify")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No scratch repair")); combo_paranoia_mode->AddEntry(i18n->TranslateString("Full cdparanoia mode")); combo_paranoia_mode->SelectNthEntry(config->GetIntValue(ConfigID, "CDParanoiaMode", 3)); ToggleParanoia(); check_paranoia->SetWidth(Math::Max(162, check_paranoia->GetUnscaledTextWidth() + 21)); combo_paranoia_mode->SetX(check_paranoia->GetWidth() + 19); group_ripping->SetWidth(check_paranoia->GetWidth() + combo_paranoia_mode->GetWidth() + 29); group_ripping->Add(check_paranoia); group_ripping->Add(combo_paranoia_mode); group_drive->SetWidth(Math::Max(group_cdinfo->GetWidth(), group_ripping->GetWidth())); group_cdinfo->SetWidth(group_drive->GetWidth()); group_ripping->SetWidth(group_drive->GetWidth()); combo_drive->SetWidth(group_drive->GetWidth() - 20); combo_speed->SetWidth(group_drive->GetWidth() - check_speed->GetWidth() - 28); slider_spinup->SetWidth(group_drive->GetWidth() - 24 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); text_spinup_seconds->SetX(group_drive->GetWidth() - 16 - text_spinup_seconds->GetUnscaledTextWidth()); check_readISRC->SetWidth(group_cdinfo->GetWidth() - 20); group_automatization = new GroupBox(i18n->TranslateString("Automatization"), Point(group_drive->GetWidth() + 15, 11), Size(190, 94)); check_autoRead = new CheckBox(i18n->TranslateString("Read CD contents on insert"), Point(10, 14), Size(170, 0), &autoRead); check_autoRead->onAction.Connect(&ConfigureCDIO::ToggleAutoRead, this); if (!notificationAvailable) check_autoRead->Deactivate(); check_autoRip = new CheckBox(i18n->TranslateString("Start ripping automatically"), check_autoRead->GetPosition() + Point(0, 26), Size(170, 0), &autoRip); check_autoEject = new CheckBox(i18n->TranslateString("Eject disc after ripping"), check_autoRip->GetPosition() + Point(0, 26), Size(170, 0), &autoEject); group_automatization->Add(check_autoRead); group_automatization->Add(check_autoRip); group_automatization->Add(check_autoEject); maxTextSize = Math::Max(Math::Max(check_autoRead->GetUnscaledTextWidth(), check_autoRip->GetUnscaledTextWidth()), check_autoEject->GetUnscaledTextWidth()); check_autoRead->SetWidth(Math::Max(149, maxTextSize + 21)); check_autoRip->SetWidth(check_autoRead->GetWidth()); check_autoEject->SetWidth(check_autoRead->GetWidth()); group_automatization->SetWidth(check_autoRead->GetWidth() + 20); ToggleAutoRead(); Add(group_drive); Add(group_ripping); Add(group_automatization); Add(group_cdinfo); SetSize(Size(group_drive->GetWidth() + group_automatization->GetWidth() + 22, 270)); } BoCA::ConfigureCDIO::~ConfigureCDIO() { DeleteObject(group_drive); DeleteObject(combo_drive); DeleteObject(check_speed); DeleteObject(combo_speed); DeleteObject(check_spinup); DeleteObject(slider_spinup); DeleteObject(text_spinup_seconds); DeleteObject(check_offset); DeleteObject(edit_offset); DeleteObject(text_offset_samples); DeleteObject(group_ripping); DeleteObject(check_paranoia); DeleteObject(combo_paranoia_mode); DeleteObject(group_automatization); DeleteObject(check_autoRead); DeleteObject(check_autoRip); DeleteObject(check_autoEject); DeleteObject(group_cdinfo); DeleteObject(check_readCDText); DeleteObject(check_readISRC); } Void BoCA::ConfigureCDIO::SelectDrive() { edit_offset->SetText(String::FromInt(driveOffsets.GetNth(combo_drive->GetSelectedEntryNumber()))); combo_speed->SelectNthEntry((48 - driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())) / 4); check_offset->SetChecked(driveOffsetUsed.GetNth(combo_drive->GetSelectedEntryNumber())); check_speed->SetChecked(driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())); check_spinup->SetChecked(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()) > 0); slider_spinup->SetValue(Math::Abs(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()))); ToggleUseOffset(); ToggleSetSpeed(); ToggleSpinUp(); } Void BoCA::ConfigureCDIO::ToggleUseOffset() { driveOffsetUsed.SetNth(combo_drive->GetSelectedEntryNumber(), useoffset); if (useoffset) { edit_offset->Activate(); text_offset_samples->Activate(); } else { edit_offset->Deactivate(); text_offset_samples->Deactivate(); } } Void BoCA::ConfigureCDIO::ChangeOffset() { if (!useoffset) return; driveOffsets.SetNth(combo_drive->GetSelectedEntryNumber(), edit_offset->GetText().ToInt()); } Void BoCA::ConfigureCDIO::ToggleSpinUp() { driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); if (spinup) { slider_spinup->Activate(); text_spinup_seconds->Activate(); } else { slider_spinup->Deactivate(); text_spinup_seconds->Deactivate(); } } Void BoCA::ConfigureCDIO::ChangeSpinUpTime() { I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); text_spinup_seconds->SetText(i18n->TranslateString("%1 seconds").Replace("%1", String::FromInt(slider_spinup->GetValue()))); driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); } Void BoCA::ConfigureCDIO::ToggleSetSpeed() { if (setspeed) { combo_speed->Activate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } else { combo_speed->Deactivate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 0); } } Void BoCA::ConfigureCDIO::SelectSpeed() { if (!setspeed) return; driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } Void BoCA::ConfigureCDIO::ToggleParanoia() { if (cdparanoia) combo_paranoia_mode->Activate(); else combo_paranoia_mode->Deactivate(); } Void BoCA::ConfigureCDIO::ToggleAutoRead() { if (autoRead) check_autoRip->Activate(); else check_autoRip->Deactivate(); } Int BoCA::ConfigureCDIO::SaveSettings() { Config *config = Config::Get(); if (driveSpeeds.Length() >= 1) config->SetIntValue(ConfigID, "ActiveDrive", combo_drive->GetSelectedEntryNumber()); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdio-info"); if (info != NIL) { for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); config->SetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), driveOffsetUsed.GetNth(i)); config->SetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), driveOffsets.GetNth(i)); config->SetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), driveSpeeds.GetNth(i)); config->SetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), driveSpinUpTimes.GetNth(i)); } boca.DeleteComponent(info); } if (config->GetIntValue("Internal", "NotificationAvailable", False)) { config->SetIntValue(ConfigID, "AutoReadContents", autoRead); config->SetIntValue(ConfigID, "AutoRip", autoRip); } config->SetIntValue(ConfigID, "EjectAfterRipping", autoEject); config->SetIntValue(ConfigID, "ReadCDText", readCDText); config->SetIntValue(ConfigID, "ReadISRC", readISRC); config->SetIntValue(ConfigID, "CDParanoia", cdparanoia); config->SetIntValue(ConfigID, "CDParanoiaMode", combo_paranoia_mode->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/config.h000066400000000000000000000041271516712004000243160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDIOCONFIG #define H_CDIOCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCDIO : public ConfigLayer { private: GroupBox *group_drive; ComboBox *combo_drive; CheckBox *check_speed; ComboBox *combo_speed; CheckBox *check_spinup; Slider *slider_spinup; Text *text_spinup_seconds; CheckBox *check_offset; EditBox *edit_offset; Text *text_offset_samples; GroupBox *group_ripping; CheckBox *check_paranoia; ComboBox *combo_paranoia_mode; GroupBox *group_automatization; CheckBox *check_autoRead; CheckBox *check_autoRip; CheckBox *check_autoEject; GroupBox *group_cdinfo; CheckBox *check_readCDText; CheckBox *check_readISRC; Bool setspeed; Bool spinup; Bool useoffset; Bool cdparanoia; Bool autoRead; Bool autoRip; Bool autoEject; Bool readCDText; Bool readISRC; Array driveOffsetUsed; Array driveOffsets; Array driveSpeeds; Array driveSpinUpTimes; slots: Void SelectDrive(); Void ToggleSetSpeed(); Void SelectSpeed(); Void ToggleSpinUp(); Void ChangeSpinUpTime(); Void ToggleUseOffset(); Void ChangeOffset(); Void ToggleParanoia(); Void ToggleAutoRead(); public: static const String ConfigID; ConfigureCDIO(); ~ConfigureCDIO(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/info/000077500000000000000000000000001516712004000236275ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/info/cdinfo.cpp000066400000000000000000000046621516712004000256050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cdinfo.h" BoCA::CDInfo::CDInfo() { } BoCA::CDInfo::~CDInfo() { } Int BoCA::CDInfo::Clear() { artist = NIL; title = NIL; songwriter = NIL; composer = NIL; arranger = NIL; comment = NIL; genre = NIL; catalog = NIL; barcode = NIL; trackArtists.RemoveAll(); trackTitles.RemoveAll(); trackSongwriters.RemoveAll(); trackComposers.RemoveAll(); trackArrangers.RemoveAll(); trackComments.RemoveAll(); trackISRCs.RemoveAll(); return Success(); } Void BoCA::CDInfo::ReserveTracks(Int n) { while (trackArtists.Length() < n) { trackArtists.Add(NIL); trackTitles.Add(NIL); trackSongwriters.Add(NIL); trackComposers.Add(NIL); trackArrangers.Add(NIL); trackComments.Add(NIL); trackISRCs.Add(NIL); } } Void BoCA::CDInfo::SetTrackArtist(Int n, const String &nArtist) { ReserveTracks(n); if (nArtist.Trim() != NIL) trackArtists.SetNth(n - 1, nArtist); } Void BoCA::CDInfo::SetTrackTitle(Int n, const String &nTitle) { ReserveTracks(n); if (nTitle.Trim() != NIL) trackTitles.SetNth(n - 1, nTitle); } Void BoCA::CDInfo::SetTrackSongwriter(Int n, const String &nSongwriter) { ReserveTracks(n); if (nSongwriter.Trim() != NIL) trackSongwriters.SetNth(n - 1, nSongwriter); } Void BoCA::CDInfo::SetTrackComposer(Int n, const String &nComposer) { ReserveTracks(n); if (nComposer.Trim() != NIL) trackComposers.SetNth(n - 1, nComposer); } Void BoCA::CDInfo::SetTrackArranger(Int n, const String &nArranger) { ReserveTracks(n); if (nArranger.Trim() != NIL) trackArrangers.SetNth(n - 1, nArranger); } Void BoCA::CDInfo::SetTrackComment(Int n, const String &nComment) { ReserveTracks(n); if (nComment.Trim() != NIL) trackComments.SetNth(n - 1, nComment); } Void BoCA::CDInfo::SetTrackISRC(Int n, const String &nISRC) { ReserveTracks(n); if (nISRC.Trim() != NIL) trackISRCs.SetNth(n - 1, nISRC.Replace(" ", NIL).Replace("-", NIL)); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/info/cdinfo.h000066400000000000000000000066241516712004000252520ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDIO_CDINFO #define H_CDIO_CDINFO #include using namespace smooth; namespace BoCA { class CDInfo { private: String artist; String title; String songwriter; String composer; String arranger; String comment; String genre; String catalog; String barcode; Array trackArtists; Array trackTitles; Array trackSongwriters; Array trackComposers; Array trackArrangers; Array trackComments; Array trackISRCs; Void ReserveTracks(Int); public: CDInfo(); ~CDInfo(); Int Clear(); accessors: /* Per-disc information. */ Void SetArtist(const String &nArtist) { artist = nArtist; } const String &GetArtist() const { return artist; } Void SetTitle(const String &nTitle) { title = nTitle; } const String &GetTitle() const { return title; } Void SetSongwriter(const String &nSongwriter) { songwriter = nSongwriter; } const String &GetSongwriter() const { return songwriter; } Void SetComposer(const String &nComposer) { composer = nComposer; } const String &GetComposer() const { return composer; } Void SetArranger(const String &nArranger) { arranger = nArranger; } const String &GetArranger() const { return arranger; } Void SetComment(const String &nComment) { comment = nComment; } const String &GetComment() const { return comment; } Void SetGenre(const String &nGenre) { genre = nGenre; } const String &GetGenre() const { return genre; } Void SetCatalog(const String &nCatalog) { catalog = nCatalog; } const String &GetCatalog() const { return catalog; } Void SetBarcode(const String &nBarcode) { barcode = nBarcode; } const String &GetBarcode() const { return barcode; } /* Optional per-track information. */ Void SetTrackArtist(Int n, const String &); const String &GetTrackArtist(Int n) const { return trackArtists.GetNth(n - 1); } Void SetTrackTitle(Int n, const String &); const String &GetTrackTitle(Int n) const { return trackTitles.GetNth(n - 1); } Void SetTrackSongwriter(Int n, const String &); const String &GetTrackSongwriter(Int n) const { return trackSongwriters.GetNth(n - 1); } Void SetTrackComposer(Int n, const String &); const String &GetTrackComposer(Int n) const { return trackComposers.GetNth(n - 1); } Void SetTrackArranger(Int n, const String &); const String &GetTrackArranger(Int n) const { return trackArrangers.GetNth(n - 1); } Void SetTrackComment(Int n, const String &); const String &GetTrackComment(Int n) const { return trackComments.GetNth(n - 1); } Void SetTrackISRC(Int n, const String &); const String &GetTrackISRC(Int n) const { return trackISRCs.GetNth(n - 1); } }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/info/cdtext.cpp000066400000000000000000000117601516712004000256330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cdtext.h" #include BoCA::CDText::CDText() { } BoCA::CDText::~CDText() { } Int BoCA::CDText::ReadCDText(const String &path) { CdIo_t *cd = cdio_open(path, DRIVER_UNKNOWN); if (cd == NIL) return Error(); cdInfo.Clear(); Int firstTrack = cdio_get_first_track_num(cd); Int lastTrack = cdio_get_last_track_num(cd); #if LIBCDIO_VERSION_NUM >= 90 cdtext_t *cdtext = cdio_get_cdtext(cd); if (cdtext != NIL) { cdInfo.SetArtist (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_PERFORMER, 0))); cdInfo.SetTitle (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_TITLE, 0))); cdInfo.SetSongwriter(ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_SONGWRITER, 0))); cdInfo.SetComposer (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_COMPOSER, 0))); cdInfo.SetArranger (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_ARRANGER, 0))); cdInfo.SetComment (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_MESSAGE, 0))); cdInfo.SetGenre (ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_GENRE, 0))); cdInfo.SetCatalog ( cdtext_get_const(cdtext, CDTEXT_FIELD_DISCID, 0)); cdInfo.SetBarcode ( cdtext_get_const(cdtext, CDTEXT_FIELD_UPC_EAN, 0)); if (cdInfo.GetGenre() == NIL) { cdtext_genre_t genre = cdtext_get_genre(cdtext); cdtext_genre_t genre_le = cdtext_genre_t((genre & 0xFF) << 8 | genre >> 8); if (genre < 28) cdInfo.SetGenre(cdtext_genre2str(genre)); else if (genre_le < 28) cdInfo.SetGenre(cdtext_genre2str(genre_le)); } for (Int i = firstTrack; i <= lastTrack; i++) { cdInfo.SetTrackArtist (i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_PERFORMER, i))); cdInfo.SetTrackTitle (i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_TITLE, i))); cdInfo.SetTrackSongwriter(i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_SONGWRITER, i))); cdInfo.SetTrackComposer (i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_COMPOSER, i))); cdInfo.SetTrackArranger (i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_ARRANGER, i))); cdInfo.SetTrackComment (i, ReplaceFullWidthChars(cdtext_get_const(cdtext, CDTEXT_FIELD_MESSAGE, i))); cdInfo.SetTrackISRC (i, cdtext_get_const(cdtext, CDTEXT_FIELD_ISRC, i)); } } #else cdtext_t *cdtext = cdio_get_cdtext(cd, 0); if (cdtext != NIL) { cdInfo.SetArtist (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_PERFORMER, cdtext))); cdInfo.SetTitle (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_TITLE, cdtext))); cdInfo.SetSongwriter(ReplaceFullWidthChars(cdtext_get_const(CDTEXT_SONGWRITER, cdtext))); cdInfo.SetComposer (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_COMPOSER, cdtext))); cdInfo.SetArranger (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_ARRANGER, cdtext))); cdInfo.SetComment (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_MESSAGE, cdtext))); cdInfo.SetGenre (ReplaceFullWidthChars(cdtext_get_const(CDTEXT_GENRE, cdtext))); cdInfo.SetCatalog ( cdtext_get_const(CDTEXT_DISCID, cdtext)); cdInfo.SetBarcode ( cdtext_get_const(CDTEXT_UPC_EAN, cdtext)); for (Int i = firstTrack; i <= lastTrack; i++) { cdtext_t *cdtext = cdio_get_cdtext(cd, i); cdInfo.SetTrackArtist (i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_PERFORMER, cdtext))); cdInfo.SetTrackTitle (i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_TITLE, cdtext))); cdInfo.SetTrackSongwriter(i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_SONGWRITER, cdtext))); cdInfo.SetTrackComposer (i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_COMPOSER, cdtext))); cdInfo.SetTrackArranger (i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_ARRANGER, cdtext))); cdInfo.SetTrackComment (i, ReplaceFullWidthChars(cdtext_get_const(CDTEXT_MESSAGE, cdtext))); cdInfo.SetTrackISRC (i, cdtext_get_const(CDTEXT_ISRC, cdtext)); } } #endif cdio_destroy(cd); return Success(); } const BoCA::CDInfo &BoCA::CDText::GetCDInfo() const { return cdInfo; } String BoCA::CDText::ReplaceFullWidthChars(const String &string) { String result = string; Int length = string.Length(); for (Int i = 0; i < length; i++) { if (result[i] >= 0xff01 && result[i] <= 0xff5e) result[i] -= 0xfee0; else if (result[i] == 0x3000 ) result[i] = 0x20; } return result; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdio/info/cdtext.h000066400000000000000000000016641516712004000253020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDIO_CDTEXT #define H_CDIO_CDTEXT #include using namespace smooth; #include "cdinfo.h" namespace BoCA { class CDText { private: CDInfo cdInfo; static String ReplaceFullWidthChars(const String &); public: CDText(); ~CDText(); Int ReadCDText(const String &); const CDInfo &GetCDInfo() const; }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/000077500000000000000000000000001516712004000240575ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/Makefile000066400000000000000000000012331516712004000255160ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdparanoia TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = cdparanoia.o config.o # Enter additional defines here: DEFINE = -I /usr/include/cdda # Enter additional library dependencies here: LIBS = -lcdda_interface -lcdda_paranoia # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/cdparanoia.cpp000066400000000000000000000312161516712004000266670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ extern "C" { # include # include } #include "cdparanoia.h" #include "config.h" using namespace smooth::IO; using namespace smooth::GUI::Dialogs; const String &BoCA::DecoderCDParanoia::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ cdparanoia Ripper Component %VERSION% \ 1.0 \ cdparanoia-dec \ decoder \ cdparanoia-info \ \ Windows CD Audio Track \ true \ cda \ \ \ \ "; #ifdef PARANOIA_CB_CACHEERR componentSpecs.Replace("%VERSION%", String("v").Append(cdda_version())); #else componentSpecs.Replace("%VERSION%", NIL); #endif return componentSpecs; } namespace BoCA { void paranoiaCallback(long offset, int state) { #ifdef PARANOIA_CB_CACHEERR if (state == PARANOIA_CB_CACHEERR) DecoderCDParanoia::readDecoder->numCacheErrors++; #endif } }; Array BoCA::DecoderCDParanoia::lastRead; Threads::Mutex BoCA::DecoderCDParanoia::readMutex; BoCA::DecoderCDParanoia *BoCA::DecoderCDParanoia::readDecoder = NIL; Bool BoCA::DecoderCDParanoia::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.StartsWith("device://cdda:") || lcURI.EndsWith(".cda"); } Error BoCA::DecoderCDParanoia::GetStreamInfo(const String &streamURI, Track &track) { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (component == NIL) return Error(); track.isCDTrack = True; Format format; format.channels = 2; format.rate = 44100; format.bits = 16; format.order = BYTE_INTEL; track.SetFormat(format); Int trackNumber = -1; Int trackLength = 0; Int audiodrive = 0; if (streamURI.StartsWith("device://cdda:")) { audiodrive = streamURI.SubString(14, 1).ToInt(); trackNumber = streamURI.SubString(16, streamURI.Length() - 16).ToInt(); } else if (streamURI.EndsWith(".cda")) { /* Find track number and length. */ { InStream in(STREAM_FILE, streamURI, IS_READ); in.Seek(22); trackNumber = in.InputNumber(2); in.Seek(32); trackLength = in.InputNumber(4); } for (audiodrive = 0; audiodrive < component->GetNumberOfDevices(); audiodrive++) { Bool done = False; const MCDI &mcdi = component->GetNthDeviceMCDI(audiodrive); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) != ENTRY_AUDIO) continue; Int length = mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i); if (length == trackLength && mcdi.GetNthEntryTrackNumber(i) == trackNumber) { done = True; break; } } if (done) break; } } if (trackNumber == -1) return Error(); /* Fill MCDI data. */ Info info; info.mcdi = component->GetNthDeviceMCDI(audiodrive); Int entryNumber = -1; if (trackNumber == 0) { if (info.mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { entryNumber = 0; trackLength = info.mcdi.GetNthEntryOffset(0); } } else { for (Int i = 0; i < info.mcdi.GetNumberOfEntries(); i++) { if (info.mcdi.GetNthEntryType(i) == ENTRY_AUDIO && info.mcdi.GetNthEntryTrackNumber(i) == trackNumber) { entryNumber = i; trackLength = info.mcdi.GetNthEntryTrackLength(i); break; } } } if (entryNumber == -1) return Error(); track.length = trackLength * samplesPerSector; track.fileSize = trackLength * bytesPerSector; track.cdTrack = trackNumber; track.drive = audiodrive; track.outputFile = NIL; info.track = trackNumber; info.numTracks = info.mcdi.GetNumberOfAudioTracks(); info.SetOtherInfo(INFO_MEDIATYPE, I18n::Get()->TranslateString("CD", "Media types")); track.SetInfo(info); /* Delete DeviceInfo component. */ boca.DeleteComponent(component); return Success(); } BoCA::DecoderCDParanoia::DecoderCDParanoia() { configLayer = NIL; drive = NIL; paranoia = NIL; nextSector = 0; sectorsLeft = 0; readOffset = 0; skipSamples = 0; prependSamples = 0; appendSamples = 0; numCacheErrors = 0; lastRead.EnableLocking(); } BoCA::DecoderCDParanoia::~DecoderCDParanoia() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderCDParanoia::Activate() { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (info != NIL) { if (lastRead.Length() == 0) for (Int i = 0; i < info->GetNumberOfDevices(); i++) lastRead.Add(0); drive = cdda_identify(info->GetNthDeviceInfo(track.drive).path, CDDA_MESSAGE_FORGETIT, NIL); boca.DeleteComponent(info); } if (drive == NIL) return False; cdda_open(drive); /* Set ripping spped. */ const Config *config = GetConfiguration(); Int speed = config->GetIntValue(ConfigureCDParanoia::ConfigID, String("RippingSpeedDrive-").Append(GetDriveID()), 0); if (speed > 0) cdda_speed_set(drive, speed); else cdda_speed_set(drive, -1); /* Enable paranoia mode. */ paranoia = NIL; if (config->GetIntValue(ConfigureCDParanoia::ConfigID, "CDParanoia", False)) { int paranoiaMode = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP; switch (config->GetIntValue(ConfigureCDParanoia::ConfigID, "CDParanoiaMode", 3)) { case 0: paranoiaMode = PARANOIA_MODE_OVERLAP; break; case 1: paranoiaMode &= ~PARANOIA_MODE_VERIFY; break; case 2: paranoiaMode &= ~(PARANOIA_MODE_SCRATCH | PARANOIA_MODE_REPAIR); break; } paranoia = paranoia_init(drive); paranoia_modeset(paranoia, paranoiaMode); } /* Call seek to initialize ripper to start of track. */ if (!Seek(0)) return False; return True; } Bool BoCA::DecoderCDParanoia::Deactivate() { if (drive == NIL) return False; /* Check for drive cache errors. */ if (numCacheErrors > 0) { Config *config = Config::Get(); Bool noCacheWarning = config->GetIntValue(ConfigureCDParanoia::ConfigID, "NoCacheWarning", False); if (!noCacheWarning) { MessageDlg *msgBox = new MessageDlg("The CD-ROM drive appears to be seeking impossibly quickly.\n" "This could be due to timer bugs, a drive that really is improbably fast,\n" "or, most likely, a bug in cdparanoia's cache modelling.\n\n" "Please consider using another drive for ripping audio CDs and send a bug\n" "report to support@freac.org to assist developers in correcting the problem.", "Warning", Message::Buttons::Ok, Message::Icon::Warning, "Do not display this warning again", &noCacheWarning); msgBox->ShowDialog(); config->SetIntValue(ConfigureCDParanoia::ConfigID, "NoCacheWarning", noCacheWarning); config->SaveSettings(); Object::DeleteObject(msgBox); } } if (paranoia != NIL) paranoia_free(paranoia); cdda_close(drive); return True; } Bool BoCA::DecoderCDParanoia::Seek(Int64 samplePosition) { const Config *config = GetConfiguration(); Int startSector = 0; Int endSector = 0; Bool lastTrack = False; if (!GetTrackSectors(startSector, endSector, lastTrack)) return False; startSector += samplePosition / samplesPerSector; /* Calculate offset values. */ readOffset = config->GetIntValue(ConfigureCDParanoia::ConfigID, String("UseOffsetDrive-").Append(GetDriveID()), 0) ? config->GetIntValue(ConfigureCDParanoia::ConfigID, String("ReadOffsetDrive-").Append(GetDriveID()), 0) : 0; startSector += readOffset / Int(samplesPerSector); endSector += readOffset / Int(samplesPerSector); if (readOffset % Int(samplesPerSector) < 0) { startSector--; skipSamples = samplesPerSector + readOffset % Int(samplesPerSector); } else if (readOffset % Int(samplesPerSector) > 0) { if (!lastTrack) endSector++; skipSamples = readOffset % Int(samplesPerSector); } if (startSector < 0) { prependSamples = -startSector * samplesPerSector; startSector = 0; } if (lastTrack && readOffset > 0) { appendSamples = readOffset; endSector -= readOffset / samplesPerSector; } skipSamples += samplePosition % samplesPerSector; /* Set nextSector and sectors left to be read. */ nextSector = startSector; sectorsLeft = endSector - startSector + 1; /* Open ripper. */ if (paranoia != NIL) paranoia_seek(paranoia, startSector, SEEK_SET); inBytes = 4 * samplePosition; /* Wait for drive to spin up if requested. */ Int spinUpTime = config->GetIntValue(ConfigureCDParanoia::ConfigID, String("SpinUpTimeDrive-").Append(GetDriveID()), 0); UnsignedInt64 startTime = S::System::System::Clock(); while (spinUpTime > 0 && startTime - lastRead.GetNth(track.drive) > 2500 && S::System::System::Clock() - startTime < (UnsignedInt64) Math::Abs(spinUpTime * 1000)) { if (paranoia != NIL) { readMutex.Lock(); readDecoder = this; paranoia_read(paranoia, ¶noiaCallback); readMutex.Release(); paranoia_seek(paranoia, startSector, SEEK_SET); } else { Buffer buffer(bytesPerSector); cdda_read(drive, buffer, nextSector, 1); } } return True; } Int BoCA::DecoderCDParanoia::ReadData(Buffer &data) { if (inBytes >= track.fileSize) return -1; /* Set up buffer respecting empty samples to prepend. */ Int sectors = Math::Min(sectorsLeft, paranoia == NIL ? 26 : 1); Int prependBytes = 4 * prependSamples; Int appendBytes = 4 * appendSamples; Int skipBytes = 4 * skipSamples; prependSamples = 0; skipSamples = 0; data.Resize(sectors * bytesPerSector + prependBytes); if (prependBytes > 0) data.Zero(); /* Append offset bytes to last track. */ if (sectors == 0) { data.Resize(prependBytes + appendBytes - skipBytes); data.Zero(); inBytes += data.Size(); return data.Size(); } /* Rip chunk. */ if (paranoia != NIL) { readMutex.Lock(); readDecoder = this; int16_t *audio = paranoia_read(paranoia, ¶noiaCallback); readMutex.Release(); if (audio == NIL) return -1; memcpy(data + prependBytes, audio, sectors * bytesPerSector); } else { int sectors = cdda_read(drive, data + prependBytes, nextSector, sectors); if (sectors <= 0) return -1; } nextSector += sectors; sectorsLeft -= sectors; lastRead.SetNth(track.drive, S::System::System::Clock()); /* Strip samples to skip from the beginning. */ Int dataBytes = Math::Min(track.fileSize - inBytes, (Int64) sectors * bytesPerSector + prependBytes - skipBytes); if (skipBytes > 0) memmove(data, data + skipBytes, dataBytes); inBytes += dataBytes; return dataBytes; } Bool BoCA::DecoderCDParanoia::GetTrackSectors(Int &startSector, Int &endSector, Bool &lastTrack) const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (component == NIL) return False; MCDI mcdi = component->GetNthDeviceMCDI(track.drive); boca.DeleteComponent(component); if (track.cdTrack == 0) { /* Special handling for hidden track one audio. */ if (mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { startSector = 0; endSector = mcdi.GetNthEntryOffset(0) - 1; lastTrack = False; return True; } } else { /* Handle regular tracks. */ for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryTrackNumber(i) == track.cdTrack) { startSector = mcdi.GetNthEntryOffset(i); endSector = startSector + mcdi.GetNthEntryTrackLength(i) - 1; if (mcdi.GetNthEntryType(i + 1) == ENTRY_AUDIO) lastTrack = False; else lastTrack = True; return True; } } } return False; } ConfigLayer *BoCA::DecoderCDParanoia::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureCDParanoia(); return configLayer; } String BoCA::DecoderCDParanoia::GetDriveID() const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (info == NIL) return NIL; const Device &device = info->GetNthDeviceInfo(track.drive); boca.DeleteComponent(info); return device.GetID(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/cdparanoia.h000066400000000000000000000036041516712004000263340ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include extern "C" { # include # include } BoCA_BEGIN_COMPONENT(DecoderCDParanoia) namespace BoCA { class DecoderCDParanoia : public CS::DecoderComponent { friend void paranoiaCallback(long, int); constants: static const UnsignedInt bytesPerSector = 2352; static const UnsignedInt samplesPerSector = 588; private: static Threads::Mutex readMutex; static DecoderCDParanoia *readDecoder; static Array lastRead; ConfigLayer *configLayer; cdrom_drive *drive; cdrom_paranoia *paranoia; Int nextSector; Int sectorsLeft; Int readOffset; Int skipSamples; Int prependSamples; Int appendSamples; Int numCacheErrors; String GetDriveID() const; Bool GetTrackSectors(Int &, Int &, Bool &) const; public: static const String &GetComponentSpecs(); DecoderCDParanoia(); ~DecoderCDParanoia(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderCDParanoia) BoCA_END_COMPONENT(DecoderCDParanoia) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/config.cpp000066400000000000000000000274471516712004000260460ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureCDParanoia::ConfigID = "Ripper"; BoCA::ConfigureCDParanoia::ConfigureCDParanoia() { const Config *config = Config::Get(); Bool notificationAvailable = config->GetIntValue("Internal", "NotificationAvailable", False); autoRead = notificationAvailable && config->GetIntValue(ConfigID, "AutoReadContents", True); autoRip = notificationAvailable && config->GetIntValue(ConfigID, "AutoRip", False); cdparanoia = config->GetIntValue(ConfigID, "CDParanoia", False); I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); group_drive = new GroupBox(i18n->TranslateString("Active CD-ROM drive"), Point(7, 11), Size(354, 121)); combo_drive = new ComboBox(Point(10, 12), Size(334, 0)); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (info != NIL) { if (info->GetNumberOfDevices() == 0) group_drive->Deactivate(); for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); combo_drive->AddEntry(device.GetName()); driveOffsetUsed.Add(config->GetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), 0)); driveOffsets.Add(config->GetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), 0)); driveSpeeds.Add(config->GetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), 0)); driveSpinUpTimes.Add(config->GetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), -5)); } boca.DeleteComponent(info); } combo_drive->SelectNthEntry(config->GetIntValue(ConfigID, "ActiveDrive", 0)); combo_drive->onSelectEntry.Connect(&ConfigureCDParanoia::SelectDrive, this); useoffset = driveOffsetUsed.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); spinup = driveSpinUpTimes.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)) > 0; setspeed = driveSpeeds.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); check_speed = new CheckBox(i18n->AddColon(i18n->TranslateString("Set drive speed limit")), Point(10, 40), Size(162, 0), &setspeed); check_speed->onAction.Connect(&ConfigureCDParanoia::ToggleSetSpeed, this); check_spinup = new CheckBox(i18n->AddColon(i18n->TranslateString("Spin up before ripping")), Point(10, 67), Size(162, 0), &spinup); check_spinup->onAction.Connect(&ConfigureCDParanoia::ToggleSpinUp, this); check_offset = new CheckBox(i18n->AddColon(i18n->TranslateString("Use read offset")), Point(10, 94), Size(162, 0), &useoffset); check_offset->onAction.Connect(&ConfigureCDParanoia::ToggleUseOffset, this); Int maxTextSize = Math::Max(Math::Max(check_speed->GetUnscaledTextWidth(), check_spinup->GetUnscaledTextWidth()), check_offset->GetUnscaledTextWidth()); check_speed->SetWidth(maxTextSize + 21); check_spinup->SetWidth(maxTextSize + 21); check_offset->SetWidth(maxTextSize + 21); combo_speed = new ComboBox(Point(39 + maxTextSize, 39), Size(305 - maxTextSize, 0)); combo_speed->onSelectEntry.Connect(&ConfigureCDParanoia::SelectSpeed, this); for (Int i = 48; i > 0; i -= 4) combo_speed->AddEntry(String::FromInt(i).Append("x")); text_spinup_seconds = new Text(i18n->TranslateString("%1 seconds").Replace("%1", "00"), Point(275, 69)); text_spinup_seconds->SetX(343 - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup = new Slider(Point(39 + maxTextSize, 67), Size(86, 0), OR_HORZ, NIL, 1, 30); slider_spinup->SetWidth(335 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup->onValueChange.Connect(&ConfigureCDParanoia::ChangeSpinUpTime, this); edit_offset = new EditBox(Point(39 + maxTextSize, 93), Size(36, 0), 5); edit_offset->SetFlags(EDB_NUMERIC); edit_offset->onInput.Connect(&ConfigureCDParanoia::ChangeOffset, this); text_offset_samples = new Text(i18n->TranslateString("samples"), Point(edit_offset->GetX() + edit_offset->GetWidth() + 8, 96)); SelectDrive(); group_drive->Add(combo_drive); group_drive->Add(check_speed); group_drive->Add(combo_speed); group_drive->Add(check_spinup); group_drive->Add(slider_spinup); group_drive->Add(text_spinup_seconds); group_drive->Add(check_offset); group_drive->Add(edit_offset); group_drive->Add(text_offset_samples); group_ripping = new GroupBox(i18n->TranslateString("Ripper settings"), Point(7, 144), Size(354, 42)); check_paranoia = new CheckBox(i18n->AddColon(i18n->TranslateString("Activate cdparanoia mode")), Point(10, 14), Size(162, 0), &cdparanoia); check_paranoia->onAction.Connect(&ConfigureCDParanoia::ToggleParanoia, this); combo_paranoia_mode = new ComboBox(Point(181, 13), Size(162, 0)); combo_paranoia_mode->AddEntry(i18n->TranslateString("Overlap only")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No verify")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No scratch repair")); combo_paranoia_mode->AddEntry(i18n->TranslateString("Full cdparanoia mode")); combo_paranoia_mode->SelectNthEntry(config->GetIntValue(ConfigID, "CDParanoiaMode", 3)); ToggleParanoia(); check_paranoia->SetWidth(Math::Max(162, check_paranoia->GetUnscaledTextWidth() + 21)); combo_paranoia_mode->SetX(check_paranoia->GetWidth() + 19); group_ripping->SetWidth(check_paranoia->GetWidth() + combo_paranoia_mode->GetWidth() + 29); group_ripping->Add(check_paranoia); group_ripping->Add(combo_paranoia_mode); group_drive->SetWidth(group_ripping->GetWidth()); combo_drive->SetWidth(group_drive->GetWidth() - 20); combo_speed->SetWidth(group_drive->GetWidth() - check_speed->GetWidth() - 28); slider_spinup->SetWidth(group_drive->GetWidth() - 24 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); text_spinup_seconds->SetX(group_drive->GetWidth() - 16 - text_spinup_seconds->GetUnscaledTextWidth()); group_automatization = new GroupBox(i18n->TranslateString("Automatization"), Point(group_drive->GetWidth() + 15, 11), Size(190, 68)); check_autoRead = new CheckBox(i18n->TranslateString("Read CD contents on insert"), Point(10, 14), Size(170, 0), &autoRead); check_autoRead->onAction.Connect(&ConfigureCDParanoia::ToggleAutoRead, this); if (!notificationAvailable) check_autoRead->Deactivate(); check_autoRip = new CheckBox(i18n->TranslateString("Start ripping automatically"), check_autoRead->GetPosition() + Point(0, 26), Size(170, 0), &autoRip); group_automatization->Add(check_autoRead); group_automatization->Add(check_autoRip); maxTextSize = Math::Max(check_autoRead->GetUnscaledTextWidth(), check_autoRip->GetUnscaledTextWidth()); check_autoRead->SetWidth(Math::Max(149, maxTextSize + 21)); check_autoRip->SetWidth(check_autoRead->GetWidth()); group_automatization->SetWidth(check_autoRead->GetWidth() + 20); ToggleAutoRead(); Add(group_drive); Add(group_ripping); Add(group_automatization); SetSize(Size(group_drive->GetWidth() + group_automatization->GetWidth() + 22, 193)); } BoCA::ConfigureCDParanoia::~ConfigureCDParanoia() { DeleteObject(group_drive); DeleteObject(combo_drive); DeleteObject(check_speed); DeleteObject(combo_speed); DeleteObject(check_spinup); DeleteObject(slider_spinup); DeleteObject(text_spinup_seconds); DeleteObject(check_offset); DeleteObject(edit_offset); DeleteObject(text_offset_samples); DeleteObject(group_ripping); DeleteObject(check_paranoia); DeleteObject(combo_paranoia_mode); DeleteObject(group_automatization); DeleteObject(check_autoRead); DeleteObject(check_autoRip); } Void BoCA::ConfigureCDParanoia::SelectDrive() { edit_offset->SetText(String::FromInt(driveOffsets.GetNth(combo_drive->GetSelectedEntryNumber()))); combo_speed->SelectNthEntry((48 - driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())) / 4); check_offset->SetChecked(driveOffsetUsed.GetNth(combo_drive->GetSelectedEntryNumber())); check_speed->SetChecked(driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())); check_spinup->SetChecked(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()) > 0); slider_spinup->SetValue(Math::Abs(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()))); ToggleUseOffset(); ToggleSetSpeed(); ToggleSpinUp(); } Void BoCA::ConfigureCDParanoia::ToggleUseOffset() { driveOffsetUsed.SetNth(combo_drive->GetSelectedEntryNumber(), useoffset); if (useoffset) { edit_offset->Activate(); text_offset_samples->Activate(); } else { edit_offset->Deactivate(); text_offset_samples->Deactivate(); } } Void BoCA::ConfigureCDParanoia::ChangeOffset() { if (!useoffset) return; driveOffsets.SetNth(combo_drive->GetSelectedEntryNumber(), edit_offset->GetText().ToInt()); } Void BoCA::ConfigureCDParanoia::ToggleSpinUp() { driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); if (spinup) { slider_spinup->Activate(); text_spinup_seconds->Activate(); } else { slider_spinup->Deactivate(); text_spinup_seconds->Deactivate(); } } Void BoCA::ConfigureCDParanoia::ChangeSpinUpTime() { I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); text_spinup_seconds->SetText(i18n->TranslateString("%1 seconds").Replace("%1", String::FromInt(slider_spinup->GetValue()))); driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); } Void BoCA::ConfigureCDParanoia::ToggleSetSpeed() { if (setspeed) { combo_speed->Activate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } else { combo_speed->Deactivate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 0); } } Void BoCA::ConfigureCDParanoia::SelectSpeed() { if (!setspeed) return; driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } Void BoCA::ConfigureCDParanoia::ToggleParanoia() { if (cdparanoia) combo_paranoia_mode->Activate(); else combo_paranoia_mode->Deactivate(); } Void BoCA::ConfigureCDParanoia::ToggleAutoRead() { if (autoRead) check_autoRip->Activate(); else check_autoRip->Deactivate(); } Int BoCA::ConfigureCDParanoia::SaveSettings() { Config *config = Config::Get(); if (driveSpeeds.Length() >= 1) config->SetIntValue(ConfigID, "ActiveDrive", combo_drive->GetSelectedEntryNumber()); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdparanoia-info"); if (info != NIL) { for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); config->SetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), driveOffsetUsed.GetNth(i)); config->SetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), driveOffsets.GetNth(i)); config->SetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), driveSpeeds.GetNth(i)); config->SetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), driveSpinUpTimes.GetNth(i)); } boca.DeleteComponent(info); } if (config->GetIntValue("Internal", "NotificationAvailable", False)) { config->SetIntValue(ConfigID, "AutoReadContents", autoRead); config->SetIntValue(ConfigID, "AutoRip", autoRip); } config->SetIntValue(ConfigID, "CDParanoia", cdparanoia); config->SetIntValue(ConfigID, "CDParanoiaMode", combo_paranoia_mode->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdparanoia/config.h000066400000000000000000000036701516712004000255030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDPARANOIACONFIG #define H_CDPARANOIACONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCDParanoia : public ConfigLayer { private: GroupBox *group_drive; ComboBox *combo_drive; CheckBox *check_speed; ComboBox *combo_speed; CheckBox *check_spinup; Slider *slider_spinup; Text *text_spinup_seconds; CheckBox *check_offset; EditBox *edit_offset; Text *text_offset_samples; GroupBox *group_ripping; CheckBox *check_paranoia; ComboBox *combo_paranoia_mode; GroupBox *group_automatization; CheckBox *check_autoRead; CheckBox *check_autoRip; Bool setspeed; Bool spinup; Bool useoffset; Bool cdparanoia; Bool autoRead; Bool autoRip; Array driveOffsetUsed; Array driveOffsets; Array driveSpeeds; Array driveSpinUpTimes; slots: Void SelectDrive(); Void ToggleSetSpeed(); Void SelectSpeed(); Void ToggleSpinUp(); Void ChangeSpinUpTime(); Void ToggleUseOffset(); Void ChangeOffset(); Void ToggleParanoia(); Void ToggleAutoRead(); public: static const String ConfigID; ConfigureCDParanoia(); ~ConfigureCDParanoia(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/000077500000000000000000000000001516712004000230575ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/Makefile000077500000000000000000000015501516712004000245230ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdrip TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = cdrip.o config.o dllinterface.o info/cdinfo.o info/cdplayerini.o info/cdtext.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = -lws2_32 # Enter addition commands for targets all and clean here: ifneq ("$(SRCDIR)","$(CURDIR)") ALLCMD1 = mkdir -p info ALLCMD2 = CLEANCMD1 = rmdir info || true CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = endif ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/cdrip.cpp000066400000000000000000000372361516712004000246770ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "cdrip.h" #include "config.h" using namespace smooth::IO; using namespace smooth::GUI::Dialogs; const String &BoCA::DecoderCDRip::GetComponentSpecs() { static String componentSpecs; if (cdripdll != NIL) { componentSpecs = " \ \ \ \ CDRip Ripper Component %VERSION% \ 1.0 \ cdrip-dec \ decoder \ cdrip-info \ \ Windows CD Audio Track \ true \ cda \ \ \ \ "; LONG cdripVersion = ex_CR_GetCDRipVersion(); componentSpecs.Replace("%VERSION%", String("v").Append(String::FromInt(cdripVersion / 100)).Append(".").Append(String::FromInt(cdripVersion % 100))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadCDRipDLL(); } Void smooth::DetachDLL() { FreeCDRipDLL(); } BoCA::CDPlayerIni BoCA::DecoderCDRip::cdPlayer; UnsignedInt32 BoCA::DecoderCDRip::cdPlayerDiscID = 0; BoCA::CDText BoCA::DecoderCDRip::cdText; UnsignedInt32 BoCA::DecoderCDRip::cdTextDiscID = 0; Array BoCA::DecoderCDRip::lastRead; Bool BoCA::DecoderCDRip::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.StartsWith("device://cdda:") || lcURI.EndsWith(".cda"); } Error BoCA::DecoderCDRip::GetStreamInfo(const String &streamURI, Track &track) { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdrip-info"); if (component == NIL) return Error(); const Config *config = GetConfiguration(); track.isCDTrack = True; Format format; format.channels = 2; format.rate = 44100; format.bits = 16; format.order = BYTE_INTEL; track.SetFormat(format); Int trackNumber = -1; Int trackLength = 0; Int audiodrive = 0; if (streamURI.StartsWith("device://cdda:")) { audiodrive = streamURI.SubString(14, 1).ToInt(); trackNumber = streamURI.SubString(16, streamURI.Length() - 16).ToInt(); } else if (streamURI.EndsWith(".cda")) { /* Find track number and length. */ { InStream in(STREAM_FILE, streamURI, IS_READ); in.Seek(22); trackNumber = in.InputNumber(2); in.Seek(32); trackLength = in.InputNumber(4); } for (audiodrive = 0; audiodrive < component->GetNumberOfDevices(); audiodrive++) { Bool done = False; const MCDI &mcdi = component->GetNthDeviceMCDI(audiodrive); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) != ENTRY_AUDIO) continue; Int length = mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i); if (length == trackLength && mcdi.GetNthEntryTrackNumber(i) == trackNumber) { done = True; break; } } if (done) break; } } if (trackNumber == -1) return Error(); /* Fill MCDI data. */ Info info; info.mcdi = component->GetNthDeviceMCDI(audiodrive); Int entryNumber = -1; if (trackNumber == 0) { if (info.mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { entryNumber = 0; trackLength = info.mcdi.GetNthEntryOffset(0); } } else { for (Int i = 0; i < info.mcdi.GetNumberOfEntries(); i++) { if (info.mcdi.GetNthEntryType(i) == ENTRY_AUDIO && info.mcdi.GetNthEntryTrackNumber(i) == trackNumber) { entryNumber = i; trackLength = info.mcdi.GetNthEntryTrackLength(i); break; } } } if (entryNumber == -1) return Error(); track.length = trackLength * samplesPerSector; track.fileSize = trackLength * bytesPerSector; track.cdTrack = trackNumber; track.drive = audiodrive; track.outputFile = NIL; info.track = trackNumber; info.numTracks = info.mcdi.GetNumberOfAudioTracks(); info.SetOtherInfo(INFO_MEDIATYPE, I18n::Get()->TranslateString("CD", "Media types")); /* Read CD-Text and cdplayer.ini. */ UnsignedInt32 discid = ComputeDiscID(info.mcdi); if (config->GetIntValue(ConfigureCDRip::ConfigID, "ReadCDText", True) && cdTextDiscID != discid) { cdText.ReadCDText(track.drive); cdTextDiscID = discid; } if (config->GetIntValue(ConfigureCDRip::ConfigID, "ReadCDPlayerIni", True) && cdPlayerDiscID != discid) { cdPlayer.ReadCDInfo(track.drive); cdPlayerDiscID = discid; } if (config->GetIntValue(ConfigureCDRip::ConfigID, "ReadCDText", True) && cdText.GetCDInfo().GetTrackTitle(trackNumber) != NIL) { const CDInfo &cdInfo = cdText.GetCDInfo(); info.SetOtherInfo(INFO_ALBUMARTIST, cdInfo.GetArtist()); info.title = cdInfo.GetTrackTitle(trackNumber); info.album = cdInfo.GetTitle(); info.genre = cdInfo.GetGenre(); if (cdInfo.GetTrackArtist(trackNumber) != NIL) info.artist = cdInfo.GetTrackArtist(trackNumber); else info.artist = cdInfo.GetArtist(); if (cdInfo.GetTrackComment(trackNumber) != NIL) info.comment = cdInfo.GetTrackComment(trackNumber); else info.comment = cdInfo.GetComment(); if (cdInfo.GetTrackSongwriter(trackNumber) != NIL) info.SetOtherInfo(INFO_LYRICIST, cdInfo.GetTrackSongwriter(trackNumber)); else if (cdInfo.GetSongwriter() != NIL) info.SetOtherInfo(INFO_LYRICIST, cdInfo.GetSongwriter()); if (cdInfo.GetTrackComposer(trackNumber) != NIL) info.SetOtherInfo(INFO_COMPOSER, cdInfo.GetTrackComposer(trackNumber)); else if (cdInfo.GetComposer() != NIL) info.SetOtherInfo(INFO_COMPOSER, cdInfo.GetComposer()); if (cdInfo.GetTrackArranger(trackNumber) != NIL) info.SetOtherInfo(INFO_ARRANGER, cdInfo.GetTrackArranger(trackNumber)); else if (cdInfo.GetArranger() != NIL) info.SetOtherInfo(INFO_ARRANGER, cdInfo.GetArranger()); if (cdInfo.GetCatalog() != NIL) info.SetOtherInfo(INFO_CATALOGNUMBER, cdInfo.GetCatalog()); if (cdInfo.GetBarcode() != NIL) info.SetOtherInfo(INFO_BARCODE, cdInfo.GetBarcode()); if (Info::IsISRC(cdInfo.GetTrackISRC(trackNumber))) info.isrc = cdInfo.GetTrackISRC(trackNumber); } else if (config->GetIntValue(ConfigureCDRip::ConfigID, "ReadCDPlayerIni", True) && cdPlayer.GetCDInfo().GetTrackTitle(trackNumber) != NIL) { const CDInfo &cdInfo = cdPlayer.GetCDInfo(); info.SetOtherInfo(INFO_ALBUMARTIST, cdInfo.GetArtist()); info.artist = cdInfo.GetArtist(); info.title = cdInfo.GetTrackTitle(trackNumber); info.album = cdInfo.GetTitle(); } /* Read ISRC if requested. */ if (config->GetIntValue(ConfigureCDRip::ConfigID, "ReadISRC", 0)) { CDROMDRIVE *cd = ex_CR_OpenCDROM(track.drive); if (cd != NIL) { ISRC data; ex_CR_ReadAndGetISRC(cd, &data, track.cdTrack); /* Check if the ISRC is valid. */ if (Info::IsISRC(data.isrc)) info.isrc = data.isrc; ex_CR_CloseCDROM(cd); } } track.SetInfo(info); /* Delete DeviceInfo component. */ boca.DeleteComponent(component); return Success(); } BoCA::DecoderCDRip::DecoderCDRip() { configLayer = NIL; cd = NIL; readOffset = 0; skipSamples = 0; prependSamples = 0; appendSamples = 0; dataBufferSize = 0; lastRead.EnableLocking(); } BoCA::DecoderCDRip::~DecoderCDRip() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderCDRip::Activate() { const Config *config = GetConfiguration(); if (lastRead.Length() == 0) for (Int i = 0; i < ex_CR_GetNumCDROM(); i++) lastRead.Add(0); /* Get paranoia mode. */ int nParanoiaMode = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP; switch (config->GetIntValue(ConfigureCDRip::ConfigID, "CDParanoiaMode", 3)) { case 0: nParanoiaMode = PARANOIA_MODE_OVERLAP; break; case 1: nParanoiaMode &= ~PARANOIA_MODE_VERIFY; break; case 2: nParanoiaMode &= ~(PARANOIA_MODE_SCRATCH | PARANOIA_MODE_REPAIR); break; } /* Change drive parameters. */ cd = ex_CR_OpenCDROM(track.drive); if (cd == NIL) return False; CDROMPARAMS params; ex_CR_GetCDROMParameters(cd, ¶ms); params.nRippingMode = config->GetIntValue(ConfigureCDRip::ConfigID, "CDParanoia", False); params.nParanoiaMode = nParanoiaMode; params.bSwapLefRightChannel = config->GetIntValue(ConfigureCDRip::ConfigID, "SwapChannels", False); params.bJitterCorrection = config->GetIntValue(ConfigureCDRip::ConfigID, "JitterCorrection", False); // params.bDetectJitterErrors = config->GetIntValue(ConfigureCDRip::ConfigID, "DetectJitterErrors", True); // params.bDetectC2Errors = config->GetIntValue(ConfigureCDRip::ConfigID, "DetectC2Errors", True); params.nSpeed = config->GetIntValue(ConfigureCDRip::ConfigID, String("RippingSpeedDrive-").Append(GetDriveID()), 0); params.bEnableMultiRead = False; params.nMultiReadCount = 0; /* Set maximum speed if no limit is requested. */ if (params.nSpeed == 0) params.nSpeed = 64; ex_CR_SetCDROMParameters(cd, ¶ms); /* Call seek to initialize ripper to start of track. */ if (!Seek(0)) return False; /* Read CD TOC to initialize internal structures. */ ex_CR_ReadToc(cd); return True; } Bool BoCA::DecoderCDRip::Deactivate() { /* Check for drive cache errors. */ if (ex_CR_GetNumberOfCacheErrors(cd) > 0) { Config *config = Config::Get(); Bool noCacheWarning = config->GetIntValue(ConfigureCDRip::ConfigID, "NoCacheWarning", False); if (!noCacheWarning) { MessageDlg *msgBox = new MessageDlg("The CD-ROM drive appears to be seeking impossibly quickly.\n" "This could be due to timer bugs, a drive that really is improbably fast,\n" "or, most likely, a bug in cdparanoia's cache modelling.\n\n" "Please consider using another drive for ripping audio CDs and send a bug\n" "report to support@freac.org to assist developers in correcting the problem.", "Warning", Message::Buttons::Ok, Message::Icon::Warning, "Do not display this warning again", &noCacheWarning); msgBox->ShowDialog(); config->SetIntValue(ConfigureCDRip::ConfigID, "NoCacheWarning", noCacheWarning); config->SaveSettings(); Object::DeleteObject(msgBox); } } ex_CR_CloseRipper(cd); ex_CR_CloseCDROM(cd); return True; } Bool BoCA::DecoderCDRip::Seek(Int64 samplePosition) { const Config *config = GetConfiguration(); ex_CR_CloseRipper(cd); Int startSector = 0; Int endSector = 0; Bool lastTrack = False; if (!GetTrackSectors(startSector, endSector, lastTrack)) return False; startSector += samplePosition / samplesPerSector; /* Calculate offset values. */ readOffset = config->GetIntValue(ConfigureCDRip::ConfigID, String("UseOffsetDrive-").Append(GetDriveID()), 0) ? config->GetIntValue(ConfigureCDRip::ConfigID, String("ReadOffsetDrive-").Append(GetDriveID()), 0) : 0; startSector += readOffset / Int(samplesPerSector); endSector += readOffset / Int(samplesPerSector); if (readOffset % Int(samplesPerSector) < 0) { startSector--; skipSamples = samplesPerSector + readOffset % Int(samplesPerSector); } else if (readOffset % Int(samplesPerSector) > 0) { if (!lastTrack) endSector++; skipSamples = readOffset % Int(samplesPerSector); } if (startSector < 0) { prependSamples = -startSector * samplesPerSector; startSector = 0; } if (lastTrack && readOffset > 0) { appendSamples = readOffset; endSector -= readOffset / samplesPerSector; } skipSamples += samplePosition % samplesPerSector; /* Open ripper. */ LONG bufferSize = 0; ex_CR_OpenRipper(cd, &bufferSize, startSector, endSector); dataBufferSize = bufferSize; inBytes = 4 * samplePosition; /* Wait for drive to spin up if requested. */ Int spinUpTime = config->GetIntValue(ConfigureCDRip::ConfigID, String("SpinUpTimeDrive-").Append(GetDriveID()), 0); UnsignedInt64 startTime = S::System::System::Clock(); while (spinUpTime > 0 && startTime - lastRead.GetNth(track.drive) > 2500 && S::System::System::Clock() - startTime < (UnsignedInt64) Math::Abs(spinUpTime * 1000)) { Buffer buffer(dataBufferSize); BOOL abort = false; LONG bytes = dataBufferSize; ex_CR_RipChunk(cd, buffer, &bytes, abort); ex_CR_CloseRipper(cd); ex_CR_OpenRipper(cd, &bufferSize, startSector, endSector); } return True; } Int BoCA::DecoderCDRip::ReadData(Buffer &data) { if (inBytes >= track.fileSize) return -1; /* Set up buffer respecting empty samples to prepend. */ Int prependBytes = 4 * prependSamples; Int appendBytes = 4 * appendSamples; Int skipBytes = 4 * skipSamples; prependSamples = 0; skipSamples = 0; data.Resize(dataBufferSize + prependBytes); if (prependBytes > 0) data.Zero(); /* Rip chunk. */ BOOL abort = false; LONG bytes = dataBufferSize; CDEX_ERR error = ex_CR_RipChunk(cd, data + prependBytes, &bytes, abort); if (error != CDEX_OK) return -1; lastRead.SetNth(track.drive, S::System::System::Clock()); /* Append offset bytes to last track. */ if (bytes == 0) { data.Resize(prependBytes + appendBytes - skipBytes); data.Zero(); inBytes += data.Size(); return data.Size(); } /* Strip samples to skip from the beginning. */ Int dataBytes = Math::Min(track.fileSize - inBytes, (Int64) bytes + prependBytes - skipBytes); if (skipBytes > 0) memmove(data, data + skipBytes, dataBytes); inBytes += dataBytes; return dataBytes; } Bool BoCA::DecoderCDRip::GetTrackSectors(Int &startSector, Int &endSector, Bool &lastTrack) const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *component = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdrip-info"); if (component == NIL) return False; MCDI mcdi = component->GetNthDeviceMCDI(track.drive); boca.DeleteComponent(component); if (track.cdTrack == 0) { /* Special handling for hidden track one audio. */ if (mcdi.GetNthEntryType(0) == ENTRY_AUDIO) { startSector = 0; endSector = mcdi.GetNthEntryOffset(0) - 1; lastTrack = False; return True; } } else { /* Handle regular tracks. */ for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryTrackNumber(i) == track.cdTrack) { startSector = mcdi.GetNthEntryOffset(i); endSector = startSector + mcdi.GetNthEntryTrackLength(i) - 1; if (mcdi.GetNthEntryType(i + 1) == ENTRY_AUDIO) lastTrack = False; else lastTrack = True; return True; } } } return False; } ConfigLayer *BoCA::DecoderCDRip::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureCDRip(); return configLayer; } String BoCA::DecoderCDRip::GetDriveID() const { AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdrip-info"); if (info == NIL) return NIL; const Device &device = info->GetNthDeviceInfo(track.drive); boca.DeleteComponent(info); return device.GetID(); } static int cddb_sum(int n) { int ret = 0; while (n > 0) { ret = ret + (n % 10); n = n / 10; } return ret; } UnsignedInt32 BoCA::DecoderCDRip::ComputeDiscID(const MCDI &mcdi) const { Int numTocEntries = mcdi.GetNumberOfEntries(); Int n = 0; for (Int i = 0; i < numTocEntries; i++) { Int offset = mcdi.GetNthEntryOffset(i) + 150; n += cddb_sum(offset / 75); } Int t = mcdi.GetNthEntryOffset(numTocEntries) / 75 - mcdi.GetNthEntryOffset(0) / 75; return ((n % 0xff) << 24 | t << 8 | numTocEntries); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/cdrip.h000066400000000000000000000035471516712004000243420ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" #include "info/cdtext.h" #include "info/cdplayerini.h" BoCA_BEGIN_COMPONENT(DecoderCDRip) namespace BoCA { class DecoderCDRip : public CS::DecoderComponent { constants: static const UnsignedInt bytesPerSector = 2352; static const UnsignedInt samplesPerSector = 588; private: static CDText cdText; static UnsignedInt32 cdTextDiscID; static CDPlayerIni cdPlayer; static UnsignedInt32 cdPlayerDiscID; static Array lastRead; ConfigLayer *configLayer; CDROMDRIVE *cd; Int dataBufferSize; Int readOffset; Int skipSamples; Int prependSamples; Int appendSamples; String GetDriveID() const; UnsignedInt32 ComputeDiscID(const MCDI &) const; Bool GetTrackSectors(Int &, Int &, Bool &) const; public: static const String &GetComponentSpecs(); DecoderCDRip(); ~DecoderCDRip(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderCDRip) BoCA_END_COMPONENT(DecoderCDRip) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/config.cpp000077500000000000000000000361441516712004000250430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "config.h" const String BoCA::ConfigureCDRip::ConfigID = "Ripper"; BoCA::ConfigureCDRip::ConfigureCDRip() { const Config *config = Config::Get(); Bool notificationAvailable = config->GetIntValue("Internal", "NotificationAvailable", False); autoRead = notificationAvailable && config->GetIntValue(ConfigID, "AutoReadContents", True); autoRip = notificationAvailable && config->GetIntValue(ConfigID, "AutoRip", False); jitter = config->GetIntValue(ConfigID, "JitterCorrection", False); swapchannels = config->GetIntValue(ConfigID, "SwapChannels", False); autoEject = config->GetIntValue(ConfigID, "EjectAfterRipping", False); readCDText = config->GetIntValue(ConfigID, "ReadCDText", True); readCDPlayerIni = config->GetIntValue(ConfigID, "ReadCDPlayerIni", True); readISRC = config->GetIntValue(ConfigID, "ReadISRC", False); cdparanoia = config->GetIntValue(ConfigID, "CDParanoia", False); I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); group_drive = new GroupBox(i18n->TranslateString("Active CD-ROM drive"), Point(7, 11), Size(354, 121)); combo_drive = new ComboBox(Point(10, 12), Size(334, 0)); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdrip-info"); if (info != NIL) { if (info->GetNumberOfDevices() == 0) group_drive->Deactivate(); for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); combo_drive->AddEntry(device.GetName()); driveOffsetUsed.Add(config->GetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), 0)); driveOffsets.Add(config->GetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), 0)); driveSpeeds.Add(config->GetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), 0)); driveSpinUpTimes.Add(config->GetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), -5)); } boca.DeleteComponent(info); } combo_drive->SelectNthEntry(config->GetIntValue(ConfigID, "ActiveDrive", 0)); combo_drive->onSelectEntry.Connect(&ConfigureCDRip::SelectDrive, this); useoffset = driveOffsetUsed.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); spinup = driveSpinUpTimes.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)) > 0; setspeed = driveSpeeds.GetNth(config->GetIntValue(ConfigID, "ActiveDrive", 0)); check_speed = new CheckBox(i18n->AddColon(i18n->TranslateString("Set drive speed limit")), Point(10, 40), Size(162, 0), &setspeed); check_speed->onAction.Connect(&ConfigureCDRip::ToggleSetSpeed, this); check_spinup = new CheckBox(i18n->AddColon(i18n->TranslateString("Spin up before ripping")), Point(10, 67), Size(162, 0), &spinup); check_spinup->onAction.Connect(&ConfigureCDRip::ToggleSpinUp, this); check_offset = new CheckBox(i18n->AddColon(i18n->TranslateString("Use read offset")), Point(10, 94), Size(162, 0), &useoffset); check_offset->onAction.Connect(&ConfigureCDRip::ToggleUseOffset, this); Int maxTextSize = Math::Max(Math::Max(check_speed->GetUnscaledTextWidth(), check_spinup->GetUnscaledTextWidth()), check_offset->GetUnscaledTextWidth()); check_speed->SetWidth(maxTextSize + 21); check_spinup->SetWidth(maxTextSize + 21); check_offset->SetWidth(maxTextSize + 21); combo_speed = new ComboBox(Point(39 + maxTextSize, 39), Size(305 - maxTextSize, 0)); combo_speed->onSelectEntry.Connect(&ConfigureCDRip::SelectSpeed, this); for (Int i = 48; i > 0; i -= 4) combo_speed->AddEntry(String::FromInt(i).Append("x")); text_spinup_seconds = new Text(i18n->TranslateString("%1 seconds").Replace("%1", "00"), Point(275, 69)); text_spinup_seconds->SetX(343 - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup = new Slider(Point(39 + maxTextSize, 67), Size(86, 0), OR_HORZ, NIL, 1, 30); slider_spinup->SetWidth(335 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); slider_spinup->onValueChange.Connect(&ConfigureCDRip::ChangeSpinUpTime, this); edit_offset = new EditBox(Point(39 + maxTextSize, 93), Size(36, 0), 5); edit_offset->SetFlags(EDB_NUMERIC); edit_offset->onInput.Connect(&ConfigureCDRip::ChangeOffset, this); text_offset_samples = new Text(i18n->TranslateString("samples"), Point(edit_offset->GetX() + edit_offset->GetWidth() + 8, 96)); SelectDrive(); group_drive->Add(combo_drive); group_drive->Add(check_speed); group_drive->Add(combo_speed); group_drive->Add(check_spinup); group_drive->Add(slider_spinup); group_drive->Add(text_spinup_seconds); group_drive->Add(check_offset); group_drive->Add(edit_offset); group_drive->Add(text_offset_samples); group_cdinfo = new GroupBox(i18n->TranslateString("CD information"), Point(7, 144), Size(354, 65)); check_readCDText = new CheckBox(i18n->TranslateString("Read CD-Text"), Point(10, 11), Size(162, 0), &readCDText); check_readCDPlayerIni = new CheckBox(i18n->TranslateString("Read cdplayer.ini"), Point(181, 11), Size(162, 0), &readCDPlayerIni); check_readISRC = new CheckBox(i18n->TranslateString("Read ISRC when adding tracks to joblist"), Point(10, 37), Size(333, 0), &readISRC); check_readCDText->SetWidth(Math::Max(162, check_readCDText->GetUnscaledTextWidth() + 21)); check_readCDPlayerIni->SetX(check_readCDText->GetWidth() + 19); check_readCDPlayerIni->SetWidth(Math::Max(162, check_readCDPlayerIni->GetUnscaledTextWidth() + 21)); check_readISRC->SetWidth(Math::Max(333, check_readISRC->GetUnscaledTextWidth() + 21)); group_cdinfo->SetWidth(Math::Max(check_readCDText->GetWidth() + check_readCDPlayerIni->GetWidth() + 9, check_readISRC->GetWidth()) + 20); group_cdinfo->Add(check_readCDText); group_cdinfo->Add(check_readCDPlayerIni); group_cdinfo->Add(check_readISRC); group_ripping = new GroupBox(i18n->TranslateString("Ripper settings"), Point(7, 221), Size(354, 68)); check_paranoia = new CheckBox(i18n->AddColon(i18n->TranslateString("Activate cdparanoia mode")), Point(10, 14), Size(162, 0), &cdparanoia); check_paranoia->onAction.Connect(&ConfigureCDRip::ToggleParanoia, this); combo_paranoia_mode = new ComboBox(Point(181, 13), Size(162, 0)); combo_paranoia_mode->AddEntry(i18n->TranslateString("Overlap only")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No verify")); combo_paranoia_mode->AddEntry(i18n->TranslateString("No scratch repair")); combo_paranoia_mode->AddEntry(i18n->TranslateString("Full cdparanoia mode")); combo_paranoia_mode->SelectNthEntry(config->GetIntValue(ConfigID, "CDParanoiaMode", 3)); ToggleParanoia(); check_jitter = new CheckBox(i18n->TranslateString("Activate jitter correction"), Point(10, 40), Size(162, 0), &jitter); check_swapchannels = new CheckBox(i18n->TranslateString("Switch stereo channels"), Point(181, 40), Size(162, 0), &swapchannels); maxTextSize = Math::Max(check_paranoia->GetUnscaledTextWidth(), check_jitter->GetUnscaledTextWidth()); check_paranoia->SetWidth(Math::Max(162, maxTextSize + 21)); check_jitter->SetWidth(check_paranoia->GetWidth()); combo_paranoia_mode->SetX(check_paranoia->GetWidth() + 19); check_swapchannels->SetX(combo_paranoia_mode->GetX()); check_swapchannels->SetWidth(Math::Max(162, check_swapchannels->GetUnscaledTextWidth() + 21)); group_ripping->SetWidth(check_paranoia->GetWidth() + check_swapchannels->GetWidth() + 29); group_ripping->Add(check_paranoia); group_ripping->Add(combo_paranoia_mode); group_ripping->Add(check_jitter); group_ripping->Add(check_swapchannels); group_drive->SetWidth(Math::Max(group_cdinfo->GetWidth(), group_ripping->GetWidth())); group_cdinfo->SetWidth(group_drive->GetWidth()); group_ripping->SetWidth(group_drive->GetWidth()); combo_drive->SetWidth(group_drive->GetWidth() - 20); combo_speed->SetWidth(group_drive->GetWidth() - check_speed->GetWidth() - 28); slider_spinup->SetWidth(group_drive->GetWidth() - 24 - slider_spinup->GetX() - text_spinup_seconds->GetUnscaledTextWidth()); text_spinup_seconds->SetX(group_drive->GetWidth() - 16 - text_spinup_seconds->GetUnscaledTextWidth()); check_readCDPlayerIni->SetWidth(group_cdinfo->GetWidth() - check_readCDText->GetWidth() - 29); check_readISRC->SetWidth(group_cdinfo->GetWidth() - 20); check_swapchannels->SetWidth(group_ripping->GetWidth() - check_paranoia->GetWidth() - 29); combo_paranoia_mode->SetWidth(check_swapchannels->GetWidth()); group_automatization = new GroupBox(i18n->TranslateString("Automatization"), Point(group_drive->GetWidth() + 15, 11), Size(190, 94)); check_autoRead = new CheckBox(i18n->TranslateString("Read CD contents on insert"), Point(10, 14), Size(170, 0), &autoRead); check_autoRead->onAction.Connect(&ConfigureCDRip::ToggleAutoRead, this); if (!notificationAvailable) check_autoRead->Deactivate(); check_autoRip = new CheckBox(i18n->TranslateString("Start ripping automatically"), check_autoRead->GetPosition() + Point(0, 26), Size(170, 0), &autoRip); check_autoEject = new CheckBox(i18n->TranslateString("Eject disc after ripping"), check_autoRip->GetPosition() + Point(0, 26), Size(170, 0), &autoEject); group_automatization->Add(check_autoRead); group_automatization->Add(check_autoRip); group_automatization->Add(check_autoEject); maxTextSize = Math::Max(Math::Max(check_autoRead->GetUnscaledTextWidth(), check_autoRip->GetUnscaledTextWidth()), check_autoEject->GetUnscaledTextWidth()); check_autoRead->SetWidth(Math::Max(149, maxTextSize + 21)); check_autoRip->SetWidth(check_autoRead->GetWidth()); check_autoEject->SetWidth(check_autoRead->GetWidth()); group_automatization->SetWidth(check_autoRead->GetWidth() + 20); ToggleAutoRead(); Add(group_drive); Add(group_ripping); Add(group_automatization); Add(group_cdinfo); SetSize(Size(group_drive->GetWidth() + group_automatization->GetWidth() + 22, 296)); } BoCA::ConfigureCDRip::~ConfigureCDRip() { DeleteObject(group_drive); DeleteObject(combo_drive); DeleteObject(check_speed); DeleteObject(combo_speed); DeleteObject(check_spinup); DeleteObject(slider_spinup); DeleteObject(text_spinup_seconds); DeleteObject(check_offset); DeleteObject(edit_offset); DeleteObject(text_offset_samples); DeleteObject(group_ripping); DeleteObject(check_paranoia); DeleteObject(combo_paranoia_mode); DeleteObject(check_jitter); DeleteObject(check_swapchannels); DeleteObject(group_automatization); DeleteObject(check_autoRead); DeleteObject(check_autoRip); DeleteObject(check_autoEject); DeleteObject(group_cdinfo); DeleteObject(check_readCDText); DeleteObject(check_readCDPlayerIni); DeleteObject(check_readISRC); } Void BoCA::ConfigureCDRip::SelectDrive() { edit_offset->SetText(String::FromInt(driveOffsets.GetNth(combo_drive->GetSelectedEntryNumber()))); combo_speed->SelectNthEntry((48 - driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())) / 4); check_offset->SetChecked(driveOffsetUsed.GetNth(combo_drive->GetSelectedEntryNumber())); check_speed->SetChecked(driveSpeeds.GetNth(combo_drive->GetSelectedEntryNumber())); check_spinup->SetChecked(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()) > 0); slider_spinup->SetValue(Math::Abs(driveSpinUpTimes.GetNth(combo_drive->GetSelectedEntryNumber()))); ToggleUseOffset(); ToggleSetSpeed(); ToggleSpinUp(); } Void BoCA::ConfigureCDRip::ToggleUseOffset() { driveOffsetUsed.SetNth(combo_drive->GetSelectedEntryNumber(), useoffset); if (useoffset) { edit_offset->Activate(); text_offset_samples->Activate(); } else { edit_offset->Deactivate(); text_offset_samples->Deactivate(); } } Void BoCA::ConfigureCDRip::ChangeOffset() { if (!useoffset) return; driveOffsets.SetNth(combo_drive->GetSelectedEntryNumber(), edit_offset->GetText().ToInt()); } Void BoCA::ConfigureCDRip::ToggleSpinUp() { driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); if (spinup) { slider_spinup->Activate(); text_spinup_seconds->Activate(); } else { slider_spinup->Deactivate(); text_spinup_seconds->Deactivate(); } } Void BoCA::ConfigureCDRip::ChangeSpinUpTime() { I18n *i18n = I18n::Get(); i18n->SetContext("Ripper"); text_spinup_seconds->SetText(i18n->TranslateString("%1 seconds").Replace("%1", String::FromInt(slider_spinup->GetValue()))); driveSpinUpTimes.SetNth(combo_drive->GetSelectedEntryNumber(), slider_spinup->GetValue() * (spinup ? 1 : -1)); } Void BoCA::ConfigureCDRip::ToggleSetSpeed() { if (setspeed) { combo_speed->Activate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } else { combo_speed->Deactivate(); driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 0); } } Void BoCA::ConfigureCDRip::SelectSpeed() { if (!setspeed) return; driveSpeeds.SetNth(combo_drive->GetSelectedEntryNumber(), 48 - (combo_speed->GetSelectedEntryNumber() * 4)); } Void BoCA::ConfigureCDRip::ToggleParanoia() { if (cdparanoia) combo_paranoia_mode->Activate(); else combo_paranoia_mode->Deactivate(); } Void BoCA::ConfigureCDRip::ToggleAutoRead() { if (autoRead) check_autoRip->Activate(); else check_autoRip->Deactivate(); } Int BoCA::ConfigureCDRip::SaveSettings() { Config *config = Config::Get(); if (driveSpeeds.Length() >= 1) config->SetIntValue(ConfigID, "ActiveDrive", combo_drive->GetSelectedEntryNumber()); AS::Registry &boca = AS::Registry::Get(); AS::DeviceInfoComponent *info = (AS::DeviceInfoComponent *) boca.CreateComponentByID("cdrip-info"); if (info != NIL) { for (Int i = 0; i < info->GetNumberOfDevices(); i++) { const Device &device = info->GetNthDeviceInfo(i); String deviceID = device.GetID(); config->SetIntValue(ConfigID, String("UseOffsetDrive-").Append(deviceID), driveOffsetUsed.GetNth(i)); config->SetIntValue(ConfigID, String("ReadOffsetDrive-").Append(deviceID), driveOffsets.GetNth(i)); config->SetIntValue(ConfigID, String("RippingSpeedDrive-").Append(deviceID), driveSpeeds.GetNth(i)); config->SetIntValue(ConfigID, String("SpinUpTimeDrive-").Append(deviceID), driveSpinUpTimes.GetNth(i)); } boca.DeleteComponent(info); } if (config->GetIntValue("Internal", "NotificationAvailable", False)) { config->SetIntValue(ConfigID, "AutoReadContents", autoRead); config->SetIntValue(ConfigID, "AutoRip", autoRip); } config->SetIntValue(ConfigID, "JitterCorrection", jitter); config->SetIntValue(ConfigID, "SwapChannels", swapchannels); config->SetIntValue(ConfigID, "EjectAfterRipping", autoEject); config->SetIntValue(ConfigID, "ReadCDText", readCDText); config->SetIntValue(ConfigID, "ReadCDPlayerIni", readCDPlayerIni); config->SetIntValue(ConfigID, "ReadISRC", readISRC); config->SetIntValue(ConfigID, "CDParanoia", cdparanoia); config->SetIntValue(ConfigID, "CDParanoiaMode", combo_paranoia_mode->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/config.h000077500000000000000000000044071516712004000245050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDRIPCONFIG #define H_CDRIPCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCDRip : public ConfigLayer { private: GroupBox *group_drive; ComboBox *combo_drive; CheckBox *check_speed; ComboBox *combo_speed; CheckBox *check_spinup; Slider *slider_spinup; Text *text_spinup_seconds; CheckBox *check_offset; EditBox *edit_offset; Text *text_offset_samples; GroupBox *group_ripping; CheckBox *check_paranoia; ComboBox *combo_paranoia_mode; CheckBox *check_jitter; CheckBox *check_swapchannels; GroupBox *group_automatization; CheckBox *check_autoRead; CheckBox *check_autoRip; CheckBox *check_autoEject; GroupBox *group_cdinfo; CheckBox *check_readCDText; CheckBox *check_readCDPlayerIni; CheckBox *check_readISRC; Bool setspeed; Bool spinup; Bool useoffset; Bool cdparanoia; Bool jitter; Bool swapchannels; Bool autoRead; Bool autoRip; Bool autoEject; Bool readCDText; Bool readCDPlayerIni; Bool readISRC; Array driveOffsetUsed; Array driveOffsets; Array driveSpeeds; Array driveSpinUpTimes; slots: Void SelectDrive(); Void ToggleSetSpeed(); Void SelectSpeed(); Void ToggleSpinUp(); Void ChangeSpinUpTime(); Void ToggleUseOffset(); Void ChangeOffset(); Void ToggleParanoia(); Void ToggleAutoRead(); public: static const String ConfigID; ConfigureCDRip(); ~ConfigureCDRip(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/dllinterface.cpp000077500000000000000000000067741516712004000262400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" CR_GETNUMCDROM ex_CR_GetNumCDROM = NIL; CR_OPENCDROM ex_CR_OpenCDROM = NIL; CR_CLOSECDROM ex_CR_CloseCDROM = NIL; CR_READTOC ex_CR_ReadToc = NIL; CR_GETNUMTOCENTRIES ex_CR_GetNumTocEntries = NIL; CR_GETTOCENTRY ex_CR_GetTocEntry = NIL; CR_OPENRIPPER ex_CR_OpenRipper = NIL; CR_CLOSERIPPER ex_CR_CloseRipper = NIL; CR_RIPCHUNK ex_CR_RipChunk = NIL; CR_GETCDROMPARAMETERS ex_CR_GetCDROMParameters = NIL; CR_SETCDROMPARAMETERS ex_CR_SetCDROMParameters = NIL; CR_READCDTEXT ex_CR_ReadCDText = NIL; CR_READANDGETISRC ex_CR_ReadAndGetISRC = NIL; CR_GETNUMBEROFCACHEERRORS ex_CR_GetNumberOfCacheErrors = NIL; CR_GETCDRIPVERSION ex_CR_GetCDRipVersion = NIL; DynamicLoader *cdripdll = NIL; Bool LoadCDRipDLL() { #ifdef __WIN32__ if (!File(GUI::Application::GetApplicationDirectory().Append("CDRip.dll")).Exists()) return False; #endif cdripdll = new DynamicLoader("CDRip"); ex_CR_GetNumCDROM = (CR_GETNUMCDROM) cdripdll->GetFunctionAddress("CR_GetNumCDROM"); ex_CR_OpenCDROM = (CR_OPENCDROM) cdripdll->GetFunctionAddress("CR_OpenCDROM"); ex_CR_CloseCDROM = (CR_CLOSECDROM) cdripdll->GetFunctionAddress("CR_CloseCDROM"); ex_CR_ReadToc = (CR_READTOC) cdripdll->GetFunctionAddress("CR_ReadToc"); ex_CR_GetNumTocEntries = (CR_GETNUMTOCENTRIES) cdripdll->GetFunctionAddress("CR_GetNumTocEntries"); ex_CR_GetTocEntry = (CR_GETTOCENTRY) cdripdll->GetFunctionAddress("CR_GetTocEntry"); ex_CR_OpenRipper = (CR_OPENRIPPER) cdripdll->GetFunctionAddress("CR_OpenRipper"); ex_CR_CloseRipper = (CR_CLOSERIPPER) cdripdll->GetFunctionAddress("CR_CloseRipper"); ex_CR_RipChunk = (CR_RIPCHUNK) cdripdll->GetFunctionAddress("CR_RipChunk"); ex_CR_GetCDROMParameters = (CR_GETCDROMPARAMETERS) cdripdll->GetFunctionAddress("CR_GetCDROMParameters"); ex_CR_SetCDROMParameters = (CR_SETCDROMPARAMETERS) cdripdll->GetFunctionAddress("CR_SetCDROMParameters"); ex_CR_ReadCDText = (CR_READCDTEXT) cdripdll->GetFunctionAddress("CR_ReadCDText"); ex_CR_ReadAndGetISRC = (CR_READANDGETISRC) cdripdll->GetFunctionAddress("CR_ReadAndGetISRC"); ex_CR_GetNumberOfCacheErrors = (CR_GETNUMBEROFCACHEERRORS) cdripdll->GetFunctionAddress("CR_GetNumberOfCacheErrors"); ex_CR_GetCDRipVersion = (CR_GETCDRIPVERSION) cdripdll->GetFunctionAddress("CR_GetCDRipVersion"); if (ex_CR_GetNumCDROM == NIL || ex_CR_OpenCDROM == NIL || ex_CR_CloseCDROM == NIL || ex_CR_ReadToc == NIL || ex_CR_GetNumTocEntries == NIL || ex_CR_GetTocEntry == NIL || ex_CR_OpenRipper == NIL || ex_CR_CloseRipper == NIL || ex_CR_RipChunk == NIL || ex_CR_GetCDROMParameters == NIL || ex_CR_SetCDROMParameters == NIL || ex_CR_ReadCDText == NIL || ex_CR_ReadAndGetISRC == NIL || ex_CR_GetNumberOfCacheErrors == NIL || ex_CR_GetCDRipVersion == NIL) { FreeCDRipDLL(); return False; } return True; } Void FreeCDRipDLL() { Object::DeleteObject(cdripdll); cdripdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/dllinterface.h000077500000000000000000000047141516712004000256750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *cdripdll; Bool LoadCDRipDLL(); Void FreeCDRipDLL(); typedef LONG (CRCCONV *CR_GETNUMCDROM) (); typedef CDROMDRIVE * (CRCCONV *CR_OPENCDROM) (LONG); typedef CDEX_ERR (CRCCONV *CR_CLOSECDROM) (CDROMDRIVE *); typedef CDEX_ERR (CRCCONV *CR_READTOC) (CDROMDRIVE *); typedef LONG (CRCCONV *CR_GETNUMTOCENTRIES) (CDROMDRIVE *); typedef TOCENTRY (CRCCONV *CR_GETTOCENTRY) (CDROMDRIVE *, LONG); typedef CDEX_ERR (CRCCONV *CR_OPENRIPPER) (CDROMDRIVE *, LONG *, LONG, LONG); typedef CDEX_ERR (CRCCONV *CR_CLOSERIPPER) (CDROMDRIVE *); typedef CDEX_ERR (CRCCONV *CR_RIPCHUNK) (CDROMDRIVE *, BYTE *, LONG *, BOOL &); typedef CDEX_ERR (CRCCONV *CR_GETCDROMPARAMETERS) (CDROMDRIVE *, CDROMPARAMS *); typedef CDEX_ERR (CRCCONV *CR_SETCDROMPARAMETERS) (CDROMDRIVE *, CDROMPARAMS *); typedef CDEX_ERR (CRCCONV *CR_READCDTEXT) (CDROMDRIVE *, BYTE *, int, LPINT); typedef CDEX_ERR (CRCCONV *CR_READANDGETISRC) (CDROMDRIVE *, ISRC *, int); typedef LONG (CRCCONV *CR_GETNUMBEROFCACHEERRORS) (CDROMDRIVE *); typedef LONG (CRCCONV *CR_GETCDRIPVERSION) (); extern CR_GETNUMCDROM ex_CR_GetNumCDROM; extern CR_OPENCDROM ex_CR_OpenCDROM; extern CR_CLOSECDROM ex_CR_CloseCDROM; extern CR_READTOC ex_CR_ReadToc; extern CR_GETNUMTOCENTRIES ex_CR_GetNumTocEntries; extern CR_GETTOCENTRY ex_CR_GetTocEntry; extern CR_OPENRIPPER ex_CR_OpenRipper; extern CR_CLOSERIPPER ex_CR_CloseRipper; extern CR_RIPCHUNK ex_CR_RipChunk; extern CR_GETCDROMPARAMETERS ex_CR_GetCDROMParameters; extern CR_SETCDROMPARAMETERS ex_CR_SetCDROMParameters; extern CR_READCDTEXT ex_CR_ReadCDText; extern CR_READANDGETISRC ex_CR_ReadAndGetISRC; extern CR_GETNUMBEROFCACHEERRORS ex_CR_GetNumberOfCacheErrors; extern CR_GETCDRIPVERSION ex_CR_GetCDRipVersion; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/000077500000000000000000000000001516712004000240125ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdinfo.cpp000066400000000000000000000046621516712004000257700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cdinfo.h" BoCA::CDInfo::CDInfo() { } BoCA::CDInfo::~CDInfo() { } Int BoCA::CDInfo::Clear() { artist = NIL; title = NIL; songwriter = NIL; composer = NIL; arranger = NIL; comment = NIL; genre = NIL; catalog = NIL; barcode = NIL; trackArtists.RemoveAll(); trackTitles.RemoveAll(); trackSongwriters.RemoveAll(); trackComposers.RemoveAll(); trackArrangers.RemoveAll(); trackComments.RemoveAll(); trackISRCs.RemoveAll(); return Success(); } Void BoCA::CDInfo::ReserveTracks(Int n) { while (trackArtists.Length() < n) { trackArtists.Add(NIL); trackTitles.Add(NIL); trackSongwriters.Add(NIL); trackComposers.Add(NIL); trackArrangers.Add(NIL); trackComments.Add(NIL); trackISRCs.Add(NIL); } } Void BoCA::CDInfo::SetTrackArtist(Int n, const String &nArtist) { ReserveTracks(n); if (nArtist.Trim() != NIL) trackArtists.SetNth(n - 1, nArtist); } Void BoCA::CDInfo::SetTrackTitle(Int n, const String &nTitle) { ReserveTracks(n); if (nTitle.Trim() != NIL) trackTitles.SetNth(n - 1, nTitle); } Void BoCA::CDInfo::SetTrackSongwriter(Int n, const String &nSongwriter) { ReserveTracks(n); if (nSongwriter.Trim() != NIL) trackSongwriters.SetNth(n - 1, nSongwriter); } Void BoCA::CDInfo::SetTrackComposer(Int n, const String &nComposer) { ReserveTracks(n); if (nComposer.Trim() != NIL) trackComposers.SetNth(n - 1, nComposer); } Void BoCA::CDInfo::SetTrackArranger(Int n, const String &nArranger) { ReserveTracks(n); if (nArranger.Trim() != NIL) trackArrangers.SetNth(n - 1, nArranger); } Void BoCA::CDInfo::SetTrackComment(Int n, const String &nComment) { ReserveTracks(n); if (nComment.Trim() != NIL) trackComments.SetNth(n - 1, nComment); } Void BoCA::CDInfo::SetTrackISRC(Int n, const String &nISRC) { ReserveTracks(n); if (nISRC.Trim() != NIL) trackISRCs.SetNth(n - 1, nISRC.Replace(" ", NIL).Replace("-", NIL)); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdinfo.h000066400000000000000000000066261516712004000254370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDRIP_CDINFO #define H_CDRIP_CDINFO #include using namespace smooth; namespace BoCA { class CDInfo { private: String artist; String title; String songwriter; String composer; String arranger; String comment; String genre; String catalog; String barcode; Array trackArtists; Array trackTitles; Array trackSongwriters; Array trackComposers; Array trackArrangers; Array trackComments; Array trackISRCs; Void ReserveTracks(Int); public: CDInfo(); ~CDInfo(); Int Clear(); accessors: /* Per-disc information. */ Void SetArtist(const String &nArtist) { artist = nArtist; } const String &GetArtist() const { return artist; } Void SetTitle(const String &nTitle) { title = nTitle; } const String &GetTitle() const { return title; } Void SetSongwriter(const String &nSongwriter) { songwriter = nSongwriter; } const String &GetSongwriter() const { return songwriter; } Void SetComposer(const String &nComposer) { composer = nComposer; } const String &GetComposer() const { return composer; } Void SetArranger(const String &nArranger) { arranger = nArranger; } const String &GetArranger() const { return arranger; } Void SetComment(const String &nComment) { comment = nComment; } const String &GetComment() const { return comment; } Void SetGenre(const String &nGenre) { genre = nGenre; } const String &GetGenre() const { return genre; } Void SetCatalog(const String &nCatalog) { catalog = nCatalog; } const String &GetCatalog() const { return catalog; } Void SetBarcode(const String &nBarcode) { barcode = nBarcode; } const String &GetBarcode() const { return barcode; } /* Optional per-track information. */ Void SetTrackArtist(Int n, const String &); const String &GetTrackArtist(Int n) const { return trackArtists.GetNth(n - 1); } Void SetTrackTitle(Int n, const String &); const String &GetTrackTitle(Int n) const { return trackTitles.GetNth(n - 1); } Void SetTrackSongwriter(Int n, const String &); const String &GetTrackSongwriter(Int n) const { return trackSongwriters.GetNth(n - 1); } Void SetTrackComposer(Int n, const String &); const String &GetTrackComposer(Int n) const { return trackComposers.GetNth(n - 1); } Void SetTrackArranger(Int n, const String &); const String &GetTrackArranger(Int n) const { return trackArrangers.GetNth(n - 1); } Void SetTrackComment(Int n, const String &); const String &GetTrackComment(Int n) const { return trackComments.GetNth(n - 1); } Void SetTrackISRC(Int n, const String &); const String &GetTrackISRC(Int n) const { return trackISRCs.GetNth(n - 1); } }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdplayerini.cpp000077500000000000000000000060721516712004000270310ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cdplayerini.h" #include "../dllinterface.h" using namespace smooth::IO; BoCA::CDPlayerIni::CDPlayerIni() { } BoCA::CDPlayerIni::~CDPlayerIni() { } Int BoCA::CDPlayerIni::ReadCDInfo(Int drive) { CDROMDRIVE *cd = ex_CR_OpenCDROM(drive); if (cd == NIL) return Error(); cdInfo.Clear(); Int numTocEntries = ex_CR_GetNumTocEntries(cd); UnsignedInt32 discID = 0; for (Int i = 0; i < numTocEntries; i++) { Int startSector = ex_CR_GetTocEntry(cd, i).dwStartSector + 150; Int minutes = startSector / 75 / 60; Int seconds = startSector / 75 % 60; Int frames = startSector % 75; discID += minutes * 0x10000 + seconds * 0x100 + frames; } if (numTocEntries < 3) { discID += ex_CR_GetTocEntry(cd, 0).dwStartSector; discID += ex_CR_GetTocEntry(cd, numTocEntries).dwStartSector; } String discIDString = DiscIDToString(discID); /* Strip leading zeroes. */ while (discIDString.StartsWith("0")) discIDString = discIDString.Tail(discIDString.Length() - 1); /* Open cdplayer.ini */ InStream *in = new InStream(STREAM_FILE, S::System::System::GetWindowsRootDirectory().Append("cdplayer.ini"), IS_READ); String idString = String("[").Append(discIDString).Append("]"); String result; while (in->GetPos() < in->Size()) { if (in->InputLine().ToLower() == idString) { while (in->GetPos() < in->Size()) { String line = in->InputLine(); if (line.ToLower().StartsWith("artist=")) { String artist; for (Int i = 7; i < line.Length(); i++) artist[i - 7] = line[i]; cdInfo.SetArtist(artist); } else if (line.ToLower().StartsWith("title=")) { String title; for (Int i = 6; i < line.Length(); i++) title[i - 6] = line[i]; cdInfo.SetTitle(title); } else if (line.StartsWith("0=") || line.ToInt() > 0) { String title; Int length = 2 + (line.ToInt() >= 10 ? 1 : 0); for (Int i = length; i < line.Length(); i++) title[i - length] = line[i]; cdInfo.SetTrackTitle(line.ToInt() + 1, title); } else if (line.StartsWith("[")) { break; } } break; } } delete in; ex_CR_CloseCDROM(cd); return Success(); } const BoCA::CDInfo &BoCA::CDPlayerIni::GetCDInfo() const { return cdInfo; } String BoCA::CDPlayerIni::DiscIDToString(UnsignedInt32 discID) { String result; for (Int i = 28; i >= 0; i -= 4) { if (((discID >> i) & 15) <= 9) result[(28 - i) / 4] = '0' + ((discID >> i) & 15); else result[(28 - i) / 4] = 'a' + ((discID >> i) & 15) - 10; } return result; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdplayerini.h000077500000000000000000000016661516712004000265020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDRIP_CDPLAYER #define H_CDRIP_CDPLAYER #include using namespace smooth; #include "cdinfo.h" namespace BoCA { class CDPlayerIni { private: static String DiscIDToString(UnsignedInt32); CDInfo cdInfo; public: CDPlayerIni(); ~CDPlayerIni(); Int ReadCDInfo(Int); const CDInfo &GetCDInfo() const; }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdtext.cpp000077500000000000000000000135071516712004000260220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cdtext.h" #include "../dllinterface.h" typedef struct { unsigned char packType; unsigned char trackNumber; unsigned char sequenceNumber; unsigned char characterPosition :4; unsigned char block :3; unsigned char bDBC :1; unsigned char data[12]; unsigned char crc0; unsigned char crc1; } cdTextPackage; static const String cdTextGenre[28] = { "Not Used", "Not Defined", "Adult Contemporary", "Alternative Rock", "Childrens Music", "Classical", "Contemporary Christian", "Country", "Dance", "Easy Listening", "Erotic", "Folk", "Gospel", "Hip Hop", "Jazz", "Latin", "Musical", "New Age", "Opera", "Operetta", "Pop Music", "Rap", "Reggae", "Rock Music", "Rhythm & Blues", "Sound Effects", "Spoken Word", "World Music" }; BoCA::CDText::CDText() { } BoCA::CDText::~CDText() { } Int BoCA::CDText::ReadCDText(Int drive) { CDROMDRIVE *cd = ex_CR_OpenCDROM(drive); if (cd == NIL) return Error(); cdInfo.Clear(); /* Read CD-Text. */ Buffer cdTextBuffer(4 + 8 * sizeof(cdTextPackage) * 256); Int cdTextSize = 0; ex_CR_ReadCDText(cd, cdTextBuffer, cdTextBuffer.Size(), &cdTextSize); if (cdTextSize < 4) { ex_CR_CloseCDROM(cd); return Error(); } /* Process CD-Text packs. */ Int numPacks = (cdTextSize - 4) / sizeof(cdTextPackage); cdTextPackage *currentPack = NIL; String data; char dataBuffer[3036] = { 0 }; Int dataBufferPos = 0; Int genreCode = 0; for (Int i = 0; i < numPacks; i++) { currentPack = (cdTextPackage *) &cdTextBuffer[i * sizeof(cdTextPackage) + 4]; if (currentPack->block != 0) continue; String::InputFormat format("ISO-8859-1"); String tabString = "\t"; Int nullBytes = 1; if (currentPack->bDBC) { String::SetInputFormat("Shift_JIS"); tabString = "\t\t"; nullBytes = 2; } /* Append pack data to buffer. */ for (Int j = 0; j < 12; j++) { if (j == 0 && currentPack->packType == 0x87 && currentPack->data[0] < 31 && currentPack->data[1] < 31) // Genre code { if (currentPack->data[0] == 0) genreCode = currentPack->data[0] << 8 | currentPack->data[1]; else genreCode = currentPack->data[1] << 8 | currentPack->data[0]; j++; continue; } dataBuffer[dataBufferPos++] = currentPack->data[j]; } /* Process pack data. */ if (String(dataBuffer) != tabString) data = ReplaceFullWidthChars(dataBuffer); while (dataBufferPos > 0) { /* Update text data. */ if (currentPack->packType == 0x80) // Album/Track title { if (currentPack->trackNumber == 0) cdInfo.SetTitle(data); else cdInfo.SetTrackTitle(currentPack->trackNumber, data); } else if (currentPack->packType == 0x81) // Artist name { if (currentPack->trackNumber == 0) cdInfo.SetArtist(data); else cdInfo.SetTrackArtist(currentPack->trackNumber, data); } else if (currentPack->packType == 0x82) // Songwriter { if (currentPack->trackNumber == 0) cdInfo.SetSongwriter(data); else cdInfo.SetTrackSongwriter(currentPack->trackNumber, data); } else if (currentPack->packType == 0x83) // Composer { if (currentPack->trackNumber == 0) cdInfo.SetComposer(data); else cdInfo.SetTrackComposer(currentPack->trackNumber, data); } else if (currentPack->packType == 0x84) // Arranger { if (currentPack->trackNumber == 0) cdInfo.SetArranger(data); else cdInfo.SetTrackArranger(currentPack->trackNumber, data); } else if (currentPack->packType == 0x85) // Message { if (currentPack->trackNumber == 0) cdInfo.SetComment(data); else cdInfo.SetTrackComment(currentPack->trackNumber, data); } else if (currentPack->packType == 0x86) // Catalog number { cdInfo.SetCatalog(data); } else if (currentPack->packType == 0x87) // Genre { cdInfo.SetGenre(data); } else if (currentPack->packType == 0x8e) // UPC/EAN and ISRC { if (currentPack->trackNumber == 0) cdInfo.SetBarcode(data); else cdInfo.SetTrackISRC(currentPack->trackNumber, data); } /* Look for string terminator. */ char *lpZero = (char *) memchr(dataBuffer, 0, dataBufferPos); if (lpZero == NIL) break; /* Shift buffer if terminated. */ Int nRemove = (lpZero - dataBuffer) + nullBytes; memmove(dataBuffer, dataBuffer + nRemove, sizeof(dataBuffer) - nRemove); dataBufferPos -= nRemove; currentPack->trackNumber++; /* Skip zero bytes. */ while (dataBufferPos >= nullBytes && dataBuffer[0] == 0) { memmove(dataBuffer, dataBuffer + nullBytes, sizeof(dataBuffer) - nullBytes); dataBufferPos -= nullBytes; currentPack->trackNumber++; } /* Update data string. */ if (dataBufferPos && String(dataBuffer) != tabString) data = ReplaceFullWidthChars(dataBuffer); } } ex_CR_CloseCDROM(cd); if (cdInfo.GetGenre().Trim() == NIL && genreCode != 0 && genreCode < 28) cdInfo.SetGenre(cdTextGenre[genreCode]); return Success(); } const BoCA::CDInfo &BoCA::CDText::GetCDInfo() const { return cdInfo; } String BoCA::CDText::ReplaceFullWidthChars(const String &string) { String result = string; Int length = string.Length(); for (Int i = 0; i < length; i++) { if (result[i] >= 0xff01 && result[i] <= 0xff5e) result[i] -= 0xfee0; else if (result[i] == 0x3000 ) result[i] = 0x20; } return result; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cdrip/info/cdtext.h000077500000000000000000000016531516712004000254660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CDRIP_CDTEXT #define H_CDRIP_CDTEXT #include using namespace smooth; #include "cdinfo.h" namespace BoCA { class CDText { private: CDInfo cdInfo; static String ReplaceFullWidthChars(const String &); public: CDText(); ~CDText(); Int ReadCDText(Int); const CDInfo &GetCDInfo() const; }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/000077500000000000000000000000001516712004000235635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/Makefile000066400000000000000000000011411516712004000252200ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cuesheet TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o cuesheet.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/config.cpp000066400000000000000000000075761516712004000255530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" using namespace smooth::GUI::Dialogs; const String BoCA::ConfigureCueSheet::ConfigID = "CueSheet"; BoCA::ConfigureCueSheet::ConfigureCueSheet() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Decoders::CueSheet"); readInfoTags = config->GetIntValue(ConfigID, "ReadInformationTags", True); preferCueSheets = config->GetIntValue(ConfigID, "PreferCueSheets", True); lookForAlternatives = config->GetIntValue(ConfigID, "LookForAlternativeFiles", False); ignoreErrors = config->GetIntValue(ConfigID, "IgnoreErrors", False); group_information = new GroupBox(i18n->TranslateString("Title information"), Point(7, 11), Size(552, 64)); check_read_tags = new CheckBox(i18n->TranslateString("Read tags from referenced files"), Point(10, 14), Size(532, 0), &readInfoTags); check_read_tags->onAction.Connect(&ConfigureCueSheet::ToggleReadTags, this); check_prefer_cue = new CheckBox(i18n->TranslateString("Prefer cue sheet metadata over referenced files' tags"), Point(27, 37), Size(515, 0), &preferCueSheets); ToggleReadTags(); group_information->Add(check_read_tags); group_information->Add(check_prefer_cue); group_alternatives = new GroupBox(i18n->TranslateString("Alternative files"), Point(7, 87), Size(552, 41)); check_alternatives = new CheckBox(i18n->TranslateString("Look for compressed alternatives if referenced Wave files cannot be located"), Point(10, 14), Size(532, 0), &lookForAlternatives); group_alternatives->Add(check_alternatives); group_errors = new GroupBox(i18n->TranslateString("Error handling"), Point(7, 140), Size(552, 41)); check_ignore_errors = new CheckBox(i18n->TranslateString("Ignore errors during cue sheet processing"), Point(10, 14), Size(532, 0), &ignoreErrors); group_errors->Add(check_ignore_errors); Int maxTextSize = Math::Max(Math::Max(check_read_tags->GetUnscaledTextWidth(), check_prefer_cue->GetUnscaledTextWidth() + 17), Math::Max(check_alternatives->GetUnscaledTextWidth(), check_ignore_errors->GetUnscaledTextWidth())); check_read_tags->SetWidth(maxTextSize + 21); check_prefer_cue->SetWidth(maxTextSize + 4); check_alternatives->SetWidth(maxTextSize + 21); check_ignore_errors->SetWidth(maxTextSize + 21); group_information->SetWidth(check_read_tags->GetWidth() + 20); group_alternatives->SetWidth(check_read_tags->GetWidth() + 20); group_errors->SetWidth(check_read_tags->GetWidth() + 20); Add(group_information); Add(group_alternatives); Add(group_errors); SetSize(Size(group_information->GetWidth() + 14, 188)); } BoCA::ConfigureCueSheet::~ConfigureCueSheet() { DeleteObject(group_information); DeleteObject(check_read_tags); DeleteObject(check_prefer_cue); DeleteObject(group_alternatives); DeleteObject(check_alternatives); DeleteObject(group_errors); DeleteObject(check_ignore_errors); } Void BoCA::ConfigureCueSheet::ToggleReadTags() { if (readInfoTags) check_prefer_cue->Activate(); else check_prefer_cue->Deactivate(); } Int BoCA::ConfigureCueSheet::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "ReadInformationTags", readInfoTags); config->SetIntValue(ConfigID, "PreferCueSheets", preferCueSheets); config->SetIntValue(ConfigID, "LookForAlternativeFiles", lookForAlternatives); config->SetIntValue(ConfigID, "IgnoreErrors", ignoreErrors); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/config.h000066400000000000000000000025061516712004000252040ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CUESHEET_CONFIG #define H_CUESHEET_CONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCueSheet : public ConfigLayer { private: GroupBox *group_information; CheckBox *check_read_tags; CheckBox *check_prefer_cue; GroupBox *group_alternatives; CheckBox *check_alternatives; GroupBox *group_errors; CheckBox *check_ignore_errors; Bool readInfoTags; Bool preferCueSheets; Bool lookForAlternatives; Bool ignoreErrors; public: static const String ConfigID; ConfigureCueSheet(); ~ConfigureCueSheet(); Int SaveSettings(); slots: Void ToggleReadTags(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/cuesheet.cpp000066400000000000000000000433031516712004000260770ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cuesheet.h" #include "config.h" using namespace smooth::IO; using namespace BoCA::AS; const String &BoCA::DecoderCueSheet::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::Decoders"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Cue Sheet Reader")).Append(" \ 1.0 \ cuesheet-dec \ decoder \ \ Cue Sheets \ cue \ \ \ \ "); return componentSpecs; } Bool BoCA::DecoderCueSheet::CanOpenStream(const String &streamURI) { return streamURI.ToLower().EndsWith(".cue"); } Error BoCA::DecoderCueSheet::GetStreamInfo(const String &streamURI, Track &track) { const Config *config = GetConfiguration(); Bool readInfoTags = config->GetIntValue(ConfigureCueSheet::ConfigID, "ReadInformationTags", True); Bool preferCueSheets = config->GetIntValue(ConfigureCueSheet::ConfigID, "PreferCueSheets", True); Bool lookForAlternatives = config->GetIntValue(ConfigureCueSheet::ConfigID, "LookForAlternativeFiles", False); Bool ignoreErrors = config->GetIntValue(ConfigureCueSheet::ConfigID, "IgnoreErrors", False); Track iTrack; Format format = track.GetFormat(); Info info; Array pictures; Track albumTrack; Info albumInfo; Bool trackMode = False; Bool dataMode = False; Int64 fileLength = 0; Int64 fileSize = 0; /* Standard format for audio discs. */ format.bits = 16; format.channels = 2; format.rate = 44100; format.order = BYTE_INTEL; track.SetFormat(format); /* Open cue sheet. */ InStream in(STREAM_FILE, streamURI, IS_READ); /* Detect input format. */ String inputFormat = "ISO-8859-1"; Int bom2 = in.InputNumberRaw(2); in.Seek(0); Int bom3 = in.InputNumberRaw(3); in.Seek(0); if (bom2 == 0xFFFE) { in.Seek(2); inputFormat = "UTF-16LE"; } else if (bom2 == 0xFEFF) { in.Seek(2); inputFormat = "UTF-16BE"; } else if (bom3 == 0xEFBBBF) { in.Seek(3); inputFormat = "UTF-8"; } else { /* Check for UTF-8, otherwise use system encoding or ISO-8859-1. */ String data = in.InputString(in.Size()); String dataUTF; if (dataUTF.ImportFrom("UTF-8", data.ConvertTo("ISO-8859-1")) == Success() && dataUTF != data) { /* Encoding appears to be UTF-8. */ inputFormat = "UTF-8"; } else if (String(String::GetDefaultEncoding()) != "UTF-8") { /* Other encoding, use system default. */ inputFormat = String::GetDefaultEncoding(); } in.Seek(0); } /* Read cue sheet data. */ Buffer data(in.Size() - in.GetPos() + 2); data.Zero(); in.InputData(data, data.Size() - 2); in.Close(); String cueSheet; cueSheet.ImportFrom(inputFormat, (char *) (UnsignedByte *) data); /* Actual parsing action. */ const Array &lines = cueSheet.Explode("\n"); foreach (String line, lines) { line = line.Trim(); /* Parse metadata comments. */ if (line.StartsWith("REM GENRE ")) { String genre; if (line.Contains("\"")) genre = UnescapeString(line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1)); else genre = UnescapeString(line.Tail(line.Length() - 10)); if (!readInfoTags || preferCueSheets) info.genre = genre; if (!trackMode && !dataMode) albumInfo.genre = genre; } if (line.StartsWith("REM DATE ")) { Int year = line.Tail(line.Length() - 9).ToInt(); if (!readInfoTags || preferCueSheets) info.year = year; if (!trackMode && !dataMode) albumInfo.year = year; } if (line.StartsWith("REM COMMENT ")) { String comment; if (line.Contains("\"")) comment = UnescapeString(line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1)); else comment = UnescapeString(line.Tail(line.Length() - 12)); if (!readInfoTags || preferCueSheets) info.comment = comment; if (!trackMode && !dataMode) albumInfo.comment = comment; } /* Parse Replay Gain comments. */ if (line.StartsWith("REM REPLAYGAIN_ALBUM_GAIN ")) { info.album_gain = line.Tail(line.Length() - 26); albumInfo.album_gain = info.album_gain; } else if (line.StartsWith("REM REPLAYGAIN_ALBUM_PEAK ")) { info.album_peak = line.Tail(line.Length() - 26); albumInfo.album_peak = info.album_peak; } else if (line.StartsWith("REM REPLAYGAIN_TRACK_GAIN ")) info.track_gain = line.Tail(line.Length() - 26); else if (line.StartsWith("REM REPLAYGAIN_TRACK_PEAK ")) info.track_peak = line.Tail(line.Length() - 26); /* Skip other comments. */ if (line.StartsWith("REM ")) continue; /* Regular metadata... */ if (line.StartsWith("PERFORMER ")) { String artist; if (line.Contains("\"")) artist = UnescapeString(line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1)); else artist = UnescapeString(line.Tail(line.Length() - 10)); if (!readInfoTags || preferCueSheets) { info.artist = artist; if (albumInfo.artist != NIL && albumInfo.artist != artist) info.SetOtherInfo(INFO_ALBUMARTIST, albumInfo.artist); } if (!trackMode && !dataMode) albumInfo.artist = artist; } if (line.StartsWith("SONGWRITER ")) { String songwriter; if (line.Contains("\"")) songwriter = UnescapeString(line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1)); else songwriter = UnescapeString(line.Tail(line.Length() - 11)); if (!readInfoTags || preferCueSheets) info.SetOtherInfo(INFO_COMPOSER, songwriter); if (!trackMode && !dataMode) albumInfo.SetOtherInfo(INFO_COMPOSER, songwriter); } if (line.StartsWith("TITLE ")) { String title; if (line.Contains("\"")) title = UnescapeString(line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1)); else title = UnescapeString(line.Tail(line.Length() - 6)); if (!readInfoTags || preferCueSheets) { if (!trackMode && !dataMode) info.album = title; else info.title = title; } if (!trackMode && !dataMode) albumInfo.album = title; } if (line.StartsWith("ISRC ")) { /* Check if the ISRC is valid. */ String isrc = line.Tail(line.Length() - 5); if (Info::IsISRC(isrc)) info.isrc = isrc; } /* Flags. */ if (line.StartsWith("FLAGS ")) { if (!trackMode) continue; const Array &flags = line.Tail(line.Length() - 6).Explode(" "); foreach (const String &flag, flags) { if (flag == "PRE") info.SetOtherInfo(INFO_PRE_EMPHASIS, "1"); } } /* Track sample offset. */ if (line.StartsWith("INDEX 01 ")) { const Array &msf = line.Tail(line.Length() - line.FindLast(" ") - 1).Explode(":"); Int64 samplePos = msf.GetNth(0).ToInt() * 60 * format.rate + msf.GetNth(1).ToInt() * format.rate + msf.GetNth(2).ToInt() * format.rate / 75; iTrack.sampleOffset = samplePos; } /* End of a track. */ if ((line.StartsWith("TRACK ") || line.StartsWith("FILE ") || foreachindex == lines.Length() - 1) && trackMode) { if ((iTrack.length == -1 && iTrack.approxLength == -1) || iTrack.length == fileLength || iTrack.approxLength == fileLength) { /* Get previous track length. */ if (line.StartsWith("FILE ") || foreachindex == lines.Length() - 1) { if (fileLength >= iTrack.sampleOffset) { iTrack.length = fileLength - iTrack.sampleOffset; iTrack.fileSize = Math::Round(Float(iTrack.fileSize) / fileLength * iTrack.length); } } if (line.StartsWith("TRACK ")) { for (Int i = foreachindex; i < lines.Length(); i++) { String line = lines.GetNth(i).Trim(); if (line.StartsWith("FILE ")) break; if (line.StartsWith("INDEX 01 ")) { const Array &msf = line.Tail(line.Length() - line.FindLast(" ") - 1).Explode(":"); Int64 samplePos = Math::Min(msf.GetNth(0).ToInt() * 60 * format.rate + msf.GetNth(1).ToInt() * format.rate + msf.GetNth(2).ToInt() * format.rate / 75, fileLength); if (samplePos > iTrack.sampleOffset) { iTrack.length = samplePos - iTrack.sampleOffset; iTrack.fileSize = Math::Round(Float(iTrack.fileSize) / fileLength * iTrack.length); } break; } } } } /* Add previous track. */ if (iTrack.length > 0 || iTrack.approxLength > 0) { iTrack.SetFormat(format); iTrack.SetInfo(info); iTrack.pictures = pictures; AddTrack(iTrack, track.tracks); } iTrack.length = -1; iTrack.approxLength = -1; iTrack.fileSize = fileSize; info.track_gain = NIL; info.track_peak = NIL; trackMode = False; } /* File reference. */ if (line.StartsWith("FILE ")) { /* Get referenced file name. */ String fileName; if (line.Contains("\"")) fileName = line.SubString(line.Find("\"") + 1, line.FindLast("\"") - line.Find("\"") - 1); else fileName = line.SubString(line.Find(" ") + 1, line.FindLast(" ") - line.Find(" ") - 1); /* Handle relative paths. */ String resolvedFileName = fileName; if (Utilities::IsRelativePath(resolvedFileName)) resolvedFileName = File(streamURI).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(resolvedFileName); /* If file is not found, try interpreting the file name using the default system encoding. */ if (!File(resolvedFileName).Exists() && String(String::GetInputFormat()) != String::GetDefaultEncoding()) { String::InputFormat inputFormat(String::GetDefaultEncoding()); String nativeFileName = fileName.ConvertTo("ISO-8859-1"); if (Utilities::IsRelativePath(nativeFileName)) nativeFileName = File(streamURI).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(nativeFileName); if (File(nativeFileName).Exists()) resolvedFileName = nativeFileName; } iTrack.fileName = File(resolvedFileName); /* Look for compressed files in place of referenced Wave, Wave64, RF64 or AIFF files. */ if (!File(iTrack.fileName).Exists() && lookForAlternatives && (iTrack.fileName.ToLower().EndsWith(".wav") || iTrack.fileName.ToLower().EndsWith(".w64") || iTrack.fileName.ToLower().EndsWith(".rf64") || iTrack.fileName.ToLower().EndsWith(".aif") || iTrack.fileName.ToLower().EndsWith(".aiff") || iTrack.fileName.ToLower().EndsWith(".aifc"))) { const char *extensions[] = { "wav", "w64", "rf64", "aif", "aiff", "aifc", "flac", "ape", "ofr", "tak", "tta", "wv", "m4a", "wma", "mp3", "ogg", "oga", "opus", "spx", NIL }; const String fileNameNoExt = iTrack.fileName.SubString(0, iTrack.fileName.FindLast(".") + 1); for (Int i = 0; extensions[i] != NIL; i++) { const String fileName = fileNameNoExt.Append(extensions[i]); if (File(fileName).Exists()) { iTrack.fileName = fileName; break; } } } /* Check file existence. */ if (!File(iTrack.fileName).Exists()) { errorState = True; errorString = "File referenced in cue sheet not found"; if (ignoreErrors) errorState = False; track = NIL; break; } /* Create decoder component. */ AS::Registry &boca = AS::Registry::Get(); AS::DecoderComponent *decoder = boca.CreateDecoderForStream(iTrack.fileName, GetConfiguration()); if (decoder == NIL) { errorState = True; errorString = "Unknown file type referenced in cue sheet"; if (ignoreErrors) errorState = False; track = NIL; break; } /* Disable reading chapters and embedded cue sheets. */ Config *decoderConfig = Config::Copy(GetConfiguration()); if (trackMode) { decoderConfig->SetIntValue("Tags", "ReadChapters", False); decoderConfig->SetIntValue("Tags", "ReadEmbeddedCueSheets", False); decoder->SetConfiguration(decoderConfig); } /* Get stream info. */ Track infoTrack; errorState = decoder->GetStreamInfo(iTrack.fileName, infoTrack); errorString = decoder->GetErrorString(); boca.DeleteComponent(decoder); Config::Free(decoderConfig); if (errorState) { if (ignoreErrors) errorState = False; track = NIL; break; } format = infoTrack.GetFormat(); if (readInfoTags) { info = infoTrack.GetInfo(); pictures = infoTrack.pictures; if (preferCueSheets) UpdateInfoWithAlbumInfo(info, albumInfo); } else { info = Info(); pictures.RemoveAll(); UpdateInfoWithAlbumInfo(info, albumInfo); } if (infoTrack.tracks.Length() > 0) albumTrack.tracks = infoTrack.tracks; if (infoTrack.length >= 0) { fileLength = infoTrack.length; iTrack.length = infoTrack.length; } else if (infoTrack.approxLength >= 0) { fileLength = infoTrack.approxLength; iTrack.approxLength = infoTrack.approxLength; } fileSize = infoTrack.fileSize; iTrack.fileSize = infoTrack.fileSize; iTrack.decoderID = infoTrack.decoderID; iTrack.lossless = infoTrack.lossless; } /* Start of a track. */ if (line.StartsWith("TRACK ")) { trackMode = line.EndsWith(" AUDIO"); dataMode = !line.EndsWith(" AUDIO"); Int track = line.SubString(line.Find(" ") + 1, line.FindLast(" ") - line.Find(" ") - 1).ToInt(); if (albumTrack.tracks.Length() >= track) { if (readInfoTags) { info = albumTrack.tracks.GetNth(track - 1).GetInfo(); pictures = albumTrack.tracks.GetNth(track - 1).pictures; if (preferCueSheets) UpdateInfoWithAlbumInfo(info, albumInfo); } else { info = Info(); pictures.RemoveAll(); UpdateInfoWithAlbumInfo(info, albumInfo); } } info.track = track; } } /* Return on error. */ if (errorState) return Error(); /* Generate offset string. */ Int offset = 150; if (track.tracks.Length() > 0) { const Track &iTrack = track.tracks.GetNth(0); const Format &format = iTrack.GetFormat(); if (iTrack.sampleOffset >= 0) offset += iTrack.sampleOffset / (format.rate / 75); } String offsets = Number((Int64) track.tracks.Length()).ToHexString(); for (Int i = 0; i < track.tracks.Length(); i++) { offsets.Append("+").Append(Number((Int64) offset).ToHexString()); const Track &iTrack = track.tracks.GetNth(i); const Format &format = iTrack.GetFormat(); if (iTrack.length >= 0) offset += iTrack.length / (format.rate / 75); else if (iTrack.approxLength >= 0) offset += iTrack.approxLength / (format.rate / 75); else { offsets = NIL; break; } } if (offsets != NIL) { offsets = offsets.Append("+").Append(Number((Int64) offset).ToHexString()).ToUpper(); /* Add offset string to all tracks. */ for (Int i = 0; i < track.tracks.Length(); i++) { Track &iTrack = track.tracks.GetNthReference(i); Info info = iTrack.GetInfo(); info.offsets = offsets; iTrack.SetInfo(info); } } /* Set lossless flag if all tracks are lossless. */ track.lossless = True; foreach (const Track &iTrack, track.tracks) { if (iTrack.lossless) continue; track.lossless = False; break; } /* Set number of tracks. */ for (Int i = 0; i < track.tracks.Length(); i++) { Track &iTrack = track.tracks.GetNthReference(i); Info info = iTrack.GetInfo(); info.numTracks = track.tracks.Length(); iTrack.SetInfo(info); } return Success(); } Void BoCA::DecoderCueSheet::UpdateInfoWithAlbumInfo(Info &info, const Info &albumInfo) const { if (albumInfo.artist != NIL) info.artist = albumInfo.artist; if (albumInfo.album != NIL) info.album = albumInfo.album; if (albumInfo.genre != NIL) info.genre = albumInfo.genre; if (albumInfo.year > 0) info.year = albumInfo.year; if (albumInfo.comment != NIL) info.comment = albumInfo.comment; if (albumInfo.HasOtherInfo(INFO_COMPOSER)) info.SetOtherInfo(INFO_COMPOSER, albumInfo.GetOtherInfo(INFO_COMPOSER)); if (albumInfo.album_gain != NIL) info.album_gain = albumInfo.album_gain; if (albumInfo.album_peak != NIL) info.album_peak = albumInfo.album_peak; } Bool BoCA::DecoderCueSheet::AddTrack(const Track &track, Array &tracks) const { /* Copy track data and add it to list of tracks. */ Track rTrack; rTrack.decoderID = track.decoderID; rTrack.fileName = track.fileName; rTrack.sampleOffset = track.sampleOffset; rTrack.length = track.length; rTrack.approxLength = track.approxLength; rTrack.fileSize = track.fileSize; rTrack.lossless = track.lossless; rTrack.pictures = track.pictures; rTrack.SetFormat(track.GetFormat()); rTrack.SetInfo(track.GetInfo()); tracks.Add(rTrack); return True; } String BoCA::DecoderCueSheet::UnescapeString(const String &string) { return string.Replace(" // ", "\n").Replace("''", "\""); } BoCA::DecoderCueSheet::DecoderCueSheet() { configLayer = NIL; } BoCA::DecoderCueSheet::~DecoderCueSheet() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderCueSheet::Activate() { return False; } Bool BoCA::DecoderCueSheet::Deactivate() { return False; } Int BoCA::DecoderCueSheet::ReadData(Buffer &data) { return -1; } ConfigLayer *BoCA::DecoderCueSheet::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureCueSheet(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/cuesheet/cuesheet.h000066400000000000000000000025211516712004000255410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DecoderCueSheet) namespace BoCA { class DecoderCueSheet : public CS::DecoderComponent { private: ConfigLayer *configLayer; Void UpdateInfoWithAlbumInfo(Info &, const Info &) const; Bool AddTrack(const Track &, Array &) const; static String UnescapeString(const String &); public: static const String &GetComponentSpecs(); DecoderCueSheet(); ~DecoderCueSheet(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderCueSheet) BoCA_END_COMPONENT(DecoderCueSheet) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/000077500000000000000000000000001516712004000227335ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/Makefile000077500000000000000000000012331516712004000243750ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = faad2 TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o faad2.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -Wno-multichar # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/dllinterface.cpp000077500000000000000000000140731516712004000261030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" NEAACDECOPEN ex_NeAACDecOpen = NIL; NEAACDECINIT ex_NeAACDecInit = NIL; NEAACDECINIT2 ex_NeAACDecInit2 = NIL; NEAACDECGETCURRENTCONFIGURATION ex_NeAACDecGetCurrentConfiguration = NIL; NEAACDECSETCONFIGURATION ex_NeAACDecSetConfiguration = NIL; NEAACDECAUDIOSPECIFICCONFIG ex_NeAACDecAudioSpecificConfig = NIL; NEAACDECDECODE ex_NeAACDecDecode = NIL; NEAACDECCLOSE ex_NeAACDecClose = NIL; NEAACDECGETERRORMESSAGE ex_NeAACDecGetErrorMessage = NIL; NEAACDECGETVERSION ex_NeAACDecGetVersion = NIL; MP4READ ex_MP4Read = NIL; MP4READCALLBACKS ex_MP4ReadCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4FREE ex_MP4Free = NIL; MP4FINDTRACKID ex_MP4FindTrackId = NIL; MP4GETTRACKAUDIOMPEG4TYPE ex_MP4GetTrackAudioMpeg4Type = NIL; MP4GETTRACKAUDIOCHANNELS ex_MP4GetTrackAudioChannels = NIL; MP4GETTRACKESCONFIGURATION ex_MP4GetTrackESConfiguration = NIL; MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale = NIL; MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples = NIL; MP4GETSAMPLETIME ex_MP4GetSampleTime = NIL; MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime = NIL; MP4GETSAMPLESIZE ex_MP4GetSampleSize = NIL; MP4READSAMPLE ex_MP4ReadSample = NIL; MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning = NIL; MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree = NIL; DynamicLoader *faad2dll = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadFAAD2DLL() { #ifdef __WIN32__ faad2dll = BoCA::Utilities::LoadCodecDLL("FAAD2"); #else faad2dll = BoCA::Utilities::LoadCodecDLL("faad"); #endif if (faad2dll == NIL) return False; ex_NeAACDecOpen = (NEAACDECOPEN) faad2dll->GetFunctionAddress("NeAACDecOpen"); ex_NeAACDecInit = (NEAACDECINIT) faad2dll->GetFunctionAddress("NeAACDecInit"); ex_NeAACDecInit2 = (NEAACDECINIT2) faad2dll->GetFunctionAddress("NeAACDecInit2"); ex_NeAACDecGetCurrentConfiguration = (NEAACDECGETCURRENTCONFIGURATION) faad2dll->GetFunctionAddress("NeAACDecGetCurrentConfiguration"); ex_NeAACDecSetConfiguration = (NEAACDECSETCONFIGURATION) faad2dll->GetFunctionAddress("NeAACDecSetConfiguration"); ex_NeAACDecAudioSpecificConfig = (NEAACDECAUDIOSPECIFICCONFIG) faad2dll->GetFunctionAddress("NeAACDecAudioSpecificConfig"); ex_NeAACDecDecode = (NEAACDECDECODE) faad2dll->GetFunctionAddress("NeAACDecDecode"); ex_NeAACDecClose = (NEAACDECCLOSE) faad2dll->GetFunctionAddress("NeAACDecClose"); ex_NeAACDecGetErrorMessage = (NEAACDECGETERRORMESSAGE) faad2dll->GetFunctionAddress("NeAACDecGetErrorMessage"); ex_NeAACDecGetVersion = (NEAACDECGETVERSION) faad2dll->GetFunctionAddress("NeAACDecGetVersion"); if (ex_NeAACDecOpen == NIL || ex_NeAACDecInit == NIL || ex_NeAACDecInit2 == NIL || ex_NeAACDecGetCurrentConfiguration == NIL || ex_NeAACDecSetConfiguration == NIL || ex_NeAACDecAudioSpecificConfig == NIL || ex_NeAACDecDecode == NIL || ex_NeAACDecClose == NIL || ex_NeAACDecGetErrorMessage == NIL || ex_NeAACDecGetVersion == NIL) { FreeFAAD2DLL(); return False; } return True; } Void FreeFAAD2DLL() { BoCA::Utilities::FreeCodecDLL(faad2dll); faad2dll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Read = (MP4READ) mp4v2dll->GetFunctionAddress("MP4Read"); ex_MP4ReadCallbacks = (MP4READCALLBACKS) mp4v2dll->GetFunctionAddress("MP4ReadCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Free = (MP4FREE) mp4v2dll->GetFunctionAddress("MP4Free"); ex_MP4FindTrackId = (MP4FINDTRACKID) mp4v2dll->GetFunctionAddress("MP4FindTrackId"); ex_MP4GetTrackAudioMpeg4Type = (MP4GETTRACKAUDIOMPEG4TYPE) mp4v2dll->GetFunctionAddress("MP4GetTrackAudioMpeg4Type"); ex_MP4GetTrackAudioChannels = (MP4GETTRACKAUDIOCHANNELS) mp4v2dll->GetFunctionAddress("MP4GetTrackAudioChannels"); ex_MP4GetTrackESConfiguration = (MP4GETTRACKESCONFIGURATION) mp4v2dll->GetFunctionAddress("MP4GetTrackESConfiguration"); ex_MP4GetTrackTimeScale = (MP4GETTRACKTIMESCALE) mp4v2dll->GetFunctionAddress("MP4GetTrackTimeScale"); ex_MP4GetTrackNumberOfSamples = (MP4GETTRACKNUMBEROFSAMPLES) mp4v2dll->GetFunctionAddress("MP4GetTrackNumberOfSamples"); ex_MP4GetSampleTime = (MP4GETSAMPLETIME) mp4v2dll->GetFunctionAddress("MP4GetSampleTime"); ex_MP4GetSampleIdFromTime = (MP4GETSAMPLEIDFROMTIME) mp4v2dll->GetFunctionAddress("MP4GetSampleIdFromTime"); ex_MP4GetSampleSize = (MP4GETSAMPLESIZE) mp4v2dll->GetFunctionAddress("MP4GetSampleSize"); ex_MP4ReadSample = (MP4READSAMPLE) mp4v2dll->GetFunctionAddress("MP4ReadSample"); ex_MP4ItmfGetItemsByMeaning = (MP4ITMFGETITEMSBYMEANING) mp4v2dll->GetFunctionAddress("MP4ItmfGetItemsByMeaning"); ex_MP4ItmfItemListFree = (MP4ITMFITEMLISTFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemListFree"); if (ex_MP4Read == NIL || ex_MP4ReadCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Free == NIL || ex_MP4FindTrackId == NIL || ex_MP4GetTrackAudioMpeg4Type == NIL || ex_MP4GetTrackAudioChannels == NIL || ex_MP4GetTrackESConfiguration == NIL || ex_MP4GetTrackTimeScale == NIL || ex_MP4GetTrackNumberOfSamples == NIL || ex_MP4GetSampleTime == NIL || ex_MP4GetSampleIdFromTime == NIL || ex_MP4GetSampleSize == NIL || ex_MP4ReadSample == NIL || ex_MP4ItmfGetItemsByMeaning == NIL || ex_MP4ItmfItemListFree == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/dllinterface.h000077500000000000000000000105221516712004000255430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *faad2dll; extern DynamicLoader *mp4v2dll; Bool LoadFAAD2DLL(); Void FreeFAAD2DLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef NeAACDecHandle (*NEAACDECOPEN) (); typedef long (*NEAACDECINIT) (NeAACDecHandle, unsigned char *, unsigned long, unsigned long *, unsigned char *); typedef long (*NEAACDECINIT2) (NeAACDecHandle, unsigned char *, unsigned long, unsigned long *, unsigned char *); typedef NeAACDecConfigurationPtr (*NEAACDECGETCURRENTCONFIGURATION) (NeAACDecHandle); typedef unsigned char (*NEAACDECSETCONFIGURATION) (NeAACDecHandle, NeAACDecConfigurationPtr); typedef char (*NEAACDECAUDIOSPECIFICCONFIG) (unsigned char *, unsigned long, mp4AudioSpecificConfig *); typedef void * (*NEAACDECDECODE) (NeAACDecHandle, NeAACDecFrameInfo *, unsigned char *, unsigned long); typedef void (*NEAACDECCLOSE) (NeAACDecHandle); typedef char * (*NEAACDECGETERRORMESSAGE) (unsigned char); typedef int (*NEAACDECGETVERSION) (char **, char **); extern NEAACDECOPEN ex_NeAACDecOpen; extern NEAACDECINIT ex_NeAACDecInit; extern NEAACDECINIT2 ex_NeAACDecInit2; extern NEAACDECGETCURRENTCONFIGURATION ex_NeAACDecGetCurrentConfiguration; extern NEAACDECSETCONFIGURATION ex_NeAACDecSetConfiguration; extern NEAACDECAUDIOSPECIFICCONFIG ex_NeAACDecAudioSpecificConfig; extern NEAACDECDECODE ex_NeAACDecDecode; extern NEAACDECCLOSE ex_NeAACDecClose; extern NEAACDECGETERRORMESSAGE ex_NeAACDecGetErrorMessage; extern NEAACDECGETVERSION ex_NeAACDecGetVersion; typedef MP4FileHandle (*MP4READ) (const char *); typedef MP4FileHandle (*MP4READCALLBACKS) (const MP4IOCallbacks *, void *); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef void (*MP4FREE) (void *); typedef MP4TrackId (*MP4FINDTRACKID) (MP4FileHandle, uint16_t, const char *, uint8_t); typedef uint8_t (*MP4GETTRACKAUDIOMPEG4TYPE) (MP4FileHandle, MP4TrackId); typedef int (*MP4GETTRACKAUDIOCHANNELS) (MP4FileHandle, MP4TrackId); typedef bool (*MP4GETTRACKESCONFIGURATION) (MP4FileHandle, MP4TrackId, uint8_t **, uint32_t *); typedef uint32_t (*MP4GETTRACKTIMESCALE) (MP4FileHandle, MP4TrackId); typedef MP4SampleId (*MP4GETTRACKNUMBEROFSAMPLES) (MP4FileHandle, MP4TrackId); typedef MP4Timestamp (*MP4GETSAMPLETIME) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef MP4SampleId (*MP4GETSAMPLEIDFROMTIME) (MP4FileHandle, MP4TrackId, MP4Timestamp, bool); typedef uint32_t (*MP4GETSAMPLESIZE) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef bool (*MP4READSAMPLE) (MP4FileHandle, MP4TrackId, MP4SampleId, uint8_t **, uint32_t *, MP4Timestamp *, MP4Duration *, MP4Duration *, bool *); typedef MP4ItmfItemList * (*MP4ITMFGETITEMSBYMEANING) (MP4FileHandle, const char *, const char *); typedef void (*MP4ITMFITEMLISTFREE) (MP4ItmfItemList *); extern MP4READ ex_MP4Read; extern MP4READCALLBACKS ex_MP4ReadCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4FREE ex_MP4Free; extern MP4FINDTRACKID ex_MP4FindTrackId; extern MP4GETTRACKAUDIOMPEG4TYPE ex_MP4GetTrackAudioMpeg4Type; extern MP4GETTRACKAUDIOCHANNELS ex_MP4GetTrackAudioChannels; extern MP4GETTRACKESCONFIGURATION ex_MP4GetTrackESConfiguration; extern MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale; extern MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples; extern MP4GETSAMPLETIME ex_MP4GetSampleTime; extern MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime; extern MP4GETSAMPLESIZE ex_MP4GetSampleSize; extern MP4READSAMPLE ex_MP4ReadSample; extern MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning; extern MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/faad2.cpp000066400000000000000000000455401516712004000244240ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "faad2.h" #ifndef PS # define PS 29 #endif using namespace smooth::IO; const String &BoCA::DecoderFAAD2::GetComponentSpecs() { static String componentSpecs; if (faad2dll != NIL) { componentSpecs = " \ \ \ \ FAAD2 MP4/AAC Decoder %VERSION% \ 1.0 \ faad2-dec \ decoder \ \ "; if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ 3gp \ 3gpp \ MP4 Metadata \ \ \ "); } componentSpecs.Append(" \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ \ "); char *faad2Version = NIL; ex_NeAACDecGetVersion(&faad2Version, NIL); componentSpecs.Replace("%VERSION%", String("v").Append(faad2Version)); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFAAD2DLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeFAAD2DLL(); FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_read(void *, void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, MP4IO_read, NIL, NIL }; }; Bool BoCA::DecoderFAAD2::CanOpenStream(const String &streamURI) { Bool isValidFile = False; InStream in(STREAM_FILE, streamURI, IS_READ); if (mp4v2dll != NIL && (in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) { Int type = ex_MP4GetTrackAudioMpeg4Type(mp4File, mp4Track); if (type == MAIN || type == LC || type == LTP || type == HE_AAC || type == LD || type == PS || type == ER_LC || type == ER_LTP) isValidFile = True; } ex_MP4Close(mp4File, 0); } else { Track track; if (GetStreamInfo(streamURI, track) == Success()) isValidFile = True; } return isValidFile; } Error BoCA::DecoderFAAD2::GetStreamInfo(const String &streamURI, Track &track) { Format format = track.GetFormat(); InStream in(STREAM_FILE, streamURI, IS_READ); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { track.fileSize = File(streamURI).GetFileSize(); track.length = -1; MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) { NeAACDecHandle handle = ex_NeAACDecOpen(); NeAACDecConfigurationPtr fConfig = ex_NeAACDecGetCurrentConfiguration(handle); fConfig->defSampleRate = 44100; fConfig->defObjectType = LC; fConfig->outputFormat = FAAD_FMT_16BIT; ex_NeAACDecSetConfiguration(handle, fConfig); /* Get codec configuration. */ unsigned char *escBuffer = NIL; unsigned long escBufferSize = 0; ex_MP4GetTrackESConfiguration(mp4File, mp4Track, (uint8_t **) &escBuffer, (uint32_t *) &escBufferSize); if (ex_NeAACDecInit2(handle, escBuffer, escBufferSize, (unsigned long *) &format.rate, (unsigned char *) &format.channels) < 0) { errorState = True; errorString = "Unsupported audio format"; } if (format.channels == 2 && ex_MP4GetTrackAudioChannels(mp4File, mp4Track) == 1) format.channels = 1; ex_MP4Free(escBuffer); /* Decode frames to get frame size. */ while (frameSize == 0 && !errorState) { unsigned int bufferSize = ex_MP4GetSampleSize(mp4File, mp4Track, sampleId); unsigned char *buffer = new unsigned char [bufferSize]; ex_MP4ReadSample(mp4File, mp4Track, sampleId++, (uint8_t **) &buffer, (uint32_t *) &bufferSize, NIL, NIL, NIL, NIL); NeAACDecFrameInfo frameInfo; ex_NeAACDecDecode(handle, &frameInfo, buffer, bufferSize); if (frameInfo.error) { errorState = True; errorString = "Unsupported audio format"; } frameSize = frameInfo.samples / frameInfo.channels; if (frameInfo.sbr == SBR_UPSAMPLED || frameInfo.sbr == NO_SBR_UPSAMPLED) sbrRatio = 2; delete [] buffer; } /* Get track length. */ track.length = Int64(ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track)) * frameSize; track.length -= frameSize; // To account for encoder delay. format.bits = 16; ex_NeAACDecClose(handle); track.SetFormat(format); /* Read gapless information. */ Int delay = 0, padding = 0; Int64 length = 0; if (ReadGaplessInfo(mp4File, delay, padding, length) && (delay + padding + length) * sbrRatio == Int64(ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track)) * frameSize) { track.length = length * sbrRatio; } } ex_MP4Close(mp4File, 0); /* Read MP4 metadata. */ if (!errorState) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } else { in.Seek(0); format.bits = 16; track.fileSize = in.Size(); track.length = -1; SkipID3v2Tag(in); if (!SyncOnAACHeader(in)) { errorState = True; errorString = "Invalid file format"; return Error(); } NeAACDecHandle handle = ex_NeAACDecOpen(); NeAACDecConfigurationPtr fConfig = ex_NeAACDecGetCurrentConfiguration(handle); fConfig->defSampleRate = 44100; fConfig->defObjectType = LC; fConfig->outputFormat = FAAD_FMT_16BIT; ex_NeAACDecSetConfiguration(handle, fConfig); /* Get sample rate and number of channels. */ Int size = Math::Min((Int64) 32768, track.fileSize - in.GetPos()); unsigned char *data = new unsigned char [size]; in.InputData((void *) data, size); if (ex_NeAACDecInit(handle, data, size, (unsigned long *) &format.rate, (unsigned char *) &format.channels) < 0) { errorState = True; errorString = "Unsupported audio format"; } /* Compute approximate length of stream. */ if (!errorState) { NeAACDecFrameInfo frameInfo; ex_NeAACDecDecode(handle, &frameInfo, data, size); if (!frameInfo.error) { Int bytesConsumed = 0; Int samplesRead = 0; while (!frameInfo.error) { bytesConsumed += frameInfo.bytesconsumed; samplesRead += frameInfo.samples; ex_NeAACDecDecode(handle, &frameInfo, data + bytesConsumed, size - bytesConsumed); } if (samplesRead > 0) track.approxLength = samplesRead / format.channels * (track.fileSize / bytesConsumed); } else { errorState = True; errorString = "Unsupported audio format"; } } /* Close handles. */ delete [] data; ex_NeAACDecClose(handle); /* Read ID3v2 tag if any. */ if (!errorState) { Bool foundTag = False; AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); if (tagger->ParseStreamInfo(streamURI, track) == Success()) foundTag = True; boca.DeleteComponent(tagger); } if (!foundTag) { tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } } track.SetFormat(format); if (!errorState) return Success(); else return Error(); } BoCA::DecoderFAAD2::DecoderFAAD2() { mp4File = NIL; handle = NIL; fConfig = NIL; mp4Track = MP4_INVALID_TRACK_ID; sampleId = 1; frameSize = 0; sbrRatio = 1; delaySamples = 0; delaySamplesLeft = 0; } BoCA::DecoderFAAD2::~DecoderFAAD2() { } Bool BoCA::DecoderFAAD2::Activate() { InStream in(STREAM_DRIVER, driver); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { mp4File = ex_MP4ReadCallbacks(&mp4Callbacks, driver); mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track == MP4_INVALID_TRACK_ID) { ex_MP4Close(mp4File, 0); return False; } } else { in.Seek(0); SkipID3v2Tag(in); SyncOnAACHeader(in); driver->Seek(in.GetPos()); } handle = ex_NeAACDecOpen(); fConfig = ex_NeAACDecGetCurrentConfiguration(handle); fConfig->defSampleRate = 44100; fConfig->defObjectType = LC; fConfig->outputFormat = FAAD_FMT_16BIT; ex_NeAACDecSetConfiguration(handle, fConfig); if (mp4File != NIL) { /* Get codec configuration. */ unsigned char *escBuffer = NIL; unsigned long escBufferSize = 0; ex_MP4GetTrackESConfiguration(mp4File, mp4Track, (uint8_t **) &escBuffer, (uint32_t *) &escBufferSize); unsigned long rate; unsigned char channels; if (ex_NeAACDecInit2(handle, escBuffer, escBufferSize, &rate, &channels) < 0) { errorState = True; errorString = "Unsupported audio format"; } ex_MP4Free(escBuffer); } else { Int size = 4096; unsigned char *data = new unsigned char [size]; size = driver->ReadData(data, size); unsigned long rate; unsigned char channels; if (ex_NeAACDecInit(handle, data, size, &rate, &channels) < 0) { errorState = True; errorString = "Unsupported audio format"; } delete [] data; driver->Seek(driver->GetPos() - size); } /* Check for error. */ if (errorState) { ex_NeAACDecClose(handle); if (mp4File != NIL) ex_MP4Close(mp4File, 0); return False; } return True; } Bool BoCA::DecoderFAAD2::Deactivate() { /* Close decoder. */ ex_NeAACDecClose(handle); if (mp4File == NIL) return True; /* Close MP4 file. */ ex_MP4Close(mp4File, 0); return True; } Bool BoCA::DecoderFAAD2::Seek(Int64 samplePosition) { if (mp4File == NIL) return False; MP4Timestamp time = Math::Round(Float(samplePosition) / track.GetFormat().rate * ex_MP4GetTrackTimeScale(mp4File, mp4Track)); sampleId = ex_MP4GetSampleIdFromTime(mp4File, mp4Track, time, true); delaySamplesLeft = delaySamples + time - ex_MP4GetSampleTime(mp4File, mp4Track, sampleId); return True; } Int BoCA::DecoderFAAD2::ReadData(Buffer &data) { const Format &format = track.GetFormat(); Void *samples = NIL; Int samplesRead = 0; samplesBuffer.Resize(0); if (mp4File != NIL) { MP4SampleId numberOfSamples = ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track); if (sampleId > numberOfSamples) return -1; unsigned int bufferSize = ex_MP4GetSampleSize(mp4File, mp4Track, sampleId); dataBuffer.Resize(bufferSize); unsigned char *buffer = dataBuffer; if (!ex_MP4ReadSample(mp4File, mp4Track, sampleId++, (uint8_t **) &buffer, (uint32_t *) &bufferSize, NIL, NIL, NIL, NIL)) return -1; NeAACDecFrameInfo frameInfo; samples = ex_NeAACDecDecode(handle, &frameInfo, buffer, bufferSize); if (!frameInfo.error && frameInfo.samples > 0 && samples != NIL) { if (frameSize == 0) { frameSize = frameInfo.samples / frameInfo.channels; if (frameInfo.sbr == SBR_UPSAMPLED || frameInfo.sbr == NO_SBR_UPSAMPLED) sbrRatio = 2; /* Get delay from gapless information. */ Int delay = 0, padding = 0; Int64 length = 0; if (ReadGaplessInfo(mp4File, delay, padding, length) && (delay + padding + length) * sbrRatio == Int64(numberOfSamples) * frameSize) { if (sbrRatio > 1) delay += 480; delaySamples = delay * sbrRatio; delaySamplesLeft = delaySamples; } /* Set delay samples to minimum encoder delay. */ if (delaySamples == 0) { delaySamples = frameSize + (sbrRatio == 1 ? 0 : 480) * sbrRatio; delaySamplesLeft = delaySamples; } /* FAAD2 automatically skips the first frame, so * subtract it from the delay sample count. */ delaySamplesLeft -= frameSize; /* Fix delay for LD/ELD object types. */ if (frameInfo.object_type == LD) delaySamplesLeft += frameSize; } samplesBuffer.Resize(samplesRead * format.channels + frameInfo.samples); if (format.channels == 1 && frameInfo.channels == 2) { for (UnsignedInt i = 0; i < frameInfo.samples; i++) samplesBuffer[samplesRead + i] = ((int16_t *) samples)[i * 2]; } else { memcpy(samplesBuffer + samplesRead * format.channels, samples, frameInfo.samples * (format.bits / 8)); } samplesRead += frameSize; } } else { dataBuffer.Resize(data.Size() + backBuffer.Size()); Int size = driver->ReadData(dataBuffer + backBuffer.Size(), data.Size()); if (size <= 0) return -1; inBytes += size; if (backBuffer.Size() > 0) { memcpy(dataBuffer, backBuffer, backBuffer.Size()); size += backBuffer.Size(); backBuffer.Resize(0); } Int bytesConsumed = 0; do { NeAACDecFrameInfo frameInfo; samples = ex_NeAACDecDecode(handle, &frameInfo, dataBuffer + bytesConsumed, size - bytesConsumed); if (!frameInfo.error && frameInfo.samples > 0 && samples != NIL) { if (frameSize == 0) { frameSize = frameInfo.samples / frameInfo.channels; if (frameInfo.sbr == SBR_UPSAMPLED || frameInfo.sbr == NO_SBR_UPSAMPLED) sbrRatio = 2; /* Set delay samples to minimum encoder delay. */ delaySamples = frameSize + (sbrRatio == 1 ? 0 : 480) * sbrRatio; delaySamplesLeft = delaySamples; /* FAAD2 automatically skips the first frame, so * subtract it from the delay sample count. */ delaySamplesLeft -= frameSize; /* Fix delay for LD/ELD object types. */ if (frameInfo.object_type == LD) delaySamplesLeft += frameSize; } samplesBuffer.Resize(samplesRead * format.channels + frameInfo.samples); memcpy(samplesBuffer + samplesRead * format.channels, samples, frameInfo.samples * (format.bits / 8)); samplesRead += frameSize; } bytesConsumed += frameInfo.bytesconsumed; if ((size - bytesConsumed < bytesConsumed) && (driver->GetPos() < driver->GetSize())) samples = NIL; } while (samples != NIL); if ((size - bytesConsumed) > 0) { backBuffer.Resize(size - bytesConsumed); memcpy(backBuffer, dataBuffer + bytesConsumed, backBuffer.Size()); } } data.Resize(0); if (samplesRead > delaySamplesLeft) { data.Resize((samplesRead - delaySamplesLeft) * format.channels * (format.bits / 8)); memcpy(data, samplesBuffer + delaySamplesLeft * format.channels, data.Size()); } delaySamplesLeft = Math::Max(0, delaySamplesLeft - samplesRead); /* Change to default channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::AAC_3_0, Channel::Default_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::AAC_5_0, Channel::Default_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::AAC_5_1, Channel::Default_5_1); return data.Size(); } Bool BoCA::DecoderFAAD2::ReadGaplessInfo(MP4FileHandle mp4File, Int &delay, Int &padding, Int64 &length) const { Bool result = False; /* Look for iTunes metadata with gapless information. */ MP4ItmfItemList *items = ex_MP4ItmfGetItemsByMeaning(mp4File, "com.apple.iTunes", "iTunSMPB"); if (items != NIL) { if (items->size == 1) { /* Read value as string. */ Buffer value(items->elements[0].dataList.elements[0].valueSize + 1); memset(value, 0, items->elements[0].dataList.elements[0].valueSize + 1); memcpy(value, items->elements[0].dataList.elements[0].value, items->elements[0].dataList.elements[0].valueSize); /* Parse value string. */ const Array &values = String(value).Trim().Explode(" "); delay = (Int64) Number::FromHexString(values.GetNth(1)); padding = (Int64) Number::FromHexString(values.GetNth(2)); length = (Int64) Number::FromHexString(values.GetNth(3)); result = True; } ex_MP4ItmfItemListFree(items); } return result; } Bool BoCA::DecoderFAAD2::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning of the * file and skip it if it exists as FAAD2 may crash * on unsynchronized tags. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } Bool BoCA::DecoderFAAD2::SyncOnAACHeader(InStream &in) { const Int startPos = in.GetPos(); const Int maxFrameSize = 8192; /* Try to sync on ADIF header. */ for (Int n = 0; n < maxFrameSize; n++) { if (in.InputNumber(1) != 'A') continue; if (in.InputNumber(1) != 'D') continue; if (in.InputNumber(1) != 'I') continue; if (in.InputNumber(1) != 'F') continue; /* ADIF magic word found. */ in.RelSeek(-4); inBytes += n; return True; } in.Seek(startPos); /* Try to sync on ADTS header. */ for (Int n = 0; n < maxFrameSize; n++) { if ( in.InputNumber(1) != 0xFF) continue; if ( (in.InputNumber(1) & 0xF6) != 0xF0) continue; if (((in.InputNumber(1) & 0x3C) >> 2) >= 12) continue; /* ADTS sync found. */ in.RelSeek(-3); inBytes += n; return True; } /* No sync. Probably not an AAC file. */ return False; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_read(void *handle, void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->ReadData((UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/faad2/faad2.h000066400000000000000000000032211516712004000240570ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderFAAD2) namespace BoCA { class DecoderFAAD2 : public CS::DecoderComponent { private: MP4FileHandle mp4File; NeAACDecHandle handle; NeAACDecConfigurationPtr fConfig; MP4TrackId mp4Track; MP4SampleId sampleId; Int frameSize; Int sbrRatio; Int delaySamples; Int delaySamplesLeft; Buffer dataBuffer; Buffer backBuffer; Buffer samplesBuffer; Bool ReadGaplessInfo(MP4FileHandle, Int &, Int &, Int64 &) const; Bool SkipID3v2Tag(IO::InStream &); Bool SyncOnAACHeader(IO::InStream &); public: static const String &GetComponentSpecs(); DecoderFAAD2(); ~DecoderFAAD2(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderFAAD2) BoCA_END_COMPONENT(DecoderFAAD2) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/000077500000000000000000000000001516712004000231675ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/Makefile000066400000000000000000000012351516712004000246300ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = fdkaac TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o fdkaac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -Wno-multichar # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/dllinterface.cpp000066400000000000000000000126641516712004000263400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" AACDECODER_OPEN ex_aacDecoder_Open = NIL; AACDECODER_CONFIGRAW ex_aacDecoder_ConfigRaw = NIL; AACDECODER_FILL ex_aacDecoder_Fill = NIL; AACDECODER_GETSTREAMINFO ex_aacDecoder_GetStreamInfo = NIL; AACDECODER_DECODEFRAME ex_aacDecoder_DecodeFrame = NIL; AACDECODER_CLOSE ex_aacDecoder_Close = NIL; AACDECODER_GETLIBINFO ex_aacDecoder_GetLibInfo = NIL; MP4READ ex_MP4Read = NIL; MP4READCALLBACKS ex_MP4ReadCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4FREE ex_MP4Free = NIL; MP4FINDTRACKID ex_MP4FindTrackId = NIL; MP4GETTRACKAUDIOMPEG4TYPE ex_MP4GetTrackAudioMpeg4Type = NIL; MP4GETTRACKAUDIOCHANNELS ex_MP4GetTrackAudioChannels = NIL; MP4GETTRACKESCONFIGURATION ex_MP4GetTrackESConfiguration = NIL; MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale = NIL; MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples = NIL; MP4GETSAMPLETIME ex_MP4GetSampleTime = NIL; MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime = NIL; MP4GETSAMPLESIZE ex_MP4GetSampleSize = NIL; MP4READSAMPLE ex_MP4ReadSample = NIL; MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning = NIL; MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree = NIL; DynamicLoader *fdkaacdll = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadFDKAACDLL() { fdkaacdll = BoCA::Utilities::LoadCodecDLL("fdk-aac"); if (fdkaacdll == NIL) return False; ex_aacDecoder_Open = (AACDECODER_OPEN) fdkaacdll->GetFunctionAddress("aacDecoder_Open"); ex_aacDecoder_ConfigRaw = (AACDECODER_CONFIGRAW) fdkaacdll->GetFunctionAddress("aacDecoder_ConfigRaw"); ex_aacDecoder_Fill = (AACDECODER_FILL) fdkaacdll->GetFunctionAddress("aacDecoder_Fill"); ex_aacDecoder_GetStreamInfo = (AACDECODER_GETSTREAMINFO) fdkaacdll->GetFunctionAddress("aacDecoder_GetStreamInfo"); ex_aacDecoder_DecodeFrame = (AACDECODER_DECODEFRAME) fdkaacdll->GetFunctionAddress("aacDecoder_DecodeFrame"); ex_aacDecoder_Close = (AACDECODER_CLOSE) fdkaacdll->GetFunctionAddress("aacDecoder_Close"); ex_aacDecoder_GetLibInfo = (AACDECODER_GETLIBINFO) fdkaacdll->GetFunctionAddress("aacDecoder_GetLibInfo"); if (ex_aacDecoder_Open == NIL || ex_aacDecoder_ConfigRaw == NIL || ex_aacDecoder_Fill == NIL || ex_aacDecoder_GetStreamInfo == NIL || ex_aacDecoder_DecodeFrame == NIL || ex_aacDecoder_Close == NIL || ex_aacDecoder_GetLibInfo == NIL) { FreeFDKAACDLL(); return False; } return True; } Void FreeFDKAACDLL() { BoCA::Utilities::FreeCodecDLL(fdkaacdll); fdkaacdll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Read = (MP4READ) mp4v2dll->GetFunctionAddress("MP4Read"); ex_MP4ReadCallbacks = (MP4READCALLBACKS) mp4v2dll->GetFunctionAddress("MP4ReadCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Free = (MP4FREE) mp4v2dll->GetFunctionAddress("MP4Free"); ex_MP4FindTrackId = (MP4FINDTRACKID) mp4v2dll->GetFunctionAddress("MP4FindTrackId"); ex_MP4GetTrackAudioMpeg4Type = (MP4GETTRACKAUDIOMPEG4TYPE) mp4v2dll->GetFunctionAddress("MP4GetTrackAudioMpeg4Type"); ex_MP4GetTrackAudioChannels = (MP4GETTRACKAUDIOCHANNELS) mp4v2dll->GetFunctionAddress("MP4GetTrackAudioChannels"); ex_MP4GetTrackESConfiguration = (MP4GETTRACKESCONFIGURATION) mp4v2dll->GetFunctionAddress("MP4GetTrackESConfiguration"); ex_MP4GetTrackTimeScale = (MP4GETTRACKTIMESCALE) mp4v2dll->GetFunctionAddress("MP4GetTrackTimeScale"); ex_MP4GetTrackNumberOfSamples = (MP4GETTRACKNUMBEROFSAMPLES) mp4v2dll->GetFunctionAddress("MP4GetTrackNumberOfSamples"); ex_MP4GetSampleTime = (MP4GETSAMPLETIME) mp4v2dll->GetFunctionAddress("MP4GetSampleTime"); ex_MP4GetSampleIdFromTime = (MP4GETSAMPLEIDFROMTIME) mp4v2dll->GetFunctionAddress("MP4GetSampleIdFromTime"); ex_MP4GetSampleSize = (MP4GETSAMPLESIZE) mp4v2dll->GetFunctionAddress("MP4GetSampleSize"); ex_MP4ReadSample = (MP4READSAMPLE) mp4v2dll->GetFunctionAddress("MP4ReadSample"); ex_MP4ItmfGetItemsByMeaning = (MP4ITMFGETITEMSBYMEANING) mp4v2dll->GetFunctionAddress("MP4ItmfGetItemsByMeaning"); ex_MP4ItmfItemListFree = (MP4ITMFITEMLISTFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemListFree"); if (ex_MP4Read == NIL || ex_MP4ReadCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Free == NIL || ex_MP4FindTrackId == NIL || ex_MP4GetTrackAudioMpeg4Type == NIL || ex_MP4GetTrackAudioChannels == NIL || ex_MP4GetTrackESConfiguration == NIL || ex_MP4GetTrackTimeScale == NIL || ex_MP4GetTrackNumberOfSamples == NIL || ex_MP4GetSampleTime == NIL || ex_MP4GetSampleIdFromTime == NIL || ex_MP4GetSampleSize == NIL || ex_MP4ReadSample == NIL || ex_MP4ItmfGetItemsByMeaning == NIL || ex_MP4ItmfItemListFree == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/dllinterface.h000066400000000000000000000077561516712004000260130ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *fdkaacdll; extern DynamicLoader *mp4v2dll; Bool LoadFDKAACDLL(); Void FreeFDKAACDLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef HANDLE_AACDECODER (LINKSPEC_H *AACDECODER_OPEN) (TRANSPORT_TYPE, UINT); typedef AAC_DECODER_ERROR (LINKSPEC_H *AACDECODER_CONFIGRAW) (HANDLE_AACDECODER, UCHAR *[], const UINT []); typedef AAC_DECODER_ERROR (LINKSPEC_H *AACDECODER_FILL) (HANDLE_AACDECODER, UCHAR *[], const UINT [], UINT *); typedef CStreamInfo * (LINKSPEC_H *AACDECODER_GETSTREAMINFO) (HANDLE_AACDECODER); typedef AAC_DECODER_ERROR (LINKSPEC_H *AACDECODER_DECODEFRAME) (HANDLE_AACDECODER, INT_PCM *, const INT, const UINT); typedef void (LINKSPEC_H *AACDECODER_CLOSE) (HANDLE_AACDECODER); typedef INT (LINKSPEC_H *AACDECODER_GETLIBINFO) (LIB_INFO *); extern AACDECODER_OPEN ex_aacDecoder_Open; extern AACDECODER_CONFIGRAW ex_aacDecoder_ConfigRaw; extern AACDECODER_FILL ex_aacDecoder_Fill; extern AACDECODER_GETSTREAMINFO ex_aacDecoder_GetStreamInfo; extern AACDECODER_DECODEFRAME ex_aacDecoder_DecodeFrame; extern AACDECODER_CLOSE ex_aacDecoder_Close; extern AACDECODER_GETLIBINFO ex_aacDecoder_GetLibInfo; typedef MP4FileHandle (*MP4READ) (const char *); typedef MP4FileHandle (*MP4READCALLBACKS) (const MP4IOCallbacks *, void *); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef void (*MP4FREE) (void *); typedef MP4TrackId (*MP4FINDTRACKID) (MP4FileHandle, uint16_t, const char *, uint8_t); typedef uint8_t (*MP4GETTRACKAUDIOMPEG4TYPE) (MP4FileHandle, MP4TrackId); typedef int (*MP4GETTRACKAUDIOCHANNELS) (MP4FileHandle, MP4TrackId); typedef bool (*MP4GETTRACKESCONFIGURATION) (MP4FileHandle, MP4TrackId, uint8_t **, uint32_t *); typedef uint32_t (*MP4GETTRACKTIMESCALE) (MP4FileHandle, MP4TrackId); typedef MP4SampleId (*MP4GETTRACKNUMBEROFSAMPLES) (MP4FileHandle, MP4TrackId); typedef MP4Timestamp (*MP4GETSAMPLETIME) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef MP4SampleId (*MP4GETSAMPLEIDFROMTIME) (MP4FileHandle, MP4TrackId, MP4Timestamp, bool); typedef uint32_t (*MP4GETSAMPLESIZE) (MP4FileHandle, MP4TrackId, MP4SampleId); typedef bool (*MP4READSAMPLE) (MP4FileHandle, MP4TrackId, MP4SampleId, uint8_t **, uint32_t *, MP4Timestamp *, MP4Duration *, MP4Duration *, bool *); typedef MP4ItmfItemList * (*MP4ITMFGETITEMSBYMEANING) (MP4FileHandle, const char *, const char *); typedef void (*MP4ITMFITEMLISTFREE) (MP4ItmfItemList *); extern MP4READ ex_MP4Read; extern MP4READCALLBACKS ex_MP4ReadCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4FREE ex_MP4Free; extern MP4FINDTRACKID ex_MP4FindTrackId; extern MP4GETTRACKAUDIOMPEG4TYPE ex_MP4GetTrackAudioMpeg4Type; extern MP4GETTRACKAUDIOCHANNELS ex_MP4GetTrackAudioChannels; extern MP4GETTRACKESCONFIGURATION ex_MP4GetTrackESConfiguration; extern MP4GETTRACKTIMESCALE ex_MP4GetTrackTimeScale; extern MP4GETTRACKNUMBEROFSAMPLES ex_MP4GetTrackNumberOfSamples; extern MP4GETSAMPLETIME ex_MP4GetSampleTime; extern MP4GETSAMPLEIDFROMTIME ex_MP4GetSampleIdFromTime; extern MP4GETSAMPLESIZE ex_MP4GetSampleSize; extern MP4READSAMPLE ex_MP4ReadSample; extern MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning; extern MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/fdkaac.cpp000066400000000000000000000524141516712004000251120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "fdkaac.h" #ifndef CAPF_AAC_USAC # define CAPF_AAC_USAC 0x00200000 #endif using namespace smooth::IO; const String &BoCA::DecoderFDKAAC::GetComponentSpecs() { static String componentSpecs; if (fdkaacdll != NIL) { componentSpecs = " \ \ \ \ FDK-AAC Decoder %VERSION% \ 1.0 \ fdkaac-dec \ decoder \ faad2-dec \ \ "; if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ 3gp \ 3gpp \ MP4 Metadata \ \ \ "); } componentSpecs.Append(" \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ \ "); UnsignedInt32 version = GetDecoderVersion(); componentSpecs.Replace("%VERSION%", String("v").Append(String::FromInt((version >> 24) & 0xff)).Append(".") .Append(String::FromInt((version >> 16) & 0xff)).Append(".") .Append(String::FromInt((version >> 8) & 0xff))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFDKAACDLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeFDKAACDLL(); FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_read(void *, void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, MP4IO_read, NIL, NIL }; }; Bool BoCA::DecoderFDKAAC::CanOpenStream(const String &streamURI) { Bool isValidFile = False; InStream in(STREAM_FILE, streamURI, IS_READ); if (mp4v2dll != NIL && (in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) { LIB_INFO info[FDK_MODULE_LAST]; FDKinitLibInfo(info); ex_aacDecoder_GetLibInfo(info); UINT aacFlags = FDKlibInfo_getCapabilities(info, FDK_AACDEC); UINT sbrFlags = FDKlibInfo_getCapabilities(info, FDK_SBRDEC); Int type = ex_MP4GetTrackAudioMpeg4Type(mp4File, mp4Track); if ((type == AOT_AAC_LC && aacFlags & CAPF_AAC_LC ) || (type == AOT_SBR && sbrFlags ) || (type == AOT_PS && sbrFlags & CAPF_SBR_PS_MPEG) || (type == AOT_USAC && aacFlags & CAPF_AAC_USAC ) || (type == AOT_ER_AAC_LC && aacFlags & CAPF_ER_AAC_LC ) || (type == AOT_ER_AAC_LD && aacFlags & CAPF_ER_AAC_LD ) || (type == AOT_ER_AAC_ELD && aacFlags & CAPF_ER_AAC_ELD ) || (type == AOT_ER_AAC_SCAL && aacFlags & CAPF_ER_AAC_SCAL) || (type == AOT_ER_BSAC && aacFlags & CAPF_ER_AAC_BSAC)) isValidFile = True; } ex_MP4Close(mp4File, 0); } else { Track track; if (GetStreamInfo(streamURI, track) == Success()) isValidFile = True; } return isValidFile; } Error BoCA::DecoderFDKAAC::GetStreamInfo(const String &streamURI, Track &track) { Format format = track.GetFormat(); InStream in(STREAM_FILE, streamURI, IS_READ); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { track.fileSize = File(streamURI).GetFileSize(); track.length = -1; MP4FileHandle mp4File = ex_MP4Read(streamURI.ConvertTo("UTF-8")); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track != MP4_INVALID_TRACK_ID && ex_MP4GetSampleSize(mp4File, mp4Track, 1) > 0) { HANDLE_AACDECODER handle = ex_aacDecoder_Open(TT_MP4_RAW, 1); /* Get codec configuration. */ unsigned char *escBuffer = NIL; unsigned int escBufferSize = 0; ex_MP4GetTrackESConfiguration(mp4File, mp4Track, (uint8_t **) &escBuffer, (uint32_t *) &escBufferSize); /* The FDK bitstream reader reads up to 4 bytes behind the buffer, * so allocate a larger buffer to prevent access violations. */ unsigned char *escBuffer2 = new unsigned char [escBufferSize + 4]; memcpy(escBuffer2, escBuffer, escBufferSize); ex_aacDecoder_ConfigRaw(handle, &escBuffer2, &escBufferSize); delete [] escBuffer2; ex_MP4Free(escBuffer); /* Decode one frame to initialize decoder. */ unsigned int bufferSize = ex_MP4GetSampleSize(mp4File, mp4Track, 1); unsigned char *buffer = new unsigned char [bufferSize + 4]; ex_MP4ReadSample(mp4File, mp4Track, 1, (uint8_t **) &buffer, (uint32_t *) &bufferSize, NIL, NIL, NIL, NIL); unsigned int bytesValid = bufferSize; ex_aacDecoder_Fill(handle, &buffer, &bufferSize, &bytesValid); short *outputBuffer = new short [16384]; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, 16384, 0) != AAC_DEC_OK) { errorState = True; errorString = "Unsupported audio format"; } delete [] outputBuffer; delete [] buffer; /* Get sample rate and number of channels. */ if (!errorState) { CStreamInfo *streamInfo = ex_aacDecoder_GetStreamInfo(handle); frameSize = streamInfo->frameSize; sbrRatio = streamInfo->frameSize / streamInfo->aacSamplesPerFrame; format.rate = streamInfo->sampleRate; format.channels = streamInfo->numChannels; if (format.channels == 2 && ex_MP4GetTrackAudioChannels(mp4File, mp4Track) == 1) format.channels = 1; track.length = Int64(ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track)) * streamInfo->frameSize; track.length -= streamInfo->frameSize; // To account for encoder delay. format.bits = 16; } ex_aacDecoder_Close(handle); track.SetFormat(format); /* Read gapless information. */ Int delay = 0, padding = 0; Int64 length = 0; if (ReadGaplessInfo(mp4File, delay, padding, length) && (delay + padding + length) * sbrRatio == Int64(ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track)) * frameSize) { track.length = length * sbrRatio; } } ex_MP4Close(mp4File, 0); /* Read MP4 metadata. */ if (!errorState) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } else { in.Seek(0); format.bits = 16; track.fileSize = in.Size(); track.length = -1; SkipID3v2Tag(in); if (!SyncOnAACHeader(in)) { errorState = True; errorString = "Invalid file format"; return Error(); } HANDLE_AACDECODER handle = ex_aacDecoder_Open( adifFound ? TT_MP4_ADIF : (adtsFound ? TT_MP4_ADTS : TT_MP4_LOAS), 1); /* Decode one frame to initialize decoder. */ unsigned int size = Math::Min((Int64) 32768, track.fileSize - in.GetPos()); unsigned char *data = new unsigned char [size]; in.InputData((void *) data, size); unsigned int bytesValid = size; ex_aacDecoder_Fill(handle, &data, &size, &bytesValid); short *outputBuffer = new short [16384]; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, 16384, 0) == AAC_DEC_OK) { /* Get sample rate and number of channels. */ CStreamInfo *streamInfo = ex_aacDecoder_GetStreamInfo(handle); format.rate = streamInfo->sampleRate; format.channels = streamInfo->numChannels; /* Compute approximate length of stream. */ Int samplesRead = streamInfo->frameSize; while (True) { if (bytesValid > 0) { unsigned char *inputBuffer = data + size - bytesValid; unsigned int inputBufferSize = bytesValid; ex_aacDecoder_Fill(handle, &inputBuffer, &inputBufferSize, &bytesValid); } if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, 16384, 0) != AAC_DEC_OK) break; samplesRead += streamInfo->frameSize; } if (samplesRead > 0) track.approxLength = samplesRead * (track.fileSize / size); } else { errorState = True; errorString = "Unsupported audio format"; } /* Close handles. */ delete [] outputBuffer; delete [] data; ex_aacDecoder_Close(handle); /* Read ID3v2 tag if any. */ if (!errorState) { Bool foundTag = False; AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); if (tagger->ParseStreamInfo(streamURI, track) == Success()) foundTag = True; boca.DeleteComponent(tagger); } if (!foundTag) { tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } } track.SetFormat(format); if (!errorState) return Success(); else return Error(); } BoCA::DecoderFDKAAC::DecoderFDKAAC() { mp4File = NIL; handle = NIL; mp4Track = MP4_INVALID_TRACK_ID; sampleId = 1; finished = False; adifFound = False; adtsFound = False; loasFound = False; frameSize = 0; sbrRatio = 1; delaySamples = 0; delaySamplesLeft = 0; } BoCA::DecoderFDKAAC::~DecoderFDKAAC() { } UnsignedInt32 BoCA::DecoderFDKAAC::GetDecoderVersion() { LIB_INFO info[FDK_MODULE_LAST]; FDKinitLibInfo(info); ex_aacDecoder_GetLibInfo(info); for (Int i = 0; i < FDK_MODULE_LAST; i++) { if (info[i].module_id != FDK_AACDEC) continue; return info[i].version; } return 0; } Bool BoCA::DecoderFDKAAC::Activate() { InStream in(STREAM_DRIVER, driver); if ((in.InputNumberRaw(8) & 0xFFFFFFFF) == 'ftyp') { mp4File = ex_MP4ReadCallbacks(&mp4Callbacks, driver); mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); if (mp4Track == MP4_INVALID_TRACK_ID) { ex_MP4Close(mp4File, 0); return False; } handle = ex_aacDecoder_Open(TT_MP4_RAW, 1); /* Get codec configuration. */ unsigned char *escBuffer = NIL; unsigned int escBufferSize = 0; ex_MP4GetTrackESConfiguration(mp4File, mp4Track, (uint8_t **) &escBuffer, (uint32_t *) &escBufferSize); /* The FDK bitstream reader reads up to 4 bytes behind the buffer, * so allocate a larger buffer to prevent access violations. */ unsigned char *escBuffer2 = new unsigned char [escBufferSize + 4]; memcpy(escBuffer2, escBuffer, escBufferSize); ex_aacDecoder_ConfigRaw(handle, &escBuffer2, &escBufferSize); delete [] escBuffer2; ex_MP4Free(escBuffer); } else { in.Seek(0); SkipID3v2Tag(in); SyncOnAACHeader(in); driver->Seek(in.GetPos()); handle = ex_aacDecoder_Open( adifFound ? TT_MP4_ADIF : (adtsFound ? TT_MP4_ADTS : TT_MP4_LOAS), 1); } return True; } Bool BoCA::DecoderFDKAAC::Deactivate() { /* Close decoder. */ ex_aacDecoder_Close(handle); if (mp4File == NIL) return True; /* Close MP4 file. */ ex_MP4Close(mp4File, 0); return True; } Bool BoCA::DecoderFDKAAC::Seek(Int64 samplePosition) { if (mp4File == NIL) return False; MP4Timestamp time = Math::Round(Float(samplePosition) / track.GetFormat().rate * ex_MP4GetTrackTimeScale(mp4File, mp4Track)); sampleId = ex_MP4GetSampleIdFromTime(mp4File, mp4Track, time, true); delaySamplesLeft = delaySamples + time - ex_MP4GetSampleTime(mp4File, mp4Track, sampleId); return True; } Int BoCA::DecoderFDKAAC::ReadData(Buffer &data) { static Int maxFrameSize = 2048; if (finished) return -1; const Format &format = track.GetFormat(); Int samplesRead = 0; samplesBuffer.Resize(0); if (mp4File != NIL) { MP4SampleId numberOfSamples = ex_MP4GetTrackNumberOfSamples(mp4File, mp4Track); if (sampleId <= numberOfSamples) { unsigned int bufferSize = ex_MP4GetSampleSize(mp4File, mp4Track, sampleId); dataBuffer.Resize(bufferSize + 4); // + 4 to account for FDK bitstream implementation overreading. unsigned char *buffer = dataBuffer; if (!ex_MP4ReadSample(mp4File, mp4Track, sampleId++, (uint8_t **) &buffer, (uint32_t *) &bufferSize, NIL, NIL, NIL, NIL)) return -1; unsigned int bytesValid = bufferSize; if (bytesValid > 0) { unsigned char *inputBuffer = buffer + bufferSize - bytesValid; unsigned int inputBufferSize = bytesValid; ex_aacDecoder_Fill(handle, &inputBuffer, &inputBufferSize, &bytesValid); } Int bufferChannels = Math::Max(2, format.channels); if (frameSize == 0) samplesBuffer.Resize(samplesRead * format.channels + maxFrameSize * bufferChannels); else samplesBuffer.Resize(samplesRead * format.channels + frameSize * bufferChannels); short *outputBuffer = samplesBuffer + samplesRead * format.channels; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, samplesBuffer.Size() - samplesRead * format.channels, 0) == AAC_DEC_OK) { CStreamInfo *streamInfo = ex_aacDecoder_GetStreamInfo(handle); if (frameSize == 0) { frameSize = streamInfo->frameSize; sbrRatio = streamInfo->frameSize / streamInfo->aacSamplesPerFrame; /* Get delay from gapless information. */ Int delay = 0, padding = 0; Int64 length = 0; if (ReadGaplessInfo(mp4File, delay, padding, length) && (delay + padding + length) * sbrRatio == Int64(numberOfSamples) * frameSize) { delaySamples = delay * sbrRatio; delaySamplesLeft = delaySamples; } /* Set delay samples to minimum encoder delay. */ if (delaySamples == 0) { delaySamples = frameSize; delaySamplesLeft = delaySamples; } /* Add FDK decoder delay. */ delaySamplesLeft += streamInfo->outputDelay; } if (format.channels == 1 && streamInfo->numChannels == 2) { for (Int i = 0; i < frameSize; i++) samplesBuffer[samplesRead + i] = samplesBuffer[samplesRead + i * 2]; } samplesBuffer.Resize((samplesRead + frameSize) * format.channels); samplesRead += frameSize; } } else { /* Flush the decoder reading up to two more frames (some decoders * keep returning AAC_DEC_OK even after the end is reached, so we * have to limit the number of read attempts). */ for (Int i = 0; i < 2; i++) { Int bufferChannels = Math::Max(2, format.channels); samplesBuffer.Resize(samplesRead * format.channels + frameSize * bufferChannels); short *outputBuffer = samplesBuffer + samplesRead * format.channels; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, samplesBuffer.Size() - samplesRead * format.channels, AACDEC_FLUSH) != AAC_DEC_OK) break; CStreamInfo *streamInfo = ex_aacDecoder_GetStreamInfo(handle); if (format.channels == 1 && streamInfo->numChannels == 2) { for (Int i = 0; i < frameSize; i++) samplesBuffer[samplesRead + i] = samplesBuffer[samplesRead + i * 2]; } samplesBuffer.Resize((samplesRead + frameSize) * format.channels); samplesRead += frameSize; } finished = True; } } else { dataBuffer.Resize(data.Size() + 4); // + 4 to account for FDK bitstream implementation overreading. Int size = driver->ReadData(dataBuffer, data.Size()); if (size <= 0) return -1; inBytes += size; UnsignedInt bytesValid = size; while (bytesValid || driver->GetPos() == driver->GetSize()) { if (bytesValid > 0) { unsigned char *inputBuffer = dataBuffer + size - bytesValid; unsigned int inputBufferSize = bytesValid; ex_aacDecoder_Fill(handle, &inputBuffer, &inputBufferSize, &bytesValid); } if (frameSize == 0) samplesBuffer.Resize((samplesRead + maxFrameSize) * format.channels); else samplesBuffer.Resize((samplesRead + frameSize) * format.channels); short *outputBuffer = samplesBuffer + samplesRead * format.channels; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, samplesBuffer.Size() - samplesRead * format.channels, 0) != AAC_DEC_OK) break; if (frameSize == 0) { CStreamInfo *streamInfo = ex_aacDecoder_GetStreamInfo(handle); frameSize = streamInfo->frameSize; /* Set delay samples to minimum encoder delay. */ delaySamples = frameSize; delaySamplesLeft = delaySamples; /* Add FDK decoder delay. */ delaySamplesLeft += streamInfo->outputDelay; samplesBuffer.Resize((samplesRead + frameSize) * format.channels); } samplesRead += frameSize; } if (driver->GetPos() == driver->GetSize()) { /* Flush the decoder reading up to two more frames (some decoders * keep returning AAC_DEC_OK even after the end is reached, so we * have to limit the number of read attempts). */ for (Int i = 0; i < 2; i++) { samplesBuffer.Resize((samplesRead + frameSize) * format.channels); short *outputBuffer = samplesBuffer + samplesRead * format.channels; if (ex_aacDecoder_DecodeFrame(handle, outputBuffer, samplesBuffer.Size() - samplesRead * format.channels, AACDEC_FLUSH) != AAC_DEC_OK) break; samplesRead += frameSize; } finished = True; } } data.Resize(0); if (samplesRead > delaySamplesLeft) { data.Resize((samplesRead - delaySamplesLeft) * format.channels * (format.bits / 8)); memcpy(data, samplesBuffer + delaySamplesLeft * format.channels, data.Size()); } delaySamplesLeft = Math::Max(0, delaySamplesLeft - samplesRead); return data.Size(); } Bool BoCA::DecoderFDKAAC::ReadGaplessInfo(MP4FileHandle mp4File, Int &delay, Int &padding, Int64 &length) const { Bool result = False; /* Look for iTunes metadata with gapless information. */ MP4ItmfItemList *items = ex_MP4ItmfGetItemsByMeaning(mp4File, "com.apple.iTunes", "iTunSMPB"); if (items != NIL) { if (items->size == 1) { /* Read value as string. */ Buffer value(items->elements[0].dataList.elements[0].valueSize + 1); memset(value, 0, items->elements[0].dataList.elements[0].valueSize + 1); memcpy(value, items->elements[0].dataList.elements[0].value, items->elements[0].dataList.elements[0].valueSize); /* Parse value string. */ const Array &values = String(value).Trim().Explode(" "); delay = (Int64) Number::FromHexString(values.GetNth(1)); padding = (Int64) Number::FromHexString(values.GetNth(2)); length = (Int64) Number::FromHexString(values.GetNth(3)); result = True; } ex_MP4ItmfItemListFree(items); } return result; } Bool BoCA::DecoderFDKAAC::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning * of the file and skip it if it exists. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } Bool BoCA::DecoderFDKAAC::SyncOnAACHeader(InStream &in) { const Int startPos = in.GetPos(); const Int maxFrameSize = 8192; /* Try to sync on ADIF header. */ for (Int n = 0; n < maxFrameSize; n++) { if (in.InputNumber(1) != 'A') continue; if (in.InputNumber(1) != 'D') continue; if (in.InputNumber(1) != 'I') continue; if (in.InputNumber(1) != 'F') continue; /* ADIF magic word found. */ in.RelSeek(-4); inBytes += n; adifFound = True; return True; } in.Seek(startPos); /* Try to sync on ADTS header. */ for (Int n = 0; n < maxFrameSize; n++) { if ( in.InputNumber(1) != 0xFF) continue; if ( (in.InputNumber(1) & 0xF6) != 0xF0) continue; if (((in.InputNumber(1) & 0x3C) >> 2) >= 12) continue; /* ADTS sync found. */ in.RelSeek(-3); inBytes += n; adtsFound = True; return True; } in.Seek(startPos); /* Try to sync on LOAS/LATM header. */ for (Int n = 0; n < maxFrameSize; n++) { if ( in.InputNumber(1) != 0x56) continue; if ( (in.InputNumber(1) & 0xE0) != 0xE0) continue; /* LOAS sync. */ in.RelSeek(-2); inBytes += n; loasFound = True; return True; } /* No sync. Probably not an AAC file. */ return False; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_read(void *handle, void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->ReadData((UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/fdkaac/fdkaac.h000066400000000000000000000033311516712004000245510ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderFDKAAC) namespace BoCA { class DecoderFDKAAC : public CS::DecoderComponent { private: MP4FileHandle mp4File; HANDLE_AACDECODER handle; MP4TrackId mp4Track; MP4SampleId sampleId; Bool finished; Bool adifFound; Bool adtsFound; Bool loasFound; Int frameSize; Int sbrRatio; Int delaySamples; Int delaySamplesLeft; Buffer dataBuffer; Buffer samplesBuffer; Bool ReadGaplessInfo(MP4FileHandle, Int &, Int &, Int64 &) const; Bool SkipID3v2Tag(IO::InStream &); Bool SyncOnAACHeader(IO::InStream &); static UnsignedInt32 GetDecoderVersion(); public: static const String &GetComponentSpecs(); DecoderFDKAAC(); ~DecoderFDKAAC(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderFDKAAC) BoCA_END_COMPONENT(DecoderFDKAAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/000077500000000000000000000000001516712004000226635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/Makefile000077500000000000000000000012121516712004000243220ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = flac TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o flac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/dllinterface.cpp000077500000000000000000000155641516712004000260410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETOUT ex_ogg_stream_packetout = NIL; OGGSTREAMPAGEIN ex_ogg_stream_pagein = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGPAGESERIALNO ex_ogg_page_serialno = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OGGSYNCINIT ex_ogg_sync_init = NIL; OGGSYNCBUFFER ex_ogg_sync_buffer = NIL; OGGSYNCWROTE ex_ogg_sync_wrote = NIL; OGGSYNCPAGEOUT ex_ogg_sync_pageout = NIL; OGGSYNCCLEAR ex_ogg_sync_clear = NIL; FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC = NIL; FLAC__STREAM_DECODER_NEW ex_FLAC__stream_decoder_new = NIL; FLAC__STREAM_DECODER_DELETE ex_FLAC__stream_decoder_delete = NIL; FLAC__STREAM_DECODER_SET_METADATA_RESPOND ex_FLAC__stream_decoder_set_metadata_respond = NIL; FLAC__STREAM_DECODER_INIT_STREAM ex_FLAC__stream_decoder_init_stream = NIL; FLAC__STREAM_DECODER_INIT_OGG_STREAM ex_FLAC__stream_decoder_init_ogg_stream = NIL; FLAC__STREAM_DECODER_FINISH ex_FLAC__stream_decoder_finish = NIL; FLAC__STREAM_DECODER_GET_CHANNELS ex_FLAC__stream_decoder_get_channels = NIL; FLAC__STREAM_DECODER_GET_BITS_PER_SAMPLE ex_FLAC__stream_decoder_get_bits_per_sample = NIL; FLAC__STREAM_DECODER_GET_SAMPLE_RATE ex_FLAC__stream_decoder_get_sample_rate = NIL; FLAC__STREAM_DECODER_SEEK_ABSOLUTE ex_FLAC__stream_decoder_seek_absolute = NIL; FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_METADATA ex_FLAC__stream_decoder_process_until_end_of_metadata = NIL; FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_STREAM ex_FLAC__stream_decoder_process_until_end_of_stream = NIL; FLAC__VERSION_STRING_TYPE ex_FLAC__VERSION_STRING = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *flacdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetout = (OGGSTREAMPACKETOUT) oggdll->GetFunctionAddress("ogg_stream_packetout"); ex_ogg_stream_pagein = (OGGSTREAMPAGEIN) oggdll->GetFunctionAddress("ogg_stream_pagein"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_page_serialno = (OGGPAGESERIALNO) oggdll->GetFunctionAddress("ogg_page_serialno"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); ex_ogg_sync_init = (OGGSYNCINIT) oggdll->GetFunctionAddress("ogg_sync_init"); ex_ogg_sync_buffer = (OGGSYNCBUFFER) oggdll->GetFunctionAddress("ogg_sync_buffer"); ex_ogg_sync_wrote = (OGGSYNCWROTE) oggdll->GetFunctionAddress("ogg_sync_wrote"); ex_ogg_sync_pageout = (OGGSYNCPAGEOUT) oggdll->GetFunctionAddress("ogg_sync_pageout"); ex_ogg_sync_clear = (OGGSYNCCLEAR) oggdll->GetFunctionAddress("ogg_sync_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetout == NIL || ex_ogg_stream_pagein == NIL || ex_ogg_page_eos == NIL || ex_ogg_page_serialno == NIL || ex_ogg_stream_clear == NIL || ex_ogg_sync_init == NIL || ex_ogg_sync_buffer == NIL || ex_ogg_sync_wrote == NIL || ex_ogg_sync_pageout == NIL || ex_ogg_sync_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadFLACDLL() { flacdll = BoCA::Utilities::LoadCodecDLL("FLAC"); if (flacdll == NIL) return False; ex_FLAC_API_SUPPORTS_OGG_FLAC = (FLAC_API_SUPPORTS_OGG_FLAC_TYPE) flacdll->GetFunctionAddress("FLAC_API_SUPPORTS_OGG_FLAC"); ex_FLAC__stream_decoder_new = (FLAC__STREAM_DECODER_NEW) flacdll->GetFunctionAddress("FLAC__stream_decoder_new"); ex_FLAC__stream_decoder_delete = (FLAC__STREAM_DECODER_DELETE) flacdll->GetFunctionAddress("FLAC__stream_decoder_delete"); ex_FLAC__stream_decoder_set_metadata_respond = (FLAC__STREAM_DECODER_SET_METADATA_RESPOND) flacdll->GetFunctionAddress("FLAC__stream_decoder_set_metadata_respond"); ex_FLAC__stream_decoder_init_stream = (FLAC__STREAM_DECODER_INIT_STREAM) flacdll->GetFunctionAddress("FLAC__stream_decoder_init_stream"); ex_FLAC__stream_decoder_init_ogg_stream = (FLAC__STREAM_DECODER_INIT_OGG_STREAM) flacdll->GetFunctionAddress("FLAC__stream_decoder_init_ogg_stream"); ex_FLAC__stream_decoder_finish = (FLAC__STREAM_DECODER_FINISH) flacdll->GetFunctionAddress("FLAC__stream_decoder_finish"); ex_FLAC__stream_decoder_get_channels = (FLAC__STREAM_DECODER_GET_CHANNELS) flacdll->GetFunctionAddress("FLAC__stream_decoder_get_channels"); ex_FLAC__stream_decoder_get_bits_per_sample = (FLAC__STREAM_DECODER_GET_BITS_PER_SAMPLE) flacdll->GetFunctionAddress("FLAC__stream_decoder_get_bits_per_sample"); ex_FLAC__stream_decoder_get_sample_rate = (FLAC__STREAM_DECODER_GET_SAMPLE_RATE) flacdll->GetFunctionAddress("FLAC__stream_decoder_get_sample_rate"); ex_FLAC__stream_decoder_seek_absolute = (FLAC__STREAM_DECODER_SEEK_ABSOLUTE) flacdll->GetFunctionAddress("FLAC__stream_decoder_seek_absolute"); ex_FLAC__stream_decoder_process_until_end_of_metadata = (FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_METADATA) flacdll->GetFunctionAddress("FLAC__stream_decoder_process_until_end_of_metadata"); ex_FLAC__stream_decoder_process_until_end_of_stream = (FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_STREAM) flacdll->GetFunctionAddress("FLAC__stream_decoder_process_until_end_of_stream"); ex_FLAC__VERSION_STRING = (FLAC__VERSION_STRING_TYPE) flacdll->GetFunctionAddress("FLAC__VERSION_STRING"); if (ex_FLAC_API_SUPPORTS_OGG_FLAC == NIL || ex_FLAC__stream_decoder_new == NIL || ex_FLAC__stream_decoder_delete == NIL || ex_FLAC__stream_decoder_set_metadata_respond == NIL || ex_FLAC__stream_decoder_init_stream == NIL || ex_FLAC__stream_decoder_init_ogg_stream == NIL || ex_FLAC__stream_decoder_finish == NIL || ex_FLAC__stream_decoder_get_channels == NIL || ex_FLAC__stream_decoder_get_bits_per_sample == NIL || ex_FLAC__stream_decoder_get_sample_rate == NIL || ex_FLAC__stream_decoder_seek_absolute == NIL || ex_FLAC__stream_decoder_process_until_end_of_metadata == NIL || ex_FLAC__stream_decoder_process_until_end_of_stream == NIL || ex_FLAC__VERSION_STRING == NIL) { FreeFLACDLL(); return False; } return True; } Void FreeFLACDLL() { BoCA::Utilities::FreeCodecDLL(flacdll); flacdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/dllinterface.h000077500000000000000000000115301516712004000254730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #undef callbacks #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *flacdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadFLACDLL(); Void FreeFLACDLL(); typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETOUT) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMPAGEIN) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGPAGESERIALNO) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); typedef int (*OGGSYNCINIT) (ogg_sync_state *); typedef char * (*OGGSYNCBUFFER) (ogg_sync_state *, int); typedef int (*OGGSYNCWROTE) (ogg_sync_state *, int); typedef int (*OGGSYNCPAGEOUT) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCCLEAR) (ogg_sync_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETOUT ex_ogg_stream_packetout; extern OGGSTREAMPAGEIN ex_ogg_stream_pagein; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGPAGESERIALNO ex_ogg_page_serialno; extern OGGSTREAMCLEAR ex_ogg_stream_clear; extern OGGSYNCINIT ex_ogg_sync_init; extern OGGSYNCBUFFER ex_ogg_sync_buffer; extern OGGSYNCWROTE ex_ogg_sync_wrote; extern OGGSYNCPAGEOUT ex_ogg_sync_pageout; extern OGGSYNCCLEAR ex_ogg_sync_clear; typedef int *FLAC_API_SUPPORTS_OGG_FLAC_TYPE; typedef FLAC__StreamDecoder * (*FLAC__STREAM_DECODER_NEW) (); typedef void (*FLAC__STREAM_DECODER_DELETE) (FLAC__StreamDecoder *); typedef FLAC__bool (*FLAC__STREAM_DECODER_SET_METADATA_RESPOND) (FLAC__StreamDecoder *, FLAC__MetadataType); typedef FLAC__StreamDecoderInitStatus (*FLAC__STREAM_DECODER_INIT_STREAM) (FLAC__StreamDecoder *, FLAC__StreamDecoderReadCallback, FLAC__StreamDecoderSeekCallback, FLAC__StreamDecoderTellCallback, FLAC__StreamDecoderLengthCallback, FLAC__StreamDecoderEofCallback, FLAC__StreamDecoderWriteCallback, FLAC__StreamDecoderMetadataCallback, FLAC__StreamDecoderErrorCallback, void *); typedef FLAC__StreamDecoderInitStatus (*FLAC__STREAM_DECODER_INIT_OGG_STREAM) (FLAC__StreamDecoder *, FLAC__StreamDecoderReadCallback, FLAC__StreamDecoderSeekCallback, FLAC__StreamDecoderTellCallback, FLAC__StreamDecoderLengthCallback, FLAC__StreamDecoderEofCallback, FLAC__StreamDecoderWriteCallback, FLAC__StreamDecoderMetadataCallback, FLAC__StreamDecoderErrorCallback, void *); typedef FLAC__bool (*FLAC__STREAM_DECODER_FINISH) (FLAC__StreamDecoder *); typedef uint32_t (*FLAC__STREAM_DECODER_GET_CHANNELS) (const FLAC__StreamDecoder *); typedef uint32_t (*FLAC__STREAM_DECODER_GET_BITS_PER_SAMPLE) (const FLAC__StreamDecoder *); typedef uint32_t (*FLAC__STREAM_DECODER_GET_SAMPLE_RATE) (const FLAC__StreamDecoder *); typedef FLAC__bool (*FLAC__STREAM_DECODER_SEEK_ABSOLUTE) (FLAC__StreamDecoder *, FLAC__uint64); typedef FLAC__bool (*FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_METADATA) (FLAC__StreamDecoder *); typedef FLAC__bool (*FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_STREAM) (FLAC__StreamDecoder *); typedef char * *FLAC__VERSION_STRING_TYPE; extern FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC; extern FLAC__STREAM_DECODER_NEW ex_FLAC__stream_decoder_new; extern FLAC__STREAM_DECODER_DELETE ex_FLAC__stream_decoder_delete; extern FLAC__STREAM_DECODER_SET_METADATA_RESPOND ex_FLAC__stream_decoder_set_metadata_respond; extern FLAC__STREAM_DECODER_INIT_STREAM ex_FLAC__stream_decoder_init_stream; extern FLAC__STREAM_DECODER_INIT_OGG_STREAM ex_FLAC__stream_decoder_init_ogg_stream; extern FLAC__STREAM_DECODER_FINISH ex_FLAC__stream_decoder_finish; extern FLAC__STREAM_DECODER_GET_CHANNELS ex_FLAC__stream_decoder_get_channels; extern FLAC__STREAM_DECODER_GET_BITS_PER_SAMPLE ex_FLAC__stream_decoder_get_bits_per_sample; extern FLAC__STREAM_DECODER_GET_SAMPLE_RATE ex_FLAC__stream_decoder_get_sample_rate; extern FLAC__STREAM_DECODER_SEEK_ABSOLUTE ex_FLAC__stream_decoder_seek_absolute; extern FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_METADATA ex_FLAC__stream_decoder_process_until_end_of_metadata; extern FLAC__STREAM_DECODER_PROCESS_UNTIL_END_OF_STREAM ex_FLAC__stream_decoder_process_until_end_of_stream; extern FLAC__VERSION_STRING_TYPE ex_FLAC__VERSION_STRING; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/flac.cpp000066400000000000000000000356611516712004000243070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "flac.h" using namespace smooth::IO; using namespace smooth::Threads; const String &BoCA::DecoderFLAC::GetComponentSpecs() { static String componentSpecs; if (flacdll != NIL) { componentSpecs = " \ \ \ \ FLAC Audio Decoder %VERSION% \ 1.0 \ flac-dec \ decoder \ \ FLAC Files \ true \ flac \ FLAC Metadata \ \ \ "; if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 1 && oggdll != NIL) { componentSpecs.Append(" \ \ \ Ogg FLAC Files \ true \ oga \ Vorbis Comment \ \ \ "); } componentSpecs.Append(" \ \ \ \ "); componentSpecs.Replace("%VERSION%", String("v").Append(*ex_FLAC__VERSION_STRING)); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadFLACDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeFLACDLL(); } namespace BoCA { FLAC__StreamDecoderReadStatus FLACStreamDecoderReadCallback(const FLAC__StreamDecoder *, FLAC__byte [], size_t *, void *); FLAC__StreamDecoderWriteStatus FLACStreamDecoderWriteCallback(const FLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *); FLAC__StreamDecoderSeekStatus FLACStreamDecoderSeekCallback(const FLAC__StreamDecoder *, FLAC__uint64, void *); FLAC__StreamDecoderTellStatus FLACStreamDecoderTellCallback(const FLAC__StreamDecoder *, FLAC__uint64 *, void *); FLAC__StreamDecoderLengthStatus FLACStreamDecoderLengthCallback(const FLAC__StreamDecoder *, FLAC__uint64 *, void *); FLAC__bool FLACStreamDecoderEofCallback(const FLAC__StreamDecoder *, void *); void FLACStreamDecoderMetadataCallback(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *); void FLACStreamDecoderErrorCallback(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *); /* Use 512kB IO buffer for reading FLAC files. */ static const Int flacStreamDecoderBufferSize = 512 * 1024; }; Bool BoCA::DecoderFLAC::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); SkipID3v2Tag(in); /* Check file signature. */ String fileType = in.InputString(4); if (fileType == "fLaC") return True; else if (fileType != "OggS") return False; if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 0 || oggdll == NIL) return False; in.RelSeek(-4); /* Check if Ogg FLAC. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); Bool result = False; Bool initialized = False; do { Int size = Math::Min((Int64) 4096, in.Size() - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); if (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; ex_ogg_stream_pagein(&os, &og); if (ex_ogg_stream_packetout(&os, &op) == 1) { if (op.packet[0] == 0x7F && op.packet[1] == 'F' && op.packet[2] == 'L' && op.packet[3] == 'A' && op.packet[4] == 'C' && op.packet[5] == 0x01) result = True; break; } } } while (in.GetPos() < in.Size()); if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return result; } Error BoCA::DecoderFLAC::GetStreamInfo(const String &streamURI, Track &track) { DriverANSI ioDriver(File(streamURI), IS_READ); InStream in(STREAM_DRIVER, &ioDriver); SkipID3v2Tag(in); /* Set up members. */ track.fileSize = in.Size(); infoTrack = &track; stop = False; finished = False; driver = &ioDriver; driver->Seek(in.GetPos()); /* Read metadata. */ ReadFLAC(False); in.Close(); ioDriver.Close(); return Success(); } BoCA::DecoderFLAC::DecoderFLAC() : samplesRequestedSignal(1), samplesAvailableSignal(1) { infoTrack = NIL; decoderThread = NIL; stop = False; finished = False; seekPosition = 0; } BoCA::DecoderFLAC::~DecoderFLAC() { } Bool BoCA::DecoderFLAC::Activate() { /* Skip headers. */ InStream in(STREAM_DRIVER, driver); SkipID3v2Tag(in); driver->Seek(in.GetPos()); /* Prepare decoder. */ infoTrack = new Track(); decoderThread = NIL; stop = False; finished = False; seekPosition = 0; samplesAvailableSignal.Wait(); return True; } Bool BoCA::DecoderFLAC::Deactivate() { if (decoderThread != NIL) { stop = True; samplesRequestedSignal.Release(); decoderThread->Wait(); } delete infoTrack; return True; } Bool BoCA::DecoderFLAC::Seek(Int64 samplePosition) { seekPosition = samplePosition; return True; } Int BoCA::DecoderFLAC::ReadData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); if (decoderThread == NIL) decoderThread = NonBlocking1(&DecoderFLAC::ReadFLAC, this).Call(True); if (finished && samplesBuffer.Size() <= 0) return -1; samplesAvailableSignal.Wait(); inBytes = driver->GetPos(); /* Convert samples to target format. */ const Format &format = track.GetFormat(); data.Resize(samplesBuffer.Size() * (format.bits / 8)); for (Int i = 0; i < samplesBuffer.Size(); i++) { if (format.bits == 8 ) ((int8_t *) (UnsignedByte *) data)[i] = samplesBuffer[i]; else if (format.bits == 16 ) ((int16_t *) (UnsignedByte *) data)[i] = samplesBuffer[i]; else if (format.bits == 24 && endianness == EndianLittle) { data[3 * i + 2] = (samplesBuffer[i] >> 16) & 0xFF; data[3 * i + 1] = (samplesBuffer[i] >> 8) & 0xFF; data[3 * i ] = samplesBuffer[i] & 0xFF; } else if (format.bits == 24 && endianness == EndianBig ) { data[3 * i ] = (samplesBuffer[i] >> 16) & 0xFF; data[3 * i + 1] = (samplesBuffer[i] >> 8) & 0xFF; data[3 * i + 2] = samplesBuffer[i] & 0xFF; } else if (format.bits == 32 ) ((int32_t *) (UnsignedByte *) data)[i] = samplesBuffer[i]; } samplesBuffer.Resize(0); samplesRequestedSignal.Release(); return data.Size(); } Int BoCA::DecoderFLAC::ReadFLAC(Bool readData) { FLAC__StreamDecoder *decoder = ex_FLAC__stream_decoder_new(); if (!readData) { ex_FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); ex_FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_PICTURE); } /* Set larger read buffer size. */ if (readData && driver->IsBuffered()) driver->SetBufferSize(flacStreamDecoderBufferSize); /* Initialize decoder. */ char signature[5] = { 0, 0, 0, 0, 0 }; driver->ReadData((UnsignedByte *) signature, 4); driver->Seek(driver->GetPos() - 4); if (String(signature) == "fLaC") ex_FLAC__stream_decoder_init_stream(decoder, &FLACStreamDecoderReadCallback, &FLACStreamDecoderSeekCallback, &FLACStreamDecoderTellCallback, &FLACStreamDecoderLengthCallback, &FLACStreamDecoderEofCallback, &FLACStreamDecoderWriteCallback, &FLACStreamDecoderMetadataCallback, &FLACStreamDecoderErrorCallback, this); else if (String(signature) == "OggS") ex_FLAC__stream_decoder_init_ogg_stream(decoder, &FLACStreamDecoderReadCallback, &FLACStreamDecoderSeekCallback, &FLACStreamDecoderTellCallback, &FLACStreamDecoderLengthCallback, &FLACStreamDecoderEofCallback, &FLACStreamDecoderWriteCallback, &FLACStreamDecoderMetadataCallback, &FLACStreamDecoderErrorCallback, this); /* Process metadata and audio. */ ex_FLAC__stream_decoder_process_until_end_of_metadata(decoder); if (readData) { ex_FLAC__stream_decoder_seek_absolute(decoder, seekPosition); ex_FLAC__stream_decoder_process_until_end_of_stream(decoder); } /* Finish and free decoder. */ finished = True; samplesAvailableSignal.Release(); ex_FLAC__stream_decoder_finish(decoder); ex_FLAC__stream_decoder_delete(decoder); /* Set chapter pictures. */ foreach (Track &track, infoTrack->tracks) track.pictures = infoTrack->pictures; return Success(); } Bool BoCA::DecoderFLAC::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning of the file * and skip it if it exists. EAC and possibly other * programs write ID3 tags fo FLAC if misconfigured. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } FLAC__StreamDecoderReadStatus BoCA::FLACStreamDecoderReadCallback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; if (filter->stop) { *bytes = 0; return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } *bytes = filter->driver->ReadData(buffer, *bytes); if (*bytes == 0) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; else return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } FLAC__StreamDecoderWriteStatus BoCA::FLACStreamDecoderWriteCallback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; if (filter->stop) return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; filter->samplesRequestedSignal.Wait(); Int oSize = filter->samplesBuffer.Size(); filter->samplesBuffer.Resize(oSize + frame->header.blocksize * frame->header.channels); for (Int i = 0; i < signed(frame->header.blocksize); i++) { for (Int j = 0; j < signed(frame->header.channels); j++) { filter->samplesBuffer[oSize + i * signed(frame->header.channels) + j] = buffer[j][i]; } } filter->samplesAvailableSignal.Release(); return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } FLAC__StreamDecoderSeekStatus BoCA::FLACStreamDecoderSeekCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; filter->driver->Seek(absolute_byte_offset); return FLAC__STREAM_DECODER_SEEK_STATUS_OK; } FLAC__StreamDecoderTellStatus BoCA::FLACStreamDecoderTellCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; *absolute_byte_offset = filter->driver->GetPos(); return FLAC__STREAM_DECODER_TELL_STATUS_OK; } FLAC__StreamDecoderLengthStatus BoCA::FLACStreamDecoderLengthCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; *stream_length = filter->driver->GetSize(); return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } FLAC__bool BoCA::FLACStreamDecoderEofCallback(const FLAC__StreamDecoder *decoder, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; return (filter->stop || filter->driver->GetPos() == filter->driver->GetSize()); } void BoCA::FLACStreamDecoderMetadataCallback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { DecoderFLAC *filter = (DecoderFLAC *) client_data; const Config *config = filter->GetConfiguration(); if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { Format format = filter->infoTrack->GetFormat(); format.bits = metadata->data.stream_info.bits_per_sample; format.channels = metadata->data.stream_info.channels; format.rate = metadata->data.stream_info.sample_rate; if (metadata->data.stream_info.total_samples > 0) filter->infoTrack->length = metadata->data.stream_info.total_samples; else filter->infoTrack->approxLength = filter->driver->GetSize() / (format.bits / 8) / format.channels * 1.5; for (Int i = 0; i < 16; i++) filter->infoTrack->md5.Append(Number((Int64) metadata->data.stream_info.md5sum[i]).ToHexString(2)); filter->infoTrack->SetFormat(format); } else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { if (metadata->data.vorbis_comment.num_comments > 0) { Buffer vcBuffer(metadata->length); OutStream out(STREAM_BUFFER, vcBuffer, vcBuffer.Size()); out.OutputNumber(metadata->data.vorbis_comment.vendor_string.length, 4); out.OutputData(metadata->data.vorbis_comment.vendor_string.entry, metadata->data.vorbis_comment.vendor_string.length); out.OutputNumber(metadata->data.vorbis_comment.num_comments, 4); for (UnsignedInt i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { out.OutputNumber(metadata->data.vorbis_comment.comments[i].length, 4); out.OutputData(metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length); } AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(filter->GetConfiguration()); tagger->ParseBuffer(vcBuffer, *filter->infoTrack); boca.DeleteComponent(tagger); } } } else if (metadata->type == FLAC__METADATA_TYPE_PICTURE && config->GetIntValue("Tags", "CoverArtReadFromTags", True)) { Picture picture; picture.type = metadata->data.picture.type; picture.mime = metadata->data.picture.mime_type; picture.description.ImportFrom("UTF-8", (char *) metadata->data.picture.description); picture.data.Set(metadata->data.picture.data, metadata->data.picture.data_length); if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) filter->infoTrack->pictures.Add(picture); } } } void BoCA::FLACStreamDecoderErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/flac/flac.h000066400000000000000000000046421516712004000237470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderFLAC) namespace BoCA { class DecoderFLAC : public CS::DecoderComponent { friend FLAC__StreamDecoderReadStatus FLACStreamDecoderReadCallback(const FLAC__StreamDecoder *, FLAC__byte [], size_t *, void *); friend FLAC__StreamDecoderWriteStatus FLACStreamDecoderWriteCallback(const FLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *); friend FLAC__StreamDecoderSeekStatus FLACStreamDecoderSeekCallback(const FLAC__StreamDecoder *, FLAC__uint64, void *); friend FLAC__StreamDecoderTellStatus FLACStreamDecoderTellCallback(const FLAC__StreamDecoder *, FLAC__uint64 *, void *); friend FLAC__StreamDecoderLengthStatus FLACStreamDecoderLengthCallback(const FLAC__StreamDecoder *, FLAC__uint64 *, void *); friend FLAC__bool FLACStreamDecoderEofCallback(const FLAC__StreamDecoder *, void *); friend void FLACStreamDecoderMetadataCallback(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *); friend void FLACStreamDecoderErrorCallback(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *); private: Bool stop; Bool finished; Int64 seekPosition; Buffer samplesBuffer; Track *infoTrack; Threads::Thread *decoderThread; Threads::Semaphore samplesRequestedSignal; Threads::Semaphore samplesAvailableSignal; Int ReadFLAC(Bool); Bool SkipID3v2Tag(IO::InStream &); public: static const String &GetComponentSpecs(); DecoderFLAC(); ~DecoderFLAC(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderFLAC) BoCA_END_COMPONENT(DecoderFLAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/000077500000000000000000000000001516712004000226745ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/Makefile000077500000000000000000000012121516712004000243330ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = lame TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o lame.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/dllinterface.cpp000077500000000000000000000035221516712004000260410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; HIP_DECODE_INIT ex_hip_decode_init = NIL; HIP_DECODE_EXIT ex_hip_decode_exit = NIL; HIP_DECODE ex_hip_decode = NIL; HIP_DECODE_HEADERS ex_hip_decode_headers = NIL; GET_LAME_SHORT_VERSION ex_get_lame_short_version = NIL; DynamicLoader *lamedll = NIL; Bool LoadLAMEDLL() { #ifdef __WIN32__ lamedll = BoCA::Utilities::LoadCodecDLL("LAME"); #else lamedll = BoCA::Utilities::LoadCodecDLL("mp3lame"); #endif if (lamedll == NIL) return False; ex_hip_decode_init = (HIP_DECODE_INIT) lamedll->GetFunctionAddress("hip_decode_init"); ex_hip_decode_exit = (HIP_DECODE_EXIT) lamedll->GetFunctionAddress("hip_decode_exit"); ex_hip_decode = (HIP_DECODE) lamedll->GetFunctionAddress("hip_decode"); ex_hip_decode_headers = (HIP_DECODE_HEADERS) lamedll->GetFunctionAddress("hip_decode_headers"); ex_get_lame_short_version = (GET_LAME_SHORT_VERSION) lamedll->GetFunctionAddress("get_lame_short_version"); if (ex_hip_decode_init == NIL || ex_hip_decode_exit == NIL || ex_hip_decode == NIL || ex_hip_decode_headers == NIL || ex_get_lame_short_version == NIL) { FreeLAMEDLL(); return False; } return True; } Void FreeLAMEDLL() { BoCA::Utilities::FreeCodecDLL(lamedll); lamedll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/dllinterface.h000077500000000000000000000025011516712004000255020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *lamedll; Bool LoadLAMEDLL(); Void FreeLAMEDLL(); typedef hip_t (CDECL *HIP_DECODE_INIT) (); typedef int (CDECL *HIP_DECODE_EXIT) (hip_t); typedef int (CDECL *HIP_DECODE) (hip_t, unsigned char *, size_t, short [], short []); typedef int (CDECL *HIP_DECODE_HEADERS) (hip_t, unsigned char *, size_t, short [], short [], mp3data_struct *); typedef char * (CDECL *GET_LAME_SHORT_VERSION) (); extern HIP_DECODE_INIT ex_hip_decode_init; extern HIP_DECODE_EXIT ex_hip_decode_exit; extern HIP_DECODE ex_hip_decode; extern HIP_DECODE_HEADERS ex_hip_decode_headers; extern GET_LAME_SHORT_VERSION ex_get_lame_short_version; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/lame.cpp000066400000000000000000000151571516712004000243270ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "lame.h" using namespace smooth::IO; const String &BoCA::DecoderLAME::GetComponentSpecs() { static String componentSpecs; if (lamedll != NIL) { componentSpecs = " \ \ \ \ LAME MP3 Decoder %VERSION% \ 1.0 \ lame-dec \ decoder \ \ MPEG 1 Audio Layer 3 \ mp3 \ ID3v1 \ ID3v2 \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(ex_get_lame_short_version())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadLAMEDLL(); } Void smooth::DetachDLL() { FreeLAMEDLL(); } Bool BoCA::DecoderLAME::CanOpenStream(const String &streamURI) { return streamURI.ToLower().EndsWith(".mp3"); } Error BoCA::DecoderLAME::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); Format format = track.GetFormat(); track.fileSize = in.Size(); track.length = -1; SkipID3v2Tag(in); ParseVBRHeaders(in); Buffer buffer(4096); Buffer pcm_l(buffer.Size() * 24); Buffer pcm_r(buffer.Size() * 24); hip_t context = ex_hip_decode_init(); Int offset = in.GetPos(); do { Int bytes = Math::Min((Int64) buffer.Size(), in.Size() - in.GetPos()); in.InputData((void *) buffer, bytes); mp3data_struct mp3data; memset(&mp3data, 0, sizeof(mp3data)); Int nSamples = ex_hip_decode_headers(context, buffer, bytes, pcm_l, pcm_r, &mp3data); if (mp3data.header_parsed && nSamples > mp3data.framesize) { format.channels = mp3data.stereo; format.rate = mp3data.samplerate; format.bits = 16; if (mp3data.nsamp > 0) track.length = mp3data.nsamp - delaySamples - padSamples; else if (mp3data.bitrate > 0) track.approxLength = (track.fileSize - offset) / (mp3data.bitrate * 1000 / 8) * format.rate; break; } } while (in.GetPos() < in.Size()); ex_hip_decode_exit(context); if (format == Format()) { errorState = True; errorString = "Invalid file format"; } track.SetFormat(format); in.Close(); if (!errorState) { Bool foundTag = False; AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); if (tagger->ParseStreamInfo(streamURI, track) == Success()) foundTag = True; boca.DeleteComponent(tagger); } if (!foundTag) { tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } if (errorState) return Error(); else return Success(); } BoCA::DecoderLAME::DecoderLAME() { context = 0; delaySamples = 0; padSamples = 0; /* Initialize to decoder delay. */ delaySamplesLeft = 529; } BoCA::DecoderLAME::~DecoderLAME() { } Bool BoCA::DecoderLAME::Activate() { /* Skip headers. */ InStream in(STREAM_DRIVER, driver); SkipID3v2Tag(in); ParseVBRHeaders(in); driver->Seek(in.GetPos()); /* Create decoder. */ context = ex_hip_decode_init(); return True; } Bool BoCA::DecoderLAME::Deactivate() { ex_hip_decode_exit(context); return True; } Int BoCA::DecoderLAME::ReadData(Buffer &data) { /* Read input data. */ Int size = driver->ReadData(data, data.Size()); if (size <= 0) return -1; inBytes += size; /* Decode samples. */ const Format &format = track.GetFormat(); pcm_l.Resize(data.Size() * 24); pcm_r.Resize(data.Size() * 24); Int nSamples = ex_hip_decode(context, data, size, pcm_l, pcm_r); /* Try harder in case we got no data yet. */ for (Int i = 0; nSamples == 0 && i < size / 384; i++) nSamples = ex_hip_decode(context, NIL, 0, pcm_l, pcm_r); data.Resize(0); if (nSamples > delaySamplesLeft) { data.Resize((nSamples - delaySamplesLeft) * format.channels * (format.bits / 8)); for (Int i = delaySamplesLeft; i < nSamples; i++) { for (Int j = 0; j < format.channels; j++) ((short *) (unsigned char *) data)[format.channels * (i - delaySamplesLeft) + j] = (j == 0) ? pcm_l[i] : pcm_r[i]; } } delaySamplesLeft = Math::Max(0, delaySamplesLeft - nSamples); return data.Size(); } Bool BoCA::DecoderLAME::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning of the * file and skip it if it exists as it might cause * problems if the tag is unsynchronized. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } Bool BoCA::DecoderLAME::ParseVBRHeaders(InStream &in) { /* Check for a LAME header and extract the number of samples if it exists. */ Buffer buffer(192); /* Read data and seek back to before the Xing header. */ in.InputData(buffer, buffer.Size()); in.RelSeek(-buffer.Size()); /* Check for a LAME header and extract length information. */ Int offset = ((buffer[1] >> 3) & 1 ? (buffer[3] >> 6 != 3 ? 32 : 17) : (buffer[3] >> 6 != 3 ? 17 : 9)) + 4; UnsignedByte *xing = buffer + offset; UnsignedInt16 crc = Hash::CRC16::Compute(buffer, offset + 0x9A); if (xing[0x9A] == (crc >> 8) && xing[0x9B] == (crc & 0xFF)) { delaySamples = ( xing[0x8D] << 4) | ((xing[0x8E] & 0xF0) >> 4); padSamples = ((xing[0x8E] & 0x0F) << 8) | ( xing[0x8F] ); delaySamplesLeft += delaySamples; return True; } return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/lame/lame.h000066400000000000000000000025061516712004000237660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderLAME) namespace BoCA { class DecoderLAME : public CS::DecoderComponent { private: hip_t context; Buffer pcm_l; Buffer pcm_r; Int delaySamples; Int padSamples; Int delaySamplesLeft; Bool SkipID3v2Tag(IO::InStream &); Bool ParseVBRHeaders(IO::InStream &); public: static const String &GetComponentSpecs(); DecoderLAME(); ~DecoderLAME(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderLAME) BoCA_END_COMPONENT(DecoderLAME) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/000077500000000000000000000000001516712004000225165ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/Makefile000077500000000000000000000015061516712004000241630ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mac TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = dllinterface.o mac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support ifeq ($(BUILD_WIN32),True) DEFINE += -DPLATFORM_WINDOWS -DWINVER=0x0500 else DEFINE += -DPLATFORM_LINUX endif # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/dllinterface.cpp000077500000000000000000000050261516712004000256640ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" APEDECOMPRESS_CREATEW ex_APEDecompress_CreateW = NIL; APEDECOMPRESS_DESTROY ex_APEDecompress_Destroy = NIL; APEDECOMPRESS_SEEK ex_APEDecompress_Seek = NIL; APEDECOMPRESS_GETDATA ex_APEDecompress_GetData = NIL; APEDECOMPRESS_GETINFO ex_APEDecompress_GetInfo = NIL; GETLIBRARYVERSIONSTRING ex_GetLibraryVersionString = NIL; GETLIBRARYINTERFACEVERSION ex_GetLibraryInterfaceVersion = NIL; DynamicLoader *macdll = NIL; Bool LoadMACDLL() { #ifdef __WIN32__ macdll = BoCA::Utilities::LoadCodecDLL("MACDll"); #else macdll = BoCA::Utilities::LoadCodecDLL("MAC"); #endif if (macdll == NIL) return False; ex_APEDecompress_CreateW = (APEDECOMPRESS_CREATEW) macdll->GetFunctionAddress("c_APEDecompress_CreateW"); ex_APEDecompress_Destroy = (APEDECOMPRESS_DESTROY) macdll->GetFunctionAddress("c_APEDecompress_Destroy"); ex_APEDecompress_Seek = (APEDECOMPRESS_SEEK) macdll->GetFunctionAddress("c_APEDecompress_Seek"); ex_APEDecompress_GetData = (APEDECOMPRESS_GETDATA) macdll->GetFunctionAddress("c_APEDecompress_GetData"); ex_APEDecompress_GetInfo = (APEDECOMPRESS_GETINFO) macdll->GetFunctionAddress("c_APEDecompress_GetInfo"); ex_GetLibraryVersionString = (GETLIBRARYVERSIONSTRING) macdll->GetFunctionAddress("GetLibraryVersionString"); ex_GetLibraryInterfaceVersion = (GETLIBRARYINTERFACEVERSION) macdll->GetFunctionAddress("GetLibraryInterfaceVersion"); if (ex_APEDecompress_CreateW == NIL || ex_APEDecompress_Destroy == NIL || ex_APEDecompress_Seek == NIL || ex_APEDecompress_GetData == NIL || ex_APEDecompress_GetInfo == NIL || ex_GetLibraryVersionString == NIL || ex_GetLibraryInterfaceVersion == NIL) { FreeMACDLL(); return False; } /* Check library interface version. */ unsigned int interfaceVersion = ex_GetLibraryInterfaceVersion(); if (interfaceVersion > 15) { FreeMACDLL(); return False; } return True; } Void FreeMACDLL() { Object::DeleteObject(macdll); macdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/dllinterface.h000077500000000000000000000034571516712004000253370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace APE; using namespace smooth; using namespace smooth::System; extern DynamicLoader *macdll; Bool LoadMACDLL(); Void FreeMACDLL(); typedef APE_DECOMPRESS_HANDLE (__stdcall *APEDECOMPRESS_CREATEW) (const APE::str_utfn *, int *); typedef void (__stdcall *APEDECOMPRESS_DESTROY) (APE_DECOMPRESS_HANDLE); typedef int (__stdcall *APEDECOMPRESS_SEEK) (APE_DECOMPRESS_HANDLE, APE::int64); typedef int (__stdcall *APEDECOMPRESS_GETDATA) (APE_DECOMPRESS_HANDLE, char *, APE::int64, APE::int64 *); typedef APE::int64 (__stdcall *APEDECOMPRESS_GETINFO) (APE_DECOMPRESS_HANDLE, APE::IAPEDecompress::APE_DECOMPRESS_FIELDS, APE::int64, APE::int64); typedef const char * (__stdcall *GETLIBRARYVERSIONSTRING) (); typedef unsigned int (__stdcall *GETLIBRARYINTERFACEVERSION) (); extern APEDECOMPRESS_CREATEW ex_APEDecompress_CreateW; extern APEDECOMPRESS_DESTROY ex_APEDecompress_Destroy; extern APEDECOMPRESS_SEEK ex_APEDecompress_Seek; extern APEDECOMPRESS_GETDATA ex_APEDecompress_GetData; extern APEDECOMPRESS_GETINFO ex_APEDecompress_GetInfo; extern GETLIBRARYVERSIONSTRING ex_GetLibraryVersionString; extern GETLIBRARYINTERFACEVERSION ex_GetLibraryInterfaceVersion; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/mac.cpp000066400000000000000000000105031516712004000237610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "mac.h" using namespace smooth::IO; const String &BoCA::DecoderMAC::GetComponentSpecs() { static String componentSpecs; if (macdll != NIL) { componentSpecs = " \ \ \ \ Monkey's Audio Decoder %VERSION% \ 1.0 \ mac-dec \ decoder \ ffmpeg-mac-dec \ \ Monkey's Audio \ true \ ape \ mac \ APEv2 \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(ex_GetLibraryVersionString())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMACDLL(); } Void smooth::DetachDLL() { FreeMACDLL(); } Bool BoCA::DecoderMAC::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.EndsWith(".ape") || lcURI.EndsWith(".mac"); } Error BoCA::DecoderMAC::GetStreamInfo(const String &streamURI, Track &track) { APE_DECOMPRESS_HANDLE hAPEDecompress = ex_APEDecompress_CreateW(streamURI, NIL); if (hAPEDecompress == NIL) return Error(); Format format = track.GetFormat(); format.fp = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_INFO_FORMAT_FLAGS, 0, 0) & APE_FORMAT_FLAG_FLOATING_POINT; format.bits = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_INFO_BITS_PER_SAMPLE, 0, 0); format.channels = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_INFO_CHANNELS, 0, 0); format.rate = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_INFO_SAMPLE_RATE, 0, 0); format.sign = format.bits != 8; track.length = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_DECOMPRESS_TOTAL_BLOCKS, 0, 0); track.SetFormat(format); ex_APEDecompress_Destroy(hAPEDecompress); track.fileSize = File(streamURI).GetFileSize(); /* Parse APE tag if present. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("apev2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } return Success(); } BoCA::DecoderMAC::DecoderMAC() { hAPEDecompress = NIL; blockId = 0; } BoCA::DecoderMAC::~DecoderMAC() { } Bool BoCA::DecoderMAC::Activate() { hAPEDecompress = ex_APEDecompress_CreateW(track.fileName, NIL); blockId = 0; return True; } Bool BoCA::DecoderMAC::Deactivate() { ex_APEDecompress_Destroy(hAPEDecompress); return True; } Bool BoCA::DecoderMAC::Seek(Int64 samplePosition) { if (ex_APEDecompress_Seek(hAPEDecompress, samplePosition) == ERROR_SUCCESS) return True; else return False; } Int BoCA::DecoderMAC::ReadData(Buffer &data) { inBytes += data.Size(); int64 nBlockAlign = ex_APEDecompress_GetInfo(hAPEDecompress, IAPEDecompress::APE_INFO_BLOCK_ALIGN, 0, 0); int64 nBlocksRetrieved = 0; int64 nTotalBlocksRetrieved = 0; do { data.Resize((nTotalBlocksRetrieved + 1024) * nBlockAlign); /* Try to decompress 1024 blocks */ if (ex_APEDecompress_GetData(hAPEDecompress, (char *) (unsigned char *) data + nTotalBlocksRetrieved * nBlockAlign, 1024, &nBlocksRetrieved) != ERROR_SUCCESS) return -1; nTotalBlocksRetrieved += nBlocksRetrieved; blockId += nBlocksRetrieved; } while (nBlocksRetrieved > 0 && blockId < (track.length * (double(inBytes) / track.fileSize))); return nTotalBlocksRetrieved * nBlockAlign; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mac/mac.h000066400000000000000000000022531516712004000234310ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderMAC) namespace BoCA { class DecoderMAC : public CS::DecoderComponent { private: APE_DECOMPRESS_HANDLE hAPEDecompress; Int blockId; public: static const String &GetComponentSpecs(); DecoderMAC(); ~DecoderMAC(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderMAC) BoCA_END_COMPONENT(DecoderMAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/000077500000000000000000000000001516712004000225175ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/Makefile000077500000000000000000000015541516712004000241670ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mad TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = ../../shared/mp3frame.o ../../shared/vbrtag.o config.o dllinterface.o mad.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter additional commands for targets all and clean here: ifneq ("$(SRCDIR)","$(CURDIR)") ALLCMD1 = mkdir -p ../../shared ALLCMD2 = CLEANCMD1 = rmdir ../../shared || true CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = endif ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/config.cpp000066400000000000000000000026511516712004000244740ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureMAD::ConfigID = "MAD"; BoCA::ConfigureMAD::ConfigureMAD() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Decoders::MAD"); enable24bit = config->GetIntValue(ConfigID, "Enable24Bit", False); group_decoding = new GroupBox(i18n->TranslateString("Decoding"), Point(7, 11), Size(200, 41)); check_enable24bit = new CheckBox(i18n->TranslateString("Enable 24 bit decoding"), Point(10, 14), Size(180, 0), &enable24bit); group_decoding->Add(check_enable24bit); Add(group_decoding); SetSize(Size(214, 169)); } BoCA::ConfigureMAD::~ConfigureMAD() { DeleteObject(group_decoding); DeleteObject(check_enable24bit); } Int BoCA::ConfigureMAD::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Enable24Bit", enable24bit); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/config.h000066400000000000000000000020071516712004000241340ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_MADCONFIG #define H_MADCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureMAD : public ConfigLayer { private: GroupBox *group_decoding; CheckBox *check_enable24bit; Bool enable24bit; public: static const String ConfigID; ConfigureMAD(); ~ConfigureMAD(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/dllinterface.cpp000077500000000000000000000030571516712004000256670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" MAD_DECODER_INIT ex_mad_decoder_init = NIL; MAD_DECODER_RUN ex_mad_decoder_run = NIL; MAD_DECODER_FINISH ex_mad_decoder_finish = NIL; MAD_STREAM_BUFFER ex_mad_stream_buffer = NIL; DynamicLoader *maddll = NIL; Bool LoadMADDLL() { maddll = BoCA::Utilities::LoadCodecDLL("mad"); if (maddll == NIL) return False; ex_mad_decoder_init = (MAD_DECODER_INIT) maddll->GetFunctionAddress("mad_decoder_init"); ex_mad_decoder_run = (MAD_DECODER_RUN) maddll->GetFunctionAddress("mad_decoder_run"); ex_mad_decoder_finish = (MAD_DECODER_FINISH) maddll->GetFunctionAddress("mad_decoder_finish"); ex_mad_stream_buffer = (MAD_STREAM_BUFFER) maddll->GetFunctionAddress("mad_stream_buffer"); if (ex_mad_decoder_init == NIL || ex_mad_decoder_run == NIL || ex_mad_decoder_finish == NIL || ex_mad_stream_buffer == NIL) { FreeMADDLL(); return False; } return True; } Void FreeMADDLL() { BoCA::Utilities::FreeCodecDLL(maddll); maddll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/dllinterface.h000077500000000000000000000027231516712004000253330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *maddll; Bool LoadMADDLL(); Void FreeMADDLL(); typedef void (*MAD_DECODER_INIT) (mad_decoder *, void *, mad_flow (*)(void *, mad_stream *), mad_flow(*)(void *, mad_header const *), mad_flow(*)(void *, mad_stream const *, mad_frame *), mad_flow(*)(void *, mad_header const *, mad_pcm *), mad_flow(*)(void *, mad_stream *, mad_frame *), mad_flow(*)(void *, void *, unsigned int *)); typedef int (*MAD_DECODER_RUN) (mad_decoder *, mad_decoder_mode); typedef int (*MAD_DECODER_FINISH) (mad_decoder *); typedef void (*MAD_STREAM_BUFFER) (mad_stream *, unsigned char const *, unsigned long); extern MAD_DECODER_INIT ex_mad_decoder_init; extern MAD_DECODER_RUN ex_mad_decoder_run; extern MAD_DECODER_FINISH ex_mad_decoder_finish; extern MAD_STREAM_BUFFER ex_mad_stream_buffer; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/mad.cpp000066400000000000000000000264501516712004000237730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "mad.h" #include "config.h" #include "../../shared/mp3frame.h" #include "../../shared/vbrtag.h" using namespace smooth::IO; using namespace smooth::Threads; const String &BoCA::DecoderMAD::GetComponentSpecs() { static String componentSpecs; if (maddll != NIL) { componentSpecs = " \ \ \ \ MAD MP3 Decoder \ 1.0 \ mad-dec \ decoder \ lame-dec \ \ MPEG Audio Files \ mp1 \ mp2 \ mp3 \ ID3v1 \ ID3v2 \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMADDLL(); } Void smooth::DetachDLL() { FreeMADDLL(); } namespace BoCA { mad_flow MADInputCallback(void *, mad_stream *); mad_flow MADOutputCallback(void *, const mad_header *, mad_pcm *); mad_flow MADHeaderCallback(void *, const mad_header *, mad_pcm *); mad_flow MADErrorCallback(void *, mad_stream *, mad_frame *); /* FIXME: This is the scaling function included in the MAD * package. It should be replaced by a more decent one. */ static inline signed int scale(mad_fixed_t sample, int scale) { /* Round */ sample += (1L << (MAD_F_FRACBITS - scale)); /* Clip */ if (sample >= MAD_F_ONE) sample = MAD_F_ONE - 1; else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE; /* Quantize */ return sample >> (MAD_F_FRACBITS + 1 - scale); } }; Bool BoCA::DecoderMAD::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.EndsWith(".mp1") || lcURI.EndsWith(".mp2") || lcURI.EndsWith(".mp3"); } Error BoCA::DecoderMAD::GetStreamInfo(const String &streamURI, Track &track) { DriverANSI ioDriver(File(streamURI), IS_READ); InStream in(STREAM_DRIVER, &ioDriver); SkipID3v2Tag(in); ParseVBRHeaders(in); track.fileSize = in.Size(); track.length = -1; infoTrack = &track; stop = False; finishing = False; finished = False; offset = in.GetPos(); driver = &ioDriver; driver->Seek(offset); ReadMAD(False); if (track.GetFormat() == Format()) { errorState = True; errorString = "Invalid file format"; } in.Close(); ioDriver.Close(); if (!errorState) { Bool foundTag = False; AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); if (tagger->ParseStreamInfo(streamURI, track) == Success()) foundTag = True; boca.DeleteComponent(tagger); } if (!foundTag) { tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } if (errorState) return Error(); else return Success(); } BoCA::DecoderMAD::DecoderMAD() : samplesRequestedSignal(1), samplesAvailableSignal(1) { configLayer = NIL; infoTrack = NIL; decoderThread = NIL; stop = False; finishing = False; finished = False; offset = 0; numBytes = 0; numFrames = 0; delaySamples = 0; padSamples = 0; /* Initialize to decoder delay. */ delaySamplesLeft = 529; } BoCA::DecoderMAD::~DecoderMAD() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderMAD::Activate() { /* Skip headers. */ InStream in(STREAM_DRIVER, driver); SkipID3v2Tag(in); ParseVBRHeaders(in); driver->Seek(in.GetPos()); /* Prepare decoder. */ infoTrack = new Track(); decoderThread = NIL; stop = False; finishing = False; finished = False; samplesAvailableSignal.Wait(); return True; } Bool BoCA::DecoderMAD::Deactivate() { if (decoderThread != NIL) { stop = True; samplesRequestedSignal.Release(); decoderThread->Wait(); } delete infoTrack; return True; } Int BoCA::DecoderMAD::ReadData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); if (decoderThread == NIL) decoderThread = NonBlocking1(&DecoderMAD::ReadMAD, this).Call(True); if (finished && samplesBuffer.Size() <= 0) return -1; samplesAvailableSignal.Wait(); /* Convert samples to target format. */ const Format &format = track.GetFormat(); data.Resize(samplesBuffer.Size() * (format.bits / 8)); for (Int i = 0; i < samplesBuffer.Size(); i++) { int sample = scale(samplesBuffer[i], format.bits); if (format.bits == 16 ) ((Short *) (unsigned char *) data)[i] = sample; else if (format.bits == 24 && endianness == EndianLittle) { data[i * 3 + 2] = (sample >> 16) & 0xFF; data[i * 3 + 1] = (sample >> 8) & 0xFF; data[i * 3 ] = sample & 0xFF; } else if (format.bits == 24 && endianness == EndianBig ) { data[i * 3 ] = (sample >> 16) & 0xFF; data[i * 3 + 1] = (sample >> 8) & 0xFF; data[i * 3 + 2] = sample & 0xFF; } } samplesBuffer.Resize(0); samplesRequestedSignal.Release(); return data.Size(); } Bool BoCA::DecoderMAD::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning of the * file and skip it if it exists as it might cause * problems if the tag is unsynchronized. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } Bool BoCA::DecoderMAD::ParseVBRHeaders(InStream &in) { /* Read MPEG header and get frame size. */ Buffer header(3); in.InputData(header, 3); in.RelSeek(-3); Int frameSize = MP3Frame::GetMPEGFrameSize(header); if (frameSize < 156) return False; /* Read frame. */ Buffer buffer(frameSize); in.InputData(buffer, frameSize); /* Check for a Xing or VBRI header and extract the number of frames. */ VbrTag vbrTag; if (vbrTag.Parse(buffer)) { if (vbrTag.flags & VbrTag::FLAG_BYTES) numBytes = vbrTag.bytes - frameSize; if (vbrTag.flags & VbrTag::FLAG_FRAMES) numFrames = vbrTag.frames; if (vbrTag.flags & VbrTag::FLAG_GAPLESS) { delaySamples = vbrTag.delay; padSamples = vbrTag.padding; delaySamplesLeft += delaySamples; } } else { /* Seek back to before the frame if no Xing or VBRI header was found. */ in.RelSeek(-frameSize); return False; } /* Sanity check for header vs. actual file size (account * for possible ID3v1 and addtional 4kB of other tags). */ if (numBytes > 0 && in.Size() - in.GetPos() > numBytes * 1.01 + 128 + 4096) { numFrames = 0; padSamples = 0; } return True; } Int BoCA::DecoderMAD::ReadMAD(Bool readData) { /* Initialize decoder. */ mad_decoder decoder; if (readData) ex_mad_decoder_init(&decoder, this, &MADInputCallback, NIL, NIL, &MADOutputCallback, &MADErrorCallback, NIL); else ex_mad_decoder_init(&decoder, this, &MADInputCallback, NIL, NIL, &MADHeaderCallback, &MADErrorCallback, NIL); /* Process header and audio. */ ex_mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); /* Finish and free decoder. */ finished = True; samplesAvailableSignal.Release(); ex_mad_decoder_finish(&decoder); return Success(); } ConfigLayer *BoCA::DecoderMAD::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureMAD(); return configLayer; } mad_flow BoCA::MADInputCallback(void *client_data, mad_stream *stream) { DecoderMAD *filter = (DecoderMAD *) client_data; if (filter->stop || filter->finishing) return MAD_FLOW_STOP; /* Check if we have any more data. If not, append an empty * frame to the last frame to allow the decoder to finish. */ if (filter->driver->GetPos() == filter->driver->GetSize()) filter->finishing = True; Int bytes = Math::Min((Int64) 131072, filter->finishing ? 1440 : filter->driver->GetSize() - filter->driver->GetPos()); Int backup = stream->bufend - stream->next_frame; memmove(filter->inputBuffer, stream->next_frame, backup); filter->inputBuffer.Resize(bytes + backup); if (!filter->finishing) filter->driver->ReadData(filter->inputBuffer + backup, bytes); else memset(filter->inputBuffer + backup, 0, bytes); ex_mad_stream_buffer(stream, filter->inputBuffer, bytes + backup); filter->inBytes += bytes; return MAD_FLOW_CONTINUE; } mad_flow BoCA::MADOutputCallback(void *client_data, const mad_header *header, mad_pcm *pcm) { DecoderMAD *filter = (DecoderMAD *) client_data; if (filter->stop) return MAD_FLOW_STOP; filter->samplesRequestedSignal.Wait(); Int oSize = filter->samplesBuffer.Size(); Int channels = header->mode == MAD_MODE_SINGLE_CHANNEL ? 1 : 2; if (pcm->length > filter->delaySamplesLeft) { filter->samplesBuffer.Resize(oSize + (pcm->length - filter->delaySamplesLeft) * channels); for (Int i = filter->delaySamplesLeft; i < (signed) pcm->length; i++) { for (Int j = 0; j < channels; j++) { filter->samplesBuffer[oSize + (i - filter->delaySamplesLeft) * channels + j] = pcm->samples[j][i]; } } } filter->delaySamplesLeft = Math::Max(0, filter->delaySamplesLeft - pcm->length); filter->samplesAvailableSignal.Release(); return MAD_FLOW_CONTINUE; } mad_flow BoCA::MADHeaderCallback(void *client_data, const mad_header *header, mad_pcm *pcm) { DecoderMAD *filter = (DecoderMAD *) client_data; const Config *config = filter->GetConfiguration(); Format format = filter->infoTrack->GetFormat(); format.bits = config->GetIntValue(ConfigureMAD::ConfigID, "Enable24Bit", False) ? 24 : 16; format.channels = header->mode == MAD_MODE_SINGLE_CHANNEL ? 1 : 2; format.rate = header->samplerate; filter->infoTrack->approxLength = (filter->infoTrack->fileSize - filter->offset) / (header->bitrate / 8) * format.rate; filter->infoTrack->SetFormat(format); /* If we previously found a Xing header, * we can compute the exact duration from * the number of frames in the file. */ if (filter->numFrames > 0) { filter->infoTrack->length = filter->numFrames * Math::Round((Float) header->duration.fraction / MAD_TIMER_RESOLUTION * format.rate); filter->infoTrack->length -= (filter->delaySamples + filter->padSamples); } return MAD_FLOW_STOP; } mad_flow BoCA::MADErrorCallback(void *client_data, mad_stream *stream, mad_frame *frame) { return MAD_FLOW_CONTINUE; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mad/mad.h000066400000000000000000000037371516712004000234430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderMAD) namespace BoCA { class DecoderMAD : public CS::DecoderComponent { friend mad_flow MADInputCallback(void *, mad_stream *); friend mad_flow MADOutputCallback(void *, const mad_header *, mad_pcm *); friend mad_flow MADHeaderCallback(void *, const mad_header *, mad_pcm *); friend mad_flow MADErrorCallback(void *, mad_stream *, mad_frame *); private: ConfigLayer *configLayer; Bool stop; Bool finishing; Bool finished; Buffer inputBuffer; Buffer samplesBuffer; Track *infoTrack; Int64 numBytes; Int64 numFrames; Int delaySamples; Int padSamples; Int delaySamplesLeft; Int offset; Threads::Thread *decoderThread; Threads::Semaphore samplesRequestedSignal; Threads::Semaphore samplesAvailableSignal; Bool SkipID3v2Tag(IO::InStream &); Bool ParseVBRHeaders(IO::InStream &); Int ReadMAD(Bool); public: static const String &GetComponentSpecs(); DecoderMAD(); ~DecoderMAD(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderMAD) BoCA_END_COMPONENT(DecoderMAD) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/000077500000000000000000000000001516712004000251245ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/Makefile000066400000000000000000000012341516712004000265640ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mediafoundation TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o mediafoundation.o mfbytestream.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lole32 -luuid -lmfuuid # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/dllinterface.cpp000066400000000000000000000047211516712004000302700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" MFSTARTUP ex_MFStartup = NIL; MFSHUTDOWN ex_MFShutdown = NIL; MFCREATEASYNCRESULT ex_MFCreateAsyncResult = NIL; MFINVOKECALLBACK ex_MFInvokeCallback = NIL; MFCREATEMEDIATYPE ex_MFCreateMediaType = NIL; MFINITMEDIATYPEFROMWAVEFORMATEX ex_MFInitMediaTypeFromWaveFormatEx = NIL; MFCREATESOURCEREADERFROMBYTESTREAM ex_MFCreateSourceReaderFromByteStream = NIL; DynamicLoader *mfplatdll = NIL; DynamicLoader *mfreadwritedll = NIL; Bool LoadMFPlatDLL() { mfplatdll = new DynamicLoader("MFPlat"); ex_MFStartup = (MFSTARTUP) mfplatdll->GetFunctionAddress("MFStartup"); ex_MFShutdown = (MFSHUTDOWN) mfplatdll->GetFunctionAddress("MFShutdown"); ex_MFCreateAsyncResult = (MFCREATEASYNCRESULT) mfplatdll->GetFunctionAddress("MFCreateAsyncResult"); ex_MFInvokeCallback = (MFINVOKECALLBACK) mfplatdll->GetFunctionAddress("MFInvokeCallback"); ex_MFCreateMediaType = (MFCREATEMEDIATYPE) mfplatdll->GetFunctionAddress("MFCreateMediaType"); ex_MFInitMediaTypeFromWaveFormatEx = (MFINITMEDIATYPEFROMWAVEFORMATEX) mfplatdll->GetFunctionAddress("MFInitMediaTypeFromWaveFormatEx"); if (ex_MFStartup == NIL || ex_MFShutdown == NIL || ex_MFCreateAsyncResult == NIL || ex_MFInvokeCallback == NIL || ex_MFCreateMediaType == NIL || ex_MFInitMediaTypeFromWaveFormatEx == NIL) { FreeMFPlatDLL(); return False; } return True; } Void FreeMFPlatDLL() { Object::DeleteObject(mfplatdll); mfplatdll = NIL; } Bool LoadMFReadWriteDLL() { mfreadwritedll = new DynamicLoader("MFReadWrite"); ex_MFCreateSourceReaderFromByteStream = (MFCREATESOURCEREADERFROMBYTESTREAM) mfreadwritedll->GetFunctionAddress("MFCreateSourceReaderFromByteStream"); if (ex_MFCreateSourceReaderFromByteStream == NIL) { FreeMFReadWriteDLL(); return False; } return True; } Void FreeMFReadWriteDLL() { Object::DeleteObject(mfreadwritedll); mfreadwritedll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/dllinterface.h000066400000000000000000000034671516712004000277430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *mfplatdll; extern DynamicLoader *mfreadwritedll; Bool LoadMFPlatDLL(); Void FreeMFPlatDLL(); Bool LoadMFReadWriteDLL(); Void FreeMFReadWriteDLL(); typedef HRESULT (WINAPI *MFSTARTUP) (ULONG, DWORD); typedef HRESULT (WINAPI *MFSHUTDOWN) (); typedef HRESULT (WINAPI *MFCREATEASYNCRESULT) (IUnknown *, IMFAsyncCallback *, IUnknown *, IMFAsyncResult **); typedef HRESULT (WINAPI *MFINVOKECALLBACK) (IMFAsyncResult *); typedef HRESULT (WINAPI *MFCREATEMEDIATYPE) (IMFMediaType **); typedef HRESULT (WINAPI *MFINITMEDIATYPEFROMWAVEFORMATEX) (IMFMediaType *, const WAVEFORMATEX *, UINT32); typedef HRESULT (WINAPI *MFCREATESOURCEREADERFROMBYTESTREAM) (IMFByteStream *, IMFAttributes *, IMFSourceReader **); extern MFSTARTUP ex_MFStartup; extern MFSHUTDOWN ex_MFShutdown; extern MFCREATEASYNCRESULT ex_MFCreateAsyncResult; extern MFINVOKECALLBACK ex_MFInvokeCallback; extern MFCREATEMEDIATYPE ex_MFCreateMediaType; extern MFINITMEDIATYPEFROMWAVEFORMATEX ex_MFInitMediaTypeFromWaveFormatEx; extern MFCREATESOURCEREADERFROMBYTESTREAM ex_MFCreateSourceReaderFromByteStream; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/mediafoundation.cpp000066400000000000000000000212661516712004000310050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include "mediafoundation.h" #include "mfbytestream.h" using namespace smooth::IO; const String &BoCA::DecoderMediaFoundation::GetComponentSpecs() { static String componentSpecs; if (mfplatdll != NIL && mfreadwritedll != NIL) { componentSpecs = " \ \ \ \ Media Foundation Decoder \ 1.0 \ mediafoundation-dec \ decoder \ wma-dec \ \ Windows Media Audio Files \ wma \ WMA Metadata \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMFPlatDLL(); LoadMFReadWriteDLL(); /* Register initialization and cleanup handlers. */ if (mfplatdll != NIL && mfreadwritedll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::DecoderMediaFoundation::Initialize); engine->onCleanup.Connect(&BoCA::DecoderMediaFoundation::Cleanup); } } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ if (mfplatdll != NIL && mfreadwritedll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::DecoderMediaFoundation::Initialize); engine->onCleanup.Disconnect(&BoCA::DecoderMediaFoundation::Cleanup); } FreeMFPlatDLL(); FreeMFReadWriteDLL(); } Void BoCA::DecoderMediaFoundation::Initialize() { /* Init COM and Media Foundation. */ CoInitialize(NIL); ex_MFStartup(MF_VERSION, MFSTARTUP_FULL); } Void BoCA::DecoderMediaFoundation::Cleanup() { /* Uninit Media Foundation and COM. */ ex_MFShutdown(); CoUninitialize(); } Bool BoCA::DecoderMediaFoundation::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); UnsignedInt64 magic = in.InputNumber(8); return (magic == 0x11CF668E75B22630); } Error BoCA::DecoderMediaFoundation::GetStreamInfo(const String &streamURI, Track &track) { DriverANSI driver(File(streamURI), IS_READ); /* Wrap stream in an IMFByteStream interface and create source reader. */ IMFByteStream *byteStream = new MFByteStream(&driver); HRESULT hr = ex_MFCreateSourceReaderFromByteStream(byteStream, NULL, &reader); byteStream->Release(); if (FAILED(hr)) return Error(); /* Select first audio stream and get input media type. */ IMFMediaType *inputType = NULL; reader->SetStreamSelection(MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE); reader->GetNativeMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &inputType); /* See if this is a lossless file. */ GUID subtype; inputType->GetGUID(MF_MT_SUBTYPE, &subtype); if (subtype == MFAudioFormat_PCM || subtype == MFAudioFormat_Float || subtype == MFAudioFormat_WMAudio_Lossless) track.lossless = True; else track.lossless = False; /* Fill format descriptor with input type. */ WAVEFORMATEX wfx = { }; wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_NUM_CHANNELS, 0); wfx.nSamplesPerSec = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0); wfx.wBitsPerSample = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16); wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; inputType->Release(); /* Create output media type. */ IMFMediaType *outputType = NULL; ex_MFCreateMediaType(&outputType); ex_MFInitMediaTypeFromWaveFormatEx(outputType, &wfx, sizeof(wfx)); /* Set output type and get resulting media type. */ reader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, outputType); reader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediaType); outputType->Release(); /* Fill format from media type. */ Format format = track.GetFormat(); format.rate = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0); format.bits = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16); format.channels = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_NUM_CHANNELS, 0); track.SetFormat(format); mediaType->Release(); /* Get track duration. */ PROPVARIANT duration; if (!FAILED(reader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &duration))) { /* Set approxLength, because WMA duration is not always 100% accurate. */ track.length = -1; track.approxLength = Math::Round(Float(duration.hVal.QuadPart) / 1e7 * format.rate); track.fileSize = driver.GetSize(); } driver.Close(); /* Read tags. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("wma-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } return Success(); } BoCA::DecoderMediaFoundation::DecoderMediaFoundation() { reader = NIL; mediaType = NIL; } BoCA::DecoderMediaFoundation::~DecoderMediaFoundation() { } Bool BoCA::DecoderMediaFoundation::Activate() { /* Wrap stream in an IMFByteStream interface and create source reader. */ IMFByteStream *byteStream = new MFByteStream(driver); HRESULT hr = ex_MFCreateSourceReaderFromByteStream(byteStream, NULL, &reader); byteStream->Release(); if (FAILED(hr)) return False; /* Select first audio stream and get input media type. */ IMFMediaType *inputType = NULL; reader->SetStreamSelection(MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE); reader->GetNativeMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &inputType); /* Fill format descriptor with input type. */ WAVEFORMATEX wfx = { }; wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_NUM_CHANNELS, 0); wfx.nSamplesPerSec = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0); wfx.wBitsPerSample = MFGetAttributeUINT32(inputType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16); wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; inputType->Release(); /* Create output media type. */ IMFMediaType *outputType = NULL; ex_MFCreateMediaType(&outputType); ex_MFInitMediaTypeFromWaveFormatEx(outputType, &wfx, sizeof(wfx)); /* Set output type and get resulting media type. */ reader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, outputType); reader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediaType); outputType->Release(); return True; } Bool BoCA::DecoderMediaFoundation::Deactivate() { mediaType->Release(); reader->Release(); return True; } Bool BoCA::DecoderMediaFoundation::Seek(Int64 samplePosition) { /* Seek to the requested position. */ PROPVARIANT position; InitPropVariantFromInt64(Float(samplePosition) * 1e7 / track.GetFormat().rate, &position); HRESULT hr = reader->SetCurrentPosition(GUID_NULL, position); if (FAILED(hr)) return False; return True; } Int BoCA::DecoderMediaFoundation::ReadData(Buffer &data) { /* Read next sample. */ IMFSample *sample = NULL; DWORD streamFlags = 0; HRESULT hr = reader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &streamFlags, NULL, &sample); if (FAILED(hr)) return -1; if (streamFlags & MF_SOURCE_READERF_ENDOFSTREAM) return -1; /* Copy sample to data buffer. */ IMFMediaBuffer *buffer = NULL; sample->ConvertToContiguousBuffer(&buffer); BYTE *bytes = NULL; DWORD length = 0; buffer->Lock(&bytes, NULL, &length); data.Resize(length); memcpy(data, bytes, length); buffer->Unlock(); buffer->Release(); sample->Release(); /* Update inBytes to indicate progress. */ if (track.approxLength > 0) inBytes += track.fileSize * data.Size() / (track.approxLength * track.GetFormat().channels * (track.GetFormat().bits / 8)); return data.Size(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/mediafoundation.h000066400000000000000000000024531516712004000304470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderMediaFoundation) namespace BoCA { class DecoderMediaFoundation : public CS::DecoderComponent { private: IMFSourceReader *reader; IMFMediaType *mediaType; public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); DecoderMediaFoundation(); ~DecoderMediaFoundation(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderMediaFoundation) BoCA_END_COMPONENT(DecoderMediaFoundation) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/mfbytestream.cpp000066400000000000000000000075411516712004000303410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "mfbytestream.h" using namespace smooth::IO; BoCA::MFByteStream::MFByteStream(Driver *driver) { refCount = 1; this->driver = driver; bytesRead = 0; bytesWritten = 0; } BoCA::MFByteStream::~MFByteStream() { } ULONG STDMETHODCALLTYPE BoCA::MFByteStream::AddRef() { return ++refCount; } ULONG STDMETHODCALLTYPE BoCA::MFByteStream::Release() { if (--refCount == 0) { delete this; return 0; } return refCount; } STDMETHODIMP BoCA::MFByteStream::QueryInterface(REFIID riid, void **ppvObject) { if (riid == IID_IUnknown) *ppvObject = (IUnknown *) this; else if (riid == IID_IMFByteStream) *ppvObject = (IMFByteStream *) this; else return E_NOINTERFACE; AddRef(); return S_OK; } STDMETHODIMP BoCA::MFByteStream::GetCapabilities(DWORD *pdwCapabilities) { *pdwCapabilities = MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_WRITABLE | MFBYTESTREAM_IS_SEEKABLE; return S_OK; } STDMETHODIMP BoCA::MFByteStream::Read(BYTE *pb, ULONG cb, ULONG *pcbRead) { *pcbRead = driver->ReadData(pb, cb); return S_OK; } STDMETHODIMP BoCA::MFByteStream::Write(const BYTE *pb, ULONG cb, ULONG *pcbWritten) { *pcbWritten = driver->WriteData(pb, cb); return S_OK; } STDMETHODIMP BoCA::MFByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, LONGLONG qwSeekOffset, DWORD dwSeekFlags, QWORD *pqwCurrentPosition) { if (SeekOrigin == msoBegin) *pqwCurrentPosition = driver->Seek(qwSeekOffset); else *pqwCurrentPosition = driver->Seek(driver->GetPos() + qwSeekOffset); return S_OK; } STDMETHODIMP BoCA::MFByteStream::GetCurrentPosition(QWORD *pqwPosition) { *pqwPosition = driver->GetPos(); return S_OK; } STDMETHODIMP BoCA::MFByteStream::SetCurrentPosition(QWORD qwPosition) { driver->Seek(qwPosition); return S_OK; } STDMETHODIMP BoCA::MFByteStream::GetLength(QWORD *pqwLength) { *pqwLength = driver->GetSize(); return S_OK; } STDMETHODIMP BoCA::MFByteStream::SetLength(QWORD qwLength) { if (!driver->Truncate(qwLength)) return E_FAIL; return S_OK; } STDMETHODIMP BoCA::MFByteStream::IsEndOfStream(BOOL *pfEndOfStream) { Int64 position = driver->GetPos(); Int64 size = driver->GetSize(); *pfEndOfStream = (position >= size); return S_OK; } STDMETHODIMP BoCA::MFByteStream::Flush() { if (!driver->Flush()) return E_FAIL; return S_OK; } STDMETHODIMP BoCA::MFByteStream::Close() { if (!driver->Close()) return E_FAIL; return S_OK; } STDMETHODIMP BoCA::MFByteStream::BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, IUnknown *punkState) { bytesRead = driver->ReadData(pb, cb); IMFAsyncResult *asyncResult = NULL; ex_MFCreateAsyncResult(NULL, pCallback, punkState, &asyncResult); ex_MFInvokeCallback(asyncResult); asyncResult->Release(); return S_OK; } STDMETHODIMP BoCA::MFByteStream::EndRead(IMFAsyncResult *pResult, ULONG *pcbRead) { *pcbRead = bytesRead; return S_OK; } STDMETHODIMP BoCA::MFByteStream::BeginWrite(const BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, IUnknown *punkState) { bytesWritten = driver->WriteData(pb, cb); IMFAsyncResult *asyncResult = NULL; ex_MFCreateAsyncResult(NULL, pCallback, punkState, &asyncResult); ex_MFInvokeCallback(asyncResult); asyncResult->Release(); return S_OK; } STDMETHODIMP BoCA::MFByteStream::EndWrite(IMFAsyncResult *pResult, ULONG *pcbWritten) { *pcbWritten = bytesWritten; return S_OK; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mediafoundation/mfbytestream.h000066400000000000000000000036201516712004000300000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BOCA_MFBYTESTREAM #define H_BOCA_MFBYTESTREAM #include #include "dllinterface.h" using namespace smooth; namespace BoCA { class MFByteStream: public IMFByteStream { private: ULONG refCount; IO::Driver *driver; ULONG bytesRead; ULONG bytesWritten; public: MFByteStream(IO::Driver *); virtual ~MFByteStream(); /* IUnknown methods. */ ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); STDMETHOD (QueryInterface)(REFIID, void **); /* IMFByteStream methods. */ STDMETHOD (GetCapabilities)(DWORD *); STDMETHOD (Read)(BYTE *, ULONG, ULONG *); STDMETHOD (Write)(const BYTE *, ULONG, ULONG *); STDMETHOD (Seek)(MFBYTESTREAM_SEEK_ORIGIN, LONGLONG, DWORD, QWORD *); STDMETHOD (GetCurrentPosition)(QWORD *); STDMETHOD (SetCurrentPosition)(QWORD); STDMETHOD (GetLength)(QWORD *); STDMETHOD (SetLength)(QWORD); STDMETHOD (IsEndOfStream)(BOOL *); STDMETHOD (Flush)(); STDMETHOD (Close)(); STDMETHOD (BeginRead)(BYTE *, ULONG, IMFAsyncCallback *, IUnknown *); STDMETHOD (EndRead)(IMFAsyncResult * pResult, ULONG * pcbRead); STDMETHOD (BeginWrite)(const BYTE *, ULONG, IMFAsyncCallback *, IUnknown *); STDMETHOD (EndWrite)(IMFAsyncResult *, ULONG *); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/000077500000000000000000000000001516712004000227675ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/Makefile000066400000000000000000000015621516712004000244330ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mpg123 TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = ../../shared/mp3frame.o ../../shared/vbrtag.o config.o dllinterface.o mpg123.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter additional commands for targets all and clean here: ifneq ("$(SRCDIR)","$(CURDIR)") ALLCMD1 = mkdir -p ../../shared ALLCMD2 = CLEANCMD1 = rmdir ../../shared || true CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = endif ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/config.cpp000066400000000000000000000042131516712004000247400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureMPG123::ConfigID = "mpg123"; BoCA::ConfigureMPG123::ConfigureMPG123() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Decoders::mpg123"); String selectedDecoder = config->GetStringValue(ConfigID, "Decoder", NIL); group_decoding = new GroupBox(i18n->TranslateString("Decoder"), Point(7, 11), Size(286, 41)); text_decoder = new Text(i18n->AddColon(i18n->TranslateString("Active decoder")), Point(10, 15)); combo_decoder = new ComboBox(Point(17 + text_decoder->GetUnscaledTextWidth(), 12), Size(259 - text_decoder->GetUnscaledTextWidth(), 0)); combo_decoder->AddEntry(i18n->TranslateString("auto select")); const char **decoders = ex_mpg123_supported_decoders(); for (Int i = 0; decoders[i] != NIL; i++) combo_decoder->AddEntry(decoders[i]); if (selectedDecoder != NIL) combo_decoder->SelectEntry(selectedDecoder); else combo_decoder->SelectNthEntry(0); group_decoding->Add(text_decoder); group_decoding->Add(combo_decoder); Add(group_decoding); SetSize(Size(300, 169)); } BoCA::ConfigureMPG123::~ConfigureMPG123() { DeleteObject(group_decoding); DeleteObject(text_decoder); DeleteObject(combo_decoder); } Int BoCA::ConfigureMPG123::SaveSettings() { Config *config = Config::Get(); String selectedDecoder = combo_decoder->GetSelectedEntry()->GetText(); if (combo_decoder->GetSelectedEntryNumber() == 0) config->SetStringValue(ConfigID, "Decoder", NIL); else config->SetStringValue(ConfigID, "Decoder", selectedDecoder); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/config.h000066400000000000000000000020221516712004000244010ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_MPG123CONFIG #define H_MPG123CONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureMPG123 : public ConfigLayer { private: GroupBox *group_decoding; Text *text_decoder; ComboBox *combo_decoder; public: static const String ConfigID; ConfigureMPG123(); ~ConfigureMPG123(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/dllinterface.cpp000066400000000000000000000064311516712004000261330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; MPG123_INIT ex_mpg123_init = NIL; MPG123_EXIT ex_mpg123_exit = NIL; MPG123_NEW ex_mpg123_new = NIL; MPG123_DELETE ex_mpg123_delete = NIL; MPG123_OPEN_FEED ex_mpg123_open_feed = NIL; MPG123_DECODE ex_mpg123_decode = NIL; MPG123_FEED ex_mpg123_feed = NIL; MPG123_FEEDSEEK ex_mpg123_feedseek = NIL; MPG123_GETFORMAT ex_mpg123_getformat = NIL; MPG123_INFO ex_mpg123_info = NIL; MPG123_SPF ex_mpg123_spf = NIL; MPG123_SUPPORTED_DECODERS ex_mpg123_supported_decoders = NIL; MPG123_DECODER ex_mpg123_decoder = NIL; MPG123_DISTVERSION ex_mpg123_distversion = NIL; DynamicLoader *mpg123dll = NIL; Bool LoadMPG123DLL() { mpg123dll = BoCA::Utilities::LoadCodecDLL("mpg123"); if (mpg123dll == NIL) return False; ex_mpg123_init = (MPG123_INIT) mpg123dll->GetFunctionAddress("mpg123_init"); ex_mpg123_exit = (MPG123_EXIT) mpg123dll->GetFunctionAddress("mpg123_exit"); ex_mpg123_new = (MPG123_NEW) mpg123dll->GetFunctionAddress("mpg123_new"); ex_mpg123_delete = (MPG123_DELETE) mpg123dll->GetFunctionAddress("mpg123_delete"); ex_mpg123_open_feed = (MPG123_OPEN_FEED) mpg123dll->GetFunctionAddress("mpg123_open_feed"); ex_mpg123_decode = (MPG123_DECODE) mpg123dll->GetFunctionAddress("mpg123_decode"); ex_mpg123_feed = (MPG123_FEED) mpg123dll->GetFunctionAddress("mpg123_feed"); ex_mpg123_feedseek = (MPG123_FEEDSEEK) mpg123dll->GetFunctionAddress("mpg123_feedseek"); ex_mpg123_getformat = (MPG123_GETFORMAT) mpg123dll->GetFunctionAddress("mpg123_getformat"); ex_mpg123_info = (MPG123_INFO) mpg123dll->GetFunctionAddress("mpg123_info2"); if (ex_mpg123_info == NIL) ex_mpg123_info = (MPG123_INFO) mpg123dll->GetFunctionAddress("mpg123_info"); ex_mpg123_spf = (MPG123_SPF) mpg123dll->GetFunctionAddress("mpg123_spf"); ex_mpg123_supported_decoders = (MPG123_SUPPORTED_DECODERS) mpg123dll->GetFunctionAddress("mpg123_supported_decoders"); ex_mpg123_decoder = (MPG123_DECODER) mpg123dll->GetFunctionAddress("mpg123_decoder"); ex_mpg123_distversion = (MPG123_DISTVERSION) mpg123dll->GetFunctionAddress("mpg123_distversion"); if (ex_mpg123_init == NIL || ex_mpg123_exit == NIL || ex_mpg123_new == NIL || ex_mpg123_delete == NIL || ex_mpg123_open_feed == NIL || ex_mpg123_decode == NIL || ex_mpg123_feed == NIL || ex_mpg123_feedseek == NIL || ex_mpg123_getformat == NIL || ex_mpg123_info == NIL || ex_mpg123_spf == NIL || ex_mpg123_supported_decoders == NIL || ex_mpg123_decoder == NIL) { FreeMPG123DLL(); return False; } return True; } Void FreeMPG123DLL() { BoCA::Utilities::FreeCodecDLL(mpg123dll); mpg123dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/dllinterface.h000066400000000000000000000044371516712004000256040ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef _MSC_VER typedef int ssize_t; #endif #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *mpg123dll; Bool LoadMPG123DLL(); Void FreeMPG123DLL(); typedef int (*MPG123_INIT) (); typedef void (*MPG123_EXIT) (); typedef mpg123_handle * (*MPG123_NEW) (const char *, int *); typedef void (*MPG123_DELETE) (mpg123_handle *); typedef int (*MPG123_OPEN_FEED) (mpg123_handle *); typedef int (*MPG123_DECODE) (mpg123_handle *, const unsigned char *, size_t, void *, size_t, size_t *); typedef int (*MPG123_FEED) (mpg123_handle *, const unsigned char *, size_t); typedef off_t (*MPG123_FEEDSEEK) (mpg123_handle *, off_t, int, off_t *); typedef int (*MPG123_GETFORMAT) (mpg123_handle *, long *, int *, int *); typedef int (*MPG123_INFO) (mpg123_handle *, mpg123_frameinfo *); typedef int (*MPG123_SPF) (mpg123_handle *); typedef const char ** (*MPG123_SUPPORTED_DECODERS) (); typedef int (*MPG123_DECODER) (mpg123_handle *, const char *); typedef const char * (*MPG123_DISTVERSION) (unsigned int *, unsigned int *, unsigned int *); extern MPG123_INIT ex_mpg123_init; extern MPG123_EXIT ex_mpg123_exit; extern MPG123_NEW ex_mpg123_new; extern MPG123_DELETE ex_mpg123_delete; extern MPG123_OPEN_FEED ex_mpg123_open_feed; extern MPG123_DECODE ex_mpg123_decode; extern MPG123_FEED ex_mpg123_feed; extern MPG123_FEEDSEEK ex_mpg123_feedseek; extern MPG123_GETFORMAT ex_mpg123_getformat; extern MPG123_INFO ex_mpg123_info; extern MPG123_SPF ex_mpg123_spf; extern MPG123_SUPPORTED_DECODERS ex_mpg123_supported_decoders; extern MPG123_DECODER ex_mpg123_decoder; extern MPG123_DISTVERSION ex_mpg123_distversion; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/mpg123.cpp000066400000000000000000000212621516712004000245070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "mpg123.h" #include "config.h" #include "../../shared/mp3frame.h" #include "../../shared/vbrtag.h" using namespace smooth::IO; const String &BoCA::DecoderMPG123::GetComponentSpecs() { static String componentSpecs; if (mpg123dll != NIL) { componentSpecs = " \ \ \ \ mpg123 Decoder %VERSION% \ 1.0 \ mpg123-dec \ decoder \ lame-dec \ mad-dec \ \ MPEG Audio Files \ mp1 \ mp2 \ mp3 \ ID3v1 \ ID3v2 \ \ \ \ "; if (ex_mpg123_distversion != NIL) componentSpecs.Replace("%VERSION%", String("v").Append(ex_mpg123_distversion(NIL, NIL, NIL))); else componentSpecs.Replace(" %VERSION%", String()); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMPG123DLL(); if (mpg123dll != NIL && ex_mpg123_init() != MPG123_OK) { FreeMPG123DLL(); } } Void smooth::DetachDLL() { if (mpg123dll == NIL) return; ex_mpg123_exit(); FreeMPG123DLL(); } Bool BoCA::DecoderMPG123::CanOpenStream(const String &streamURI) { String lcURI = streamURI.ToLower(); return lcURI.EndsWith(".mp1") || lcURI.EndsWith(".mp2") || lcURI.EndsWith(".mp3"); } Error BoCA::DecoderMPG123::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); Format format = track.GetFormat(); track.fileSize = in.Size(); track.length = -1; SkipID3v2Tag(in); ParseVBRHeaders(in); Buffer buffer(4096); mpg123_handle *context = ex_mpg123_new(NIL, NIL); Int offset = in.GetPos(); ex_mpg123_open_feed(context); do { Int bytes = Math::Min((Int64) buffer.Size(), in.Size() - in.GetPos()); in.InputData((void *) buffer, bytes); int result = ex_mpg123_decode(context, buffer, bytes, NIL, 0, NIL); if (result == MPG123_NEW_FORMAT) { long rate = 0; int channels = 0; int enc = MPG123_ENC_ANY; ex_mpg123_getformat(context, &rate, &channels, &enc); format.channels = channels; format.rate = rate; if (enc & MPG123_ENC_8) format.bits = 8; else if (enc & MPG123_ENC_16) format.bits = 16; else if (enc & MPG123_ENC_24) format.bits = 24; else if (enc & MPG123_ENC_32) format.bits = 32; mpg123_frameinfo mp3data; ex_mpg123_info(context, &mp3data); if (numFrames > 0) track.length = numFrames * ex_mpg123_spf(context) - delaySamples - padSamples; else if (mp3data.bitrate > 0) track.approxLength = (track.fileSize - offset) / (mp3data.bitrate * 1000 / 8) * format.rate; break; } } while (in.GetPos() < in.Size()); ex_mpg123_delete(context); if (format == Format()) { errorState = True; errorString = "Invalid file format"; } track.SetFormat(format); in.Close(); if (!errorState) { Bool foundTag = False; AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); if (tagger->ParseStreamInfo(streamURI, track) == Success()) foundTag = True; boca.DeleteComponent(tagger); } if (!foundTag) { tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } } if (errorState) return Error(); else return Success(); } BoCA::DecoderMPG123::DecoderMPG123() { configLayer = NIL; context = 0; numBytes = 0; numFrames = 0; delaySamples = 0; padSamples = 0; dataOffset = 0; /* Initialize to decoder delay. */ delaySamplesLeft = 529; } BoCA::DecoderMPG123::~DecoderMPG123() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderMPG123::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); String selectedDecoder = config->GetStringValue(ConfigureMPG123::ConfigID, "Decoder", NIL); /* Skip headers and get data offset. */ InStream in(STREAM_DRIVER, driver); SkipID3v2Tag(in); ParseVBRHeaders(in); dataOffset = in.GetPos(); driver->Seek(dataOffset); /* Create decoder. */ context = ex_mpg123_new(NIL, NIL); if (selectedDecoder != NIL) ex_mpg123_decoder(context, selectedDecoder); ex_mpg123_open_feed(context); return True; } Bool BoCA::DecoderMPG123::Deactivate() { ex_mpg123_delete(context); return True; } Bool BoCA::DecoderMPG123::Seek(Int64 samplePosition) { Buffer data(131072); off_t target = 0; while (ex_mpg123_feedseek(context, samplePosition, SEEK_SET, &target) == MPG123_NEED_MORE) { Int64 size = driver->ReadData(data, data.Size()); if (size == 0) break; ex_mpg123_feed(context, data, size); } driver->Seek(dataOffset + target); return True; } Int BoCA::DecoderMPG123::ReadData(Buffer &data) { /* Read input data. */ Int size = driver->ReadData(data, data.Size()); if (size <= 0) return -1; inBytes += size; /* Decode samples. */ const Format &format = track.GetFormat(); size_t samplesDone = 0; samples.Resize(size * 48); if (ex_mpg123_decode(context, data, size, samples, samples.Size(), &samplesDone) == MPG123_NEW_FORMAT) { /* Call mpg123_decode again after MPG123_NEW_FORMAT to get decoded data. */ ex_mpg123_decode(context, NIL, 0, samples, samples.Size(), &samplesDone); } data.Resize(0); samplesDone = samplesDone / format.channels / (format.bits / 8); if (samplesDone > (unsigned) delaySamplesLeft) { data.Resize((samplesDone - delaySamplesLeft) * format.channels * (format.bits / 8)); memcpy(data, samples + (delaySamplesLeft * format.channels * (format.bits / 8)), data.Size()); } delaySamplesLeft = Math::Max(0, delaySamplesLeft - samplesDone); return data.Size(); } Bool BoCA::DecoderMPG123::SkipID3v2Tag(InStream &in) { /* Check for an ID3v2 tag at the beginning of the * file and skip it if it exists as it might cause * problems if the tag is unsynchronized. */ if (in.InputString(3) == "ID3") { in.InputNumber(2); // ID3 version in.InputNumber(1); // Flags /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.RelSeek(tagSize); inBytes += (tagSize + 10); } else { in.Seek(0); } return True; } Bool BoCA::DecoderMPG123::ParseVBRHeaders(InStream &in) { /* Read MPEG header and get frame size. */ Buffer header(3); in.InputData(header, 3); in.RelSeek(-3); Int frameSize = MP3Frame::GetMPEGFrameSize(header); if (frameSize < 156) return False; /* Read frame. */ Buffer buffer(frameSize); in.InputData(buffer, frameSize); /* Check for a Xing or VBRI header and extract the number of frames. */ VbrTag vbrTag; if (vbrTag.Parse(buffer)) { if (vbrTag.flags & VbrTag::FLAG_BYTES) numBytes = vbrTag.bytes - frameSize; if (vbrTag.flags & VbrTag::FLAG_FRAMES) numFrames = vbrTag.frames; if (vbrTag.flags & VbrTag::FLAG_GAPLESS) { delaySamples = vbrTag.delay; padSamples = vbrTag.padding; delaySamplesLeft += delaySamples; } } else { /* Seek back to before the frame if no Xing or VBRI header was found. */ in.RelSeek(-frameSize); return False; } /* Sanity check for header vs. actual file size (account * for possible ID3v1 and addtional 4kB of other tags). */ if (numBytes > 0 && in.Size() - in.GetPos() > numBytes * 1.01 + 128 + 4096) { numFrames = 0; padSamples = 0; } return True; } ConfigLayer *BoCA::DecoderMPG123::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureMPG123(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/mpg123/mpg123.h000066400000000000000000000027601516712004000241560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderMPG123) namespace BoCA { class DecoderMPG123 : public CS::DecoderComponent { private: ConfigLayer *configLayer; mpg123_handle *context; Buffer samples; Int64 numBytes; Int64 numFrames; Int delaySamples; Int padSamples; Int delaySamplesLeft; Int dataOffset; Bool SkipID3v2Tag(IO::InStream &); Bool ParseVBRHeaders(IO::InStream &); public: static const String &GetComponentSpecs(); DecoderMPG123(); ~DecoderMPG123(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderMPG123) BoCA_END_COMPONENT(DecoderMPG123) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/000077500000000000000000000000001516712004000227445ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/Makefile000066400000000000000000000012231516712004000244020ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = opus TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o opus.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/config.cpp000066400000000000000000000067761516712004000247350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureOpus::ConfigID = "OpusDecoder"; BoCA::ConfigureOpus::ConfigureOpus(Bool iOsceSupported, Bool iBweSupported) { osceSupported = iOsceSupported; bweSupported = iBweSupported; const Config *config = Config::Get(); complexity = config->GetIntValue(ConfigID, "Complexity", 10); enableBwe = bweSupported && config->GetIntValue(ConfigID, "BandwidthExtension", False); I18n *i18n = I18n::Get(); i18n->SetContext("Decoders::Opus"); group_format = new GroupBox(i18n->TranslateString("Format"), Point(7, 11), Size(286, 40)); text_format = new Text(i18n->AddColon(i18n->TranslateString("Sample format")), Point(10, 14)); combo_format = new ComboBox(Point(text_format->GetX() + text_format->GetUnscaledTextWidth() + 7, 11), Size(259 - text_format->GetUnscaledTextWidth(), 0)); combo_format->AddEntry(i18n->TranslateString("16 bit integer")); combo_format->AddEntry(i18n->TranslateString("32 bit float")); combo_format->SelectNthEntry(config->GetIntValue(ConfigID, "DecodeFloat", False)); group_format->Add(text_format); group_format->Add(combo_format); Add(group_format); if (osceSupported) { group_quality = new GroupBox(i18n->TranslateString("Quality"), Point(7, 62), Size(286, 64)); text_complexity = new Text(i18n->AddColon(i18n->TranslateString("Complexity")), Point(10, 14)); slider_complexity = new Slider(Point(17 + text_complexity->GetUnscaledTextWidth(), 12), Size(240 - text_complexity->GetUnscaledTextWidth(), 0), OR_HORZ, &complexity, 0, 10); slider_complexity->onValueChange.Connect(&ConfigureOpus::SetComplexity, this); text_complexity_value = new Text(NIL, Point(264, 14)); check_enable_bwe = new CheckBox(i18n->TranslateString("Enable Speech Bandwidth Extension"), Point(10, text_complexity->GetY() + 23), Size(266, 0), &enableBwe); group_quality->Add(text_complexity); group_quality->Add(slider_complexity); group_quality->Add(text_complexity_value); group_quality->Add(check_enable_bwe); SetComplexity(); Add(group_quality); } SetSize(Size(300, 58 + (osceSupported ? 75 : 0))); } BoCA::ConfigureOpus::~ConfigureOpus() { DeleteObject(group_format); DeleteObject(text_format); DeleteObject(combo_format); if (osceSupported) { DeleteObject(group_quality); DeleteObject(text_complexity); DeleteObject(slider_complexity); DeleteObject(text_complexity_value); DeleteObject(check_enable_bwe); } } Int BoCA::ConfigureOpus::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "DecodeFloat", combo_format->GetSelectedEntryNumber()); if (osceSupported) config->SetIntValue(ConfigID, "Complexity", complexity); if (bweSupported) config->SetIntValue(ConfigID, "BandwidthExtension", enableBwe); return Success(); } Void BoCA::ConfigureOpus::SetComplexity() { text_complexity_value->SetText(String::FromInt(complexity)); if (bweSupported && complexity >= 4) check_enable_bwe->Activate(); else check_enable_bwe->Deactivate(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/config.h000066400000000000000000000024601516712004000243640ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_OPUSCONFIG #define H_OPUSCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureOpus : public ConfigLayer { private: Bool osceSupported; Bool bweSupported; GroupBox *group_format; Text *text_format; ComboBox *combo_format; GroupBox *group_quality; Text *text_complexity; Slider *slider_complexity; Text *text_complexity_value; CheckBox *check_enable_bwe; Int complexity; Bool enableBwe; slots: Void SetComplexity(); public: static const String ConfigID; ConfigureOpus(Bool, Bool); ~ConfigureOpus(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/dllinterface.cpp000066400000000000000000000126221516712004000261070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETOUT ex_ogg_stream_packetout = NIL; OGGSTREAMPAGEIN ex_ogg_stream_pagein = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGPAGESERIALNO ex_ogg_page_serialno = NIL; OGGPAGEGRANULEPOS ex_ogg_page_granulepos = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OGGSYNCINIT ex_ogg_sync_init = NIL; OGGSYNCBUFFER ex_ogg_sync_buffer = NIL; OGGSYNCWROTE ex_ogg_sync_wrote = NIL; OGGSYNCPAGEOUT ex_ogg_sync_pageout = NIL; OGGSYNCPAGESEEK ex_ogg_sync_pageseek = NIL; OGGSYNCRESET ex_ogg_sync_reset = NIL; OGGSYNCCLEAR ex_ogg_sync_clear = NIL; OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create = NIL; OPUSMULTISTREAMDECODE ex_opus_multistream_decode = NIL; OPUSMULTISTREAMDECODEFLOAT ex_opus_multistream_decode_float = NIL; OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl = NIL; OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy = NIL; OPUSDECODERCREATE ex_opus_decoder_create = NIL; OPUSDECODERCTL ex_opus_decoder_ctl = NIL; OPUSDECODERDESTROY ex_opus_decoder_destroy = NIL; OPUSGETVERSIONSTRING ex_opus_get_version_string = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *opusdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetout = (OGGSTREAMPACKETOUT) oggdll->GetFunctionAddress("ogg_stream_packetout"); ex_ogg_stream_pagein = (OGGSTREAMPAGEIN) oggdll->GetFunctionAddress("ogg_stream_pagein"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_page_serialno = (OGGPAGESERIALNO) oggdll->GetFunctionAddress("ogg_page_serialno"); ex_ogg_page_granulepos = (OGGPAGEGRANULEPOS) oggdll->GetFunctionAddress("ogg_page_granulepos"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); ex_ogg_sync_init = (OGGSYNCINIT) oggdll->GetFunctionAddress("ogg_sync_init"); ex_ogg_sync_buffer = (OGGSYNCBUFFER) oggdll->GetFunctionAddress("ogg_sync_buffer"); ex_ogg_sync_wrote = (OGGSYNCWROTE) oggdll->GetFunctionAddress("ogg_sync_wrote"); ex_ogg_sync_pageout = (OGGSYNCPAGEOUT) oggdll->GetFunctionAddress("ogg_sync_pageout"); ex_ogg_sync_pageseek = (OGGSYNCPAGESEEK) oggdll->GetFunctionAddress("ogg_sync_pageseek"); ex_ogg_sync_reset = (OGGSYNCRESET) oggdll->GetFunctionAddress("ogg_sync_reset"); ex_ogg_sync_clear = (OGGSYNCCLEAR) oggdll->GetFunctionAddress("ogg_sync_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetout == NIL || ex_ogg_stream_pagein == NIL || ex_ogg_page_eos == NIL || ex_ogg_page_serialno == NIL || ex_ogg_page_granulepos == NIL || ex_ogg_stream_clear == NIL || ex_ogg_sync_init == NIL || ex_ogg_sync_buffer == NIL || ex_ogg_sync_wrote == NIL || ex_ogg_sync_pageout == NIL || ex_ogg_sync_pageseek == NIL || ex_ogg_sync_reset == NIL || ex_ogg_sync_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadOpusDLL() { opusdll = BoCA::Utilities::LoadCodecDLL("opus"); if (opusdll == NIL) return False; ex_opus_multistream_decoder_create = (OPUSMULTISTREAMDECODERCREATE) opusdll->GetFunctionAddress("opus_multistream_decoder_create"); ex_opus_multistream_decode = (OPUSMULTISTREAMDECODE) opusdll->GetFunctionAddress("opus_multistream_decode"); ex_opus_multistream_decode_float = (OPUSMULTISTREAMDECODEFLOAT) opusdll->GetFunctionAddress("opus_multistream_decode_float"); ex_opus_multistream_decoder_ctl = (OPUSMULTISTREAMDECODERCTL) opusdll->GetFunctionAddress("opus_multistream_decoder_ctl"); ex_opus_multistream_decoder_destroy = (OPUSMULTISTREAMDECODERDESTROY) opusdll->GetFunctionAddress("opus_multistream_decoder_destroy"); ex_opus_decoder_create = (OPUSDECODERCREATE) opusdll->GetFunctionAddress("opus_decoder_create"); ex_opus_decoder_ctl = (OPUSDECODERCTL) opusdll->GetFunctionAddress("opus_decoder_ctl"); ex_opus_decoder_destroy = (OPUSDECODERDESTROY) opusdll->GetFunctionAddress("opus_decoder_destroy"); ex_opus_get_version_string = (OPUSGETVERSIONSTRING) opusdll->GetFunctionAddress("opus_get_version_string"); if (ex_opus_multistream_decoder_create == NIL || ex_opus_multistream_decode == NIL || ex_opus_multistream_decode_float == NIL || ex_opus_multistream_decoder_ctl == NIL || ex_opus_multistream_decoder_destroy == NIL || ex_opus_decoder_create == NIL || ex_opus_decoder_ctl == NIL || ex_opus_decoder_destroy == NIL || ex_opus_get_version_string == NIL) { FreeOpusDLL(); return False; } return True; } Void FreeOpusDLL() { BoCA::Utilities::FreeCodecDLL(opusdll); opusdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/dllinterface.h000066400000000000000000000070731516712004000255600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *opusdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadOpusDLL(); Void FreeOpusDLL(); typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETOUT) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMPAGEIN) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGPAGESERIALNO) (ogg_page *); typedef ogg_int64_t (*OGGPAGEGRANULEPOS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); typedef int (*OGGSYNCINIT) (ogg_sync_state *); typedef char * (*OGGSYNCBUFFER) (ogg_sync_state *, int); typedef int (*OGGSYNCWROTE) (ogg_sync_state *, int); typedef int (*OGGSYNCPAGEOUT) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCPAGESEEK) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCRESET) (ogg_sync_state *); typedef int (*OGGSYNCCLEAR) (ogg_sync_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETOUT ex_ogg_stream_packetout; extern OGGSTREAMPAGEIN ex_ogg_stream_pagein; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGPAGESERIALNO ex_ogg_page_serialno; extern OGGPAGEGRANULEPOS ex_ogg_page_granulepos; extern OGGSTREAMCLEAR ex_ogg_stream_clear; extern OGGSYNCINIT ex_ogg_sync_init; extern OGGSYNCBUFFER ex_ogg_sync_buffer; extern OGGSYNCWROTE ex_ogg_sync_wrote; extern OGGSYNCPAGEOUT ex_ogg_sync_pageout; extern OGGSYNCPAGESEEK ex_ogg_sync_pageseek; extern OGGSYNCRESET ex_ogg_sync_reset; extern OGGSYNCCLEAR ex_ogg_sync_clear; typedef OpusMSDecoder * (*OPUSMULTISTREAMDECODERCREATE) (opus_int32, int, int, int, const unsigned char *, int *); typedef int (*OPUSMULTISTREAMDECODE) (OpusMSDecoder *, const unsigned char *, opus_int32, opus_int16 *, int, int); typedef int (*OPUSMULTISTREAMDECODEFLOAT) (OpusMSDecoder *, const unsigned char *, opus_int32, float *, int, int); typedef int (*OPUSMULTISTREAMDECODERCTL) (OpusMSDecoder *, int, ...); typedef void (*OPUSMULTISTREAMDECODERDESTROY) (OpusMSDecoder *); typedef OpusDecoder * (*OPUSDECODERCREATE) (opus_int32, int, int *); typedef int (*OPUSDECODERCTL) (OpusDecoder *, int, ...); typedef void (*OPUSDECODERDESTROY) (OpusDecoder *); typedef const char * (*OPUSGETVERSIONSTRING) (); extern OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create; extern OPUSMULTISTREAMDECODE ex_opus_multistream_decode; extern OPUSMULTISTREAMDECODEFLOAT ex_opus_multistream_decode_float; extern OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl; extern OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy; extern OPUSDECODERCREATE ex_opus_decoder_create; extern OPUSDECODERCTL ex_opus_decoder_ctl; extern OPUSDECODERDESTROY ex_opus_decoder_destroy; extern OPUSGETVERSIONSTRING ex_opus_get_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/opus.cpp000066400000000000000000000363641516712004000244520ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "opus.h" #include "config.h" using namespace smooth::IO; static Bool osceSupported = False; static Bool bweSupported = False; const String &BoCA::DecoderOpus::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && opusdll != NIL) { componentSpecs = " \ \ \ \ Opus Audio Decoder %VERSION% \ 1.0 \ opus-dec \ decoder \ \ Opus Audio \ opus \ ogg \ oga \ Vorbis Comment \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_opus_get_version_string()).Replace("libopus ", NIL))); /* Check availability of Opus Speech Coding Enhancement (OSCE). */ const Array &version = String(ex_opus_get_version_string()).Replace("libopus ", NIL).Explode("."); if (version.GetNth(0).ToInt() > 1 || (version.GetNth(0).ToInt() == 1 && version.GetNth(1).ToInt() >= 5)) osceSupported = True; if (version.GetNth(0).ToInt() > 1 || (version.GetNth(0).ToInt() == 1 && version.GetNth(1).ToInt() >= 6)) { int error = OPUS_OK; OpusDecoder *decoder = ex_opus_decoder_create(48000, 2, &error); if (error == OPUS_OK) { if (ex_opus_decoder_ctl(decoder, OPUS_SET_OSCE_BWE(1)) == OPUS_OK) bweSupported = True; ex_opus_decoder_destroy(decoder); } } } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadOpusDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeOpusDLL(); } namespace BoCA { /* Constants. */ const Int maxFrameSize = 5760; /* Opus header definition. */ struct OpusHeader { char codec_id[8]; /**< MUST be "OpusHead" */ uint8_t version_id; /**< Version number */ uint8_t nb_channels; /**< Number of channels */ uint16_t preskip; /**< Pre-skip */ uint32_t sample_rate; /**< Input sample rate; informational only */ int16_t output_gain; /**< Output gain to apply when decoding */ uint8_t channel_mapping; /**< Channel mapping family */ uint8_t nb_streams; /**< Stream count */ uint8_t nb_coupled; /**< Two-channel stream count */ uint8_t stream_map[255]; /**< Channel mapping */ }; }; Bool BoCA::DecoderOpus::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) != "OggS") return False; in.Seek(0); /* Check if Opus stream. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); Bool result = False; Bool initialized = False; do { Int size = Math::Min(Int64(4096), in.Size() - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); if (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; ex_ogg_stream_pagein(&os, &og); if (ex_ogg_stream_packetout(&os, &op) == 1) { if (op.packet[0] == 'O' && op.packet[1] == 'p' && op.packet[2] == 'u' && op.packet[3] == 's' && op.packet[4] == 'H' && op.packet[5] == 'e' && op.packet[6] == 'a' && op.packet[7] == 'd') { /* Check Opus version and number of channels. */ OpusHeader *setup = (OpusHeader *) op.packet; if (setup->version_id >> 4 == 0 && setup->channel_mapping <= 1 && setup->nb_channels <= 8) result = True; } break; } } } while (in.GetPos() < in.Size()); if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return result; } Error BoCA::DecoderOpus::GetStreamInfo(const String &streamURI, Track &track) { static Endianness endianness = CPU().GetEndianness(); /* Get configuration. */ const Config *config = GetConfiguration(); Bool decodeFloat = config->GetIntValue(ConfigureOpus::ConfigID, "DecodeFloat", False); Int complexity = config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10); Bool enableBwe = config->GetIntValue(ConfigureOpus::ConfigID, "BandwidthExtension", False); /* Open file. */ InStream in(STREAM_FILE, streamURI, IS_READ); /* Set up track format. */ Format format; format.bits = 16; format.rate = 48000; if (decodeFloat) { format.bits = 32; format.fp = True; } track.fileSize = in.Size(); /* Set up Ogg reader. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); /* Get stream format. */ OpusHeader setup; Buffer comments; Bool initialized = False; Bool done = False; Int packetNum = 0; do { Int size = Math::Min(Int64(4096), track.fileSize - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { /* Found header packet. */ if (packetNum == 0) { memcpy(&setup, op.packet, sizeof(OpusHeader)); if (endianness != EndianLittle) { BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.preskip, sizeof(setup.preskip)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.sample_rate, sizeof(setup.sample_rate)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.output_gain, sizeof(setup.output_gain)); } format.channels = setup.nb_channels; if (setup.sample_rate != 0 && (!bweSupported || complexity < 4 || !enableBwe)) { if (setup.sample_rate <= 8000) format.rate = 8000; else if (setup.sample_rate <= 12000) format.rate = 12000; else if (setup.sample_rate <= 16000) format.rate = 16000; else if (setup.sample_rate <= 24000) format.rate = 24000; else format.rate = 48000; } preSkip = setup.preskip; track.length = -1; } /* Found Vorbis Comment packet. */ if (packetNum == 1) { if (op.packet[0] == 'O' && op.packet[1] == 'p' && op.packet[2] == 'u' && op.packet[3] == 's' && op.packet[4] == 'T' && op.packet[5] == 'a' && op.packet[6] == 'g' && op.packet[7] == 's') { comments.Resize(op.bytes - 8); memcpy(comments, op.packet + 8, op.bytes - 8); } } /* Found audio packet. */ if (packetNum == 3) { int error = OPUS_OK; unsigned char mapping[2] = { 0, 1 }; OpusMSDecoder *decoder = NIL; if (setup.channel_mapping == 0) decoder = ex_opus_multistream_decoder_create(format.rate, setup.nb_channels, 1, setup.nb_channels - 1, mapping, &error); else decoder = ex_opus_multistream_decoder_create(format.rate, setup.nb_channels, setup.nb_streams, setup.nb_coupled, setup.stream_map, &error); if (error == OPUS_OK) { Buffer samples(maxFrameSize * format.channels); track.approxLength = track.fileSize / (op.bytes * 1.05) * ex_opus_multistream_decode(decoder, op.packet, op.bytes, samples, maxFrameSize, 0); ex_opus_multistream_decoder_destroy(decoder); } } /* Done if we reached packet three. */ if (packetNum >= 3) done = True; packetNum++; } } if (done) break; } while (in.GetPos() < in.Size()); track.SetFormat(format); /* Find real length of stream. */ ex_ogg_sync_reset(&oy); Int size = Math::Min(in.Size(), 65536); char *buffer = ex_ogg_sync_buffer(&oy, size); in.Seek(in.Size() - size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (true) { Int seek = ex_ogg_sync_pageseek(&oy, &og); if (seek == 0) break; if (seek < 0 || ex_ogg_page_serialno(&og) != os.serialno) continue; track.length = (ex_ogg_page_granulepos(&og) - preSkip) / (48000 / format.rate); if (ex_ogg_page_eos(&og)) break; } /* Read tags. */ if (comments.Size() > 0) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(comments, track); boca.DeleteComponent(tagger); } } /* Clean up. */ if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return Success(); } BoCA::DecoderOpus::DecoderOpus() { configLayer = NIL; decoder = NIL; preSkip = 0; preSkipLeft = 0; skipSamples = 0; memset(&oy, 0, sizeof(oy)); memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); } BoCA::DecoderOpus::~DecoderOpus() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderOpus::Activate() { static Endianness endianness = CPU().GetEndianness(); /* Get configuration. */ const Config *config = GetConfiguration(); Int complexity = config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10); Bool enableBwe = config->GetIntValue(ConfigureOpus::ConfigID, "BandwidthExtension", False); /* Parse packets and init decoder. */ ex_ogg_sync_init(&oy); Bool initialized = False; Bool done = False; Int packetNum = 0; while (!done) { Int size = 4096; char *buffer = ex_ogg_sync_buffer(&oy, size); size = driver->ReadData((unsigned char *) buffer, 4096); inBytes += size; ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { /* Found header packet. */ if (packetNum == 0) { OpusHeader *setup = (OpusHeader *) op.packet; if (endianness != EndianLittle) { BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup->preskip, sizeof(setup->preskip)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup->sample_rate, sizeof(setup->sample_rate)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup->output_gain, sizeof(setup->output_gain)); } const Format &format = track.GetFormat(); int error = OPUS_OK; unsigned char mapping[2] = { 0, 1 }; if (setup->channel_mapping == 0) decoder = ex_opus_multistream_decoder_create(format.rate, setup->nb_channels, 1, setup->nb_channels - 1, mapping, &error); else decoder = ex_opus_multistream_decoder_create(format.rate, setup->nb_channels, setup->nb_streams, setup->nb_coupled, setup->stream_map, &error); preSkip = setup->preskip / (48000 / format.rate); preSkipLeft = setup->preskip / (48000 / format.rate); if (osceSupported && error == OPUS_OK) { for (Int i = 0; i < (setup->channel_mapping == 0 ? 1 : setup->nb_streams); i++) { OpusDecoder *streamDecoder = NIL; ex_opus_multistream_decoder_ctl(decoder, OPUS_MULTISTREAM_GET_DECODER_STATE(i, &streamDecoder)); ex_opus_decoder_ctl(streamDecoder, OPUS_SET_COMPLEXITY(complexity)); ex_opus_decoder_ctl(streamDecoder, OPUS_SET_OSCE_BWE(enableBwe)); } } } if (packetNum >= 1) done = True; packetNum++; } } } return True; } Bool BoCA::DecoderOpus::Deactivate() { ex_ogg_stream_clear(&os); ex_opus_multistream_decoder_destroy(decoder); ex_ogg_sync_clear(&oy); return True; } Bool BoCA::DecoderOpus::Seek(Int64 samplePosition) { const Format &format = track.GetFormat(); while (ex_ogg_page_granulepos(&og) / (48000 / format.rate) - preSkip <= samplePosition || ex_ogg_page_serialno(&og) != os.serialno) { skipSamples = preSkip + samplePosition - ex_ogg_page_granulepos(&og) / (48000 / format.rate); while (ex_ogg_sync_pageseek(&oy, &og) == 0) { char *buffer = ex_ogg_sync_buffer(&oy, 131072); Int size = driver->ReadData((unsigned char *) buffer, 131072); inBytes += size; ex_ogg_sync_wrote(&oy, size); if (size == 0) return False; } } ex_ogg_stream_pagein(&os, &og); preSkipLeft += skipSamples; ex_opus_multistream_decoder_ctl(decoder, OPUS_RESET_STATE); return True; } Int BoCA::DecoderOpus::ReadData(Buffer &data) { const Format &format = track.GetFormat(); Int size = 0; Int dataBufferLen = 0; while (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_pagein(&os, &og); while (ex_ogg_stream_packetout(&os, &op) == 1) { if (dataBufferLen < size + maxFrameSize * format.channels * (format.bits / 8)) { dataBufferLen += 2 * maxFrameSize * format.channels * (format.bits / 8); data.Resize(dataBufferLen); } Int frameSize = 0; if (format.bits == 16) frameSize = ex_opus_multistream_decode(decoder, op.packet, op.bytes, (opus_int16 *) (UnsignedByte *) (data + size), maxFrameSize, 0); else frameSize = ex_opus_multistream_decode_float(decoder, op.packet, op.bytes, (float *) (UnsignedByte *) (data + size), maxFrameSize, 0); if (frameSize > preSkipLeft) { if (preSkipLeft) memmove((unsigned char *) data + size, (unsigned char *) data + size + preSkipLeft * format.channels * (format.bits / 8), (frameSize - preSkipLeft) * format.channels * (format.bits / 8)); size += Math::Max(0, (frameSize - preSkipLeft) * format.channels * (format.bits / 8)); } preSkipLeft = Math::Max(0, preSkipLeft - frameSize); } if (ex_ogg_page_eos(&og)) break; } data.Resize(size); /* Bail out if no more data available. */ char *buffer = ex_ogg_sync_buffer(&oy, 8192); Int bytes = driver->ReadData((unsigned char *) buffer, 8192); if (size == 0 && bytes <= 0) return -1; inBytes += bytes; ex_ogg_sync_wrote(&oy, bytes); if (size == 0) return ReadData(data); /* Change to default channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_3_0, Channel::Default_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_5_0, Channel::Default_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_5_1, Channel::Default_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_6_1, Channel::Default_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_7_1, Channel::Default_7_1); return size; } ConfigLayer *BoCA::DecoderOpus::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureOpus(osceSupported, bweSupported); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/opus/opus.h000066400000000000000000000025641516712004000241120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderOpus) namespace BoCA { class DecoderOpus : public CS::DecoderComponent { private: ConfigLayer *configLayer; ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; OpusMSDecoder *decoder; Int preSkip; Int preSkipLeft; Int skipSamples; public: static const String &GetComponentSpecs(); DecoderOpus(); ~DecoderOpus(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderOpus) BoCA_END_COMPONENT(DecoderOpus) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/000077500000000000000000000000001516712004000234025ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/Makefile000077500000000000000000000012201516712004000250400ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = sndfile TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o sndfile.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/dllinterface.cpp000077500000000000000000000045571516712004000265600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" SF_OPEN_FD ex_sf_open_fd = NIL; SF_CLOSE ex_sf_close = NIL; SF_SEEK ex_sf_seek = NIL; SF_READ_SHORT ex_sf_read_short = NIL; SF_READ_INT ex_sf_read_int = NIL; SF_READ_FLOAT ex_sf_read_float = NIL; SF_GET_STRING ex_sf_get_string = NIL; SF_COMMAND ex_sf_command = NIL; SF_STRERROR ex_sf_strerror = NIL; SF_VERSION_STRING ex_sf_version_string = NIL; DynamicLoader *sndfiledll = NIL; Bool LoadSndFileDLL() { sndfiledll = BoCA::Utilities::LoadCodecDLL("sndfile"); if (sndfiledll == NIL) return False; ex_sf_open_fd = (SF_OPEN_FD) sndfiledll->GetFunctionAddress("sf_open_fd"); ex_sf_close = (SF_CLOSE) sndfiledll->GetFunctionAddress("sf_close"); ex_sf_seek = (SF_SEEK) sndfiledll->GetFunctionAddress("sf_seek"); ex_sf_read_short = (SF_READ_SHORT) sndfiledll->GetFunctionAddress("sf_read_short"); ex_sf_read_int = (SF_READ_INT) sndfiledll->GetFunctionAddress("sf_read_int"); ex_sf_read_float = (SF_READ_FLOAT) sndfiledll->GetFunctionAddress("sf_read_float"); ex_sf_get_string = (SF_GET_STRING) sndfiledll->GetFunctionAddress("sf_get_string"); ex_sf_command = (SF_COMMAND) sndfiledll->GetFunctionAddress("sf_command"); ex_sf_strerror = (SF_STRERROR) sndfiledll->GetFunctionAddress("sf_strerror"); ex_sf_version_string = (SF_VERSION_STRING) sndfiledll->GetFunctionAddress("sf_version_string"); if (ex_sf_open_fd == NIL || ex_sf_close == NIL || ex_sf_seek == NIL || ex_sf_read_short == NIL || ex_sf_read_int == NIL || ex_sf_read_float == NIL || ex_sf_get_string == NIL || ex_sf_command == NIL || ex_sf_strerror == NIL || ex_sf_version_string == NIL) { FreeSndFileDLL(); return False; } return True; } Void FreeSndFileDLL() { BoCA::Utilities::FreeCodecDLL(sndfiledll); sndfiledll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/dllinterface.h000077500000000000000000000033071516712004000262150ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *sndfiledll; Bool LoadSndFileDLL(); Void FreeSndFileDLL(); typedef SNDFILE * (*SF_OPEN_FD) (int, int, SF_INFO *, int); typedef int (*SF_CLOSE) (SNDFILE *); typedef sf_count_t (*SF_SEEK) (SNDFILE *, sf_count_t, int); typedef sf_count_t (*SF_READ_SHORT) (SNDFILE *, short *, sf_count_t); typedef sf_count_t (*SF_READ_INT) (SNDFILE *, int *, sf_count_t); typedef sf_count_t (*SF_READ_FLOAT) (SNDFILE *, float *, sf_count_t); typedef const char * (*SF_GET_STRING) (SNDFILE *, int); typedef int (*SF_COMMAND) (SNDFILE *, int, void *, int); typedef const char * (*SF_STRERROR) (SNDFILE *); typedef const char * (*SF_VERSION_STRING) (); extern SF_OPEN_FD ex_sf_open_fd; extern SF_CLOSE ex_sf_close; extern SF_SEEK ex_sf_seek; extern SF_READ_SHORT ex_sf_read_short; extern SF_READ_INT ex_sf_read_int; extern SF_READ_FLOAT ex_sf_read_float; extern SF_GET_STRING ex_sf_get_string; extern SF_COMMAND ex_sf_command; extern SF_STRERROR ex_sf_strerror; extern SF_VERSION_STRING ex_sf_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/sndfile.cpp000066400000000000000000000305071516712004000255370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "sndfile.h" using namespace smooth::IO; const String &BoCA::DecoderSndFile::GetComponentSpecs() { static String componentSpecs; if (sndfiledll != NIL) { componentSpecs = " \ \ \ \ SndFile Input Component %VERSION% \ 1.0 \ sndfile-dec \ decoder \ aiff-dec \ au-dec \ voc-dec \ wave-dec \ \ Microsoft Wave Files \ true \ wav \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ Apple Audio Files \ true \ aif \ aiff \ aifc \ ID3v2 \ .TOC.plist \ \ \ Apple Core Audio Files \ true \ caf \ \ \ Sony Media Wave64 Files \ true \ w64 \ RIFF INFO Tag \ \ \ RIFF 64 Audio Files \ true \ rf64 \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ Sun Audio Files \ true \ au \ snd \ \ \ Creative Voice Files \ true \ voc \ \ \ Amiga Audio Files \ true \ iff \ svx \ \ \ IRCAM Sound Files \ true \ sf \ \ \ Paris Audio Files \ true \ paf \ \ \ Portable Voice Format \ true \ pvf \ \ \ Psion WVE Files \ true \ wve \ \ \ HMM Toolkit Format \ true \ htk \ \ \ Audio Visual Research Format \ true \ avr \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_sf_version_string()).Replace("libsndfile-", NIL))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadSndFileDLL(); } Void smooth::DetachDLL() { FreeSndFileDLL(); } Bool BoCA::DecoderSndFile::CanOpenStream(const String &streamURI) { /* Do not open Ogg files with SndFile. */ InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) == "OggS") return False; in.Close(); /* Check if we can handle this file. */ FILE *file = 0; #ifdef __WIN32__ file = _wfopen(Directory::MakeExtendedPath(File(streamURI)), L"rbN"); #else file = fopen(streamURI.ConvertTo("UTF-8"), "rbe"); #endif if (file != NIL) { SF_INFO sinfo; memset(&sinfo, 0, sizeof(SF_INFO)); SNDFILE *sndf = ex_sf_open_fd(fileno(file), SFM_READ, &sinfo, False); if (sndf != NIL) ex_sf_close(sndf); fclose(file); if (sndf != NIL) return True; } return False; } Error BoCA::DecoderSndFile::GetStreamInfo(const String &streamURI, Track &track) { FILE *file = 0; #ifdef __WIN32__ file = _wfopen(Directory::MakeExtendedPath(File(streamURI)), L"rbN"); #else file = fopen(streamURI.ConvertTo("UTF-8"), "rbe"); #endif if (file == NIL) { errorState = True; errorString = "File not found"; } if (file != NIL) { SF_INFO sinfo; memset(&sinfo, 0, sizeof(SF_INFO)); SNDFILE *sndf = ex_sf_open_fd(fileno(file), SFM_READ, &sinfo, False); if (sndf == NIL) { errorState = True; errorString = "Unknown file type"; } if (sndf != NIL) { Format format = track.GetFormat(); track.fileSize = File(streamURI).GetFileSize(); format.channels = sinfo.channels; format.rate = sinfo.samplerate; switch (sinfo.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_U8: case SF_FORMAT_PCM_S8: format.bits = 8; break; case SF_FORMAT_PCM_24: format.bits = 24; break; case SF_FORMAT_PCM_32: format.bits = 32; break; case SF_FORMAT_FLOAT: case SF_FORMAT_DOUBLE: format.bits = 32; format.fp = True; break; default: format.bits = 16; break; } track.SetFormat(format); track.length = sinfo.frames; Info info = track.GetInfo(); info.artist = ex_sf_get_string(sndf, SF_STR_ARTIST); info.title = ex_sf_get_string(sndf, SF_STR_TITLE); info.album = ex_sf_get_string(sndf, SF_STR_ALBUM); info.track = (Int64) Number::FromIntString(ex_sf_get_string(sndf, SF_STR_TRACKNUMBER)); info.year = (Int64) Number::FromIntString(ex_sf_get_string(sndf, SF_STR_DATE)); info.genre = ex_sf_get_string(sndf, SF_STR_GENRE); info.comment = ex_sf_get_string(sndf, SF_STR_COMMENT); SF_LOOP_INFO loopInfo; if (ex_sf_command(sndf, SFC_GET_LOOP_INFO, &loopInfo, sizeof(loopInfo)) == SF_TRUE) { info.SetOtherInfo(INFO_BPM, String::FromFloat(Math::Round(loopInfo.bpm * 1000.0) / 1000.0)); } track.SetInfo(info); ex_sf_close(sndf); } fclose(file); } if (!errorState) { AS::Registry &boca = AS::Registry::Get(); /* Read CART tag if any. */ AS::TaggerComponent *cartTagger = (AS::TaggerComponent *) boca.CreateComponentByID("cart-tag"); if (cartTagger != NIL) { cartTagger->SetConfiguration(GetConfiguration()); cartTagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(cartTagger); } /* Read RIFF tags if any. */ AS::TaggerComponent *riffTagger = (AS::TaggerComponent *) boca.CreateComponentByID("riff-tag"); if (riffTagger != NIL) { riffTagger->SetConfiguration(GetConfiguration()); riffTagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(riffTagger); } /* Read .TOC.plist if it exists. */ AS::TaggerComponent *tocTagger = (AS::TaggerComponent *) boca.CreateComponentByID("tocplist-tag"); if (tocTagger != NIL) { tocTagger->SetConfiguration(GetConfiguration()); tocTagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tocTagger); } /* Read RIFF or AIFF embedded ID3 tag. */ InStream in(STREAM_FILE, streamURI, IS_READ); String magic = in.InputString(4); if (magic == "RIFF" || magic == "RF64" || magic == "FORM") { UnsignedInt32 rSize = (magic != "FORM") ? in.InputNumber(4) : in.InputNumberRaw(4); Int64 dSize = -1; String type = in.InputString(4); while (type == "WAVE" || type == "AIFF" || type == "AIFC") { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ String chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) (magic != "FORM" ? in.InputNumber(4) : in.InputNumberRaw(4)); if (chunk == "id3 " || chunk == "ID3 ") { Buffer buffer(cSize); in.InputData(buffer, cSize); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(buffer, track); boca.DeleteComponent(tagger); } break; } else if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(-16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) cSize = in.Size() - in.GetPos(); if (dSize >= 0) cSize = dSize; } /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) break; } } in.Close(); } if (errorState) return Error(); else return Success(); } BoCA::DecoderSndFile::DecoderSndFile() { fileFormat = 0; file = 0; sndf = NIL; } BoCA::DecoderSndFile::~DecoderSndFile() { } Bool BoCA::DecoderSndFile::Activate() { /* Open input file. */ #ifdef __WIN32__ file = _wfopen(Directory::MakeExtendedPath(File(track.fileName)), L"rbN"); #else file = fopen(track.fileName.ConvertTo("UTF-8"), "rb"); #endif if (file == NIL) return False; /* Open sndfile handle. */ SF_INFO sinfo; memset(&sinfo, 0, sizeof(SF_INFO)); sndf = ex_sf_open_fd(fileno(file), SFM_READ, &sinfo, False); if (sndf == NIL) { fclose(file); return False; } fileFormat = sinfo.format & SF_FORMAT_TYPEMASK; return True; } Bool BoCA::DecoderSndFile::Deactivate() { /* Close sndfile handle. */ ex_sf_close(sndf); fclose(file); return True; } Bool BoCA::DecoderSndFile::Seek(Int64 samplePosition) { if (ex_sf_seek(sndf, samplePosition, SEEK_SET) != -1) return True; else return False; } Int BoCA::DecoderSndFile::ReadData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); /* Set size to a multiple of the number of channels. */ Int size = data.Size() - data.Size() % (format.bits / 8 * format.channels); data.Resize(size); if (format.bits == 8) { Buffer buffer(size); size = ex_sf_read_short(sndf, buffer, size); for (Int i = 0; i < size; i++) ((signed char *) (UnsignedByte *) data)[i] = buffer[i] >> 8; } else if (format.bits == 16) { size = ex_sf_read_short(sndf, (short *) (UnsignedByte *) data, size / 2) * 2; } else if (format.bits == 24) { Buffer buffer(size / 2); size = ex_sf_read_int(sndf, buffer, size / 2) * 3; data.Resize(size); for (Int i = 0; i < size / 3; i++) { if (endianness == EndianLittle) { data[i * 3 + 0] = (buffer[i] >> 8) & 0xFF; data[i * 3 + 1] = (buffer[i] >> 16) & 0xFF; data[i * 3 + 2] = (buffer[i] >> 24) & 0xFF; } else { data[i * 3 + 2] = (buffer[i] >> 8) & 0xFF; data[i * 3 + 1] = (buffer[i] >> 16) & 0xFF; data[i * 3 + 0] = (buffer[i] >> 24) & 0xFF; } } } else if (format.bits == 32 && !format.fp) { size = ex_sf_read_int(sndf, (int *) (UnsignedByte *) data, size / 4) * 4; } else if (format.bits == 32 && format.fp) { size = ex_sf_read_float(sndf, (float *) (UnsignedByte *) data, size / 4) * 4; } /* Reorder channels. */ if (fileFormat == SF_FORMAT_AIFF || fileFormat == SF_FORMAT_CAF) { if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::AIFF_5_1, Channel::Default_5_1); } if (size == 0) return -1; else return size; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/sndfile/sndfile.h000066400000000000000000000023011516712004000251730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderSndFile) namespace BoCA { class DecoderSndFile : public CS::DecoderComponent { private: Int fileFormat; FILE *file; SNDFILE *sndf; public: static const String &GetComponentSpecs(); DecoderSndFile(); ~DecoderSndFile(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderSndFile) BoCA_END_COMPONENT(DecoderSndFile) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/000077500000000000000000000000001516712004000231025ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/Makefile000077500000000000000000000012141516712004000245430ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = speex TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o speex.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/dllinterface.cpp000077500000000000000000000130571516712004000262530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETOUT ex_ogg_stream_packetout = NIL; OGGSTREAMPAGEIN ex_ogg_stream_pagein = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGPAGESERIALNO ex_ogg_page_serialno = NIL; OGGPAGEGRANULEPOS ex_ogg_page_granulepos = NIL; OGGPAGEPACKETS ex_ogg_page_packets = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OGGSYNCINIT ex_ogg_sync_init = NIL; OGGSYNCBUFFER ex_ogg_sync_buffer = NIL; OGGSYNCWROTE ex_ogg_sync_wrote = NIL; OGGSYNCPAGEOUT ex_ogg_sync_pageout = NIL; OGGSYNCPAGESEEK ex_ogg_sync_pageseek = NIL; OGGSYNCRESET ex_ogg_sync_reset = NIL; OGGSYNCCLEAR ex_ogg_sync_clear = NIL; SPEEXBITSINIT ex_speex_bits_init = NIL; SPEEXBITSDESTROY ex_speex_bits_destroy = NIL; SPEEXBITSREADFROM ex_speex_bits_read_from = NIL; SPEEXDECODERINIT ex_speex_decoder_init = NIL; SPEEXDECODERDESTROY ex_speex_decoder_destroy = NIL; SPEEXDECODERCTL ex_speex_decoder_ctl = NIL; SPEEXDECODEINT ex_speex_decode_int = NIL; SPEEXDECODESTEREOINT ex_speex_decode_stereo_int = NIL; SPEEXPACKETTOHEADER ex_speex_packet_to_header = NIL; SPEEXLIBCTL ex_speex_lib_ctl = NIL; SPEEXLIBGETMODE ex_speex_lib_get_mode = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *speexdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetout = (OGGSTREAMPACKETOUT) oggdll->GetFunctionAddress("ogg_stream_packetout"); ex_ogg_stream_pagein = (OGGSTREAMPAGEIN) oggdll->GetFunctionAddress("ogg_stream_pagein"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_page_serialno = (OGGPAGESERIALNO) oggdll->GetFunctionAddress("ogg_page_serialno"); ex_ogg_page_granulepos = (OGGPAGEGRANULEPOS) oggdll->GetFunctionAddress("ogg_page_granulepos"); ex_ogg_page_packets = (OGGPAGEPACKETS) oggdll->GetFunctionAddress("ogg_page_packets"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); ex_ogg_sync_init = (OGGSYNCINIT) oggdll->GetFunctionAddress("ogg_sync_init"); ex_ogg_sync_buffer = (OGGSYNCBUFFER) oggdll->GetFunctionAddress("ogg_sync_buffer"); ex_ogg_sync_wrote = (OGGSYNCWROTE) oggdll->GetFunctionAddress("ogg_sync_wrote"); ex_ogg_sync_pageout = (OGGSYNCPAGEOUT) oggdll->GetFunctionAddress("ogg_sync_pageout"); ex_ogg_sync_pageseek = (OGGSYNCPAGESEEK) oggdll->GetFunctionAddress("ogg_sync_pageseek"); ex_ogg_sync_reset = (OGGSYNCRESET) oggdll->GetFunctionAddress("ogg_sync_reset"); ex_ogg_sync_clear = (OGGSYNCCLEAR) oggdll->GetFunctionAddress("ogg_sync_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetout == NIL || ex_ogg_stream_pagein == NIL || ex_ogg_page_eos == NIL || ex_ogg_page_serialno == NIL || ex_ogg_page_granulepos == NIL || ex_ogg_page_packets == NIL || ex_ogg_stream_clear == NIL || ex_ogg_sync_init == NIL || ex_ogg_sync_buffer == NIL || ex_ogg_sync_wrote == NIL || ex_ogg_sync_pageout == NIL || ex_ogg_sync_pageseek == NIL || ex_ogg_sync_reset == NIL || ex_ogg_sync_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadSpeexDLL() { speexdll = BoCA::Utilities::LoadCodecDLL("speex"); if (speexdll == NIL) return False; ex_speex_bits_init = (SPEEXBITSINIT) speexdll->GetFunctionAddress("speex_bits_init"); ex_speex_bits_destroy = (SPEEXBITSDESTROY) speexdll->GetFunctionAddress("speex_bits_destroy"); ex_speex_bits_read_from = (SPEEXBITSREADFROM) speexdll->GetFunctionAddress("speex_bits_read_from"); ex_speex_decoder_init = (SPEEXDECODERINIT) speexdll->GetFunctionAddress("speex_decoder_init"); ex_speex_decoder_destroy = (SPEEXDECODERDESTROY) speexdll->GetFunctionAddress("speex_decoder_destroy"); ex_speex_decoder_ctl = (SPEEXDECODERCTL) speexdll->GetFunctionAddress("speex_decoder_ctl"); ex_speex_decode_int = (SPEEXDECODEINT) speexdll->GetFunctionAddress("speex_decode_int"); ex_speex_decode_stereo_int = (SPEEXDECODESTEREOINT) speexdll->GetFunctionAddress("speex_decode_stereo_int"); ex_speex_packet_to_header = (SPEEXPACKETTOHEADER) speexdll->GetFunctionAddress("speex_packet_to_header"); ex_speex_lib_ctl = (SPEEXLIBCTL) speexdll->GetFunctionAddress("speex_lib_ctl"); ex_speex_lib_get_mode = (SPEEXLIBGETMODE) speexdll->GetFunctionAddress("speex_lib_get_mode"); if (ex_speex_bits_init == NIL || ex_speex_bits_destroy == NIL || ex_speex_bits_read_from == NIL || ex_speex_decoder_init == NIL || ex_speex_decoder_destroy == NIL || ex_speex_decoder_ctl == NIL || ex_speex_decode_int == NIL || ex_speex_decode_stereo_int == NIL || ex_speex_packet_to_header == NIL || ex_speex_lib_ctl == NIL || ex_speex_lib_get_mode == NIL) { FreeSpeexDLL(); return False; } return True; } Void FreeSpeexDLL() { BoCA::Utilities::FreeCodecDLL(speexdll); speexdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/dllinterface.h000077500000000000000000000070531516712004000257170ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *speexdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadSpeexDLL(); Void FreeSpeexDLL(); typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETOUT) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMPAGEIN) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGPAGESERIALNO) (ogg_page *); typedef ogg_int64_t (*OGGPAGEGRANULEPOS) (ogg_page *); typedef int (*OGGPAGEPACKETS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); typedef int (*OGGSYNCINIT) (ogg_sync_state *); typedef char * (*OGGSYNCBUFFER) (ogg_sync_state *, int); typedef int (*OGGSYNCWROTE) (ogg_sync_state *, int); typedef int (*OGGSYNCPAGEOUT) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCPAGESEEK) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCRESET) (ogg_sync_state *); typedef int (*OGGSYNCCLEAR) (ogg_sync_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETOUT ex_ogg_stream_packetout; extern OGGSTREAMPAGEIN ex_ogg_stream_pagein; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGPAGESERIALNO ex_ogg_page_serialno; extern OGGPAGEGRANULEPOS ex_ogg_page_granulepos; extern OGGPAGEPACKETS ex_ogg_page_packets; extern OGGSTREAMCLEAR ex_ogg_stream_clear; extern OGGSYNCINIT ex_ogg_sync_init; extern OGGSYNCBUFFER ex_ogg_sync_buffer; extern OGGSYNCWROTE ex_ogg_sync_wrote; extern OGGSYNCPAGEOUT ex_ogg_sync_pageout; extern OGGSYNCPAGESEEK ex_ogg_sync_pageseek; extern OGGSYNCRESET ex_ogg_sync_reset; extern OGGSYNCCLEAR ex_ogg_sync_clear; typedef void (*SPEEXBITSINIT) (SpeexBits *); typedef void (*SPEEXBITSDESTROY) (SpeexBits *); typedef void (*SPEEXBITSREADFROM) (SpeexBits *, char *, int); typedef void * (*SPEEXDECODERINIT) (const SpeexMode *); typedef void (*SPEEXDECODERDESTROY) (void *); typedef int (*SPEEXDECODERCTL) (void *, int, void *); typedef int (*SPEEXDECODEINT) (void *, SpeexBits *, spx_int16_t *); typedef void (*SPEEXDECODESTEREOINT) (spx_int16_t *, int, SpeexStereoState *); typedef SpeexHeader * (*SPEEXPACKETTOHEADER) (char *, int); typedef int (*SPEEXLIBCTL) (int, void *); typedef const SpeexMode * (*SPEEXLIBGETMODE) (int); extern SPEEXBITSINIT ex_speex_bits_init; extern SPEEXBITSDESTROY ex_speex_bits_destroy; extern SPEEXBITSREADFROM ex_speex_bits_read_from; extern SPEEXDECODERINIT ex_speex_decoder_init; extern SPEEXDECODERDESTROY ex_speex_decoder_destroy; extern SPEEXDECODERCTL ex_speex_decoder_ctl; extern SPEEXDECODEINT ex_speex_decode_int; extern SPEEXDECODESTEREOINT ex_speex_decode_stereo_int; extern SPEEXPACKETTOHEADER ex_speex_packet_to_header; extern SPEEXLIBCTL ex_speex_lib_ctl; extern SPEEXLIBGETMODE ex_speex_lib_get_mode; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/speex.cpp000066400000000000000000000214011516712004000247300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "speex.h" using namespace smooth::IO; const String &BoCA::DecoderSpeex::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && speexdll != NIL) { componentSpecs = " \ \ \ \ Speex Speech Decoder %VERSION% \ 1.0 \ speex-dec \ decoder \ \ Speex Files \ spx \ Vorbis Comment \ \ \ \ "; const char *speexVersion = NIL; ex_speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &speexVersion); componentSpecs.Replace("%VERSION%", String("v").Append(speexVersion)); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadSpeexDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeSpeexDLL(); } Bool BoCA::DecoderSpeex::CanOpenStream(const String &streamURI) { return streamURI.ToLower().EndsWith(".spx"); } Error BoCA::DecoderSpeex::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); /* Set up track format. */ Format format = track.GetFormat(); format.bits = 16; track.fileSize = in.Size(); /* Set up Ogg reader. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); /* Get stream format. */ Buffer comments; Bool initialized = False; Bool done = False; Int packetNum = 0; do { Int size = Math::Min(Int64(4096), track.fileSize - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { /* Found header packet. */ if (packetNum == 0) { SpeexHeader *header = ex_speex_packet_to_header((char *) op.packet, op.bytes); format.rate = header->rate; format.channels = header->nb_channels; track.length = -1; free(header); } /* Found Vorbis Comment packet. */ if (packetNum == 1) { comments.Resize(op.bytes); memcpy(comments, op.packet, op.bytes); } /* Done if we reached packet one. */ if (packetNum >= 1) done = True; packetNum++; } } if (done) break; } while (in.GetPos() < in.Size()); track.SetFormat(format); /* Find real length of stream. */ ex_ogg_sync_reset(&oy); Int size = Math::Min(in.Size(), 65536); char *buffer = ex_ogg_sync_buffer(&oy, size); in.Seek(in.Size() - size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (true) { Int seek = ex_ogg_sync_pageseek(&oy, &og); if (seek == 0) break; if (seek < 0 || ex_ogg_page_serialno(&og) != os.serialno) continue; track.length = ex_ogg_page_granulepos(&og); if (ex_ogg_page_eos(&og)) break; } /* Read tags. */ if (comments.Size() > 0) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(comments, track); boca.DeleteComponent(tagger); } } /* Clean up. */ if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return Success(); } BoCA::DecoderSpeex::DecoderSpeex() { decoder = NIL; frameSize = 0; lookAhead = 0; nFrames = 0; preSkip = 0; preSkipLeft = 0; skipSamples = 0; pageNumber = 0; memset(&oy, 0, sizeof(oy)); memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); memset(&bits, 0, sizeof(bits)); memset(&stereo, 0, sizeof(stereo)); } BoCA::DecoderSpeex::~DecoderSpeex() { } Bool BoCA::DecoderSpeex::Activate() { SpeexHeader *header = NIL; ex_ogg_sync_init(&oy); Bool initialized = False; Bool done = False; Int packetNum = 0; while (!done) { Int size = 4096; char *buffer = ex_ogg_sync_buffer(&oy, size); size = driver->ReadData((unsigned char *) buffer, 4096); inBytes += size; ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { if (packetNum == 0) { header = ex_speex_packet_to_header((char *) op.packet, op.bytes); } if (packetNum >= 1 + header->extra_headers) done = True; packetNum++; } } } const SpeexMode *mode = ex_speex_lib_get_mode(header->mode); decoder = ex_speex_decoder_init(mode); ex_speex_decoder_ctl(decoder, SPEEX_SET_SAMPLING_RATE, &header->rate); ex_speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &frameSize); ex_speex_decoder_ctl(decoder, SPEEX_GET_LOOKAHEAD, &lookAhead); nFrames = Math::Max(1, (Int) header->frames_per_packet); pageNumber = 0; stereo.balance = 1; stereo.e_ratio = 0.5; stereo.smooth_left = 1; stereo.smooth_right = 1; stereo.reserved1 = 0; stereo.reserved2 = 0; ex_speex_bits_init(&bits); free(header); return True; } Bool BoCA::DecoderSpeex::Deactivate() { ex_ogg_stream_clear(&os); ex_speex_decoder_destroy(decoder); ex_speex_bits_destroy(&bits); ex_ogg_sync_clear(&oy); return True; } Bool BoCA::DecoderSpeex::Seek(Int64 samplePosition) { while (ex_ogg_page_granulepos(&og) <= samplePosition || ex_ogg_page_serialno(&og) != os.serialno) { skipSamples = samplePosition - ex_ogg_page_granulepos(&og); while (ex_ogg_sync_pageseek(&oy, &og) == 0) { char *buffer = ex_ogg_sync_buffer(&oy, 131072); Int size = driver->ReadData((unsigned char *) buffer, 131072); inBytes += size; ex_ogg_sync_wrote(&oy, size); if (size == 0) return False; } } ex_ogg_stream_pagein(&os, &og); preSkipLeft += skipSamples; ex_speex_decoder_ctl(decoder, SPEEX_RESET_STATE, 0); return True; } Int BoCA::DecoderSpeex::ReadData(Buffer &data) { const Format &format = track.GetFormat(); Int size = 0; Int dataBufferLen = 0; while (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_pagein(&os, &og); if (pageNumber++ == 0) { if (ex_ogg_page_granulepos(&og) < ex_ogg_page_packets(&og) * nFrames * frameSize) preSkip += ex_ogg_page_packets(&og) * nFrames * frameSize - ex_ogg_page_granulepos(&og); preSkip += lookAhead; preSkipLeft += preSkip; } while (ex_ogg_stream_packetout(&os, &op) == 1) { pcmBuffer.Resize(frameSize * format.channels); ex_speex_bits_read_from(&bits, (char *) op.packet, op.bytes); for (Int i = 0; i < nFrames; i++) { if (ex_speex_decode_int(decoder, &bits, pcmBuffer) < 0) break; if (format.channels == 2) ex_speex_decode_stereo_int(pcmBuffer, frameSize, &stereo); if (frameSize > preSkipLeft) { if (preSkipLeft) memmove((short *) pcmBuffer, (short *) pcmBuffer + preSkipLeft * format.channels, (frameSize - preSkipLeft) * format.channels * 2); if (dataBufferLen < size + ((frameSize - preSkipLeft) * format.channels * 2)) { dataBufferLen += (((frameSize - preSkipLeft) * format.channels * 2) + 131072); data.Resize(dataBufferLen); } for (Int j = 0; j < (frameSize - preSkipLeft) * format.channels; j++) { ((short *) (UnsignedByte *) data)[size / 2 + j] = pcmBuffer[j]; } size += ((frameSize - preSkipLeft) * format.channels * 2); } preSkipLeft = Math::Max(0, preSkipLeft - frameSize); } } if (ex_ogg_page_eos(&og)) break; } /* Bail out if no more data available. */ char *buffer = ex_ogg_sync_buffer(&oy, 8192); Int bytes = driver->ReadData((unsigned char *) buffer, 8192); if (size == 0 && bytes <= 0) return -1; inBytes += bytes; ex_ogg_sync_wrote(&oy, bytes); if (size == 0) return ReadData(data); return size; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/speex/speex.h000066400000000000000000000027701516712004000244050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderSpeex) namespace BoCA { class DecoderSpeex : public CS::DecoderComponent { private: ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; void *decoder; SpeexBits bits; SpeexStereoState stereo; spx_int32_t frameSize; spx_int32_t lookAhead; spx_int32_t nFrames; spx_int32_t preSkip; spx_int32_t preSkipLeft; spx_int32_t skipSamples; Int pageNumber; Buffer pcmBuffer; public: static const String &GetComponentSpecs(); DecoderSpeex(); ~DecoderSpeex(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderSpeex) BoCA_END_COMPONENT(DecoderSpeex) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/voc/000077500000000000000000000000001516712004000225455ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/voc/Makefile000077500000000000000000000011161516712004000242070ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = voc TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = voc.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/voc/voc.cpp000066400000000000000000000073761516712004000240550ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "voc.h" using namespace smooth::IO; const String &BoCA::DecoderVoc::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Creative Voice File Decoder \ 1.0 \ voc-dec \ decoder \ \ Creative Voice Files \ true \ voc \ \ \ \ "; return componentSpecs; } Bool BoCA::DecoderVoc::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(19) == "Creative Voice File" && in.InputNumber(1) == 0x1A) { /* Skip rest of header. */ in.RelSeek(6); /* Read block type. */ Int blockType = in.InputNumber(1); if (blockType == 0x09) return True; } return False; } Error BoCA::DecoderVoc::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); track.fileSize = in.Size(); /* Skip main header. */ in.RelSeek(26); /* Read block type. */ Int blockType = in.InputNumber(1); if (blockType == 0x09) { /* Read block size. */ Int blockSize = in.InputNumber(3); /* Read format data. */ Format format = track.GetFormat(); format.order = BYTE_INTEL; format.rate = UnsignedInt32(in.InputNumber(4)); format.bits = UnsignedInt8(in.InputNumber(1)); format.channels = UnsignedInt8(in.InputNumber(1)); if (format.bits == 8) format.sign = False; track.SetFormat(format); in.RelSeek(6); in.RelSeek(blockSize - 12); /* Get track length. */ track.length = (blockSize - 12) / format.channels / (format.bits / 8); if (in.InputNumber(1) == 0x02) { do { Int blockSize = in.InputNumber(3); track.length += blockSize / format.channels / (format.bits / 8); in.RelSeek(blockSize); } while (in.InputNumber(1) == 0x02); } else { track.length = (track.fileSize - 42) / format.channels / (format.bits / 8); } } return Success(); } BoCA::DecoderVoc::DecoderVoc() { bytesLeft = 0; } BoCA::DecoderVoc::~DecoderVoc() { } Bool BoCA::DecoderVoc::Activate() { InStream in(STREAM_DRIVER, driver); /* Skip main header. */ in.RelSeek(26); /* Read block type. */ Int blockType = in.InputNumber(1); if (blockType == 0x09) { /* Read block size and continue. */ bytesLeft = in.InputNumber(3) - 12; driver->Seek(in.GetPos() + 12); } return True; } Int BoCA::DecoderVoc::ReadData(Buffer &data) { Int size = driver->ReadData(data, data.Size()); if (size <= 0) return -1; Int outSize = size; if (size > bytesLeft) { if ((data + bytesLeft)[0] == 0x02) { Int newBytesLeft = (data + bytesLeft)[1] + 256 * (data + bytesLeft)[2] + 65536 * (data + bytesLeft)[3]; outSize = size - 4; memmove(data + bytesLeft, data + bytesLeft + 4, size - bytesLeft - 4); data.Resize(outSize); bytesLeft = newBytesLeft - (size - bytesLeft - 4); } else { /* Possibly broken format. */ bytesLeft = driver->GetSize(); } } else { bytesLeft -= size; } return outSize; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/voc/voc.h000066400000000000000000000020661516712004000235110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DecoderVoc) namespace BoCA { class DecoderVoc : public CS::DecoderComponent { private: Int bytesLeft; public: static const String &GetComponentSpecs(); DecoderVoc(); ~DecoderVoc(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderVoc) BoCA_END_COMPONENT(DecoderVoc) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/000077500000000000000000000000001516712004000232625ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/Makefile000077500000000000000000000012161516712004000247250ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = vorbis TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o vorbis.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/dllinterface.cpp000077500000000000000000000177211516712004000264350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETOUT ex_ogg_stream_packetout = NIL; OGGSTREAMPAGEIN ex_ogg_stream_pagein = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGPAGESERIALNO ex_ogg_page_serialno = NIL; OGGPAGEGRANULEPOS ex_ogg_page_granulepos = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OGGSYNCINIT ex_ogg_sync_init = NIL; OGGSYNCBUFFER ex_ogg_sync_buffer = NIL; OGGSYNCWROTE ex_ogg_sync_wrote = NIL; OGGSYNCPAGEOUT ex_ogg_sync_pageout = NIL; OGGSYNCPAGESEEK ex_ogg_sync_pageseek = NIL; OGGSYNCRESET ex_ogg_sync_reset = NIL; OGGSYNCCLEAR ex_ogg_sync_clear = NIL; VORBISINFOINIT ex_vorbis_info_init = NIL; VORBISCOMMENTINIT ex_vorbis_comment_init = NIL; VORBISCOMMENTADDTAG ex_vorbis_comment_add_tag = NIL; VORBISANALYSISINIT ex_vorbis_analysis_init = NIL; VORBISBLOCKINIT ex_vorbis_block_init = NIL; VORBISANALYSISHEADEROUT ex_vorbis_analysis_headerout = NIL; VORBISANALYSISBUFFER ex_vorbis_analysis_buffer = NIL; VORBISANALYSISWROTE ex_vorbis_analysis_wrote = NIL; VORBISANALYSISBLOCKOUT ex_vorbis_analysis_blockout = NIL; VORBISANALYSIS ex_vorbis_analysis = NIL; VORBISBITRATEADDBLOCK ex_vorbis_bitrate_addblock = NIL; VORBISBITRATEFLUSHPACKET ex_vorbis_bitrate_flushpacket = NIL; VORBISSYNTHESISINIT ex_vorbis_synthesis_init = NIL; VORBISSYNTHESIS ex_vorbis_synthesis = NIL; VORBISSYNTHESISBLOCKIN ex_vorbis_synthesis_blockin = NIL; VORBISSYNTHESISPCMOUT ex_vorbis_synthesis_pcmout = NIL; VORBISSYNTHESISREAD ex_vorbis_synthesis_read = NIL; VORBISSYNTHESISHEADERIN ex_vorbis_synthesis_headerin = NIL; VORBISSYNTHESISRESTART ex_vorbis_synthesis_restart = NIL; VORBISBLOCKCLEAR ex_vorbis_block_clear = NIL; VORBISDSPCLEAR ex_vorbis_dsp_clear = NIL; VORBISCOMMENTCLEAR ex_vorbis_comment_clear = NIL; VORBISINFOCLEAR ex_vorbis_info_clear = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *vorbisdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetout = (OGGSTREAMPACKETOUT) oggdll->GetFunctionAddress("ogg_stream_packetout"); ex_ogg_stream_pagein = (OGGSTREAMPAGEIN) oggdll->GetFunctionAddress("ogg_stream_pagein"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_page_serialno = (OGGPAGESERIALNO) oggdll->GetFunctionAddress("ogg_page_serialno"); ex_ogg_page_granulepos = (OGGPAGEGRANULEPOS) oggdll->GetFunctionAddress("ogg_page_granulepos"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); ex_ogg_sync_init = (OGGSYNCINIT) oggdll->GetFunctionAddress("ogg_sync_init"); ex_ogg_sync_buffer = (OGGSYNCBUFFER) oggdll->GetFunctionAddress("ogg_sync_buffer"); ex_ogg_sync_wrote = (OGGSYNCWROTE) oggdll->GetFunctionAddress("ogg_sync_wrote"); ex_ogg_sync_pageout = (OGGSYNCPAGEOUT) oggdll->GetFunctionAddress("ogg_sync_pageout"); ex_ogg_sync_pageseek = (OGGSYNCPAGESEEK) oggdll->GetFunctionAddress("ogg_sync_pageseek"); ex_ogg_sync_reset = (OGGSYNCRESET) oggdll->GetFunctionAddress("ogg_sync_reset"); ex_ogg_sync_clear = (OGGSYNCCLEAR) oggdll->GetFunctionAddress("ogg_sync_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetout == NIL || ex_ogg_stream_pagein == NIL || ex_ogg_page_eos == NIL || ex_ogg_page_serialno == NIL || ex_ogg_page_granulepos == NIL || ex_ogg_stream_clear == NIL || ex_ogg_sync_init == NIL || ex_ogg_sync_buffer == NIL || ex_ogg_sync_wrote == NIL || ex_ogg_sync_pageout == NIL || ex_ogg_sync_pageseek == NIL || ex_ogg_sync_reset == NIL || ex_ogg_sync_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadVorbisDLL() { vorbisdll = BoCA::Utilities::LoadCodecDLL("vorbis"); if (vorbisdll == NIL) return False; ex_vorbis_info_init = (VORBISINFOINIT) vorbisdll->GetFunctionAddress("vorbis_info_init"); ex_vorbis_comment_init = (VORBISCOMMENTINIT) vorbisdll->GetFunctionAddress("vorbis_comment_init"); ex_vorbis_comment_add_tag = (VORBISCOMMENTADDTAG) vorbisdll->GetFunctionAddress("vorbis_comment_add_tag"); ex_vorbis_analysis_init = (VORBISANALYSISINIT) vorbisdll->GetFunctionAddress("vorbis_analysis_init"); ex_vorbis_block_init = (VORBISBLOCKINIT) vorbisdll->GetFunctionAddress("vorbis_block_init"); ex_vorbis_analysis_headerout = (VORBISANALYSISHEADEROUT) vorbisdll->GetFunctionAddress("vorbis_analysis_headerout"); ex_vorbis_analysis_buffer = (VORBISANALYSISBUFFER) vorbisdll->GetFunctionAddress("vorbis_analysis_buffer"); ex_vorbis_analysis_wrote = (VORBISANALYSISWROTE) vorbisdll->GetFunctionAddress("vorbis_analysis_wrote"); ex_vorbis_analysis_blockout = (VORBISANALYSISBLOCKOUT) vorbisdll->GetFunctionAddress("vorbis_analysis_blockout"); ex_vorbis_analysis = (VORBISANALYSIS) vorbisdll->GetFunctionAddress("vorbis_analysis"); ex_vorbis_bitrate_addblock = (VORBISBITRATEADDBLOCK) vorbisdll->GetFunctionAddress("vorbis_bitrate_addblock"); ex_vorbis_bitrate_flushpacket = (VORBISBITRATEFLUSHPACKET) vorbisdll->GetFunctionAddress("vorbis_bitrate_flushpacket"); ex_vorbis_synthesis_init = (VORBISSYNTHESISINIT) vorbisdll->GetFunctionAddress("vorbis_synthesis_init"); ex_vorbis_synthesis = (VORBISSYNTHESIS) vorbisdll->GetFunctionAddress("vorbis_synthesis"); ex_vorbis_synthesis_blockin = (VORBISSYNTHESISBLOCKIN) vorbisdll->GetFunctionAddress("vorbis_synthesis_blockin"); ex_vorbis_synthesis_pcmout = (VORBISSYNTHESISPCMOUT) vorbisdll->GetFunctionAddress("vorbis_synthesis_pcmout"); ex_vorbis_synthesis_read = (VORBISSYNTHESISREAD) vorbisdll->GetFunctionAddress("vorbis_synthesis_read"); ex_vorbis_synthesis_headerin = (VORBISSYNTHESISHEADERIN) vorbisdll->GetFunctionAddress("vorbis_synthesis_headerin"); ex_vorbis_synthesis_restart = (VORBISSYNTHESISRESTART) vorbisdll->GetFunctionAddress("vorbis_synthesis_restart"); ex_vorbis_block_clear = (VORBISBLOCKCLEAR) vorbisdll->GetFunctionAddress("vorbis_block_clear"); ex_vorbis_dsp_clear = (VORBISDSPCLEAR) vorbisdll->GetFunctionAddress("vorbis_dsp_clear"); ex_vorbis_comment_clear = (VORBISCOMMENTCLEAR) vorbisdll->GetFunctionAddress("vorbis_comment_clear"); ex_vorbis_info_clear = (VORBISINFOCLEAR) vorbisdll->GetFunctionAddress("vorbis_info_clear"); if (ex_vorbis_info_init == NIL || ex_vorbis_comment_init == NIL || ex_vorbis_comment_add_tag == NIL || ex_vorbis_analysis_init == NIL || ex_vorbis_block_init == NIL || ex_vorbis_analysis_headerout == NIL || ex_vorbis_analysis_buffer == NIL || ex_vorbis_analysis_wrote == NIL || ex_vorbis_analysis_blockout == NIL || ex_vorbis_analysis == NIL || ex_vorbis_bitrate_addblock == NIL || ex_vorbis_bitrate_flushpacket == NIL || ex_vorbis_synthesis_init == NIL || ex_vorbis_synthesis == NIL || ex_vorbis_synthesis_blockin == NIL || ex_vorbis_synthesis_pcmout == NIL || ex_vorbis_synthesis_read == NIL || ex_vorbis_synthesis_headerin == NIL || ex_vorbis_synthesis_restart == NIL || ex_vorbis_block_clear == NIL || ex_vorbis_dsp_clear == NIL || ex_vorbis_comment_clear == NIL || ex_vorbis_info_clear == NIL) { FreeVorbisDLL(); return False; } return True; } Void FreeVorbisDLL() { BoCA::Utilities::FreeCodecDLL(vorbisdll); vorbisdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/dllinterface.h000077500000000000000000000117601516712004000260770ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *vorbisdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadVorbisDLL(); Void FreeVorbisDLL(); typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETOUT) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMPAGEIN) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGPAGESERIALNO) (ogg_page *); typedef ogg_int64_t (*OGGPAGEGRANULEPOS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); typedef int (*OGGSYNCINIT) (ogg_sync_state *); typedef char * (*OGGSYNCBUFFER) (ogg_sync_state *, int); typedef int (*OGGSYNCWROTE) (ogg_sync_state *, int); typedef int (*OGGSYNCPAGEOUT) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCPAGESEEK) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCRESET) (ogg_sync_state *); typedef int (*OGGSYNCCLEAR) (ogg_sync_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETOUT ex_ogg_stream_packetout; extern OGGSTREAMPAGEIN ex_ogg_stream_pagein; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGPAGESERIALNO ex_ogg_page_serialno; extern OGGPAGEGRANULEPOS ex_ogg_page_granulepos; extern OGGSTREAMCLEAR ex_ogg_stream_clear; extern OGGSYNCINIT ex_ogg_sync_init; extern OGGSYNCBUFFER ex_ogg_sync_buffer; extern OGGSYNCWROTE ex_ogg_sync_wrote; extern OGGSYNCPAGEOUT ex_ogg_sync_pageout; extern OGGSYNCPAGESEEK ex_ogg_sync_pageseek; extern OGGSYNCRESET ex_ogg_sync_reset; extern OGGSYNCCLEAR ex_ogg_sync_clear; typedef void (*VORBISINFOINIT) (vorbis_info *); typedef void (*VORBISCOMMENTINIT) (vorbis_comment *); typedef void (*VORBISCOMMENTADDTAG) (vorbis_comment *, char *, char *); typedef int (*VORBISANALYSISINIT) (vorbis_dsp_state *, vorbis_info *); typedef int (*VORBISBLOCKINIT) (vorbis_dsp_state *, vorbis_block *); typedef int (*VORBISANALYSISHEADEROUT) (vorbis_dsp_state *, vorbis_comment *, ogg_packet *, ogg_packet *, ogg_packet *); typedef float ** (*VORBISANALYSISBUFFER) (vorbis_dsp_state *, int); typedef int (*VORBISANALYSISWROTE) (vorbis_dsp_state *, int); typedef int (*VORBISANALYSISBLOCKOUT) (vorbis_dsp_state *, vorbis_block *); typedef int (*VORBISANALYSIS) (vorbis_block *, ogg_packet *); typedef int (*VORBISBITRATEADDBLOCK) (vorbis_block *); typedef int (*VORBISBITRATEFLUSHPACKET) (vorbis_dsp_state *, ogg_packet *); typedef int (*VORBISSYNTHESISINIT) (vorbis_dsp_state *, vorbis_info *); typedef int (*VORBISSYNTHESIS) (vorbis_block *, ogg_packet *); typedef int (*VORBISSYNTHESISBLOCKIN) (vorbis_dsp_state *, vorbis_block *); typedef int (*VORBISSYNTHESISPCMOUT) (vorbis_dsp_state *, float ***); typedef int (*VORBISSYNTHESISREAD) (vorbis_dsp_state *, int); typedef int (*VORBISSYNTHESISHEADERIN) (vorbis_info *, vorbis_comment *, ogg_packet *); typedef int (*VORBISSYNTHESISRESTART) (vorbis_dsp_state *); typedef int (*VORBISBLOCKCLEAR) (vorbis_block *); typedef void (*VORBISDSPCLEAR) (vorbis_dsp_state *); typedef void (*VORBISCOMMENTCLEAR) (vorbis_comment *); typedef void (*VORBISINFOCLEAR) (vorbis_info *); extern VORBISINFOINIT ex_vorbis_info_init; extern VORBISCOMMENTINIT ex_vorbis_comment_init; extern VORBISCOMMENTADDTAG ex_vorbis_comment_add_tag; extern VORBISANALYSISINIT ex_vorbis_analysis_init; extern VORBISBLOCKINIT ex_vorbis_block_init; extern VORBISANALYSISHEADEROUT ex_vorbis_analysis_headerout; extern VORBISANALYSISBUFFER ex_vorbis_analysis_buffer; extern VORBISANALYSISWROTE ex_vorbis_analysis_wrote; extern VORBISANALYSISBLOCKOUT ex_vorbis_analysis_blockout; extern VORBISANALYSIS ex_vorbis_analysis; extern VORBISBITRATEADDBLOCK ex_vorbis_bitrate_addblock; extern VORBISBITRATEFLUSHPACKET ex_vorbis_bitrate_flushpacket; extern VORBISSYNTHESISINIT ex_vorbis_synthesis_init; extern VORBISSYNTHESIS ex_vorbis_synthesis; extern VORBISSYNTHESISBLOCKIN ex_vorbis_synthesis_blockin; extern VORBISSYNTHESISPCMOUT ex_vorbis_synthesis_pcmout; extern VORBISSYNTHESISREAD ex_vorbis_synthesis_read; extern VORBISSYNTHESISHEADERIN ex_vorbis_synthesis_headerin; extern VORBISSYNTHESISRESTART ex_vorbis_synthesis_restart; extern VORBISBLOCKCLEAR ex_vorbis_block_clear; extern VORBISDSPCLEAR ex_vorbis_dsp_clear; extern VORBISCOMMENTCLEAR ex_vorbis_comment_clear; extern VORBISINFOCLEAR ex_vorbis_info_clear; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/vorbis.cpp000066400000000000000000000236261516712004000253030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "vorbis.h" using namespace smooth::IO; const String &BoCA::DecoderVorbis::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && vorbisdll != NIL) { componentSpecs = " \ \ \ \ Ogg Vorbis Decoder \ 1.0 \ vorbis-dec \ decoder \ \ Ogg Vorbis Audio \ ogg \ oga \ Vorbis Comment \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadVorbisDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeVorbisDLL(); } Bool BoCA::DecoderVorbis::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) != "OggS") return False; in.Seek(0); /* Check if Vorbis stream. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); Bool result = False; Bool initialized = False; do { Int size = Math::Min(Int64(4096), in.Size() - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); if (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; ex_ogg_stream_pagein(&os, &og); if (ex_ogg_stream_packetout(&os, &op) == 1) { if (op.packet[0] == 1 && op.packet[1] == 'v' && op.packet[2] == 'o' && op.packet[3] == 'r' && op.packet[4] == 'b' && op.packet[5] == 'i' && op.packet[6] == 's') result = True; break; } } } while (in.GetPos() < in.Size()); if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return result; } Error BoCA::DecoderVorbis::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); /* Set up track format. */ Format format = track.GetFormat(); format.bits = 16; track.fileSize = in.Size(); /* Set up Ogg reader. */ ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; ex_ogg_sync_init(&oy); vorbis_info vi; vorbis_comment vc; ex_vorbis_info_init(&vi); ex_vorbis_comment_init(&vc); /* Get stream format. */ Buffer comments; Bool initialized = False; Bool done = False; Int packetNum = 0; do { Int size = Math::Min(Int64(4096), track.fileSize - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { ex_vorbis_synthesis_headerin(&vi, &vc, &op); /* Found header packet. */ if (packetNum == 0) { format.rate = vi.rate; format.channels = vi.channels; track.length = -1; Int bitrate = 0; if (vi.bitrate_nominal > 0) bitrate = vi.bitrate_nominal; else if (vi.bitrate_lower > 0 && vi.bitrate_upper > 0) bitrate = (vi.bitrate_lower + vi.bitrate_upper) / 2; if (bitrate > 0) track.approxLength = Math::Round(Float(track.fileSize) / (bitrate / 8) * format.rate); } /* Found Vorbis Comment packet. */ if (packetNum == 1) { comments.Resize(op.bytes - 7); memcpy(comments, op.packet + 7, op.bytes - 7); } /* Done if we reached packet two. */ if (packetNum >= 2) done = True; packetNum++; } } if (done) break; } while (in.GetPos() < in.Size()); track.SetFormat(format); /* Find real length of stream. */ ex_ogg_sync_reset(&oy); Int size = Math::Min(in.Size(), 65536); char *buffer = ex_ogg_sync_buffer(&oy, size); in.Seek(in.Size() - size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); while (true) { Int seek = ex_ogg_sync_pageseek(&oy, &og); if (seek == 0) break; if (seek < 0 || ex_ogg_page_serialno(&og) != os.serialno) continue; track.length = ex_ogg_page_granulepos(&og); if (ex_ogg_page_eos(&og)) break; } /* Read tags. */ if (comments.Size() > 0) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(comments, track); boca.DeleteComponent(tagger); } } /* Clean up. */ ex_vorbis_comment_clear(&vc); ex_vorbis_info_clear(&vi); if (initialized) ex_ogg_stream_clear(&os); ex_ogg_sync_clear(&oy); return Success(); } BoCA::DecoderVorbis::DecoderVorbis() { skipSamples = 0; memset(&oy, 0, sizeof(oy)); memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); memset(&vi, 0, sizeof(vi)); memset(&vc, 0, sizeof(vc)); memset(&vd, 0, sizeof(vd)); memset(&vb, 0, sizeof(vb)); memset(convBuffer, 0, sizeof(convBuffer)); } BoCA::DecoderVorbis::~DecoderVorbis() { } Bool BoCA::DecoderVorbis::Activate() { ex_ogg_sync_init(&oy); Bool initialized = False; Bool done = False; Int packetNum = 0; while (!done) { Int size = 4096; char *buffer = ex_ogg_sync_buffer(&oy, size); size = driver->ReadData((unsigned char *) buffer, 4096); inBytes += size; ex_ogg_sync_wrote(&oy, size); while (!done && ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os, ex_ogg_page_serialno(&og)); ex_vorbis_info_init(&vi); ex_vorbis_comment_init(&vc); initialized = True; } ex_ogg_stream_pagein(&os, &og); while (!done && ex_ogg_stream_packetout(&os, &op) == 1) { ex_vorbis_synthesis_headerin(&vi, &vc, &op); if (packetNum >= 2) done = True; packetNum++; } } } ex_vorbis_synthesis_init(&vd, &vi); ex_vorbis_block_init(&vd, &vb); return True; } Bool BoCA::DecoderVorbis::Deactivate() { ex_ogg_stream_clear(&os); ex_vorbis_block_clear(&vb); ex_vorbis_dsp_clear(&vd); ex_vorbis_comment_clear(&vc); ex_vorbis_info_clear(&vi); ex_ogg_sync_clear(&oy); return True; } Bool BoCA::DecoderVorbis::Seek(Int64 samplePosition) { while (ex_ogg_page_granulepos(&og) + 1024 <= samplePosition || ex_ogg_page_serialno(&og) != os.serialno) { skipSamples = samplePosition - ex_ogg_page_granulepos(&og) - 1024; while (ex_ogg_sync_pageseek(&oy, &og) == 0) { char *buffer = ex_ogg_sync_buffer(&oy, 131072); Int size = driver->ReadData((unsigned char *) buffer, 131072); inBytes += size; ex_ogg_sync_wrote(&oy, size); if (size == 0) return False; } } ex_ogg_stream_pagein(&os, &og); ex_vorbis_synthesis_restart(&vd); return True; } Int BoCA::DecoderVorbis::ReadData(Buffer &data) { const Format &format = track.GetFormat(); Int size = 0; Int dataBufferLen = 0; while (ex_ogg_sync_pageout(&oy, &og) == 1) { ex_ogg_stream_pagein(&os, &og); while (ex_ogg_stream_packetout(&os, &op) == 1) { float **pcm; int samples; if (ex_vorbis_synthesis(&vb, &op) != 0) continue; ex_vorbis_synthesis_blockin(&vd, &vb); while ((samples = ex_vorbis_synthesis_pcmout(&vd, &pcm)) > 0) { Int bout = Math::Min(samples, sizeof(convBuffer) / vi.channels / 2); for (Int i = 0; i < vi.channels; i++) { short *ptr = convBuffer + i; float *mono = pcm[i]; for (Int j = 0; j < bout; j++) { Int val = Int(mono[j] * 32767.f); val = Math::Min(val, 32767); val = Math::Max(val, -32768); *ptr = val; ptr += vi.channels; } } if (bout > skipSamples) { if (dataBufferLen < size + ((bout - skipSamples) * vi.channels * 2)) { dataBufferLen += (((bout - skipSamples) * vi.channels * 2) + 131072); data.Resize(dataBufferLen); } memcpy(((unsigned char *) data) + size, convBuffer + skipSamples * vi.channels, (bout - skipSamples) * vi.channels * 2); size += ((bout - skipSamples) * vi.channels * 2); } skipSamples = Math::Max(0, skipSamples - bout); ex_vorbis_synthesis_read(&vd, bout); } } if (ex_ogg_page_eos(&og)) break; } data.Resize(size); /* Bail out if no more data available. */ char *buffer = ex_ogg_sync_buffer(&oy, 8192); Int bytes = driver->ReadData((unsigned char *) buffer, 8192); if (size == 0 && bytes <= 0) return -1; inBytes += bytes; ex_ogg_sync_wrote(&oy, bytes); if (size == 0) return ReadData(data); /* Change to default channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_3_0, Channel::Default_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_5_0, Channel::Default_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_5_1, Channel::Default_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_6_1, Channel::Default_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Vorbis_7_1, Channel::Default_7_1); return size; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/vorbis/vorbis.h000066400000000000000000000025521516712004000247430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderVorbis) namespace BoCA { class DecoderVorbis : public CS::DecoderComponent { private: ogg_sync_state oy; ogg_stream_state os; ogg_page og; ogg_packet op; vorbis_info vi; vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; short convBuffer[6144]; Int skipSamples; public: static const String &GetComponentSpecs(); DecoderVorbis(); ~DecoderVorbis(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderVorbis) BoCA_END_COMPONENT(DecoderVorbis) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wave/000077500000000000000000000000001516712004000227205ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wave/Makefile000077500000000000000000000011201516712004000243550ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wave TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = wave.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wave/wave.cpp000066400000000000000000000162151516712004000243730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef __WIN32__ # include # include #else # define WAVE_FORMAT_PCM 0x0001 # define WAVE_FORMAT_IEEE_FLOAT 0x0003 # define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif #include "wave.h" using namespace smooth::IO; const String &BoCA::DecoderWave::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Windows Wave File Input \ 1.0 \ wave-dec \ decoder \ \ Microsoft Wave Files \ true \ wav \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ \ "; return componentSpecs; } Bool BoCA::DecoderWave::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); if (in.InputString(4) != "RIFF") return False; in.RelSeek(4); if (in.InputString(4) != "WAVE") return False; String chunk; while (chunk != "fmt ") { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt32 cSize = in.InputNumber(4); if (chunk == "fmt ") { Int waveFormat = in.InputNumber(2); if (waveFormat == WAVE_FORMAT_PCM || waveFormat == WAVE_FORMAT_IEEE_FLOAT || waveFormat == WAVE_FORMAT_EXTENSIBLE) return True; /* Skip rest of chunk. */ if (!in.RelSeek(cSize - 2 + cSize % 2)) break; } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) break; } } return False; } Error BoCA::DecoderWave::GetStreamInfo(const String &streamURI, Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ); track.fileSize = in.Size(); /* Read RIFF chunk. */ if (in.InputString(4) != "RIFF") { errorState = True; errorString = "Unknown file type"; } UnsignedInt32 rSize = in.InputNumber(4); if (in.InputString(4) != "WAVE") { errorState = True; errorString = "Unknown file type"; } String chunk; while (!errorState) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) in.InputNumber(4); if (chunk == "fmt ") { Int waveFormat = in.InputNumber(2); if (waveFormat != WAVE_FORMAT_PCM && waveFormat != WAVE_FORMAT_IEEE_FLOAT && waveFormat != WAVE_FORMAT_EXTENSIBLE) { errorState = True; errorString = "Unsupported audio format"; } Format format = track.GetFormat(); format.channels = (unsigned short) in.InputNumber(2); format.rate = (unsigned long) in.InputNumber(4); in.RelSeek(6); format.fp = (waveFormat == WAVE_FORMAT_IEEE_FLOAT); format.bits = (unsigned short) in.InputNumber(2); format.order = (waveFormat == WAVE_FORMAT_IEEE_FLOAT && format.bits == 64) ? BYTE_NATIVE : BYTE_INTEL; if (format.bits == 8) format.sign = False; track.SetFormat(format); /* Skip rest of chunk. */ in.RelSeek(cSize - 16 + cSize % 2); } else if (chunk == "data") { Format format = track.GetFormat(); if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) cSize = in.Size() - in.GetPos(); track.length = cSize / format.channels / (format.bits / 8); format.bits = Math::Min(32, format.bits); track.SetFormat(format); /* Skip rest of chunk. */ in.RelSeek(cSize + cSize % 2); } else if (chunk == "id3 ") { Buffer buffer(cSize); in.InputData(buffer, cSize); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseBuffer(buffer, track); boca.DeleteComponent(tagger); } /* Skip rest of chunk. */ in.RelSeek(cSize % 2); } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) { errorState = True; errorString = "Invalid file format"; } } } if (!errorState) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *cartTagger = (AS::TaggerComponent *) boca.CreateComponentByID("cart-tag"); if (cartTagger != NIL) { cartTagger->SetConfiguration(GetConfiguration()); cartTagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(cartTagger); } AS::TaggerComponent *riffTagger = (AS::TaggerComponent *) boca.CreateComponentByID("riff-tag"); if (riffTagger != NIL) { riffTagger->SetConfiguration(GetConfiguration()); riffTagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(riffTagger); } } if (errorState) return Error(); else return Success(); } BoCA::DecoderWave::DecoderWave() { floatFormat = False; floatFormatBits = 32; dataOffset = 0; } BoCA::DecoderWave::~DecoderWave() { } Bool BoCA::DecoderWave::Activate() { InStream in(STREAM_DRIVER, driver); in.Seek(12); String chunk; do { /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt32 cSize = in.InputNumber(4); if (chunk == "fmt ") { Int waveFormat = in.InputNumber(2); if (waveFormat == WAVE_FORMAT_IEEE_FLOAT) floatFormat = True; in.RelSeek(12); floatFormatBits = (unsigned short) in.InputNumber(2); /* Skip rest of chunk. */ in.RelSeek(cSize - 16 + cSize % 2); } else if (chunk != "data") { if (!in.RelSeek(cSize + cSize % 2)) return False; } } while (chunk != "data"); dataOffset = in.GetPos(); driver->Seek(dataOffset); return True; } Bool BoCA::DecoderWave::Seek(Int64 samplePosition) { const Format &format = track.GetFormat(); driver->Seek(dataOffset + samplePosition * format.channels * (format.bits / 8) * (floatFormatBits / 32)); return True; } Int BoCA::DecoderWave::ReadData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); if (driver->GetPos() == driver->GetSize()) return -1; /* Read data. */ if (floatFormat && floatFormatBits == 64) data.Resize(data.Size() * 2); Int size = driver->ReadData(data, data.Size()); /* Convert 64 bit float to 32 bit. */ if (floatFormat && floatFormatBits == 64) { if (endianness != EndianLittle) BoCA::Utilities::SwitchBufferByteOrder(data, 8); for (Int i = 0; i < size / 8; i++) { Float64 sample64 = ((Float64 *) (unsigned char *) data)[i]; Float32 &sample32 = ((Float32 *) (unsigned char *) data)[i]; sample32 = sample64; } size /= 2; data.Resize(size); } return size; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wave/wave.h000066400000000000000000000022121516712004000240300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DecoderWave) namespace BoCA { class DecoderWave : public CS::DecoderComponent { private: Bool floatFormat; Int floatFormatBits; Int dataOffset; public: static const String &GetComponentSpecs(); DecoderWave(); ~DecoderWave(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderWave) BoCA_END_COMPONENT(DecoderWave) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/000077500000000000000000000000001516712004000232515ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/Makefile000077500000000000000000000012271516712004000247160ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = winamp TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o winamp.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/config.cpp000077500000000000000000000045731516712004000252360ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" BoCA::ConfigureWinamp::ConfigureWinamp() { I18n *i18n = I18n::Get(); i18n->SetContext("Extensions::Winamp Adapter"); list_input = new ListBox(Point(7, 7), Size(425, 170)); list_input->onSelectEntry.Connect(&ConfigureWinamp::SelectInputPlugin, this); for (Int k = 0; k < winamp_in_modules.Length(); k++) { if (winamp_in_modules.GetNth(k)->version == IN_VER_OLD) list_input->AddEntry(winamp_in_modules.GetNth(k)->description); else list_input->AddEntry((wchar_t *) winamp_in_modules.GetNth(k)->description); } button_input = new Button(i18n->TranslateString("Configure"), Point(440, 7), Size()); button_input->onAction.Connect(&ConfigureWinamp::ConfigureInputPlugin, this); button_input->Deactivate(); button_input_about = new Button(i18n->TranslateString("About"), Point(440, 37), Size()); button_input_about->onAction.Connect(&ConfigureWinamp::AboutInputPlugin, this); button_input_about->Deactivate(); Add(list_input); Add(button_input); Add(button_input_about); SetSize(Size(527, 184)); } BoCA::ConfigureWinamp::~ConfigureWinamp() { DeleteObject(list_input); DeleteObject(button_input); DeleteObject(button_input_about); } Int BoCA::ConfigureWinamp::SaveSettings() { return Success(); } Void BoCA::ConfigureWinamp::SelectInputPlugin() { button_input->Activate(); button_input_about->Activate(); } Void BoCA::ConfigureWinamp::ConfigureInputPlugin() { if (list_input->GetSelectedEntry() == NIL) return; winamp_in_modules.GetNth(list_input->GetSelectedEntryNumber())->Config((HWND) GetContainerWindow()->GetSystemWindow()); } Void BoCA::ConfigureWinamp::AboutInputPlugin() { if (list_input->GetSelectedEntry() == NIL) return; winamp_in_modules.GetNth(list_input->GetSelectedEntryNumber())->About((HWND) GetContainerWindow()->GetSystemWindow()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/config.h000077500000000000000000000021231516712004000246700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_WINAMPCONFIG #define H_WINAMPCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureWinamp : public ConfigLayer { private: ListBox *list_input; Button *button_input; Button *button_input_about; slots: Void SelectInputPlugin(); Void ConfigureInputPlugin(); Void AboutInputPlugin(); public: ConfigureWinamp(); ~ConfigureWinamp(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/dllinterface.cpp000077500000000000000000000042401516712004000264140ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" Array winamp_in_plugins; Array winamp_in_modules; Bool LoadWinampDLLs() { MoveFileA(GUI::Application::GetApplicationDirectory().Append("plugins\\plugins.ini"), GUI::Application::GetApplicationDirectory().Append("freac.ini")); Directory directory = GUI::Application::GetApplicationDirectory().Append("plugins\\"); const Array &in_dlls = directory.GetFilesByPattern("in_*.dll"); for (Int i = 0; i < in_dlls.Length(); i++) { DynamicLoader *dll = new DynamicLoader(in_dlls.GetNth(i)); if (dll == NIL) continue; /* Get winampGetInModule2 function address. */ In_Module *(*proc)() = (In_Module *(*)()) dll->GetFunctionAddress("winampGetInModule2"); if (proc == NIL) { Object::DeleteObject(dll); continue; } /* Get input module description. */ In_Module *module = proc(); if (module->version != IN_VER && module->version != IN_VER_OLD) { Object::DeleteObject(dll); continue; } /* Add module to list. */ winamp_in_plugins.Add(dll); winamp_in_modules.Add(module); module->hDllInstance = (HINSTANCE) dll->GetSystemModuleHandle(); module->hMainWindow = NULL; module->Init(); } return True; } Void FreeWinampDLLs() { for (Int i = 0; i < winamp_in_plugins.Length(); i++) { winamp_in_modules.GetNth(i)->Quit(); Object::DeleteObject(winamp_in_plugins.GetNth(i)); } winamp_in_plugins.RemoveAll(); winamp_in_modules.RemoveAll(); MoveFileA(GUI::Application::GetApplicationDirectory().Append("freac.ini"), GUI::Application::GetApplicationDirectory().Append("plugins\\plugins.ini")); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/dllinterface.h000077500000000000000000000015421516712004000260630ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern Array winamp_in_plugins; extern Array winamp_in_modules; Bool LoadWinampDLLs(); Void FreeWinampDLLs(); boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/winamp.cpp000066400000000000000000000302711516712004000252530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "winamp.h" #include "config.h" using namespace smooth::IO; using namespace smooth::Threads; const String &BoCA::DecoderWinamp::GetComponentSpecs() { static String componentSpecs; if (winamp_in_plugins.Length() > 0) { componentSpecs = " \ \ \ \ Winamp Input Plug-In Adapter \ 1.0 \ winamp-dec \ decoder \ \ "; } for (Int i = 0; i < winamp_in_plugins.Length(); i++) { Int n = 1; Array extensions; for (Int j = 0; true; j++) { String value = winamp_in_modules.GetNth(i)->FileExtensions + j; if (n & 1) { String extension; Int o = 0; for (Int m = 0; m < value.Length(); m++) { extension[m - o] = value[m]; if (value[m + 1] == ';' || value[m + 1] == 0) { extensions.Add(extension); m++; o = m; extension = NIL; } } } else { componentSpecs.Append(" \ \ \ ").Append(value).Append(" \ \ "); for (Int l = 0; l < extensions.Length(); l++) { componentSpecs.Append(" \ \ ").Append(extensions.GetNth(l).ToLower()).Append(" \ \ "); } \ componentSpecs.Append(" \ \ \ \ "); extensions.RemoveAll(); } j += value.Length(); n++; if (winamp_in_modules.GetNth(i)->FileExtensions[j] == 0 && winamp_in_modules.GetNth(i)->FileExtensions[j + 1] == 0) break; } } if (winamp_in_plugins.Length() > 0) { componentSpecs.Append(" \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadWinampDLLs(); } Void smooth::DetachDLL() { FreeWinampDLLs(); } namespace BoCA { DecoderWinamp *filter = NIL; void SetInfo(int, int, int, int); void VSASetInfo(int, int); void VSAAddPCMData(void *, int, int, int); int VSAGetMode(int *, int *); int VSAAdd(void *, int); void SAVSAInit(int, int); void SAVSADeInit(); void SAAddPCMData(void *, int, int, int); int SAGetMode(); int SAAdd(void *, int, int); int dsp_isactive(); int dsp_dosamples(short int *, int, int, int, int); int Out_Open(int, int, int, int, int); void Out_Close(); void Out_Flush(int); int Out_Write(char *, int); int Out_CanWrite(); int Out_IsPlaying(); int Out_Pause(int); void Out_SetVolume(int); void Out_SetPan(int); int Out_GetOutputTime(); int Out_GetWrittenTime(); }; Bool BoCA::DecoderWinamp::CanOpenStream(const String &streamURI) { return (GetModuleForFile(streamURI) != NIL); } Error BoCA::DecoderWinamp::GetStreamInfo(const String &streamURI, Track &track) { InStream *f_in = new InStream(STREAM_FILE, streamURI, IS_READ); track.fileSize = f_in->Size(); track.length = -1; delete f_in; /* Get the correct module and set callback functions. */ In_Module *module = GetModuleForFile(streamURI); module->SetInfo = SetInfo; module->VSASetInfo = VSASetInfo; module->VSAAddPCMData = VSAAddPCMData; module->VSAGetMode = VSAGetMode; module->VSAAdd = VSAAdd; module->SAVSAInit = SAVSAInit; module->SAVSADeInit = SAVSADeInit; module->SAAddPCMData = SAAddPCMData; module->SAGetMode = SAGetMode; module->SAAdd = SAAdd; module->dsp_isactive = dsp_isactive; module->dsp_dosamples = dsp_dosamples; module->outMod = new Out_Module(); module->outMod->Open = Out_Open; module->outMod->Close = Out_Close; module->outMod->Flush = Out_Flush; module->outMod->Write = Out_Write; module->outMod->CanWrite = Out_CanWrite; module->outMod->IsPlaying = Out_IsPlaying; module->outMod->Pause = Out_Pause; module->outMod->SetVolume = Out_SetVolume; module->outMod->SetPan = Out_SetPan; module->outMod->GetOutputTime = Out_GetOutputTime; module->outMod->GetWrittenTime = Out_GetWrittenTime; /* Create and setup mutex. */ samplesBufferMutex = new Mutex(); filter = this; infoTrack = &track; String trackTitle; /* Copy the file and play the temporary copy * if the file name contains Unicode characters. */ if (String::IsUnicode(streamURI)) { File(streamURI).Copy(Utilities::GetNonUnicodeTempFileName(streamURI).Append(".in")); errorState = module->Play(Utilities::GetNonUnicodeTempFileName(streamURI).Append(".in")); } else { errorState = module->Play(streamURI); } if (!errorState) { /* Give the module one second to start sending samples. */ UnsignedInt64 start = S::System::System::Clock(); while (S::System::System::Clock() - start < 1000 && samplesBuffer.Size() <= 0) S::System::System::Sleep(1); /* Get track info and stop module. */ int length_ms = -1; char *title = new char [1024]; module->GetFileInfo(NIL, title, &length_ms); track.approxLength = (Int) (Float(length_ms) * Float(track.GetFormat().rate) / 1000.0); trackTitle = title; delete [] title; module->Stop(); } delete module->outMod; delete samplesBufferMutex; /* Remove temporary copy if necessary. */ if (String::IsUnicode(streamURI)) { File(Utilities::GetNonUnicodeTempFileName(streamURI).Append(".in")).Delete(); } if (!trackTitle.Contains(File( streamURI ).GetFileName()) && !trackTitle.Contains(File(Utilities::GetNonUnicodeTempFileName(streamURI)).GetFileName())) { const Array &parts = trackTitle.Explode(" - "); if (parts.Length() > 1) { Info info = track.GetInfo(); info.artist = parts.GetFirst(); info.title = parts.GetLast(); track.SetInfo(info); } } /* Return an error if we didn't get useful format data. */ if (track.GetFormat().rate == 0 || track.GetFormat().channels == 0 || track.GetFormat().bits == 0) { errorState = True; } if (errorState) return Error(); else return Success(); } BoCA::DecoderWinamp::DecoderWinamp() { configLayer = NIL; infoTrack = NIL; module = NIL; samplesBufferMutex = NIL; samplesDone = 0; } BoCA::DecoderWinamp::~DecoderWinamp() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderWinamp::Activate() { /* Get the correct module and set callback functions. */ module = GetModuleForFile(track.fileName); module->SetInfo = SetInfo; module->VSASetInfo = VSASetInfo; module->VSAAddPCMData = VSAAddPCMData; module->VSAGetMode = VSAGetMode; module->VSAAdd = VSAAdd; module->SAVSAInit = SAVSAInit; module->SAVSADeInit = SAVSADeInit; module->SAAddPCMData = SAAddPCMData; module->SAGetMode = SAGetMode; module->SAAdd = SAAdd; module->dsp_isactive = dsp_isactive; module->dsp_dosamples = dsp_dosamples; module->outMod = new Out_Module(); module->outMod->Open = Out_Open; module->outMod->Close = Out_Close; module->outMod->Flush = Out_Flush; module->outMod->Write = Out_Write; module->outMod->CanWrite = Out_CanWrite; module->outMod->IsPlaying = Out_IsPlaying; module->outMod->Pause = Out_Pause; module->outMod->SetVolume = Out_SetVolume; module->outMod->SetPan = Out_SetPan; module->outMod->GetOutputTime = Out_GetOutputTime; module->outMod->GetWrittenTime = Out_GetWrittenTime; /* Create and setup mutex. */ samplesBufferMutex = new Mutex(); samplesBufferMutex->Lock(); filter = this; /* Copy the file and play the temporary copy * if the file name contains Unicode characters. */ if (String::IsUnicode(track.fileName)) { File(track.fileName).Copy(Utilities::GetNonUnicodeTempFileName(track.fileName).Append(".in")); module->Play(Utilities::GetNonUnicodeTempFileName(track.fileName).Append(".in")); } else { module->Play(track.fileName); } return True; } Bool BoCA::DecoderWinamp::Deactivate() { samplesBufferMutex->Release(); module->Stop(); delete module->outMod; delete samplesBufferMutex; /* Remove temporary copy if necessary. */ if (String::IsUnicode(track.fileName)) { File(Utilities::GetNonUnicodeTempFileName(track.fileName).Append(".in")).Delete(); } return True; } Int BoCA::DecoderWinamp::ReadData(Buffer &data) { /* Give the module one second to send more samples. */ samplesBufferMutex->Release(); UnsignedInt64 start = S::System::System::Clock(); while (S::System::System::Clock() - start < 1000 && samplesBuffer.Size() <= 0) S::System::System::Sleep(1); samplesBufferMutex->Lock(); /* Copy samples to output buffer. */ Int size = samplesBuffer.Size(); data.Resize(size); memcpy(data, samplesBuffer, size); samplesBuffer.Resize(0); /* Set inBytes to a value that reflects * our approximate position in the file. */ samplesDone += size / track.GetFormat().channels / (track.GetFormat().bits / 8); inBytes = track.fileSize * samplesDone / track.approxLength; if (size == 0) return -1; else return size; } ConfigLayer *BoCA::DecoderWinamp::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureWinamp(); return configLayer; } In_Module *BoCA::DecoderWinamp::GetModuleForFile(const String &file) const { In_Module *module = NIL; for (Int i = 0; i < winamp_in_plugins.Length(); i++) { Int n = 1; for (Int j = 0; True; j++) { String value = winamp_in_modules.GetNth(i)->FileExtensions + j; if (n & 1) { String extension; Int o = 0; for (Int m = 0; m < value.Length(); m++) { extension[m - o] = value[m]; if (value[m + 1] == ';' || value[m + 1] == 0) { if (extension.ToLower() == file.Tail(extension.Length()).ToLower()) { module = winamp_in_modules.GetNth(i); break; } m++; o = m + 1; extension = NIL; } } if (module != NIL) break; } j += value.Length(); n++; if (winamp_in_modules.GetNth(i)->FileExtensions[j] == 0 && winamp_in_modules.GetNth(i)->FileExtensions[j + 1] == 0) break; } } return module; } void BoCA::SetInfo(int bitrate, int srate, int stereo, int synched) { } void BoCA::VSASetInfo(int srate, int nch) { } void BoCA::VSAAddPCMData(void *PCMData, int nch, int bps, int timestamp) { } int BoCA::VSAGetMode(int *specNch, int *waveNch) { return 0; } int BoCA::VSAAdd(void *data, int timestamp) { return 0; } void BoCA::SAVSAInit(int latency, int srate) { } void BoCA::SAVSADeInit() { } void BoCA::SAAddPCMData(void *PCMData, int nch, int bps, int timestamp) { } int BoCA::SAGetMode() { return 0; } int BoCA::SAAdd(void *data, int timestamp, int csa) { return 0; } int BoCA::dsp_isactive() { return false; } int BoCA::dsp_dosamples(short int *samples, int numsamples, int bps, int nch, int srate) { return numsamples; } int BoCA::Out_Open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms) { if (filter->infoTrack == NIL) return 0; Format format = filter->infoTrack->GetFormat(); format.channels = numchannels; format.rate = samplerate; format.bits = bitspersamp; filter->infoTrack->SetFormat(format); return 0; } void BoCA::Out_Close() { } void BoCA::Out_Flush(int t) { } int BoCA::Out_Write(char *buf, int len) { filter->samplesBufferMutex->Lock(); Int oSize = filter->samplesBuffer.Size(); filter->samplesBuffer.Resize(oSize + len); memcpy(filter->samplesBuffer + oSize, buf, len); filter->samplesBufferMutex->Release(); return 0; } int BoCA::Out_CanWrite() { return Math::Max(0, 32768 - filter->samplesBuffer.Size()); } int BoCA::Out_IsPlaying() { return true; } int BoCA::Out_Pause(int pause) { return 0; } void BoCA::Out_SetVolume(int vol) { } void BoCA::Out_SetPan(int pan) { } int BoCA::Out_GetOutputTime() { return 0; } int BoCA::Out_GetWrittenTime() { return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/winamp/winamp.h000066400000000000000000000027601516712004000247220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DecoderWinamp) namespace BoCA { class DecoderWinamp : public CS::DecoderComponent { friend int Out_Open(int, int, int, int, int); friend int Out_CanWrite(); friend int Out_Write(char *, int); private: ConfigLayer *configLayer; Buffer samplesBuffer; Threads::Mutex *samplesBufferMutex; Int64 samplesDone; Track *infoTrack; In_Module *module; In_Module *GetModuleForFile(const String &) const; public: static const String &GetComponentSpecs(); DecoderWinamp(); ~DecoderWinamp(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Int ReadData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderWinamp) BoCA_END_COMPONENT(DecoderWinamp) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/000077500000000000000000000000001516712004000225425ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/Makefile000077500000000000000000000012431516712004000242050ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wma TYPE = decoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o wma.o wmareader.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = -lole32 -luuid # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/dllinterface.cpp000077500000000000000000000017601516712004000257110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" WMCREATEREADER ex_WMCreateReader = NIL; DynamicLoader *wmvcoredll = NIL; Bool LoadWMVCoreDLL() { wmvcoredll = new DynamicLoader("WMVCore"); ex_WMCreateReader = (WMCREATEREADER) wmvcoredll->GetFunctionAddress("WMCreateReader"); if (ex_WMCreateReader == NIL) { FreeWMVCoreDLL(); return False; } return True; } Void FreeWMVCoreDLL() { Object::DeleteObject(wmvcoredll); wmvcoredll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/dllinterface.h000077500000000000000000000016101516712004000253500ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *wmvcoredll; Bool LoadWMVCoreDLL(); Void FreeWMVCoreDLL(); typedef HRESULT (STDMETHODCALLTYPE *WMCREATEREADER) (IUnknown *, DWORD, IWMReader **); extern WMCREATEREADER ex_WMCreateReader; boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/wma.cpp000066400000000000000000000313401516712004000240330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "wmsdk/asferr.h" #include "wma.h" using namespace smooth::IO; const String &BoCA::DecoderWMA::GetComponentSpecs() { static String componentSpecs; if (wmvcoredll != NIL) { componentSpecs = " \ \ \ \ Windows Media Audio Decoder \ 1.0 \ wma-dec \ decoder \ \ Windows Media Audio Files \ wma \ WMA Metadata \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadWMVCoreDLL(); /* Register initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::DecoderWMA::Initialize); engine->onCleanup.Connect(&BoCA::DecoderWMA::Cleanup); } } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::DecoderWMA::Initialize); engine->onCleanup.Disconnect(&BoCA::DecoderWMA::Cleanup); } FreeWMVCoreDLL(); } Void BoCA::DecoderWMA::Initialize() { /* Init the Microsoft COM library. */ CoInitialize(NIL); } Void BoCA::DecoderWMA::Cleanup() { /* Uninit the Microsoft COM library. */ CoUninitialize(); } Bool BoCA::DecoderWMA::CanOpenStream(const String &streamURI) { InStream in(STREAM_FILE, streamURI, IS_READ); UnsignedInt64 magic = in.InputNumber(8); return (magic == 0x11CF668E75B22630); } Error BoCA::DecoderWMA::GetStreamInfo(const String &streamURI, Track &track) { /* Get file size. */ InStream in(STREAM_FILE, streamURI, IS_READ); track.fileSize = in.Size(); /* Create WMA reader object. */ HRESULT hr = ex_WMCreateReader(NIL, WMT_RIGHT_PLAYBACK, &reader); if (FAILED(hr)) return Error(); hr = reader->QueryInterface(IID_IWMReaderAdvanced2, (void **) &readerAdvanced); if (FAILED(hr)) { reader->Release(); return Error(); } /* Initialize reader callback. */ readerCallback = new WMAReader(); asyncEvent = readerCallback->GetAsyncEventHandle(); /* Open file. */ hr = reader->Open(Directory::MakeExtendedPath(File(streamURI)), readerCallback, NIL); /* Wait for the Open call to complete. The event is set in the * OnStatus callback when the reader reports completion. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); if (!errorState) { DWORD cOutputs = 0; WAVEFORMATEX *pWfx = NIL; /* Find out the output count */ reader->GetOutputCount(&cOutputs); /* Find the first audio output. */ for (DWORD i = 0; i < cOutputs; i++) { /* Enable high definition output. */ BOOL enableDiscreteOutput = TRUE; DWORD speakerConfig = DSSPEAKER_DIRECTOUT; readerAdvanced->SetOutputSetting(i, g_wszEnableDiscreteOutput, WMT_TYPE_BOOL, (BYTE *) &enableDiscreteOutput, sizeof(WMT_TYPE_BOOL)); readerAdvanced->SetOutputSetting(i, g_wszSpeakerConfig, WMT_TYPE_DWORD, (BYTE *) &speakerConfig, sizeof(WMT_TYPE_DWORD)); /* Set the first output format as it is * the one with the highest quality. */ IWMOutputMediaProps *pProps = NIL; if (!FAILED(reader->GetOutputFormat(i, 0, &pProps))) { if (!FAILED(reader->SetOutputProps(i, pProps))) { /* Find out the space needed for pMediaType */ ULONG cbType = 0; if (!FAILED(pProps->GetMediaType(NIL, &cbType))) { WM_MEDIA_TYPE *pMediaType = (WM_MEDIA_TYPE *) new BYTE[cbType]; /* Get the value for MediaType */ if (!FAILED(pProps->GetMediaType(pMediaType, &cbType)) && pMediaType->majortype == WMMEDIATYPE_Audio) { /* Store the wave format for this output */ pWfx = (WAVEFORMATEX *) new BYTE[pMediaType->cbFormat]; CopyMemory(pWfx, pMediaType->pbFormat, pMediaType->cbFormat); } delete [] pMediaType; } } pProps->Release(); } if (pWfx != NIL) break; } if (pWfx != NIL) { Format format = track.GetFormat(); format.bits = pWfx->wBitsPerSample; format.rate = pWfx->nSamplesPerSec; format.channels = pWfx->nChannels; track.SetFormat(format); delete [] pWfx; } if (pWfx == NIL) { errorState = True; errorString = "Unknown file type"; } } if (!errorState) { IWMHeaderInfo2 *pHeaderInfo = NIL; BYTE *pbValue = NIL; hr = reader->QueryInterface(IID_IWMHeaderInfo2, (void **) &pHeaderInfo); /* Get attribute "Duration". */ if (!FAILED(hr)) hr = GetHeaderAttribute(pHeaderInfo, g_wszWMDuration, &pbValue); if (!FAILED(hr) && pbValue != NIL && *(QWORD *) pbValue != 0) { /* Set approxLength, because WMA duration is not always 100% accurate. */ Format format = track.GetFormat(); track.length = -1; track.approxLength = *(QWORD *) pbValue / 1e7 * format.rate; delete [] pbValue; } /* Get codec infos. */ DWORD nCodecInfos; if (!FAILED(hr)) hr = pHeaderInfo->GetCodecInfoCount(&nCodecInfos); if (!FAILED(hr)) { /* See if this is a lossless file. */ for (UnsignedInt i = 0; i < nCodecInfos; i++) { WORD wNameSize = 0; WORD wDescSize = 0; WORD wCodecInfoSize = sizeof(WORD); WORD wCodecInfo = 0; WMT_CODEC_INFO_TYPE codecType = WMT_CODECINFO_UNKNOWN; hr = pHeaderInfo->GetCodecInfo(i, &wNameSize, NIL, &wDescSize, NIL, &codecType, &wCodecInfoSize, (BYTE *) &wCodecInfo); if (!FAILED(hr) && codecType == WMT_CODECINFO_AUDIO && wCodecInfoSize == sizeof(WORD)) { if (wCodecInfo == WAVE_FORMAT_PCM || wCodecInfo == WAVE_FORMAT_IEEE_FLOAT || wCodecInfo == WAVE_FORMAT_WMAUDIO_LOSSLESS) track.lossless = True; else track.lossless = False; break; } } } pHeaderInfo->Release(); } hr = reader->Close(); /* Wait for the reader to deliver a WMT_CLOSED event to the * OnStatus callback. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); readerAdvanced->Release(); reader->Release(); readerCallback->Release(); if (!errorState) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("wma-tag"); if (tagger != NIL) { tagger->SetConfiguration(GetConfiguration()); tagger->ParseStreamInfo(streamURI, track); boca.DeleteComponent(tagger); } } if (errorState) return Error(); else return Success(); } BoCA::DecoderWMA::DecoderWMA() { reader = NIL; readerAdvanced = NIL; asyncEvent = NIL; readerCallback = NIL; userProvidedClock = True; } BoCA::DecoderWMA::~DecoderWMA() { } Bool BoCA::DecoderWMA::Activate() { /* Create WMA reader object. */ HRESULT hr = ex_WMCreateReader(NIL, WMT_RIGHT_PLAYBACK, &reader); if (FAILED(hr)) return False; hr = reader->QueryInterface(IID_IWMReaderAdvanced2, (void **) &readerAdvanced); if (FAILED(hr)) { reader->Release(); return False; } /* Initialize reader callback. */ readerCallback = new WMAReader(); readerCallback->SetReaderAdvanced(readerAdvanced); readerCallback->SetSamplesBuffer(&samplesBuffer, &samplesBufferMutex); asyncEvent = readerCallback->GetAsyncEventHandle(); /* Open file. */ hr = reader->Open(Directory::MakeExtendedPath(File(track.fileName)), readerCallback, NIL); /* Wait for the Open call to complete. The event is set in the * OnStatus callback when the reader reports completion. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); readerAdvanced->SetUserProvidedClock(userProvidedClock); DWORD cOutputs = 0; /* Find out the output count */ reader->GetOutputCount(&cOutputs); /* Find the first audio output. */ for (DWORD i = 0; i < cOutputs; i++) { /* Enable high definition output. */ BOOL enableDiscreteOutput = TRUE; DWORD speakerConfig = 0; readerAdvanced->SetOutputSetting(i, g_wszEnableDiscreteOutput, WMT_TYPE_BOOL, (BYTE *) &enableDiscreteOutput, sizeof(WMT_TYPE_BOOL)); readerAdvanced->SetOutputSetting(i, g_wszSpeakerConfig, WMT_TYPE_DWORD, (BYTE *) &speakerConfig, sizeof(WMT_TYPE_DWORD)); /* Set the first output format as it is * the one with the highest quality. */ IWMOutputMediaProps *pProps = NIL; if (!FAILED(reader->GetOutputFormat(i, 0, &pProps))) { if (!FAILED(reader->SetOutputProps(i, pProps))) { /* Find out the space needed for pMediaType */ ULONG cbType = 0; if (!FAILED(pProps->GetMediaType(NIL, &cbType))) { WM_MEDIA_TYPE *pMediaType = (WM_MEDIA_TYPE *) new BYTE[cbType]; /* Get the value for MediaType */ if (!FAILED(pProps->GetMediaType(pMediaType, &cbType)) && pMediaType->majortype == WMMEDIATYPE_Audio) { readerCallback->SetAudioOutputNum(i); hr = reader->Start(0, 0, 1.0, NIL); /* Wait for the Start call to complete. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); } delete [] pMediaType; } } pProps->Release(); } } /* Some streams do not work with a user provided clock. * Detect this here and try without it in case of an error. */ while (readerCallback->IsActive() && samplesBuffer.Size() <= 0) S::System::System::Sleep(1); if (!readerCallback->IsActive() && samplesBuffer.Size() <= 0) { if (!userProvidedClock) return False; Deactivate(); userProvidedClock = False; errorState = False; return Activate(); } return True; } Bool BoCA::DecoderWMA::Deactivate() { readerCallback->SetActive(False); HRESULT hr = reader->Stop(); /* Wait for the reader to stop. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); hr = reader->Close(); /* Wait for the reader to deliver a WMT_CLOSED event to the * OnStatus callback. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); readerAdvanced->Release(); reader->Release(); readerCallback->Release(); return True; } Bool BoCA::DecoderWMA::Seek(Int64 samplePosition) { /* Stop reader before seeking. */ readerCallback->SetActive(False); HRESULT hr = reader->Stop(); /* Wait for the reader to stop. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); /* Clear samples buffer. */ samplesBuffer.Resize(0); /* Restart reader at new position. */ QWORD position = samplePosition * 1e7 / track.GetFormat().rate; hr = reader->Start(position, 0, 1.0, &position); /* Wait for the Start call to complete. */ if (!FAILED(hr)) WaitForEvent(asyncEvent); return True; } Int BoCA::DecoderWMA::ReadData(Buffer &data) { if (!readerCallback->IsActive() && samplesBuffer.Size() <= 0) return -1; while (readerCallback->IsActive() && samplesBuffer.Size() <= 0) S::System::System::Sleep(1); /* Copy any data from the sample buffer. */ samplesBufferMutex.Lock(); data.Resize(samplesBuffer.Size()); memcpy(data, samplesBuffer, samplesBuffer.Size()); samplesBuffer.Resize(0); samplesBufferMutex.Release(); /* Update inBytes to indicate progress. */ if (track.approxLength > 0) inBytes += track.fileSize * data.Size() / (track.approxLength * track.GetFormat().channels * (track.GetFormat().bits / 8)); return data.Size(); } HRESULT BoCA::DecoderWMA::GetHeaderAttribute(IWMHeaderInfo *pHeaderInfo, LPCWSTR pwszName, BYTE **ppbValue) { WMT_ATTR_DATATYPE wmtType; WORD wStreamNum = 0; WORD cbLength = 0; *ppbValue = NIL; /* Get the number of bytes to be allocated for pbValue */ HRESULT hr = pHeaderInfo->GetAttributeByName(&wStreamNum, pwszName, &wmtType, NIL, &cbLength); /* No such an attribute, so return */ if (hr == ASF_E_NOTFOUND) return S_OK; if (FAILED(hr)) return hr; /* Allocate space and get the actual value */ *ppbValue = new BYTE[cbLength]; pHeaderInfo->GetAttributeByName(&wStreamNum, pwszName, &wmtType, *ppbValue, &cbLength); return S_OK; } Void BoCA::DecoderWMA::WaitForEvent(HANDLE hEvent, DWORD msMaxWaitTime) { for (DWORD i = 0; i < msMaxWaitTime; i += 10) { MSG msg; if (PeekMessage(&msg, (HWND) NIL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if (WaitForSingleObject(hEvent, 10) != WAIT_TIMEOUT) break; } if (readerCallback->IsError()) { errorState = True; errorString = readerCallback->GetErrorString(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/wma.h000066400000000000000000000030751516712004000235040ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" #include "wmareader.h" BoCA_BEGIN_COMPONENT(DecoderWMA) namespace BoCA { class DecoderWMA : public CS::DecoderComponent { friend class WMAReader; private: WMAReader *readerCallback; Buffer samplesBuffer; Threads::Mutex samplesBufferMutex; Bool userProvidedClock; HANDLE asyncEvent; IWMReader *reader; IWMReaderAdvanced2 *readerAdvanced; HRESULT GetHeaderAttribute(IWMHeaderInfo *, LPCWSTR, BYTE **); Void WaitForEvent(HANDLE, DWORD = INFINITE); public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); DecoderWMA(); ~DecoderWMA(); Bool CanOpenStream(const String &); Error GetStreamInfo(const String &, Track &); Bool Activate(); Bool Deactivate(); Bool Seek(Int64); Int ReadData(Buffer &); }; }; BoCA_DEFINE_DECODER_COMPONENT(DecoderWMA) BoCA_END_COMPONENT(DecoderWMA) boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/wmareader.cpp000066400000000000000000000124611516712004000252210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "wmareader.h" using namespace smooth::Threads; BoCA::WMAReader::WMAReader() { m_cRef = 1; m_fEOF = false; m_qwTime = 0; m_dwAudioOutputNum = 0; m_hAsyncEvent = CreateEvent(NIL, FALSE, FALSE, NIL); m_pReaderAdvanced = NIL; active = False; error = False; samplesBuffer = NIL; samplesBufferMutex = NIL; } BoCA::WMAReader::~WMAReader() { CloseHandle(m_hAsyncEvent); } STDMETHODIMP BoCA::WMAReader::QueryInterface(REFIID riid, void __RPC_FAR * __RPC_FAR *ppvObject) { if (ppvObject == NIL) return E_INVALIDARG; if (riid == IID_IUnknown) *ppvObject = (this); else if (riid == IID_IWMStatusCallback) *ppvObject = static_cast (this); else if (riid == IID_IWMReaderCallback) *ppvObject = static_cast (this); else if (riid == IID_IWMReaderCallbackAdvanced) *ppvObject = static_cast(this); else *ppvObject = NIL; if (*ppvObject == NIL) return E_NOINTERFACE; AddRef(); return S_OK; } STDMETHODIMP_(ULONG) BoCA::WMAReader::AddRef() { return InterlockedIncrement(&m_cRef); } STDMETHODIMP_(ULONG) BoCA::WMAReader::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; } return m_cRef; } STDMETHODIMP BoCA::WMAReader::OnStatus(WMT_STATUS status, HRESULT hr, WMT_ATTR_DATATYPE dwType, BYTE __RPC_FAR *pValue, void __RPC_FAR *pvContext) { /* This switch checks for the important messages sent by the reader object. */ switch (status) { /* The reader is finished opening a file. */ case WMT_OPENED: SetAsyncEvent(hr); break; /* The reader is finished closing a file. */ case WMT_CLOSED: SetAsyncEvent(hr); break; /* Playback of the opened file has begun. */ case WMT_STARTED: if (pvContext == NIL) m_qwTime = 10000000; else m_qwTime = *(QWORD *) pvContext + 10000000; m_pReaderAdvanced->DeliverTime(m_qwTime); active = True; SetAsyncEvent(hr); break; /* The previously playing reader has stopped. */ case WMT_STOPPED: active = False; SetAsyncEvent(hr); break; case WMT_EOF: active = False; m_fEOF = true; break; /* This class reacts to any errors by changing its state to stopped. */ case WMT_ERROR: active = False; error = True; errorString = "Unknown error"; break; case WMT_MISSING_CODEC: error = True; errorString = "Missing appropriate codec"; break; case WMT_NO_RIGHTS: case WMT_NO_RIGHTS_EX: error = True; errorString = "Cannot open protected files"; break; /* Do nothing on other events. */ default: break; } return S_OK; } STDMETHODIMP BoCA::WMAReader::OnSample(DWORD dwOutputNum, QWORD cnsSampleTime, QWORD cnsSampleDuration, DWORD dwFlags, INSSBuffer *pSample, void *pvContext) { /* Check the output number of the sample against the stored output number. * Because only the first audio output is stored, all other outputs, * regardless of type, will be ignored. */ if (dwOutputNum != m_dwAudioOutputNum) return S_OK; BYTE *pData = NIL; DWORD cbData = 0; /* Get the sample from the buffer object. */ HRESULT hr = pSample->GetBufferAndLength(&pData, &cbData); if (hr == S_OK) { while (IsActive() && samplesBuffer->Size() >= 131072) S::System::System::Sleep(1); /* Copy the sample to the sample buffer. */ if (IsActive()) { samplesBufferMutex->Lock(); samplesBuffer->Resize(samplesBuffer->Size() + cbData); memcpy((UnsignedByte *) *samplesBuffer + samplesBuffer->Size() - cbData, pData, cbData); samplesBufferMutex->Release(); } } return hr; } STDMETHODIMP BoCA::WMAReader::OnTime(QWORD cnsCurrentTime, void *pvContext) { HRESULT hr = S_OK; /* Keep asking for the specific duration of the stream till EOF */ if (m_fEOF == false) { m_qwTime += 10000000; // 1 second hr = m_pReaderAdvanced->DeliverTime(m_qwTime); } return hr; } Void BoCA::WMAReader::SetAsyncEvent(HRESULT hrAsync) { SetEvent(m_hAsyncEvent); } Bool BoCA::WMAReader::IsActive() { return active; } Void BoCA::WMAReader::SetActive(Bool nActive) { active = nActive; } Bool BoCA::WMAReader::IsError() { return error; } const String &BoCA::WMAReader::GetErrorString() { return errorString; } HANDLE BoCA::WMAReader::GetAsyncEventHandle() const { return m_hAsyncEvent; } Void BoCA::WMAReader::SetReaderAdvanced(IWMReaderAdvanced *pReaderAdvanced) { m_pReaderAdvanced = pReaderAdvanced; } Void BoCA::WMAReader::SetAudioOutputNum(DWORD dwAudioOutputNum) { m_dwAudioOutputNum = dwAudioOutputNum; } Void BoCA::WMAReader::SetSamplesBuffer(Buffer *buffer, Mutex *mutex) { samplesBuffer = buffer; samplesBufferMutex = mutex; /* Allocate 128kB for the sample buffer. */ samplesBuffer->Resize(131072); samplesBuffer->Resize(0); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/decoder/wma/wmareader.h000066400000000000000000000052561516712004000246720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BOCA_WMA_READER #define H_BOCA_WMA_READER #include #include "dllinterface.h" namespace BoCA { class WMAReader : public IWMReaderCallback, public IWMReaderCallbackAdvanced { private: LONG m_cRef; BOOL m_fEOF; QWORD m_qwTime; DWORD m_dwAudioOutputNum; HANDLE m_hAsyncEvent; IWMReaderAdvanced *m_pReaderAdvanced; Bool active; Bool error; String errorString; Buffer *samplesBuffer; Threads::Mutex *samplesBufferMutex; public: WMAReader(); virtual ~WMAReader(); Void SetAsyncEvent(HRESULT hrAsync); accessors: Bool IsActive(); Void SetActive(Bool); Bool IsError(); const String &GetErrorString(); HANDLE GetAsyncEventHandle() const; Void SetReaderAdvanced(IWMReaderAdvanced *); Void SetAudioOutputNum(DWORD); Void SetSamplesBuffer(Buffer *, Threads::Mutex *); public: /* IUnknown methods */ STDMETHOD(QueryInterface)(REFIID, void __RPC_FAR * __RPC_FAR *); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); /* IWMStatusCallback methods */ STDMETHOD(OnStatus)(WMT_STATUS, HRESULT, WMT_ATTR_DATATYPE, BYTE *, void *); /* IWMReaderCallback methods */ STDMETHOD(OnSample)(DWORD, QWORD, QWORD, DWORD, INSSBuffer *, void *); /* IWMReaderCallbackAdvanced methods */ STDMETHOD(OnTime)(QWORD, void *); STDMETHOD(OnStreamSample)(WORD wStreamNum, QWORD cnsSampleTime, QWORD cnsSampleDuration, DWORD dwFlags, INSSBuffer *pSample, void *pvContext) { return S_OK; } STDMETHOD(OnStreamSelection)(WORD wStreamCount, WORD *pStreamNumbers, WMT_STREAM_SELECTION *pSelections, void *pvContext) { return S_OK; } STDMETHOD(OnOutputPropsChanged)(DWORD dwOutputNum, WM_MEDIA_TYPE *pMediaType, void *pvContext) { return S_OK; } STDMETHOD(AllocateForStream)(WORD wStreamNum, DWORD cbBuffer, INSSBuffer **ppBuffer, void *pvContext) { return E_NOTIMPL; } STDMETHOD(AllocateForOutput)(DWORD dwOutputNum, DWORD cbBuffer, INSSBuffer **ppBuffer, void *pvContext) { return E_NOTIMPL; } }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/000077500000000000000000000000001516712004000224645ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/Makefile000077500000000000000000000015621516712004000241330ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = ifeq ($(BUILD_UNIX),True) ifneq ($(BUILD_HAIKU),True) ifneq ($(BUILD_OPENBSD),True) FOLDERS += cdio else FOLDERS += cdparanoia endif endif else ifeq ($(BUILD_WIN32),True) FOLDERS += cdrip endif .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdio/000077500000000000000000000000001516712004000234025ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdio/Makefile000066400000000000000000000013431516712004000250430ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdio TYPE = deviceinfo VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = cdio.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lcdio ifeq ($(BUILD_WIN32),True) LIBS += -lws2_32 -lwinmm endif # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdio/cdio.cpp000066400000000000000000000213031516712004000250230ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include #ifndef __WIN32__ # include #endif #ifndef PATH_MAX # define PATH_MAX 32768 #endif #include "cdio.h" static Int numDrives = 0; const String &BoCA::DeviceInfoCDIO::GetComponentSpecs() { static String componentSpecs; #ifndef __APPLE__ if (numDrives >= 1) #endif { componentSpecs = " \ \ \ \ CDIO Device Info Component \ 1.0 \ cdio-info \ deviceinfo \ cdparanoia-info \ \ \ "; } return componentSpecs; } const Array &BoCA::DeviceInfoCDIO::FindDrives() { static Array driveNames; static Bool initialized = False; #ifndef __APPLE__ if (initialized) return driveNames; #else /* Do not query drives again if the last request * was less than a quarter of a second ago. */ static UnsignedInt64 lastAccess = 0; { UnsignedInt64 clockValue = S::System::System::Clock(); if (clockValue - lastAccess < 250) { lastAccess = clockValue; return driveNames; } } #endif driveNames.RemoveAll(); #ifndef __NetBSD__ char **deviceNames = cdio_get_devices(DRIVER_DEVICE); #else char *deviceNames[3] = { "/dev/cd0d", "/dev/cd1d", NIL }; #endif for (Int i = 0; deviceNames != NIL && deviceNames[i] != NIL; i++) { String deviceName = deviceNames[i]; #ifndef __WIN32__ /* Resolve link if it is one. */ Buffer buffer(PATH_MAX + 1); buffer.Zero(); if (readlink(deviceName, buffer, buffer.Size() - 1) >= 0) { if (buffer[0] == '/') deviceName = buffer; else deviceName = File(deviceName).GetFilePath().Append("/").Append((char *) buffer); } #endif /* Check if we aleady know this device. */ foreach (const String &driveName, driveNames) { if (driveName == deviceName) { deviceName = NIL; break; } } if (deviceName == NIL) continue; /* Try to open device and add it to the list. */ CdIo_t *cd = cdio_open(deviceName, DRIVER_UNKNOWN); if (cd != NIL) { driveNames.Add(deviceName); cdio_destroy(cd); } } #ifndef __NetBSD__ cdio_free_device_list(deviceNames); #endif #ifdef __APPLE__ lastAccess = S::System::System::Clock(); #endif initialized = True; return driveNames; } Void smooth::AttachDLL(Void *instance) { BoCA::Config *config = BoCA::Config::Get(); const Array &driveNames = BoCA::DeviceInfoCDIO::FindDrives(); numDrives = driveNames.Length(); if (numDrives <= config->GetIntValue("Ripper", "ActiveDrive", 0)) config->SetIntValue("Ripper", "ActiveDrive", 0); } Void smooth::DetachDLL() { } namespace BoCA { static Bool OpenDriveTray(Int n) { const Array &driveNames = DeviceInfoCDIO::FindDrives(); /* Eject. */ if (cdio_eject_media_drive(driveNames.GetNth(n)) == DRIVER_OP_SUCCESS) return True; else return False; } }; BoCA::DeviceInfoCDIO::DeviceInfoCDIO() { CollectDriveInfo(); } BoCA::DeviceInfoCDIO::~DeviceInfoCDIO() { } Bool BoCA::DeviceInfoCDIO::IsNthDeviceTrayOpen(Int n) { #ifndef __APPLE__ const Array &driveNames = FindDrives(); CdIo_t *cd = cdio_open(driveNames.GetNth(n), DRIVER_UNKNOWN); if (cd == NIL) return False; /* Get tray status. */ Bool status = mmc_get_tray_status(cd); cdio_destroy(cd); return status; #else /* On macOS, drives are available only when closed. */ return False; #endif } Bool BoCA::DeviceInfoCDIO::OpenNthDeviceTray(Int n) { Int nDrives = GetNumberOfDevices(); if (n >= nDrives) return False; NonBlocking1(&OpenDriveTray).Call(n); return True; } Bool BoCA::DeviceInfoCDIO::CloseNthDeviceTray(Int n) { const Array &driveNames = FindDrives(); /* Close tray. */ if (cdio_close_tray(driveNames.GetNth(n), NIL) == DRIVER_OP_SUCCESS) return True; else return False; } const Array &BoCA::DeviceInfoCDIO::GetNthDeviceTrackList(Int n) { static Array trackList; trackList.RemoveAll(); const MCDI &mcdi = GetNthDeviceMCDI(n); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { /* Find all valid audio tracks (tracks with a positive length). */ if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i) > 0) { /* Look for hidden track before the first track (HTOA). */ if (i == 0 && mcdi.GetNthEntryOffset(i) >= 450) { trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(0))); } /* Add CD track to joblist using a device:// URI */ trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(mcdi.GetNthEntryTrackNumber(i)))); } } return trackList; } const BoCA::MCDI &BoCA::DeviceInfoCDIO::GetNthDeviceMCDI(Int n) { static MCDI mcdi = MCDI(Buffer()); /* Do not read the TOC again if the last request * was less than a quarter of a second ago. */ static Int lastDrive = -1; static UnsignedInt64 lastAccess = 0; { UnsignedInt64 clockValue = S::System::System::Clock(); if (lastDrive == n && clockValue - lastAccess < 250) { lastAccess = clockValue; return mcdi; } } mcdi.SetData(Buffer()); const Array &driveNames = FindDrives(); CdIo_t *cd = cdio_open(driveNames.GetNth(n), DRIVER_UNKNOWN); if (cd != NIL) { typedef struct { uint8_t rsvd; uint8_t ADR; uint8_t trackNumber; uint8_t rsvd2; uint32_t addr; } __attribute__((__packed__)) TOCTRACK; typedef struct { uint16_t tocLen; uint8_t firstTrack; uint8_t lastTrack; TOCTRACK tracks[100]; } __attribute__((__packed__)) TOC; if (cdio_get_discmode(cd) != CDIO_DISC_MODE_ERROR && cdio_get_num_tracks(cd) != CDIO_INVALID_TRACK) { TOC toc; toc.tocLen = htons(2 + cdio_get_num_tracks(cd) * 8 + 8); toc.firstTrack = cdio_get_first_track_num(cd); toc.lastTrack = cdio_get_last_track_num(cd); for (Int i = 0; i <= toc.lastTrack - toc.firstTrack; i++) { toc.tracks[i].rsvd = 0; toc.tracks[i].ADR = (0x01 << 4) | ((cdio_get_track_format(cd, toc.firstTrack + i) != TRACK_FORMAT_AUDIO) << 2) | (cdio_get_track_copy_permit(cd, toc.firstTrack + i) << 1) | (cdio_get_track_preemphasis(cd, toc.firstTrack + i)); toc.tracks[i].trackNumber = toc.firstTrack + i; toc.tracks[i].rsvd2 = 0; toc.tracks[i].addr = htonl(cdio_get_track_lsn(cd, toc.firstTrack + i)); } toc.tracks[toc.lastTrack - toc.firstTrack + 1].rsvd = 0; toc.tracks[toc.lastTrack - toc.firstTrack + 1].ADR = (0x01 << 4) | ((cdio_get_track_format(cd, CDIO_CDROM_LEADOUT_TRACK) != TRACK_FORMAT_AUDIO) << 2) | (cdio_get_track_copy_permit(cd, CDIO_CDROM_LEADOUT_TRACK) << 1) | (cdio_get_track_preemphasis(cd, CDIO_CDROM_LEADOUT_TRACK)); toc.tracks[toc.lastTrack - toc.firstTrack + 1].trackNumber = 0xAA; toc.tracks[toc.lastTrack - toc.firstTrack + 1].rsvd2 = 0; toc.tracks[toc.lastTrack - toc.firstTrack + 1].addr = htonl(cdio_get_track_lsn(cd, CDIO_CDROM_LEADOUT_TRACK)); Buffer buffer(ntohs(toc.tocLen) + 2); memcpy(buffer, &toc, ntohs(toc.tocLen) + 2); mcdi.SetData(buffer); } cdio_destroy(cd); } lastDrive = n; lastAccess = S::System::System::Clock(); return mcdi; } Void BoCA::DeviceInfoCDIO::CollectDriveInfo() { static Bool initialized = False; #ifndef __APPLE__ if (initialized) return; #endif devices.RemoveAll(); const Array &driveNames = FindDrives(); foreach (const String &driveName, driveNames) { CdIo_t *cd = cdio_open(driveName, DRIVER_UNKNOWN); cdio_hwinfo_t device; if (cd == NIL) continue; cdio_get_hwinfo(cd, &device); Device drive; drive.type = DEVICE_CDROM; drive.vendor = String(device.psz_vendor).Trim(); drive.model = String(device.psz_model).Trim(); drive.revision = String(device.psz_revision).Trim(); drive.path = driveName; drive.canOpenTray = True; devices.Add(drive); cdio_destroy(cd); } initialized = True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdio/cdio.h000066400000000000000000000022731516712004000244750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DeviceInfoCDIO) namespace BoCA { class DeviceInfoCDIO : public CS::DeviceInfoComponent { private: Void CollectDriveInfo(); public: static const String &GetComponentSpecs(); static const Array &FindDrives(); DeviceInfoCDIO(); ~DeviceInfoCDIO(); Bool IsNthDeviceTrayOpen(Int); Bool OpenNthDeviceTray(Int); Bool CloseNthDeviceTray(Int); const Array &GetNthDeviceTrackList(Int); const MCDI &GetNthDeviceMCDI(Int); }; }; BoCA_DEFINE_DEVICEINFO_COMPONENT(DeviceInfoCDIO) BoCA_END_COMPONENT(DeviceInfoCDIO) boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdparanoia/000077500000000000000000000000001516712004000245655ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdparanoia/Makefile000066400000000000000000000012051516712004000262230ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdparanoia TYPE = deviceinfo VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = cdparanoia.o # Enter additional defines here: DEFINE = -I /usr/include/cdda # Enter additional library dependencies here: LIBS = -lcdda_interface # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdparanoia/cdparanoia.cpp000066400000000000000000000204321516712004000273730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include extern "C" { # include } #include #include #include #include #ifdef __linux__ # include #else # include #endif #include "cdparanoia.h" static Int numDrives = 0; const String &BoCA::DeviceInfoCDParanoia::GetComponentSpecs() { static String componentSpecs; if (numDrives >= 1) { componentSpecs = " \ \ \ \ cdparanoia Device Info Component \ 1.0 \ cdparanoia-info \ deviceinfo \ \ \ "; } return componentSpecs; } const Array &BoCA::DeviceInfoCDParanoia::FindDrives() { #if defined __linux__ static const char *deviceNames[] = { "/dev/hd?", "/dev/sr?", "/dev/scd?", NIL }; #elif defined __FreeBSD__ static const char *deviceNames[] = { "/dev/acd?", "/dev/cd?", NIL }; #elif defined __OpenBSD__ static const char *deviceNames[] = { "/dev/cd?c", NIL }; #elif defined __NetBSD__ static const char *deviceNames[] = { "/dev/cd?d", NIL }; #else static const char *deviceNames[] = { "/dev/cdrom?", NIL }; #endif static Array driveNames; static Bool initialized = False; if (initialized) return driveNames; for (Int i = 0; deviceNames[i] != NIL; i++) { glob_t fileData = { 0 }; if (glob(deviceNames[i], 0, NIL, &fileData) == 0) { for (UnsignedInt n = 0; n < fileData.gl_pathc; n++) { cdrom_drive *cd = cdda_identify(fileData.gl_pathv[n], CDDA_MESSAGE_FORGETIT, NIL); if (cd != NIL) { driveNames.Add(fileData.gl_pathv[n]); cdda_close(cd); } } globfree(&fileData); } } initialized = True; return driveNames; } Void smooth::AttachDLL(Void *instance) { BoCA::Config *config = BoCA::Config::Get(); const Array &driveNames = BoCA::DeviceInfoCDParanoia::FindDrives(); numDrives = driveNames.Length(); if (numDrives <= config->GetIntValue("Ripper", "ActiveDrive", 0)) config->SetIntValue("Ripper", "ActiveDrive", 0); } Void smooth::DetachDLL() { } namespace BoCA { static Bool OpenDriveTray(Int n) { const Array &driveNames = DeviceInfoCDParanoia::FindDrives(); cdrom_drive *cd = cdda_identify(driveNames.GetNth(n), CDDA_MESSAGE_FORGETIT, NIL); if (cd == NIL) return False; cdda_open(cd); /* Unlock tray, then eject. */ #if defined __linux__ ioctl(cd->ioctl_fd, CDROM_LOCKDOOR, 0); ioctl(cd->ioctl_fd, CDROMEJECT); #else ioctl(cd->ioctl_fd, CDIOCALLOW); ioctl(cd->ioctl_fd, CDIOCEJECT); #endif cdda_close(cd); return True; } }; BoCA::DeviceInfoCDParanoia::DeviceInfoCDParanoia() { CollectDriveInfo(); } BoCA::DeviceInfoCDParanoia::~DeviceInfoCDParanoia() { } Bool BoCA::DeviceInfoCDParanoia::IsNthDeviceTrayOpen(Int n) { const Array &driveNames = FindDrives(); cdrom_drive *cd = cdda_identify(driveNames.GetNth(n), CDDA_MESSAGE_FORGETIT, NIL); if (cd == NIL) return False; cdda_open(cd); /* Get tray status. */ Bool status = False; #if defined __linux__ status = (ioctl(cd->ioctl_fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_TRAY_OPEN); #endif cdda_close(cd); return status; } Bool BoCA::DeviceInfoCDParanoia::OpenNthDeviceTray(Int n) { Int nDrives = GetNumberOfDevices(); if (n >= nDrives) return False; NonBlocking1(&OpenDriveTray).Call(n); return True; } Bool BoCA::DeviceInfoCDParanoia::CloseNthDeviceTray(Int n) { const Array &driveNames = FindDrives(); cdrom_drive *cd = cdda_identify(driveNames.GetNth(n), CDDA_MESSAGE_FORGETIT, NIL); if (cd == NIL) return False; cdda_open(cd); /* Close tray. */ #if defined __linux__ ioctl(cd->ioctl_fd, CDROMCLOSETRAY); #else ioctl(cd->ioctl_fd, CDIOCCLOSE); #endif cdda_close(cd); return True; } const Array &BoCA::DeviceInfoCDParanoia::GetNthDeviceTrackList(Int n) { static Array trackList; trackList.RemoveAll(); const MCDI &mcdi = GetNthDeviceMCDI(n); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { /* Find all valid audio tracks (tracks with a positive length). */ if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i) > 0) { /* Look for hidden track before the first track (HTOA). */ if (i == 0 && mcdi.GetNthEntryOffset(i) >= 450) { trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(0))); } /* Add CD track to joblist using a device:// URI */ trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(mcdi.GetNthEntryTrackNumber(i)))); } } return trackList; } const BoCA::MCDI &BoCA::DeviceInfoCDParanoia::GetNthDeviceMCDI(Int n) { static MCDI mcdi = MCDI(Buffer()); /* Do not read the TOC again if the last request * was less than a quarter of a second ago. */ static Int lastDrive = -1; static UnsignedInt64 lastAccess = 0; { UnsignedInt64 clockValue = S::System::System::Clock(); if (lastDrive == n && clockValue - lastAccess < 250) { lastAccess = clockValue; return mcdi; } } mcdi.SetData(Buffer()); const Array &driveNames = FindDrives(); cdrom_drive *cd = cdda_identify(driveNames.GetNth(n), CDDA_MESSAGE_FORGETIT, NIL); if (cd != NIL) { typedef struct { uint8_t rsvd; uint8_t ADR; uint8_t trackNumber; uint8_t rsvd2; uint32_t addr; } __attribute__((__packed__)) TOCTRACK; typedef struct { uint16_t tocLen; uint8_t firstTrack; uint8_t lastTrack; TOCTRACK tracks[100]; } __attribute__((__packed__)) TOC; if (cdda_open(cd) == 0) { TOC toc; toc.tocLen = htons(2 + cd->tracks * 8 + 8); toc.firstTrack = 1; toc.lastTrack = cd->tracks; for (Int i = 0; i <= cd->tracks; i++) { toc.tracks[i].rsvd = 0; toc.tracks[i].ADR = cd->disc_toc[i].bFlags; toc.tracks[i].trackNumber = cd->disc_toc[i].bTrack; toc.tracks[i].rsvd2 = 0; toc.tracks[i].addr = htonl(cd->disc_toc[i].dwStartSector); #ifndef __FreeBSD__ /* cdparanoia accounts for the session gap on mixed mode discs, so we need to undo that to build the * correct MCDI. The FreeBSD port has the corresponding code removed, so this is not necessary there. */ if ((i > 1 && (cd->disc_toc[i - 1].bFlags & 4) != (cd->disc_toc[i].bFlags & 4) && cd->disc_toc[i].bTrack != 0xAA) || (i < cd->tracks && cd->disc_toc[i + 1].dwStartSector - cd->disc_toc[i].dwStartSector <= 0)) { toc.tracks[i].addr = htonl(cd->disc_toc[i].dwStartSector + 11400); } #endif } Buffer buffer(ntohs(toc.tocLen) + 2); memcpy(buffer, &toc, ntohs(toc.tocLen) + 2); mcdi.SetData(buffer); } cdda_close(cd); } lastDrive = n; lastAccess = S::System::System::Clock(); return mcdi; } Void BoCA::DeviceInfoCDParanoia::CollectDriveInfo() { static Bool initialized = False; if (initialized) return; const Array &driveNames = FindDrives(); foreach (const String &driveName, driveNames) { cdrom_drive *cd = cdda_identify(driveName, CDDA_MESSAGE_FORGETIT, NIL); if (cd == NIL) continue; Device drive; String model = String(cd->drive_model).Trim(); drive.type = DEVICE_CDROM; drive.vendor = model.Head( model.Find(" ") ).Trim(); drive.model = model.SubString(model.Find(" ") + 1, model.FindLast(" ") - model.Find(" ") - 1).Trim(); drive.revision = model.Tail( model.Length() - model.FindLast(" ") - 1).Trim(); drive.path = driveName; drive.canOpenTray = True; devices.Add(drive); cdda_close(cd); } initialized = True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdparanoia/cdparanoia.h000066400000000000000000000023371516712004000270440ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DeviceInfoCDParanoia) namespace BoCA { class DeviceInfoCDParanoia : public CS::DeviceInfoComponent { private: Void CollectDriveInfo(); public: static const String &GetComponentSpecs(); static const Array &FindDrives(); DeviceInfoCDParanoia(); ~DeviceInfoCDParanoia(); Bool IsNthDeviceTrayOpen(Int); Bool OpenNthDeviceTray(Int); Bool CloseNthDeviceTray(Int); const Array &GetNthDeviceTrackList(Int); const MCDI &GetNthDeviceMCDI(Int); }; }; BoCA_DEFINE_DEVICEINFO_COMPONENT(DeviceInfoCDParanoia) BoCA_END_COMPONENT(DeviceInfoCDParanoia) boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/000077500000000000000000000000001516712004000235655ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/Makefile000077500000000000000000000012301516712004000252240ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cdrip TYPE = deviceinfo VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = cdrip.o dllinterface.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = -lws2_32 # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/cdrip.cpp000066400000000000000000000144131516712004000253750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "cdrip.h" const String &BoCA::DeviceInfoCDRip::GetComponentSpecs() { static String componentSpecs; if (cdripdll != NIL && ex_CR_GetNumCDROM() >= 1) { componentSpecs = " \ \ \ \ CDRip Ripper Device Info Component \ 1.0 \ cdrip-info \ deviceinfo \ \ \ "; } return componentSpecs; } static Bool initializedCDRip = False; Void smooth::AttachDLL(Void *instance) { LoadCDRipDLL(); if (cdripdll == NIL) return; if (!ex_CR_IsInitialized()) { BoCA::Config *config = BoCA::Config::Get(); Long error = ex_CR_Init(True); if (error == CDEX_ACCESSDENIED) BoCA::Utilities::ErrorMessage("Access to CD-ROM drives was denied by Windows.\n\nPlease contact your system administrator in order\nto be granted the right to access the CD-ROM drive."); else if (error != CDEX_OK && error != CDEX_NOCDROMDEVICES) BoCA::Utilities::ErrorMessage("Unable to load NT SCSI drivers! CD ripping disabled!"); if (ex_CR_GetNumCDROM() <= config->GetIntValue("Ripper", "ActiveDrive", 0)) config->SetIntValue("Ripper", "ActiveDrive", 0); initializedCDRip = True; } } Void smooth::DetachDLL() { if (cdripdll == NIL) return; if (initializedCDRip) ex_CR_DeInit(); FreeCDRipDLL(); } namespace BoCA { static Bool OpenDriveTray(Int n) { Int nDrives = ex_CR_GetNumCDROM(); if (n >= nDrives) return False; CDROMDRIVE *cd = ex_CR_OpenCDROM(n); ex_CR_EjectCD(cd, True); ex_CR_CloseCDROM(cd); return True; } }; BoCA::DeviceInfoCDRip::DeviceInfoCDRip() { CollectDriveInfo(); } BoCA::DeviceInfoCDRip::~DeviceInfoCDRip() { } Bool BoCA::DeviceInfoCDRip::IsNthDeviceTrayOpen(Int n) { Int nDrives = ex_CR_GetNumCDROM(); if (n >= nDrives) return False; CDROMDRIVE *cd = ex_CR_OpenCDROM(n); CDMEDIASTATUS status; ex_CR_IsMediaLoaded(cd, status); ex_CR_CloseCDROM(cd); return (status == CDMEDIA_NOT_PRESENT_TRAY_OPEN); } Bool BoCA::DeviceInfoCDRip::OpenNthDeviceTray(Int n) { Int nDrives = ex_CR_GetNumCDROM(); if (n >= nDrives) return False; NonBlocking1(&OpenDriveTray).Call(n); return True; } Bool BoCA::DeviceInfoCDRip::CloseNthDeviceTray(Int n) { Int nDrives = ex_CR_GetNumCDROM(); if (n >= nDrives) return False; CDROMDRIVE *cd = ex_CR_OpenCDROM(n); ex_CR_EjectCD(cd, False); ex_CR_CloseCDROM(cd); return True; } const Array &BoCA::DeviceInfoCDRip::GetNthDeviceTrackList(Int n) { static Array trackList; trackList.RemoveAll(); const MCDI &mcdi = GetNthDeviceMCDI(n); for (Int i = 0; i < mcdi.GetNumberOfEntries(); i++) { /* Find all valid audio tracks (tracks with a positive length). */ if (mcdi.GetNthEntryType(i) == ENTRY_AUDIO && mcdi.GetNthEntryOffset(i + 1) - mcdi.GetNthEntryOffset(i) > 0) { /* Look for hidden track before the first track (HTOA). */ if (i == 0 && mcdi.GetNthEntryOffset(i) >= 450) { trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(0))); } /* Add CD track to joblist using a device:// URI */ trackList.Add(String("device://cdda:") .Append(String::FromInt(n)) .Append("/") .Append(String::FromInt(mcdi.GetNthEntryTrackNumber(i)))); } } return trackList; } const BoCA::MCDI &BoCA::DeviceInfoCDRip::GetNthDeviceMCDI(Int n) { static MCDI mcdi = MCDI(Buffer()); /* Do not read the TOC again if the last request * was less than a quarter of a second ago. */ static Int lastDrive = -1; static UnsignedInt64 lastAccess = 0; { UnsignedInt64 clockValue = S::System::System::Clock(); if (lastDrive == n && clockValue - lastAccess < 250) { lastAccess = clockValue; return mcdi; } } mcdi.SetData(Buffer()); Int nDrives = ex_CR_GetNumCDROM(); if (n < nDrives) { CDROMDRIVE *cd = ex_CR_OpenCDROM(n); if (ex_CR_ReadToc(cd) == CDEX_OK) { Int numTocEntries = ex_CR_GetNumTocEntries(cd); Buffer buffer(4 + 8 * numTocEntries + 8); ((UnsignedInt16 *) (UnsignedByte *) buffer)[0] = htons(buffer.Size() - 2); buffer[2] = ex_CR_GetTocEntry(cd, 0).btTrackNumber; buffer[3] = ex_CR_GetTocEntry(cd, numTocEntries - 1).btTrackNumber; for (Int i = 0; i <= numTocEntries; i++) { TOCENTRY entry = ex_CR_GetTocEntry(cd, i); buffer[4 + 8 * i + 0] = 0; buffer[4 + 8 * i + 1] = entry.btFlag; buffer[4 + 8 * i + 2] = entry.btTrackNumber; buffer[4 + 8 * i + 3] = 0; Int32 address = entry.dwStartSector; if (address < 0) address = ~((-address) - 1) & ((1 << 24) - 1); ((UnsignedInt32 *) (UnsignedByte *) buffer)[1 + 2 * i + 1] = htonl(address); } mcdi.SetData(buffer); } ex_CR_CloseCDROM(cd); } lastDrive = n; lastAccess = S::System::System::Clock(); return mcdi; } Void BoCA::DeviceInfoCDRip::CollectDriveInfo() { static Bool initialized = False; if (initialized) return; Int nDrives = ex_CR_GetNumCDROM(); for (Int i = 0; i < nDrives; i++) { CDROMDRIVE *cd = ex_CR_OpenCDROM(i); CDROMPARAMS params; if (cd == NIL) continue; ex_CR_GetCDROMParameters(cd, ¶ms); Device drive; drive.type = DEVICE_CDROM; drive.vendor = String(params.lpszCDROMID).SubString(0, 8).Trim(); drive.model = String(params.lpszCDROMID).SubString(8, 16).Trim(); drive.path = String::FromInt(params.btAdapterID).Append(":").Append(String::FromInt(params.btTargetID)).Append(":").Append(String::FromInt(params.btLunID)); drive.canOpenTray = True; devices.Add(drive); ex_CR_CloseCDROM(cd); } initialized = True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/cdrip.h000066400000000000000000000022441516712004000250410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DeviceInfoCDRip) namespace BoCA { class DeviceInfoCDRip : public CS::DeviceInfoComponent { private: Void CollectDriveInfo(); public: static const String &GetComponentSpecs(); DeviceInfoCDRip(); ~DeviceInfoCDRip(); Bool IsNthDeviceTrayOpen(Int); Bool OpenNthDeviceTray(Int); Bool CloseNthDeviceTray(Int); const Array &GetNthDeviceTrackList(Int); const MCDI &GetNthDeviceMCDI(Int); }; }; BoCA_DEFINE_DEVICEINFO_COMPONENT(DeviceInfoCDRip) BoCA_END_COMPONENT(DeviceInfoCDRip) boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/dllinterface.cpp000077500000000000000000000055341516712004000267370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" CR_INIT ex_CR_Init = NIL; CR_DEINIT ex_CR_DeInit = NIL; CR_ISINITIALIZED ex_CR_IsInitialized = NIL; CR_GETNUMCDROM ex_CR_GetNumCDROM = NIL; CR_OPENCDROM ex_CR_OpenCDROM = NIL; CR_CLOSECDROM ex_CR_CloseCDROM = NIL; CR_READTOC ex_CR_ReadToc = NIL; CR_GETNUMTOCENTRIES ex_CR_GetNumTocEntries = NIL; CR_GETTOCENTRY ex_CR_GetTocEntry = NIL; CR_GETCDROMPARAMETERS ex_CR_GetCDROMParameters = NIL; CR_ISMEDIALOADED ex_CR_IsMediaLoaded = NIL; CR_EJECTCD ex_CR_EjectCD = NIL; DynamicLoader *cdripdll = NIL; Bool LoadCDRipDLL() { #ifdef __WIN32__ if (!File(GUI::Application::GetApplicationDirectory().Append("CDRip.dll")).Exists()) return False; #endif cdripdll = new DynamicLoader("CDRip"); ex_CR_Init = (CR_INIT) cdripdll->GetFunctionAddress("CR_Init"); ex_CR_DeInit = (CR_DEINIT) cdripdll->GetFunctionAddress("CR_DeInit"); ex_CR_IsInitialized = (CR_ISINITIALIZED) cdripdll->GetFunctionAddress("CR_IsInitialized"); ex_CR_GetNumCDROM = (CR_GETNUMCDROM) cdripdll->GetFunctionAddress("CR_GetNumCDROM"); ex_CR_OpenCDROM = (CR_OPENCDROM) cdripdll->GetFunctionAddress("CR_OpenCDROM"); ex_CR_CloseCDROM = (CR_CLOSECDROM) cdripdll->GetFunctionAddress("CR_CloseCDROM"); ex_CR_ReadToc = (CR_READTOC) cdripdll->GetFunctionAddress("CR_ReadToc"); ex_CR_GetNumTocEntries = (CR_GETNUMTOCENTRIES) cdripdll->GetFunctionAddress("CR_GetNumTocEntries"); ex_CR_GetTocEntry = (CR_GETTOCENTRY) cdripdll->GetFunctionAddress("CR_GetTocEntry"); ex_CR_GetCDROMParameters = (CR_GETCDROMPARAMETERS) cdripdll->GetFunctionAddress("CR_GetCDROMParameters"); ex_CR_IsMediaLoaded = (CR_ISMEDIALOADED) cdripdll->GetFunctionAddress("CR_IsMediaLoaded"); ex_CR_EjectCD = (CR_EJECTCD) cdripdll->GetFunctionAddress("CR_EjectCD"); if (ex_CR_Init == NIL || ex_CR_DeInit == NIL || ex_CR_IsInitialized == NIL || ex_CR_GetNumCDROM == NIL || ex_CR_OpenCDROM == NIL || ex_CR_CloseCDROM == NIL || ex_CR_ReadToc == NIL || ex_CR_GetNumTocEntries == NIL || ex_CR_GetTocEntry == NIL || ex_CR_GetCDROMParameters == NIL || ex_CR_IsMediaLoaded == NIL || ex_CR_EjectCD == NIL) { FreeCDRipDLL(); return False; } return True; } Void FreeCDRipDLL() { Object::DeleteObject(cdripdll); cdripdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/deviceinfo/cdrip/dllinterface.h000077500000000000000000000037331516712004000264030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *cdripdll; Bool LoadCDRipDLL(); Void FreeCDRipDLL(); typedef CDEX_ERR (CRCCONV *CR_INIT) (int); typedef CDEX_ERR (CRCCONV *CR_DEINIT) (); typedef BOOL (CRCCONV *CR_ISINITIALIZED) (); typedef LONG (CRCCONV *CR_GETNUMCDROM) (); typedef CDROMDRIVE * (CRCCONV *CR_OPENCDROM) (LONG); typedef CDEX_ERR (CRCCONV *CR_CLOSECDROM) (CDROMDRIVE *); typedef CDEX_ERR (CRCCONV *CR_READTOC) (CDROMDRIVE *); typedef LONG (CRCCONV *CR_GETNUMTOCENTRIES) (CDROMDRIVE *); typedef TOCENTRY (CRCCONV *CR_GETTOCENTRY) (CDROMDRIVE *, LONG); typedef CDEX_ERR (CRCCONV *CR_GETCDROMPARAMETERS) (CDROMDRIVE *, CDROMPARAMS *); typedef CDEX_ERR (CRCCONV *CR_ISMEDIALOADED) (CDROMDRIVE *, CDMEDIASTATUS &); typedef BOOL (CRCCONV *CR_EJECTCD) (CDROMDRIVE *, BOOL); extern CR_INIT ex_CR_Init; extern CR_DEINIT ex_CR_DeInit; extern CR_ISINITIALIZED ex_CR_IsInitialized; extern CR_GETNUMCDROM ex_CR_GetNumCDROM; extern CR_OPENCDROM ex_CR_OpenCDROM; extern CR_CLOSECDROM ex_CR_CloseCDROM; extern CR_READTOC ex_CR_ReadToc; extern CR_GETNUMTOCENTRIES ex_CR_GetNumTocEntries; extern CR_GETTOCENTRY ex_CR_GetTocEntry; extern CR_GETCDROMPARAMETERS ex_CR_GetCDROMParameters; extern CR_ISMEDIALOADED ex_CR_IsMediaLoaded; extern CR_EJECTCD ex_CR_EjectCD; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/000077500000000000000000000000001516712004000211375ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/Makefile000077500000000000000000000013541516712004000226050ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = channels format hdcd resample rnnoise rubberband surround volume .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/000077500000000000000000000000001516712004000227325ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/Makefile000066400000000000000000000011351516712004000243720ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = channels TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = channels.o config.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/channels.cpp000066400000000000000000000165021516712004000252350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "channels.h" #include "config.h" const String &BoCA::DSPChannels::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Channel Converter")).Append(" \ 1.0 \ channels-dsp \ dsp \ \ \ \ "); return componentSpecs; } BoCA::DSPChannels::DSPChannels() { configLayer = NIL; swapChannels = False; } BoCA::DSPChannels::~DSPChannels() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPChannels::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); Int channels = config->GetIntValue(ConfigureChannels::ConfigID, "Channels", 2); swapChannels = config->GetIntValue(ConfigureChannels::ConfigID, "SwapChannels", False); /* Check output format. * * Supported: 7.1/6.1 => 5.1 => 2.1 => Stereo => Mono * 7.1/6.1 => 5.1 => 4.0 => Stereo => Mono * Mono => Stereo */ if (!(format.channels == 8 && (channels == 6 || channels <= 4)) && !(format.channels == 7 && (channels == 6 || channels <= 4)) && !(format.channels == 6 && channels <= 4 ) && !(format.channels <= 4 && channels <= 2 )) { errorState = True; errorString = String("Requested conversion from ").Append(String::FromInt(format.channels)).Append(" to ").Append(String::FromInt(channels)).Append(" channels is not supported."); return False; } /* Set output channels. */ this->format.channels = channels; return True; } Int BoCA::DSPChannels::TransformData(Buffer &data) { /* Check if we need to do anything. */ const Format &format = track.GetFormat(); Int source = format.channels; Int target = this->format.channels; if (source != target) { /* Channel conversion routines. */ Int numSamples = data.Size() / format.channels / (format.bits / 8); Float32 *samples = (Float32 *) (UnsignedByte *) data; /* 7.1 source. */ if (source == 8 && target <= 6) { /* Convert 7.1 to 5.1. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 8 ], fr = samples[i * 8 + 1]; Float32 fc = samples[i * 8 + 2], lfe = samples[i * 8 + 3]; Float32 rl = samples[i * 8 + 4], rr = samples[i * 8 + 5]; Float32 sl = samples[i * 8 + 6], sr = samples[i * 8 + 7]; samples[i * 6 ] = fl; samples[i * 6 + 1] = fr; samples[i * 6 + 2] = fc; samples[i * 6 + 3] = lfe; samples[i * 6 + 4] = sl + rl * 0.871; samples[i * 6 + 5] = sr + rr * 0.871; } data.Resize(data.Size() / 4 * 3); source = 6; } /* 6.1 source. */ if (source == 7 && target <= 6) { /* Convert 6.1 to 5.1. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 7 ], fr = samples[i * 7 + 1]; Float32 fc = samples[i * 7 + 2], lfe = samples[i * 7 + 3]; Float32 rc = samples[i * 7 + 4]; Float32 sl = samples[i * 7 + 5], sr = samples[i * 7 + 6]; samples[i * 6 ] = fl; samples[i * 6 + 1] = fr; samples[i * 6 + 2] = fc; samples[i * 6 + 3] = lfe; samples[i * 6 + 4] = sl + rc * 0.708; samples[i * 6 + 5] = sr + rc * 0.708; } data.Resize(data.Size() / 7 * 6); source = 6; } /* 5.1 source. */ if (source == 6 && target <= 2) { /* Convert 5.1 to Stereo. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 6 ], fr = samples[i * 6 + 1]; Float32 fc = samples[i * 6 + 2], lfe = samples[i * 6 + 3]; Float32 rl = samples[i * 6 + 4], rr = samples[i * 6 + 5]; samples[i * 2 ] = fl + (fc + lfe + rl) * 0.708; samples[i * 2 + 1] = fr + (fc + lfe + rr) * 0.708; } data.Resize(data.Size() / 3); source = 2; } else if (source == 6 && target == 3) { /* Convert 5.1 to 2.1. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 6 ], fr = samples[i * 6 + 1]; Float32 fc = samples[i * 6 + 2], lfe = samples[i * 6 + 3]; Float32 rl = samples[i * 6 + 4], rr = samples[i * 6 + 5]; samples[i * 3 ] = fl + (fc + rl) * 0.708; samples[i * 3 + 1] = fr + (fc + rr) * 0.708; samples[i * 3 + 2] = lfe; } data.Resize(data.Size() / 2); } else if (source == 6 && target == 4) { /* Convert 5.1 to 4.0. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 6 ], fr = samples[i * 6 + 1]; Float32 fc = samples[i * 6 + 2], lfe = samples[i * 6 + 3]; Float32 rl = samples[i * 6 + 4], rr = samples[i * 6 + 5]; samples[i * 4 ] = fl + (fc + lfe) * 0.708; samples[i * 4 + 1] = fr + (fc + lfe) * 0.708; samples[i * 4 + 2] = rl; samples[i * 4 + 3] = rr; } data.Resize(data.Size() / 3 * 2); } /* 4.0 source. */ if (source == 4 && target <= 2) { /* Convert 4.0 to Stereo. */ for (Int i = 0; i < numSamples; i++) { Float32 fl = samples[i * 4 ], fr = samples[i * 4 + 1]; Float32 rl = samples[i * 4 + 2], rr = samples[i * 4 + 3]; samples[i * 2 ] = fl + rl * 0.708; samples[i * 2 + 1] = fr + rr * 0.708; } data.Resize(data.Size() / 2); source = 2; } /* 2.1 source. */ if (source == 3 && target <= 2) { /* Convert 2.1 to Stereo. */ for (Int i = 0; i < numSamples; i++) { Float32 l = samples[i * 3 ]; Float32 r = samples[i * 3 + 1]; Float32 lfe = samples[i * 3 + 2]; samples[i * 2 ] = l + lfe * 0.708; samples[i * 2 + 1] = r + lfe * 0.708; } data.Resize(data.Size() / 3 * 2); source = 2; } /* Stereo source. */ if (source == 2 && target == 1) { /* Convert Stereo to Mono. */ for (Int i = 0; i < numSamples; i++) { Float32 l = samples[i * 2 ]; Float32 r = samples[i * 2 + 1]; samples[i] = (l + r) * 0.5; } data.Resize(data.Size() / 2); } /* Mono source. */ if (source == 1 && target == 2) { /* Convert Mono to Stereo. */ data.Resize(data.Size() * 2); Float32 *samples = (Float32 *) (UnsignedByte *) data; for (Int i = numSamples - 1; i >= 0; i--) { Float32 m = samples[i]; samples[i * 2 ] = m; samples[i * 2 + 1] = m; } } } /* Swap Stereo channels if requested. */ if (swapChannels && source > 1 && target == 2) { const Channel::Layout Mirrored_2_0 = { Channel::FrontRight, Channel::FrontLeft }; Utilities::ChangeChannelOrder(data, this->format, Mirrored_2_0, Channel::Default_2_0); } return data.Size(); } ConfigLayer *BoCA::DSPChannels::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureChannels(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/channels.h000066400000000000000000000020501516712004000246730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DSPChannels) namespace BoCA { class DSPChannels : public CS::DSPComponent { private: ConfigLayer *configLayer; Bool swapChannels; public: static const String &GetComponentSpecs(); DSPChannels(); ~DSPChannels(); Bool Activate(); Int TransformData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPChannels) BoCA_END_COMPONENT(DSPChannels) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/config.cpp000066400000000000000000000051321516712004000247040ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureChannels::ConfigID = "Channels"; BoCA::ConfigureChannels::ConfigureChannels() { const Config *config = Config::Get(); Int channels = config->GetIntValue(ConfigID, "Channels", 2); swapChannels = config->GetIntValue(ConfigID, "SwapChannels", False); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Channels"); group_output = new GroupBox(i18n->TranslateString("Output channels"), Point(7, 11), Size(250, 67)); check_swap = new CheckBox(i18n->TranslateString("Switch stereo channels"), Point(10, 40), Size(230, 0), &swapChannels); text_channels = new Text(i18n->AddColon(i18n->TranslateString("Channel configuration")), Point(10, 16)); combo_channels = new ComboBox(Point(17 + text_channels->GetUnscaledTextWidth(), 13), Size(223 - text_channels->GetUnscaledTextWidth(), 0)); combo_channels->onSelectEntry.Connect(&ConfigureChannels::OnSelectChannels, this); combo_channels->AddEntry(i18n->TranslateString("Mono")); combo_channels->AddEntry(i18n->TranslateString("Stereo")); combo_channels->AddEntry("2.1"); combo_channels->AddEntry("4.0"); combo_channels->AddEntry("5.1"); combo_channels->AddEntry("7.1"); combo_channels->SelectNthEntry(channels <= 4 ? channels - 1 : channels / 2 + 1); group_output->Add(text_channels); group_output->Add(combo_channels); group_output->Add(check_swap); Add(group_output); SetSize(Size(264, 85)); } BoCA::ConfigureChannels::~ConfigureChannels() { DeleteObject(group_output); DeleteObject(text_channels); DeleteObject(combo_channels); DeleteObject(check_swap); } Int BoCA::ConfigureChannels::SaveSettings() { Config *config = Config::Get(); Int entry = combo_channels->GetSelectedEntryNumber(); config->SetIntValue(ConfigID, "Channels", entry <= 3 ? entry + 1 : (entry - 1) * 2); config->SetIntValue(ConfigID, "SwapChannels", swapChannels); return Success(); } Void BoCA::ConfigureChannels::OnSelectChannels() { if (combo_channels->GetSelectedEntryNumber() == 1) check_swap->Activate(); else check_swap->Deactivate(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/channels/config.h000066400000000000000000000021721516712004000243520ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_CHANNELSCONFIG #define H_CHANNELSCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureChannels : public ConfigLayer { private: GroupBox *group_output; Text *text_channels; ComboBox *combo_channels; CheckBox *check_swap; Bool swapChannels; public: static const String ConfigID; ConfigureChannels(); ~ConfigureChannels(); Int SaveSettings(); slots: Void OnSelectChannels(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/000077500000000000000000000000001516712004000224275ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/Makefile000066400000000000000000000011311516712004000240630ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = format TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o format.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/config.cpp000066400000000000000000000152161516712004000244050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureFormat::ConfigID = "Format"; BoCA::ConfigureFormat::ConfigureFormat() { const Config *config = Config::Get(); unsignedSamples = !config->GetIntValue(ConfigID, "Signed", True); applyDither = config->GetIntValue(ConfigID, "ApplyDither", True); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Format"); group_format = new GroupBox(i18n->TranslateString("Sample format"), Point(7, 11), Size(296, 94)); text_numbers = new Text(i18n->AddColon(i18n->TranslateString("Number format")), Point(10, 16)); text_resolution = new Text(i18n->AddColon(i18n->TranslateString("Sample resolution")), Point(10, 43)); text_dither_type = new Text(i18n->AddColon(i18n->TranslateString("Dither type")), Point(10, 41)); text_bit = new Text(i18n->TranslateString("bit"), Point(0, 43)); text_bit->SetX(10 + text_bit->GetUnscaledTextWidth()); text_bit->SetOrientation(OR_UPPERRIGHT); Int maxTextSize = Math::Max(Math::Max(text_numbers->GetUnscaledTextWidth(), text_resolution->GetUnscaledTextWidth()), text_dither_type->GetUnscaledTextWidth()); combo_numbers = new ComboBox(Point(17 + maxTextSize, 13), Size(263, 0)); combo_numbers->AddEntry(i18n->TranslateString("Integer")); combo_numbers->AddEntry(i18n->TranslateString("Float")); combo_numbers->SelectNthEntry(config->GetIntValue(ConfigID, "Float", False)); combo_numbers->onSelectEntry.Connect(&ConfigureFormat::OnChangeNumberFormat, this); combo_resolution = new ComboBox(Point(17 + maxTextSize, 40), Size(263, 0)); combo_resolution->onSelectEntry.Connect(&ConfigureFormat::OnChangeResolution, this); check_unsigned = new CheckBox(i18n->TranslateString("unsigned"), Point(17 + maxTextSize, 67), Size(263, 0), &unsignedSamples); group_format->Add(text_numbers); group_format->Add(combo_numbers); group_format->Add(text_resolution); group_format->Add(combo_resolution); group_format->Add(text_bit); group_format->Add(check_unsigned); group_dither = new GroupBox(i18n->TranslateString("Dithering"), Point(7, 116), Size(296, 67)); check_dither = new CheckBox(i18n->TranslateString("Apply dither when reducing sample resolution"), Point(10, 13), Size(276, 0), &applyDither); check_dither->onAction.Connect(&ConfigureFormat::OnToggleDither, this); combo_dither_type = new ComboBox(Point(17 + maxTextSize, 38), Size(269, 0)); combo_dither_type->AddEntry(i18n->TranslateString("RPDF")); combo_dither_type->AddEntry(i18n->TranslateString("TPDF")); combo_dither_type->SelectNthEntry(config->GetIntValue(ConfigID, "DitherType", 1)); group_dither->Add(check_dither); group_dither->Add(text_dither_type); group_dither->Add(combo_dither_type); /* Adjust element widths. */ check_dither->SetWidth(Math::Max(276, check_dither->GetUnscaledTextWidth() + 21)); group_format->SetWidth(check_dither->GetWidth() + 20); group_dither->SetWidth(check_dither->GetWidth() + 20); combo_numbers->SetWidth(check_dither->GetWidth() - maxTextSize - 13 - text_bit->GetUnscaledTextWidth()); combo_resolution->SetWidth(check_dither->GetWidth() - maxTextSize - 13 - text_bit->GetUnscaledTextWidth()); check_unsigned->SetWidth(check_dither->GetWidth() - maxTextSize - 13 - text_bit->GetUnscaledTextWidth()); combo_dither_type->SetWidth(check_dither->GetWidth() - maxTextSize - 7); /* Add groups to layers. */ Add(group_format); Add(group_dither); OnChangeNumberFormat(); OnToggleDither(); if (combo_numbers->GetSelectedEntryNumber() == 0) combo_resolution->SelectNthEntry(config->GetIntValue(ConfigID, "Bits", 16) / 8 - 1); else combo_resolution->SelectNthEntry(config->GetIntValue(ConfigID, "Bits", 32) / 32 - 1); check_unsigned->SetChecked(!config->GetIntValue(ConfigID, "Signed", True)); SetSize(Size(check_dither->GetWidth() + 34, 190)); } BoCA::ConfigureFormat::~ConfigureFormat() { DeleteObject(group_format); DeleteObject(text_numbers); DeleteObject(combo_numbers); DeleteObject(text_resolution); DeleteObject(combo_resolution); DeleteObject(text_bit); DeleteObject(check_unsigned); DeleteObject(group_dither); DeleteObject(check_dither); DeleteObject(text_dither_type); DeleteObject(combo_dither_type); } Void BoCA::ConfigureFormat::OnChangeNumberFormat() { I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Format"); combo_resolution->RemoveAllEntries(); if (combo_numbers->GetSelectedEntryNumber() == 1) { combo_resolution->AddEntry("32"); combo_resolution->AddEntry("64"); combo_resolution->SelectNthEntry(0); combo_resolution->Deactivate(); check_unsigned->SetChecked(False); check_unsigned->Deactivate(); group_dither->Deactivate(); } else { combo_resolution->AddEntry("8"); combo_resolution->AddEntry("16"); combo_resolution->AddEntry("24"); combo_resolution->AddEntry("32"); combo_resolution->SelectNthEntry(1); combo_resolution->Activate(); OnChangeResolution(); } } Void BoCA::ConfigureFormat::OnChangeResolution() { if (combo_numbers->GetSelectedEntryNumber() == 1) return; if (combo_resolution->GetSelectedEntryNumber() != 0) check_unsigned->SetChecked(False); if (combo_resolution->GetSelectedEntryNumber() == 0) check_unsigned->Activate(); else check_unsigned->Deactivate(); if (combo_resolution->GetSelectedEntryNumber() == 3) group_dither->Deactivate(); else group_dither->Activate(); } Void BoCA::ConfigureFormat::OnToggleDither() { if (applyDither) { text_dither_type->Activate(); combo_dither_type->Activate(); } else { text_dither_type->Deactivate(); combo_dither_type->Deactivate(); } } Int BoCA::ConfigureFormat::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Float", combo_numbers->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Signed", !unsignedSamples); if (combo_numbers->GetSelectedEntryNumber() == 0) config->SetIntValue(ConfigID, "Bits", (combo_resolution->GetSelectedEntryNumber() + 1) * 8); else config->SetIntValue(ConfigID, "Bits", (combo_resolution->GetSelectedEntryNumber() + 1) * 32); config->SetIntValue(ConfigID, "ApplyDither", applyDither); config->SetIntValue(ConfigID, "DitherType", combo_dither_type->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/config.h000066400000000000000000000026331516712004000240510ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_FORMATCONFIG #define H_FORMATCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureFormat : public ConfigLayer { private: GroupBox *group_format; Text *text_numbers; ComboBox *combo_numbers; Text *text_resolution; ComboBox *combo_resolution; Text *text_bit; CheckBox *check_unsigned; GroupBox *group_dither; CheckBox *check_dither; Text *text_dither_type; ComboBox *combo_dither_type; Bool unsignedSamples; Bool applyDither; public: static const String ConfigID; ConfigureFormat(); ~ConfigureFormat(); Int SaveSettings(); slots: Void OnChangeNumberFormat(); Void OnChangeResolution(); Void OnToggleDither(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/format.cpp000066400000000000000000000152511516712004000244270ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "format.h" #include "config.h" #include static Buffer dither; static const Int ditherSize = 32768; const String &BoCA::DSPFormat::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Sample Format Converter")).Append(" \ 1.0 \ format-dsp \ dsp \ \ \ "); return componentSpecs; } BoCA::DSPFormat::DSPFormat() { configLayer = NIL; applyDither = True; ditherType = 1; ditherIndex = 0; } BoCA::DSPFormat::~DSPFormat() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPFormat::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); Bool fp = config->GetIntValue(ConfigureFormat::ConfigID, "Float", False); Int bits = config->GetIntValue(ConfigureFormat::ConfigID, "Bits", 16); Bool sign = config->GetIntValue(ConfigureFormat::ConfigID, "Signed", True); applyDither = config->GetIntValue(ConfigureFormat::ConfigID, "ApplyDither", True); ditherType = config->GetIntValue(ConfigureFormat::ConfigID, "DitherType", 1); /* Set output format. */ const Format &format = track.GetFormat(); this->format = format; this->format.fp = fp; this->format.bits = fp ? 32 : bits; this->format.sign = fp ? True : sign; /* Generate dither table if needed. */ if (applyDither && this->format.bits < format.bits) GenerateDither(); return True; } Int BoCA::DSPFormat::TransformData(Buffer &data) { /* Check if we need to do anything. */ const Format &format = track.GetFormat(); if (format.fp == this->format.fp && format.bits == this->format.bits && format.sign == this->format.sign) return data.Size(); /* Convert samples. */ Int inBytesPerSample = ( format.bits / 8); Int outBytesPerSample = (this->format.bits / 8); Int numSamples = data.Size() / inBytesPerSample; if (format.bits < this->format.bits) data.Resize(numSamples * outBytesPerSample); TransformSamples(data, format, data, this->format, numSamples); if (format.bits > this->format.bits) data.Resize(numSamples * outBytesPerSample); return data.Size(); } Void BoCA::DSPFormat::TransformSamples(const UnsignedByte *in, const Format &inFormat, UnsignedByte *out, const Format &outFormat, Int numSamples) { static Endianness endianness = CPU().GetEndianness(); /* Shortcuts for common conversions. */ if (inFormat.bits == 16 && outFormat.fp) { for (Int i = numSamples - 1; i >= 0; i--) ((Float32 *) out)[i] = (((Int16 *) in)[i] + 32768) / 32768.0 - 1.0; return; } if (inFormat.bits == 8 && outFormat.bits == 8 && inFormat.sign != outFormat.sign) { for (Int i = 0; i < numSamples; i++) out[i] = (in[i] + 128) & 0xFF; return; } /* Resize intermediate buffer. */ samplesBuffer.Resize(numSamples); Int64 *samples = samplesBuffer; /* Read samples. */ for (Int i = 0; i < numSamples; i++) { if (inFormat.fp ) samples[i] = (((Float32 *) in)[i] + 1.0) * (1U << 31) - 0.5 - (1U << 31); else if (inFormat.bits == 8 && !inFormat.sign ) samples[i] = ( in [i] - 128) << 24; else if (inFormat.bits == 8 && inFormat.sign ) samples[i] = ((Int8 *) in)[i] << 24; else if (inFormat.bits == 16 ) samples[i] = ((Int16 *) in)[i] << 16; else if (inFormat.bits == 32 ) samples[i] = ((Int32 *) in)[i]; else if (inFormat.bits == 24 && endianness == EndianLittle) samples[i] = in[i * 3 + 2] << 24 | in[i * 3 + 1] << 16 | in[i * 3 ] << 8; else if (inFormat.bits == 24 && endianness == EndianBig ) samples[i] = in[i * 3 ] << 24 | in[i * 3 + 1] << 16 | in[i * 3 + 2] << 8; } /* Apply dither. */ if (applyDither && outFormat.bits < inFormat.bits) { if (ditherType == 0) // RPDF { for (Int i = 0; i < numSamples; i++) { Float32 r = dither[ditherIndex++ % ditherSize] - 0.5; samples[i] += Int32(r * (1 << (32 - outFormat.bits))); } } else if (ditherType == 1) // TPDF { Float32 p = dither[ditherIndex++ % ditherSize]; for (Int i = 0; i < numSamples; i++) { Float32 r = dither[ditherIndex++ % ditherSize]; samples[i] += Int32((r - p) * (1 << (32 - outFormat.bits))); p = r; } } } /* Apply rounding and clipping. */ if (inFormat.fp || outFormat.bits < inFormat.bits) { for (Int i = 0; i < numSamples; i++) { if (outFormat.bits < 32) samples[i] += 1 << (31 - outFormat.bits); /* Clip out of range samples. */ if (samples[i] > 0x7FFFFFFF) samples[i] = 0x7FFFFFFF; else if (samples[i] < ~0x7FFFFFFF) samples[i] = ~0x7FFFFFFF; } } /* Write samples. */ for (Int i = 0; i < numSamples; i++) { if (outFormat.fp ) ((Float32 *) out)[i] = (samples[i] + (1U << 31)) / ((1U << 31) + 0.5) - 1.0; else if (outFormat.bits == 8 && !outFormat.sign ) out [i] = (samples[i] + (1U << 31)) >> 24; else if (outFormat.bits == 8 && outFormat.sign ) ((Int8 *) out)[i] = samples[i] >> 24; else if (outFormat.bits == 16 ) ((Int16 *) out)[i] = samples[i] >> 16; else if (outFormat.bits == 32 ) ((Int32 *) out)[i] = samples[i]; else if (outFormat.bits == 24 && endianness == EndianLittle) { out[i * 3 + 2] = (samples[i] >> 24) & 0xFF; out[i * 3 + 1] = (samples[i] >> 16) & 0xFF; out[i * 3 ] = (samples[i] >> 8) & 0xFF; } else if (outFormat.bits == 24 && endianness == EndianBig ) { out[i * 3 ] = (samples[i] >> 24) & 0xFF; out[i * 3 + 1] = (samples[i] >> 16) & 0xFF; out[i * 3 + 2] = (samples[i] >> 8) & 0xFF; } } } Void BoCA::DSPFormat::GenerateDither() { static Threads::Mutex mutex; Threads::Lock lock(mutex); if (dither.Size() != 0) return; dither.Resize(ditherSize); for (Int i = 0; i < ditherSize; i++) dither[i] = Float32(rand()) / RAND_MAX; } ConfigLayer *BoCA::DSPFormat::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureFormat(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/format/format.h000066400000000000000000000023771516712004000241010ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DSPFormat) namespace BoCA { class DSPFormat : public CS::DSPComponent { private: ConfigLayer *configLayer; Buffer samplesBuffer; Bool applyDither; Int ditherType; UnsignedInt ditherIndex; static Void GenerateDither(); Void TransformSamples(const UnsignedByte *, const Format &, UnsignedByte *, const Format &, Int); public: static const String &GetComponentSpecs(); DSPFormat(); ~DSPFormat(); Bool Activate(); Int TransformData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPFormat) BoCA_END_COMPONENT(DSPFormat) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/000077500000000000000000000000001516712004000220415ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/Makefile000066400000000000000000000013761516712004000235100ustar00rootroot00000000000000########## BoCA component makefile ########## .NOTPARALLEL: # Change these variables to fit your project: TARGET = hdcd TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = hdcd.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/libhdcd # Enter additional library dependencies here: LIBS = libhdcd/libhdcd.a # Enter addition commands for targets all and clean here: ALLCMD1 = $(call makein,libhdcd) ALLCMD2 = CLEANCMD1 = $(call cleanin,libhdcd) CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/hdcd.cpp000066400000000000000000000111071516712004000234470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "hdcd.h" using namespace smooth::IO; const String &BoCA::DSPHDCD::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("HDCD Decoder")).Append(" \ 1.0 \ hdcd-dsp \ dsp \ \ \ "); return componentSpecs; } BoCA::DSPHDCD::DSPHDCD() { context = NIL; } BoCA::DSPHDCD::~DSPHDCD() { } Bool BoCA::DSPHDCD::Activate() { /* Do nothing if no HDCD content. */ if (!IsHDCDContent()) return True; context = hdcd_new(); /* Set output format. */ const Format &format = track.GetFormat(); this->format = format; this->format.bits = 24; return True; } Bool BoCA::DSPHDCD::Deactivate() { if (context != NIL) hdcd_free(context); return True; } Int BoCA::DSPHDCD::TransformData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); if (context == NIL) return data.Size(); /* Write samples to 32 bit processing buffer. */ Int16 *inSamples = (Int16 *) (UnsignedByte *) data; Int numSamples = data.Size() / 2; samplesBuffer.Resize(numSamples); for (Int i = 0; i < numSamples; i++) samplesBuffer[i] = inSamples[i]; /* Process samples. */ hdcd_process(context, samplesBuffer, numSamples / 2); /* Write processed samples back to data buffer. */ data.Resize(numSamples * 3); for (Int i = 0; i < numSamples; i++) { if (endianness == EndianLittle) { data[i * 3 + 2] = (samplesBuffer[i] >> 24) & 0xFF; data[i * 3 + 1] = (samplesBuffer[i] >> 16) & 0xFF; data[i * 3 ] = (samplesBuffer[i] >> 8) & 0xFF; } else if (endianness == EndianBig ) { data[i * 3 ] = (samplesBuffer[i] >> 24) & 0xFF; data[i * 3 + 1] = (samplesBuffer[i] >> 16) & 0xFF; data[i * 3 + 2] = (samplesBuffer[i] >> 8) & 0xFF; } } return data.Size(); } Bool BoCA::DSPHDCD::IsHDCDContent() { /* Check input format. */ const Format &format = track.GetFormat(); if (!track.lossless || format.bits != 16 || format.channels != 2 || format.rate != 44100) return False; /* Create decoder for stream. */ AS::Registry &boca = AS::Registry::Get(); AS::DecoderComponent *decoder = boca.CreateDecoderForStream(track.fileName, GetConfiguration()); if (decoder == NIL) return False; decoder->SetAudioTrackInfo(track); static DriverZero zero_in; InStream *stream = NIL; if (track.fileName.StartsWith("device://")) stream = new InStream(STREAM_DRIVER, &zero_in); else stream = new InStream(STREAM_FILE, track.fileName, IS_READ); stream->SetPackageSize(track.length >= 0 ? 131072 : 16384); stream->SetFilter(decoder); /* Seek to sampleOffset if necessary. */ if (track.sampleOffset > 0 && !decoder->Seek(track.sampleOffset)) { Int64 bytesLeft = track.sampleOffset * format.channels * (format.bits / 8); Buffer buffer; while (bytesLeft) { buffer.Resize(Math::Min(Int64(1024), bytesLeft)); bytesLeft -= stream->InputData(buffer, buffer.Size()); } } /* Read beginning of audio data. */ Buffer buffer(2352); Int numAudioSectors = 0; Bool hdcdDetected = False; hdcd_simple *context = hdcd_new(); while (!hdcdDetected && numAudioSectors < 75) { Int16 *inSamples = (Int16 *) (UnsignedByte *) buffer; Int numSamples = stream->InputData(buffer, buffer.Size()) / 2; Int64 energy = 0; samplesBuffer.Resize(numSamples); for (Int i = 0; i < numSamples; i++) { samplesBuffer[i] = inSamples[i]; energy += Math::Abs(inSamples[i]); } if (energy > numSamples * 256) numAudioSectors++; /* Check for HDCD signaling codes in input. */ if (hdcd_scan(context, samplesBuffer, numSamples / 2, 0) != HDCD_NONE) hdcdDetected = True; } hdcd_free(context); delete stream; boca.DeleteComponent(decoder); return hdcdDetected; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/hdcd.h000066400000000000000000000021001516712004000231050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "libhdcd/hdcd_simple.h" BoCA_BEGIN_COMPONENT(DSPHDCD) namespace BoCA { class DSPHDCD : public CS::DSPComponent { private: hdcd_simple *context; Buffer samplesBuffer; Bool IsHDCDContent(); public: static const String &GetComponentSpecs(); DSPHDCD(); ~DSPHDCD(); Bool Activate(); Bool Deactivate(); Int TransformData(Buffer &); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPHDCD) BoCA_END_COMPONENT(DSPHDCD) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/000077500000000000000000000000001516712004000234325ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/Makefile000066400000000000000000000006561516712004000251010ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = hdcd_analyze_tonegen.o hdcd_decode2.o hdcd_libversion.o hdcd_simple.o hdcd_strings.o TARGET = libhdcd.a CCOPTS = AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_analyze.h000066400000000000000000000052721516712004000262360ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _HDCD_ANALYZE_H_ #define _HDCD_ANALYZE_H_ #ifdef __cplusplus extern "C" { #endif /** Analyze mode(s) * * In analyze mode, the audio is replaced by a solid tone, and * amplitude is changed to signal when the specified feature is * used, or some decoding state exists. */ typedef enum { HDCD_ANA_OFF = 0, HDCD_ANA_LLE = 1, HDCD_ANA_PE = 2, HDCD_ANA_CDT = 3, HDCD_ANA_TGM = 4, HDCD_ANA_PEL = 5, /* added with simple api */ HDCD_ANA_LTGM = 6, /* added with simple api */ } hdcd_ana_mode; #define HDCD_ANA_OFF_DESC "disabled" #define HDCD_ANA_LLE_DESC "gain adjustment level at each sample" #define HDCD_ANA_PE_DESC "samples where peak extend occurs" #define HDCD_ANA_CDT_DESC "samples where the code detect timer is active" #define HDCD_ANA_TGM_DESC "samples where the target gain does not match between channels" #define HDCD_ANA_PEL_DESC "any samples above peak extend level" #define HDCD_ANA_LTGM_DESC "gain adjustment level at each sample, in each channel" /** get a nice description of what a mode does */ const char* hdcd_str_analyze_mode_desc(hdcd_ana_mode mode); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_analyze_tonegen.c000066400000000000000000000335451516712004000277540ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file exists to remove a dependency on the math lib in libhdcd * that only exists so that sin() can be used in the analyze mode tone * generator. This version uses simple lookup tables instead. * * HDCD is possible in CDDA (44.1kHz) and all DVD-Audio sample rates. * Supported rates: 44.1, 48, 88.2, 96, 176.4, and 192 kHz * * To generate tables: * gcc -o tone_tab -DHDCD_PRINT_TONE_TAB hdcd_analyze_tonegen.c -lm * ./tone_tab >tone_tab.csnip */ #ifdef HDCD_PRINT_TONE_TAB #include #include #endif #include static const int16_t tone_tab_192000[640] = { 0x0000, 0x0020, 0x0040, 0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e1, 0x0101, 0x0121, 0x0141, 0x0161, 0x0181, 0x01a1, 0x01c0, 0x01e0, 0x0200, 0x0220, 0x0240, 0x025f, 0x027f, 0x029e, 0x02be, 0x02dd, 0x02fc, 0x031c, 0x033b, 0x035a, 0x0379, 0x0398, 0x03b7, 0x03d5, 0x03f4, 0x0413, 0x0431, 0x044f, 0x046e, 0x048c, 0x04aa, 0x04c8, 0x04e5, 0x0503, 0x0521, 0x053e, 0x055b, 0x0578, 0x0595, 0x05b2, 0x05cf, 0x05ec, 0x0608, 0x0624, 0x0641, 0x065d, 0x0678, 0x0694, 0x06b0, 0x06cb, 0x06e6, 0x0701, 0x071c, 0x0737, 0x0751, 0x076b, 0x0785, 0x079f, 0x07b9, 0x07d3, 0x07ec, 0x0805, 0x081e, 0x0837, 0x0850, 0x0868, 0x0880, 0x0898, 0x08b0, 0x08c7, 0x08df, 0x08f6, 0x090c, 0x0923, 0x093a, 0x0950, 0x0966, 0x097b, 0x0991, 0x09a6, 0x09bb, 0x09d0, 0x09e4, 0x09f9, 0x0a0d, 0x0a21, 0x0a34, 0x0a47, 0x0a5a, 0x0a6d, 0x0a80, 0x0a92, 0x0aa4, 0x0ab6, 0x0ac7, 0x0ad8, 0x0ae9, 0x0afa, 0x0b0a, 0x0b1b, 0x0b2a, 0x0b3a, 0x0b49, 0x0b58, 0x0b67, 0x0b76, 0x0b84, 0x0b92, 0x0b9f, 0x0bad, 0x0bba, 0x0bc6, 0x0bd3, 0x0bdf, 0x0beb, 0x0bf6, 0x0c02, 0x0c0d, 0x0c17, 0x0c22, 0x0c2c, 0x0c36, 0x0c3f, 0x0c48, 0x0c51, 0x0c5a, 0x0c62, 0x0c6a, 0x0c72, 0x0c79, 0x0c80, 0x0c87, 0x0c8d, 0x0c93, 0x0c99, 0x0c9f, 0x0ca4, 0x0ca9, 0x0cad, 0x0cb2, 0x0cb5, 0x0cb9, 0x0cbc, 0x0cbf, 0x0cc2, 0x0cc4, 0x0cc7, 0x0cc8, 0x0cca, 0x0ccb, 0x0ccc, 0x0ccc, 0x0ccc, 0x0ccc, 0x0ccc, 0x0ccb, 0x0cca, 0x0cc8, 0x0cc7, 0x0cc4, 0x0cc2, 0x0cbf, 0x0cbc, 0x0cb9, 0x0cb5, 0x0cb2, 0x0cad, 0x0ca9, 0x0ca4, 0x0c9f, 0x0c99, 0x0c93, 0x0c8d, 0x0c87, 0x0c80, 0x0c79, 0x0c72, 0x0c6a, 0x0c62, 0x0c5a, 0x0c51, 0x0c48, 0x0c3f, 0x0c36, 0x0c2c, 0x0c22, 0x0c17, 0x0c0d, 0x0c02, 0x0bf6, 0x0beb, 0x0bdf, 0x0bd3, 0x0bc6, 0x0bba, 0x0bad, 0x0b9f, 0x0b92, 0x0b84, 0x0b76, 0x0b67, 0x0b58, 0x0b49, 0x0b3a, 0x0b2a, 0x0b1b, 0x0b0a, 0x0afa, 0x0ae9, 0x0ad8, 0x0ac7, 0x0ab6, 0x0aa4, 0x0a92, 0x0a80, 0x0a6d, 0x0a5a, 0x0a47, 0x0a34, 0x0a21, 0x0a0d, 0x09f9, 0x09e4, 0x09d0, 0x09bb, 0x09a6, 0x0991, 0x097b, 0x0966, 0x0950, 0x093a, 0x0923, 0x090c, 0x08f6, 0x08df, 0x08c7, 0x08b0, 0x0898, 0x0880, 0x0868, 0x0850, 0x0837, 0x081e, 0x0805, 0x07ec, 0x07d3, 0x07b9, 0x079f, 0x0785, 0x076b, 0x0751, 0x0737, 0x071c, 0x0701, 0x06e6, 0x06cb, 0x06b0, 0x0694, 0x0678, 0x065d, 0x0641, 0x0624, 0x0608, 0x05ec, 0x05cf, 0x05b2, 0x0595, 0x0578, 0x055b, 0x053e, 0x0521, 0x0503, 0x04e5, 0x04c8, 0x04aa, 0x048c, 0x046e, 0x044f, 0x0431, 0x0413, 0x03f4, 0x03d5, 0x03b7, 0x0398, 0x0379, 0x035a, 0x033b, 0x031c, 0x02fc, 0x02dd, 0x02be, 0x029e, 0x027f, 0x025f, 0x0240, 0x0220, 0x0200, 0x01e0, 0x01c0, 0x01a1, 0x0181, 0x0161, 0x0141, 0x0121, 0x0101, 0x00e1, 0x00c0, 0x00a0, 0x0080, 0x0060, 0x0040, 0x0020, 0x0000, 0xffe0, 0xffc0, 0xffa0, 0xff80, 0xff60, 0xff40, 0xff1f, 0xfeff, 0xfedf, 0xfebf, 0xfe9f, 0xfe7f, 0xfe5f, 0xfe40, 0xfe20, 0xfe00, 0xfde0, 0xfdc0, 0xfda1, 0xfd81, 0xfd62, 0xfd42, 0xfd23, 0xfd04, 0xfce4, 0xfcc5, 0xfca6, 0xfc87, 0xfc68, 0xfc49, 0xfc2b, 0xfc0c, 0xfbed, 0xfbcf, 0xfbb1, 0xfb92, 0xfb74, 0xfb56, 0xfb38, 0xfb1b, 0xfafd, 0xfadf, 0xfac2, 0xfaa5, 0xfa88, 0xfa6b, 0xfa4e, 0xfa31, 0xfa14, 0xf9f8, 0xf9dc, 0xf9bf, 0xf9a3, 0xf988, 0xf96c, 0xf950, 0xf935, 0xf91a, 0xf8ff, 0xf8e4, 0xf8c9, 0xf8af, 0xf895, 0xf87b, 0xf861, 0xf847, 0xf82d, 0xf814, 0xf7fb, 0xf7e2, 0xf7c9, 0xf7b0, 0xf798, 0xf780, 0xf768, 0xf750, 0xf739, 0xf721, 0xf70a, 0xf6f4, 0xf6dd, 0xf6c6, 0xf6b0, 0xf69a, 0xf685, 0xf66f, 0xf65a, 0xf645, 0xf630, 0xf61c, 0xf607, 0xf5f3, 0xf5df, 0xf5cc, 0xf5b9, 0xf5a6, 0xf593, 0xf580, 0xf56e, 0xf55c, 0xf54a, 0xf539, 0xf528, 0xf517, 0xf506, 0xf4f6, 0xf4e5, 0xf4d6, 0xf4c6, 0xf4b7, 0xf4a8, 0xf499, 0xf48a, 0xf47c, 0xf46e, 0xf461, 0xf453, 0xf446, 0xf43a, 0xf42d, 0xf421, 0xf415, 0xf40a, 0xf3fe, 0xf3f3, 0xf3e9, 0xf3de, 0xf3d4, 0xf3ca, 0xf3c1, 0xf3b8, 0xf3af, 0xf3a6, 0xf39e, 0xf396, 0xf38e, 0xf387, 0xf380, 0xf379, 0xf373, 0xf36d, 0xf367, 0xf361, 0xf35c, 0xf357, 0xf353, 0xf34e, 0xf34b, 0xf347, 0xf344, 0xf341, 0xf33e, 0xf33c, 0xf339, 0xf338, 0xf336, 0xf335, 0xf334, 0xf334, 0xf334, 0xf334, 0xf334, 0xf335, 0xf336, 0xf338, 0xf339, 0xf33c, 0xf33e, 0xf341, 0xf344, 0xf347, 0xf34b, 0xf34e, 0xf353, 0xf357, 0xf35c, 0xf361, 0xf367, 0xf36d, 0xf373, 0xf379, 0xf380, 0xf387, 0xf38e, 0xf396, 0xf39e, 0xf3a6, 0xf3af, 0xf3b8, 0xf3c1, 0xf3ca, 0xf3d4, 0xf3de, 0xf3e9, 0xf3f3, 0xf3fe, 0xf40a, 0xf415, 0xf421, 0xf42d, 0xf43a, 0xf446, 0xf453, 0xf461, 0xf46e, 0xf47c, 0xf48a, 0xf499, 0xf4a8, 0xf4b7, 0xf4c6, 0xf4d6, 0xf4e5, 0xf4f6, 0xf506, 0xf517, 0xf528, 0xf539, 0xf54a, 0xf55c, 0xf56e, 0xf580, 0xf593, 0xf5a6, 0xf5b9, 0xf5cc, 0xf5df, 0xf5f3, 0xf607, 0xf61c, 0xf630, 0xf645, 0xf65a, 0xf66f, 0xf685, 0xf69a, 0xf6b0, 0xf6c6, 0xf6dd, 0xf6f4, 0xf70a, 0xf721, 0xf739, 0xf750, 0xf768, 0xf780, 0xf798, 0xf7b0, 0xf7c9, 0xf7e2, 0xf7fb, 0xf814, 0xf82d, 0xf847, 0xf861, 0xf87b, 0xf895, 0xf8af, 0xf8c9, 0xf8e4, 0xf8ff, 0xf91a, 0xf935, 0xf950, 0xf96c, 0xf988, 0xf9a3, 0xf9bf, 0xf9dc, 0xf9f8, 0xfa14, 0xfa31, 0xfa4e, 0xfa6b, 0xfa88, 0xfaa5, 0xfac2, 0xfadf, 0xfafd, 0xfb1b, 0xfb38, 0xfb56, 0xfb74, 0xfb92, 0xfbb1, 0xfbcf, 0xfbed, 0xfc0c, 0xfc2b, 0xfc49, 0xfc68, 0xfc87, 0xfca6, 0xfcc5, 0xfce4, 0xfd04, 0xfd23, 0xfd42, 0xfd62, 0xfd81, 0xfda1, 0xfdc0, 0xfde0, 0xfe00, 0xfe20, 0xfe40, 0xfe5f, 0xfe7f, 0xfe9f, 0xfebf, 0xfedf, 0xfeff, 0xff1f, 0xff40, 0xff60, 0xff80, 0xffa0, 0xffc0, 0xffe0, }; static const int16_t tone_tab_176400[588] = { 0x0000, 0x0023, 0x0046, 0x0069, 0x008c, 0x00ae, 0x00d1, 0x00f4, 0x0117, 0x013a, 0x015d, 0x0180, 0x01a3, 0x01c5, 0x01e8, 0x020a, 0x022d, 0x024f, 0x0272, 0x0294, 0x02b6, 0x02d9, 0x02fb, 0x031d, 0x033f, 0x0360, 0x0382, 0x03a4, 0x03c5, 0x03e7, 0x0408, 0x0429, 0x044a, 0x046b, 0x048c, 0x04ad, 0x04cd, 0x04ee, 0x050e, 0x052e, 0x054e, 0x056e, 0x058d, 0x05ad, 0x05cc, 0x05eb, 0x060a, 0x0629, 0x0647, 0x0666, 0x0684, 0x06a2, 0x06c0, 0x06de, 0x06fb, 0x0718, 0x0735, 0x0752, 0x076f, 0x078b, 0x07a7, 0x07c3, 0x07df, 0x07fa, 0x0816, 0x0831, 0x084c, 0x0866, 0x0880, 0x089a, 0x08b4, 0x08ce, 0x08e7, 0x0900, 0x0919, 0x0931, 0x094a, 0x0961, 0x0979, 0x0991, 0x09a8, 0x09bf, 0x09d5, 0x09eb, 0x0a01, 0x0a17, 0x0a2c, 0x0a41, 0x0a56, 0x0a6b, 0x0a7f, 0x0a93, 0x0aa6, 0x0aba, 0x0acd, 0x0adf, 0x0af2, 0x0b04, 0x0b15, 0x0b27, 0x0b38, 0x0b48, 0x0b59, 0x0b69, 0x0b78, 0x0b88, 0x0b97, 0x0ba5, 0x0bb4, 0x0bc2, 0x0bcf, 0x0bdd, 0x0bea, 0x0bf6, 0x0c03, 0x0c0e, 0x0c1a, 0x0c25, 0x0c30, 0x0c3b, 0x0c45, 0x0c4f, 0x0c58, 0x0c61, 0x0c6a, 0x0c72, 0x0c7a, 0x0c82, 0x0c89, 0x0c90, 0x0c96, 0x0c9c, 0x0ca2, 0x0ca8, 0x0cad, 0x0cb1, 0x0cb6, 0x0cba, 0x0cbd, 0x0cc0, 0x0cc3, 0x0cc5, 0x0cc8, 0x0cc9, 0x0ccb, 0x0ccb, 0x0ccc, 0x0ccc, 0x0ccc, 0x0ccb, 0x0ccb, 0x0cc9, 0x0cc8, 0x0cc5, 0x0cc3, 0x0cc0, 0x0cbd, 0x0cba, 0x0cb6, 0x0cb1, 0x0cad, 0x0ca8, 0x0ca2, 0x0c9c, 0x0c96, 0x0c90, 0x0c89, 0x0c82, 0x0c7a, 0x0c72, 0x0c6a, 0x0c61, 0x0c58, 0x0c4f, 0x0c45, 0x0c3b, 0x0c30, 0x0c25, 0x0c1a, 0x0c0e, 0x0c03, 0x0bf6, 0x0bea, 0x0bdd, 0x0bcf, 0x0bc2, 0x0bb4, 0x0ba5, 0x0b97, 0x0b88, 0x0b78, 0x0b69, 0x0b59, 0x0b48, 0x0b38, 0x0b27, 0x0b15, 0x0b04, 0x0af2, 0x0adf, 0x0acd, 0x0aba, 0x0aa6, 0x0a93, 0x0a7f, 0x0a6b, 0x0a56, 0x0a41, 0x0a2c, 0x0a17, 0x0a01, 0x09eb, 0x09d5, 0x09bf, 0x09a8, 0x0991, 0x0979, 0x0961, 0x094a, 0x0931, 0x0919, 0x0900, 0x08e7, 0x08ce, 0x08b4, 0x089a, 0x0880, 0x0866, 0x084c, 0x0831, 0x0816, 0x07fa, 0x07df, 0x07c3, 0x07a7, 0x078b, 0x076f, 0x0752, 0x0735, 0x0718, 0x06fb, 0x06de, 0x06c0, 0x06a2, 0x0684, 0x0666, 0x0647, 0x0629, 0x060a, 0x05eb, 0x05cc, 0x05ad, 0x058d, 0x056e, 0x054e, 0x052e, 0x050e, 0x04ee, 0x04cd, 0x04ad, 0x048c, 0x046b, 0x044a, 0x0429, 0x0408, 0x03e7, 0x03c5, 0x03a4, 0x0382, 0x0360, 0x033f, 0x031d, 0x02fb, 0x02d9, 0x02b6, 0x0294, 0x0272, 0x024f, 0x022d, 0x020a, 0x01e8, 0x01c5, 0x01a3, 0x0180, 0x015d, 0x013a, 0x0117, 0x00f4, 0x00d1, 0x00ae, 0x008c, 0x0069, 0x0046, 0x0023, 0x0000, 0xffdd, 0xffba, 0xff97, 0xff74, 0xff52, 0xff2f, 0xff0c, 0xfee9, 0xfec6, 0xfea3, 0xfe80, 0xfe5d, 0xfe3b, 0xfe18, 0xfdf6, 0xfdd3, 0xfdb1, 0xfd8e, 0xfd6c, 0xfd4a, 0xfd27, 0xfd05, 0xfce3, 0xfcc1, 0xfca0, 0xfc7e, 0xfc5c, 0xfc3b, 0xfc19, 0xfbf8, 0xfbd7, 0xfbb6, 0xfb95, 0xfb74, 0xfb53, 0xfb33, 0xfb12, 0xfaf2, 0xfad2, 0xfab2, 0xfa92, 0xfa73, 0xfa53, 0xfa34, 0xfa15, 0xf9f6, 0xf9d7, 0xf9b9, 0xf99a, 0xf97c, 0xf95e, 0xf940, 0xf922, 0xf905, 0xf8e8, 0xf8cb, 0xf8ae, 0xf891, 0xf875, 0xf859, 0xf83d, 0xf821, 0xf806, 0xf7ea, 0xf7cf, 0xf7b4, 0xf79a, 0xf780, 0xf766, 0xf74c, 0xf732, 0xf719, 0xf700, 0xf6e7, 0xf6cf, 0xf6b6, 0xf69f, 0xf687, 0xf66f, 0xf658, 0xf641, 0xf62b, 0xf615, 0xf5ff, 0xf5e9, 0xf5d4, 0xf5bf, 0xf5aa, 0xf595, 0xf581, 0xf56d, 0xf55a, 0xf546, 0xf533, 0xf521, 0xf50e, 0xf4fc, 0xf4eb, 0xf4d9, 0xf4c8, 0xf4b8, 0xf4a7, 0xf497, 0xf488, 0xf478, 0xf469, 0xf45b, 0xf44c, 0xf43e, 0xf431, 0xf423, 0xf416, 0xf40a, 0xf3fd, 0xf3f2, 0xf3e6, 0xf3db, 0xf3d0, 0xf3c5, 0xf3bb, 0xf3b1, 0xf3a8, 0xf39f, 0xf396, 0xf38e, 0xf386, 0xf37e, 0xf377, 0xf370, 0xf36a, 0xf364, 0xf35e, 0xf358, 0xf353, 0xf34f, 0xf34a, 0xf346, 0xf343, 0xf340, 0xf33d, 0xf33b, 0xf338, 0xf337, 0xf335, 0xf335, 0xf334, 0xf334, 0xf334, 0xf335, 0xf335, 0xf337, 0xf338, 0xf33b, 0xf33d, 0xf340, 0xf343, 0xf346, 0xf34a, 0xf34f, 0xf353, 0xf358, 0xf35e, 0xf364, 0xf36a, 0xf370, 0xf377, 0xf37e, 0xf386, 0xf38e, 0xf396, 0xf39f, 0xf3a8, 0xf3b1, 0xf3bb, 0xf3c5, 0xf3d0, 0xf3db, 0xf3e6, 0xf3f2, 0xf3fd, 0xf40a, 0xf416, 0xf423, 0xf431, 0xf43e, 0xf44c, 0xf45b, 0xf469, 0xf478, 0xf488, 0xf497, 0xf4a7, 0xf4b8, 0xf4c8, 0xf4d9, 0xf4eb, 0xf4fc, 0xf50e, 0xf521, 0xf533, 0xf546, 0xf55a, 0xf56d, 0xf581, 0xf595, 0xf5aa, 0xf5bf, 0xf5d4, 0xf5e9, 0xf5ff, 0xf615, 0xf62b, 0xf641, 0xf658, 0xf66f, 0xf687, 0xf69f, 0xf6b6, 0xf6cf, 0xf6e7, 0xf700, 0xf719, 0xf732, 0xf74c, 0xf766, 0xf780, 0xf79a, 0xf7b4, 0xf7cf, 0xf7ea, 0xf806, 0xf821, 0xf83d, 0xf859, 0xf875, 0xf891, 0xf8ae, 0xf8cb, 0xf8e8, 0xf905, 0xf922, 0xf940, 0xf95e, 0xf97c, 0xf99a, 0xf9b9, 0xf9d7, 0xf9f6, 0xfa15, 0xfa34, 0xfa53, 0xfa73, 0xfa92, 0xfab2, 0xfad2, 0xfaf2, 0xfb12, 0xfb33, 0xfb53, 0xfb74, 0xfb95, 0xfbb6, 0xfbd7, 0xfbf8, 0xfc19, 0xfc3b, 0xfc5c, 0xfc7e, 0xfca0, 0xfcc1, 0xfce3, 0xfd05, 0xfd27, 0xfd4a, 0xfd6c, 0xfd8e, 0xfdb1, 0xfdd3, 0xfdf6, 0xfe18, 0xfe3b, 0xfe5d, 0xfe80, 0xfea3, 0xfec6, 0xfee9, 0xff0c, 0xff2f, 0xff52, 0xff74, 0xff97, 0xffba, 0xffdd, }; /* prototype to avoid a warning. */ int _hdcd_tone16(int *sn, int rate); int _hdcd_tone16(int *sn, int rate) { (*sn)++; switch(rate) { case 192000: *sn %= 640; return tone_tab_192000[*sn]; case 96000: *sn %= 320; return tone_tab_192000[(*sn)<<1]; case 48000: *sn %= 160; return tone_tab_192000[(*sn)<<2]; case 176400: *sn %= 588; return tone_tab_176400[*sn]; case 88200: *sn %= 294; return tone_tab_176400[(*sn)<<1]; case 44100: default: *sn %= 147; return tone_tab_176400[(*sn)<<2]; } } #ifdef HDCD_PRINT_TONE_TAB /** tone generator: sample_number, frequency, sample_rate, amplitude */ #define TONEGEN16(sn, f, sr, a) (int16_t)(sin((6.28318530718 * (sn) * (f)) /(sr)) * (a) * 0x7fff) int main() { int n; int freq = 300; int rate = 192000; int max = rate / freq; printf("static const int16_t tone_tab_%d[%d] = {\n ", rate, max); for (n = 0; n < max; n++) { printf("0x%04hx, ", TONEGEN16(n, freq, rate, 0.1) ); if (n%8 == 7) printf("\n "); } printf("\n};\n"); rate = 176400; max = rate / freq; printf("static const int16_t tone_tab_%d[%d] = {\n ", rate, max); for (n = 0; n < max; n++) { printf("0x%04hx, ", TONEGEN16(n, freq, rate, 0.1) ); if (n%8 == 7) printf("\n "); } printf("\n};\n"); } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_decode2.c000066400000000000000000000664711516712004000261030ustar00rootroot00000000000000/* * Copyright (C) 2010, Chris Moeller, * All rights reserved. * Optimizations by Gumboot * Additional work by Burt P. * Original code reverse engineered from HDCD decoder library by Christopher Key, * which was likely reverse engineered from Windows Media Player. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "hdcd_decode2.h" #include "hdcd_tables.c" // code was developed as part of FFmpeg and uses these macros #if !defined(FFMIN) #define FFMIN(x, y) ((x) <= (y) ? (x) : (y)) #endif #if !defined(FFMAX) #define FFMAX(x, y) ((x) >= (y) ? (x) : (y)) #endif /** convert to float from 4-bit (3.1) fixed-point * the always-negative value is stored positive, so make it negative */ #define GAINTOFLOAT(g) (g) ? -(float)(g>>1) - ((g & 1) ? 0.5 : 0.0) : 0.0 /** apply gain, 11-bit (3.8) fixed point, * always negative but stored positive. */ #define APPLY_GAIN(s,g) do{int64_t s64 = s; s64 *= gaintab[g]; s = (int32_t)(s64 >> 23); }while(0); /** used in _hdcd_scan_x() and _hdcd_integrate_x() */ #define HDCD_MAX_CHANNELS 2 /** internal data structure identities **/ enum { HDCD_SID_UNDEF = 0, HDCD_SID_STATE = 1, HDCD_SID_STATE_STEREO = 2, HDCD_SID_DETECTION_DATA = 3, HDCD_SID_LOGGER = 4, }; static void _hdcd_default_logger(void *ignored, const char* fmt, va_list args) { vfprintf(stderr, fmt, args); /* fix for -Wunused-parameter: The callback requires * the parameter, but it is not used here. */ ignored = ignored; } int _hdcd_log_init(hdcd_log *log, hdcd_log_callback func, void *priv) { if (!log) return -1; memset(log, 0, sizeof(*log)); log->sid = HDCD_SID_LOGGER; log->priv = priv; if (func) log->log_func = func; else log->log_func = (hdcd_log_callback)_hdcd_default_logger; log->enable = 1; return 0; } void _hdcd_log_enable(hdcd_log *log) { if (log) log->enable = 1; } void _hdcd_log_disable(hdcd_log *log) { if (log) log->enable = 0; } void _hdcd_log(hdcd_log *log, const char* fmt, ...) { if (!log) return; if (log->enable) { va_list args; va_start(args, fmt); log->log_func(log->priv, fmt, args); va_end(args); } } void _hdcd_reset(hdcd_state *state, unsigned rate, unsigned bits, int sustain_period_ms, int flags) { int i; uint32_t sustain_reset; /* check parameters */ if (!state) return; if (!rate) rate = 44100; if (!bits) bits = 16; if (!sustain_period_ms) sustain_period_ms = 2000; else { sustain_period_ms = FFMIN(sustain_period_ms, 60000); sustain_period_ms = FFMAX(sustain_period_ms, 100); } /* Formerly: sustain_period_ms * rate / 1000, but * max period (60000) * max sample rate (192000) overflows uint32. * Attempted to do it as uint64, but causes a strange problem with * the i686-w64-mingw32 build. * Valid HDCD rate is always a multiple of 100, * worst case is now 60000 * 1920; fits in uint32. */ sustain_reset = sustain_period_ms * (rate/100) / 10; /* initialize memory area */ memset(state, 0, sizeof(*state)); state->sid = HDCD_SID_STATE; /* set options */ state->decoder_options = flags; state->cdt_period = sustain_period_ms; state->rate = rate; state->bits = bits; /* decoding state */ state->window = 0; state->readahead = 32; state->arg = 0; state->control = 0; state->running_gain = 0; state->sustain_reset = sustain_reset; state->sustain = 0; /* reset all counters */ state->code_counterA = 0; state->code_counterA_almost = 0; state->code_counterB = 0; state->code_counterB_checkfails = 0; state->code_counterC = 0; state->code_counterC_unmatched = 0; state->count_peak_extend = 0; state->count_transient_filter = 0; for(i = 0; i < 16; i++) state->gain_counts[i] = 0; state->max_gain = 0; state->count_sustain_expired = -1; /* log and location */ state->log = NULL; state->sample_count = 0; /* analyze mode */ state->ana_mode = HDCD_ANA_OFF; state->_ana_snb = 0; } void _hdcd_reset_stereo(hdcd_state_stereo *state, unsigned rate, unsigned bits, int sustain_period_ms, int flags) { if (!state) return; memset(state, 0, sizeof(*state)); state->sid = HDCD_SID_STATE_STEREO; state->ana_mode = HDCD_ANA_OFF; _hdcd_reset(&state->channel[0], rate, bits, sustain_period_ms, flags); _hdcd_reset(&state->channel[1], rate, bits, sustain_period_ms, flags); state->val_target_gain = 0; state->count_tg_mismatch = 0; } void _hdcd_set_analyze_mode(void *state, hdcd_ana_mode mode) { hdcd_state *s = state; hdcd_state_stereo *ss = state; if (!state) return; if (s->sid == HDCD_SID_STATE) s->ana_mode = mode; if (ss->sid == HDCD_SID_STATE_STEREO) ss->ana_mode = ss->channel[0].ana_mode = ss->channel[1].ana_mode = mode; } void _hdcd_attach_logger(void *state, hdcd_log *log) { hdcd_state *s = state; hdcd_state_stereo *ss = state; if (!state) return; if (s->sid == HDCD_SID_STATE) s->log = log; if (ss->sid == HDCD_SID_STATE_STEREO) ss->channel[0].log = ss->channel[1].log = log; } static int _hdcd_integrate_x(hdcd_state *states, int channels, int *flag, const int32_t *samples, int count, int stride) { uint32_t bits[HDCD_MAX_CHANNELS]; int result = count; int i, j, f; *flag = 0; memset(bits, 0, sizeof(bits)); if (stride < channels) stride = channels; for (i = 0; i < channels; i++) result = FFMIN(states[i].readahead, result); for (j = result - 1; j >= 0; j--) { for (i = 0; i < channels; i++) bits[i] |= (*(samples++) & 1) << j; samples += stride - channels; } for (i = 0; i < channels; i++) { states[i].window = (states[i].window << result) | bits[i]; states[i].readahead -= result; if (states[i].readahead == 0) { uint32_t wbits = (uint32_t)(states[i].window ^ states[i].window >> 5 ^ states[i].window >> 23); if (states[i].arg) { f = 0; if ((wbits & 0x0fa00500) == 0x0fa00500) { /* A: 8-bit code 0x7e0fa005[..] */ if ((wbits & 0xc8) == 0) { /* [..pt gggg] * 0x0fa005[..] -> 0b[00.. 0...], gain part doubled (shifted left 1) */ states[i].control = (wbits & 255) + (wbits & 7); f = 1; states[i].code_counterA++; } else { /* one of bits 3, 6, or 7 was not 0 */ states[i].code_counterA_almost++; _hdcd_log(states[i].log, "hdcd error: Control A almost: 0x%02x near %d\n", wbits & 0xff, states[i].sample_count); } } else if ((wbits & 0xa0060000) == 0xa0060000) { /* B: 8-bit code, 8-bit XOR check, 0x7e0fa006[....] */ if (((wbits ^ (~wbits >> 8 & 255)) & 0xffff00ff) == 0xa0060000) { /* check: [..pt gggg ~(..pt gggg)] * 0xa006[....] -> 0b[.... .... .... .... ] */ states[i].control = wbits >> 8 & 255; f = 1; states[i].code_counterB++; } else { /* XOR check failed */ states[i].code_counterB_checkfails++; _hdcd_log(states[i].log, "hdcd error: Control B check failed: 0x%04x (0x%02x vs 0x%02x) near %d\n", wbits & 0xffff, (wbits & 0xff00) >> 8, ~wbits & 0xff, states[i].sample_count); } } if (f) { *flag |= (1< [0b0101 or 0b0110] */ states[i].readahead = (wbits & 3) * 8; states[i].arg = 1; states[i].code_counterC++; } else { if (wbits) states[i].readahead = readaheadtab[wbits & 0xff]; else states[i].readahead = 31; /* ffwd over digisilence */ } } } return result; } static int _hdcd_scan_x(hdcd_state *states, int channels, const int32_t *samples, int max, int stride) { int result; int i; int cdt_active[HDCD_MAX_CHANNELS]; memset(cdt_active, 0, sizeof(cdt_active)); if (stride < channels) stride = channels; /* code detect timers for each channel */ for(i = 0; i < channels; i++) { if (states[i].sustain > 0) { cdt_active[i] = 1; if (states[i].sustain <= (unsigned)max) { states[i].control = 0; max = states[i].sustain; } states[i].sustain -= max; } } result = 0; while (result < max) { int flag; int consumed = _hdcd_integrate_x(states, channels, &flag, samples, max - result, stride); result += consumed; if (flag) { /* reset timer if code detected in a channel */ for(i = 0; i < channels; i++) { if (flag & (1<= 0) ? 2 : 0; /* above PE level */ save |= samples[n] & 1; /* save LSB for HDCD packets */ samples[n] = _hdcd_tone16(&state->_ana_snb, state->rate); samples[n] = (samples[n] | 3) ^ ((~save) & 3); } } /** analyze mode: encode a value in the given sample by adjusting the amplitude */ static int32_t _hdcd_analyze_gen(int32_t sample, unsigned int v, unsigned int maxv) { static const int r = 18, m = 1024; int64_t s64 = sample; v = m + (v * r * m / maxv); return (int32_t)(s64 * v / m); } /** behaves like _hdcd_envelope(), but encodes processing information in * a way that is audible (and visible in an audio editor) to aid analysis. */ static int _hdcd_analyze(int32_t *samples, int count, int stride, int gain, int target_gain, int extend, int mode, int cdt_active, int tg_mismatch) { static const int maxg = 0xf << 7; int i, limit = count * stride; for (i = 0; i < limit; i += stride) { samples[i] <<= 15; if (mode == HDCD_ANA_PE) { int pel = (samples[i] >> 16) & 1; int32_t sample = samples[i]; samples[i] = _hdcd_analyze_gen(sample, !!(pel && extend), 1); } else if (mode == HDCD_ANA_TGM && tg_mismatch > 0) samples[i] = _hdcd_analyze_gen(samples[i], 1, 1); else if (mode == HDCD_ANA_CDT && cdt_active) samples[i] = _hdcd_analyze_gen(samples[i], 1, 1); } if (gain <= target_gain) { int len = FFMIN(count, target_gain - gain); /* attenuate slowly */ for (i = 0; i < len; i++) { ++gain; if (mode == HDCD_ANA_LLE) *samples = _hdcd_analyze_gen(*samples, gain, maxg); samples += stride; } count -= len; } else { int len = FFMIN(count, (gain - target_gain) >> 3); /* amplify quickly */ for (i = 0; i < len; i++) { gain -= 8; if (mode == HDCD_ANA_LLE) *samples = _hdcd_analyze_gen(*samples, gain, maxg); samples += stride; } if (gain - 8 < target_gain) gain = target_gain; count -= len; } /* hold a steady level */ if (gain == 0) { if (count > 0) samples += count * stride; } else { while (--count >= 0) { if (mode == HDCD_ANA_LLE) *samples = _hdcd_analyze_gen(*samples, gain, maxg); samples += stride; } } return gain; } /** apply HDCD decoding parameters to a series of samples */ static int _hdcd_envelope(int32_t *samples, int count, int stride, int bits, int gain, int target_gain, int extend) { int i, limit = count * stride; int pe_level = peak_ext_level, shft = 15; if (bits != 16) { pe_level = (1 << (bits - 1)) - (0x8000 - peak_ext_level); shft = 32 - bits - 1; } if (extend) { for (i = 0; i < limit; i += stride) { int32_t sample = samples[i]; int32_t asample = abs(sample) - pe_level; if (asample >= 0) { if (asample > pe_max_asample ) asample = pe_max_asample; sample = sample >= 0 ? peaktab[asample] : -peaktab[asample]; } else sample <<= shft; samples[i] = sample; } } else { for (i = 0; i < limit; i += stride) samples[i] <<= shft; } if (gain <= target_gain) { int len = FFMIN(count, target_gain - gain); /* attenuate slowly */ for (i = 0; i < len; i++) { ++gain; APPLY_GAIN(*samples, gain); samples += stride; } count -= len; } else { int len = FFMIN(count, (gain - target_gain) >> 3); /* amplify quickly */ for (i = 0; i < len; i++) { gain -= 8; APPLY_GAIN(*samples, gain); samples += stride; } if (gain - 8 < target_gain) gain = target_gain; count -= len; } /* hold a steady level */ if (gain == 0) { if (count > 0) samples += count * stride; } else { while (--count >= 0) { APPLY_GAIN(*samples, gain); samples += stride; } } return gain; } /** extract fields from control code */ static void _hdcd_control(hdcd_state *state, int *peak_extend, int *target_gain) { *peak_extend = (state->control & 16 || state->decoder_options & HDCD_FLAG_FORCE_PE); *target_gain = (state->control & 15) << 7; } typedef enum { HDCD_OK=0, HDCD_TG_MISMATCH } hdcd_control_result; static hdcd_control_result _hdcd_control_stereo(hdcd_state_stereo *state, int *peak_extend0, int *peak_extend1) { int target_gain[2]; _hdcd_control(&state->channel[0], peak_extend0, &target_gain[0]); _hdcd_control(&state->channel[1], peak_extend1, &target_gain[1]); if (target_gain[0] == target_gain[1]) state->val_target_gain = target_gain[0]; else { if (!(state->channel[0].decoder_options & HDCD_FLAG_TGM_LOG_OFF)) { _hdcd_log(state->channel[0].log, "hdcd error: Unmatched target_gain near %d: tg0: %0.1f, tg1: %0.1f, lvg: %0.1f\n", state->channel[0].sample_count, GAINTOFLOAT(target_gain[0] >>7), GAINTOFLOAT(target_gain[1] >>7), GAINTOFLOAT(state->val_target_gain >>7) ); } return HDCD_TG_MISMATCH; } return HDCD_OK; } void _hdcd_process(hdcd_state *state, int32_t *samples, int count, int stride) { int full_count = count; int gain = state->running_gain; int peak_extend, target_gain; int lead = 0; if (state->ana_mode) _hdcd_analyze_prepare(state, samples, count, stride); _hdcd_control(state, &peak_extend, &target_gain); while (count > lead) { int envelope_run; int run; run = _hdcd_scan_x(state, 1, samples + lead * stride, count - lead, stride) + lead; envelope_run = run - 1; if (state->ana_mode) gain = _hdcd_analyze(samples, envelope_run, stride, gain, target_gain, peak_extend, state->ana_mode, state->sustain, -1); else gain = _hdcd_envelope(samples, envelope_run, stride, state->bits, gain, target_gain, peak_extend); samples += envelope_run * stride; count -= envelope_run; lead = run - envelope_run; _hdcd_control(state, &peak_extend, &target_gain); } if (lead > 0) { if (state->ana_mode) gain = _hdcd_analyze(samples, lead, stride, gain, target_gain, peak_extend, state->ana_mode, state->sustain, -1); else gain = _hdcd_envelope(samples, lead, stride, state->bits, gain, target_gain, peak_extend); } state->running_gain = gain; state->sample_count += full_count; } void _hdcd_process_stereo(hdcd_state_stereo *state, int32_t *samples, int count) { const int stride = 2; int full_count = count; int gain[2] = {state->channel[0].running_gain, state->channel[1].running_gain}; int peak_extend[2]; int lead = 0; int ctlret; if (state->ana_mode) { _hdcd_analyze_prepare(&state->channel[0], samples, count, stride); _hdcd_analyze_prepare(&state->channel[1], samples + 1, count, stride); } ctlret = _hdcd_control_stereo(state, &peak_extend[0], &peak_extend[1]); while (count > lead) { int envelope_run, run; run = _hdcd_scan_x(&state->channel[0], 2, samples + lead * stride, count - lead, 0) + lead; envelope_run = run - 1; if (ctlret == HDCD_TG_MISMATCH) state->count_tg_mismatch += envelope_run; if (state->ana_mode) { gain[0] = _hdcd_analyze(samples, envelope_run, stride, gain[0], state->val_target_gain, peak_extend[0], state->ana_mode, state->channel[0].sustain, (ctlret == HDCD_TG_MISMATCH) ); gain[1] = _hdcd_analyze(samples + 1, envelope_run, stride, gain[1], state->val_target_gain, peak_extend[1], state->ana_mode, state->channel[1].sustain, (ctlret == HDCD_TG_MISMATCH) ); } else { gain[0] = _hdcd_envelope(samples, envelope_run, stride, state->channel[0].bits, gain[0], state->val_target_gain, peak_extend[0]); gain[1] = _hdcd_envelope(samples + 1, envelope_run, stride, state->channel[1].bits, gain[1], state->val_target_gain, peak_extend[1]); } samples += envelope_run * stride; count -= envelope_run; lead = run - envelope_run; ctlret = _hdcd_control_stereo(state, &peak_extend[0], &peak_extend[1]); } if (lead > 0) { if (ctlret == HDCD_TG_MISMATCH) state->count_tg_mismatch += lead; if (state->ana_mode) { gain[0] = _hdcd_analyze(samples, lead, stride, gain[0], state->val_target_gain, peak_extend[0], state->ana_mode, state->channel[0].sustain, (ctlret == HDCD_TG_MISMATCH) ); gain[1] = _hdcd_analyze(samples + 1, lead, stride, gain[1], state->val_target_gain, peak_extend[1], state->ana_mode, state->channel[1].sustain, (ctlret == HDCD_TG_MISMATCH) ); } else { gain[0] = _hdcd_envelope(samples, lead, stride, state->channel[0].bits, gain[0], state->val_target_gain, peak_extend[0]); gain[1] = _hdcd_envelope(samples + 1, lead, stride, state->channel[1].bits, gain[1], state->val_target_gain, peak_extend[1]); } } state->channel[0].running_gain = gain[0]; state->channel[1].running_gain = gain[1]; state->channel[0].sample_count += full_count; state->channel[1].sample_count += full_count; } void _hdcd_detect_reset(hdcd_detection_data *detect) { if (!detect) return; memset(detect, 0, sizeof(*detect)); detect->sid = HDCD_SID_DETECTION_DATA; detect->hdcd_detected = HDCD_NONE; detect->packet_type = HDCD_PVER_NONE; detect->total_packets = 0; detect->errors = 0; detect->peak_extend = HDCD_PE_NEVER; detect->uses_transient_filter = 0; detect->max_gain_adjustment = 0.0; detect->cdt_expirations = -1; detect->_active_count = 0; } void _hdcd_detect_start(hdcd_detection_data *detect) { if (!detect) return; detect->errors = 0; /* re-sum every pass */ detect->total_packets = 0; detect->_active_count = 0; /* will need to match channels at _hdcd_detect_end() */ detect->cdt_expirations = -1; } void _hdcd_detect_onech(hdcd_state *state, hdcd_detection_data *detect) { hdcd_pe pe = HDCD_PE_NEVER; if (!detect) return; detect->uses_transient_filter |= !!(state->count_transient_filter); detect->total_packets += state->code_counterA + state->code_counterB; if (state->code_counterA) detect->packet_type |= HDCD_PVER_A; if (state->code_counterB) detect->packet_type |= HDCD_PVER_B; if (state->count_peak_extend) { /* if every valid packet has used PE, call it permanent */ if (state->count_peak_extend == state->code_counterA + state->code_counterB) pe = HDCD_PE_PERMANENT; else pe = HDCD_PE_INTERMITTENT; if (detect->peak_extend != HDCD_PE_INTERMITTENT) detect->peak_extend = pe; } detect->max_gain_adjustment = FFMIN(detect->max_gain_adjustment, GAINTOFLOAT(state->max_gain)); detect->errors += state->code_counterA_almost + state->code_counterB_checkfails + state->code_counterC_unmatched; if (state->sustain) detect->_active_count++; if (state->count_sustain_expired >= 0) { if (detect->cdt_expirations == -1) detect->cdt_expirations = 0; detect->cdt_expirations += state->count_sustain_expired; } } void _hdcd_detect_end(hdcd_detection_data *detect, int channels) { if (!detect) return; /* HDCD is detected if a valid packet is active in all * channels at the same time. */ if (detect->_active_count == channels) { if (detect->max_gain_adjustment || detect->peak_extend) detect->hdcd_detected = HDCD_EFFECTUAL; else detect->hdcd_detected = HDCD_NO_EFFECT; } } void _hdcd_detect_stereo(hdcd_state_stereo *state, hdcd_detection_data *detect) { _hdcd_detect_start(detect); _hdcd_detect_onech(&state->channel[0], detect); _hdcd_detect_onech(&state->channel[1], detect); _hdcd_detect_end(detect, 2); } void _hdcd_detect_str(hdcd_detection_data *detect, char *str, int maxlen) { if (!detect) return; /* create an HDCD detection data string for logging */ if (detect->hdcd_detected) snprintf(str, maxlen, "HDCD detected: yes (%s:%d), peak_extend: %s, max_gain_adj: %0.1f dB, transient_filter: %s, detectable errors: %d", hdcd_str_pformat(detect->packet_type), detect->total_packets, hdcd_str_pe(detect->peak_extend), detect->max_gain_adjustment, (detect->uses_transient_filter) ? "detected" : "not detected", detect->errors ); else strcpy(str, "HDCD detected: no"); } void _hdcd_dump_state_to_log(hdcd_state *state, int channel) { int j; char ctag[20] = ""; if (!state) return; if (channel >= 0) snprintf(ctag, sizeof(ctag), ".channel%d", channel); _hdcd_log(state->log, "%s.code_counterA: %d\n" "%s.code_counterA_almost: %d\n" "%s.code_counterB: %d\n" "%s.code_counterB_checkfails: %d\n" "%s.code_counterC: %d\n" "%s.code_counterC_unmatched: %d\n" "%s.count_peak_extend: %d\n" "%s.count_transient_filter: %d\n" "%s.count_sustain_expired: %d\n" "%s.max_gain: [%02d] %0.1f dB\n", ctag, state->code_counterA, ctag, state->code_counterA_almost, ctag, state->code_counterB, ctag, state->code_counterB_checkfails, ctag, state->code_counterC, ctag, state->code_counterC_unmatched, ctag, state->count_peak_extend, ctag, state->count_transient_filter, ctag, state->count_sustain_expired, ctag, state->max_gain, GAINTOFLOAT(state->max_gain) ); for (j = 0; j <= state->max_gain; j++) _hdcd_log(state->log, "%s.tg[%02d] %0.1f dB: %d\n", ctag, j, GAINTOFLOAT(j), state->gain_counts[j] ); } void _hdcd_dump_state_to_log_ffmpeg(hdcd_state *state, int channel) { int j; char ctag[20] = ""; if (!state) return; if (channel >= 0) snprintf(ctag, sizeof(ctag), "Channel %d: ", channel); _hdcd_log(state->log, "%s""counter A: %d, B: %d, C: %d\n", ctag, state->code_counterA, state->code_counterB, state->code_counterC); _hdcd_log(state->log, "%s""pe: %d, tf: %d, almost_A: %d, checkfail_B: %d, unmatched_C: %d, cdt_expired: %d\n", ctag, state->count_peak_extend, state->count_transient_filter, state->code_counterA_almost, state->code_counterB_checkfails, state->code_counterC_unmatched, state->count_sustain_expired); for (j = 0; j <= state->max_gain; j++) _hdcd_log(state->log, "%s""tg %0.1f: %d\n", ctag, GAINTOFLOAT(j), state->gain_counts[j]); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_decode2.h000066400000000000000000000167401516712004000261020ustar00rootroot00000000000000/* * Copyright (C) 2010, Chris Moeller, * All rights reserved. * Optimizations by Gumboot * Additional work by Burt P. * Original code reverse engineered from HDCD decoder library by Christopher Key, * which was likely reverse engineered from Windows Media Player. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * HDCD is High Definition Compatible Digital * http://wiki.hydrogenaud.io/index.php?title=High_Definition_Compatible_Digital * * More information about HDCD-encoded audio CDs: * http://www.audiomisc.co.uk/HFN/HDCD/Enigma.html * http://www.audiomisc.co.uk/HFN/HDCD/Examined.html */ #ifndef _HDCD_DECODE2_H_ #define _HDCD_DECODE2_H_ #include #include #include "hdcd_libversion.h" #include "hdcd_detect.h" /* enums for various detection values */ #include "hdcd_analyze.h" /* enums and definitions for analyze modes */ #ifdef __cplusplus extern "C" { #endif /********************* optional logging ************************/ typedef void (*hdcd_log_callback)(const void *priv, const char* fmt, va_list args); typedef struct { uint32_t sid; /**< internal struct identity = HDCD_SID_LOGGER */ int enable; void *priv; hdcd_log_callback log_func; } hdcd_log; int _hdcd_log_init(hdcd_log *log, hdcd_log_callback func, void *priv); void _hdcd_log(hdcd_log *log, const char* fmt, ...); void _hdcd_log_enable(hdcd_log *log); void _hdcd_log_disable(hdcd_log *log); /********************* decoding ********************************/ #define HDCD_FLAG_FORCE_PE 128 #define HDCD_FLAG_TGM_LOG_OFF 64 typedef struct { uint32_t sid; /**< internal struct identity = HDCD_SID_STATE */ int decoder_options; /**< as flags HDCD_FLAG_* */ uint64_t window; unsigned char readahead; /** arg is set when a packet prefix is found. * control is the active control code, where * bit 0-3: target_gain, 4-bit (3.1) fixed-point value * bit 4 : peak_extend * bit 5 : transient_filter * bit 6,7: always zero */ uint8_t arg, control; unsigned int sustain, sustain_reset; /**< code detect timer */ int running_gain; /**< 11-bit (3.8) fixed point, extended from target_gain */ int bits; /**< sample bit depth: 16, 20, 24 */ int rate; /**< sample rate */ int cdt_period; /**< cdt period in ms */ /** counters */ int code_counterA; /**< 8-bit format packet */ int code_counterA_almost; /**< looks like an A code, but a bit expected to be 0 is 1 */ int code_counterB; /**< 16-bit format packet, 8-bit code, 8-bit XOR of code */ int code_counterB_checkfails; /**< looks like a B code, but doesn't pass the XOR check */ int code_counterC; /**< packet prefix was found, expect a code */ int code_counterC_unmatched; /**< told to look for a code, but didn't find one */ int count_peak_extend; /**< valid packets where peak_extend was enabled */ int count_transient_filter; /**< valid packets where filter was detected */ /** target_gain is a 4-bit (3.1) fixed-point value, always * negative, but stored positive. * The 16 possible values range from -7.5 to 0.0 dB in * steps of 0.5, but no value below -6.0 dB should appear. */ int gain_counts[16]; int max_gain; /** occurences of code detect timer expiring without detecting * a code. -1 for timer never set. */ int count_sustain_expired; hdcd_log *log; /**< optional logging */ int sample_count; /**< used in logging */ hdcd_ana_mode ana_mode; /**< analyze mode */ int _ana_snb; /**< used in the analyze mode tone generator */ } hdcd_state; typedef struct { uint32_t sid; /**< internal struct identity = HDCD_SID_STATE_STEREO */ hdcd_state channel[2]; /**< individual channel states */ hdcd_ana_mode ana_mode; /**< analyze mode */ int val_target_gain; /**< last valid matching target_gain */ int count_tg_mismatch; /**< target_gain mismatch samples */ } hdcd_state_stereo; /* n-channel versions */ void _hdcd_reset(hdcd_state *state, unsigned rate, unsigned bits, int sustain_period_ms, int flags); void _hdcd_process(hdcd_state *state, int *samples, int count, int stride); /* stereo versions */ void _hdcd_reset_stereo(hdcd_state_stereo *state, unsigned rate, unsigned bits, int sustain_period_ms, int flags); void _hdcd_process_stereo(hdcd_state_stereo *state, int *samples, int count); /* hdcd_state* or hdcd_state_stereo* */ void _hdcd_attach_logger(void *state, hdcd_log *log); /* log = NULL to use the default logger */ void _hdcd_set_analyze_mode(void *state, hdcd_ana_mode mode); /********************* optional detection and stats ************/ typedef struct { uint32_t sid; /**< internal struct identity = HDCD_SID_DETECTION_DATA */ hdcd_dv hdcd_detected; hdcd_pf packet_type; int total_packets; /**< valid packets */ int errors; /**< detectable errors */ hdcd_pe peak_extend; int uses_transient_filter; float max_gain_adjustment; /**< in dB, expected in the range -7.5 to 0.0 */ int cdt_expirations; /**< -1 for never set, 0 for set but never expired */ int _active_count; /**< used internally */ } hdcd_detection_data; void _hdcd_detect_reset(hdcd_detection_data *detect); void _hdcd_detect_start(hdcd_detection_data *detect); void _hdcd_detect_onech(hdcd_state *state, hdcd_detection_data *detect); void _hdcd_detect_end(hdcd_detection_data *detect, int channels); /* combines _start() _onech()(x2) _end */ void _hdcd_detect_stereo(hdcd_state_stereo *state, hdcd_detection_data *detect); /* get a string with an HDCD detection summary */ void _hdcd_detect_str(hdcd_detection_data *detect, char *str, int maxlen); /* [256] should be enough */ /* dump the hdcd_state struct to the log */ void _hdcd_dump_state_to_log(hdcd_state *state, int channel); /* ... in the ffmpeg af_hdcd style */ void _hdcd_dump_state_to_log_ffmpeg(hdcd_state *state, int channel); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_detect.h000066400000000000000000000054521516712004000260430ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _HDCD_DETECT_H_ #define _HDCD_DETECT_H_ #ifdef __cplusplus extern "C" { #endif typedef enum { HDCD_NONE = 0, /**< HDCD packets do not (yet) appear */ HDCD_NO_EFFECT = 1, /**< HDCD packets appear, but all control codes are NOP */ HDCD_EFFECTUAL = 2, /**< HDCD packets appear, and change the output in some way */ } hdcd_dv; typedef enum { HDCD_PE_NEVER = 0, /**< All valid packets have PE set to off */ HDCD_PE_INTERMITTENT = 1, /**< Some valid packets have PE set to on */ HDCD_PE_PERMANENT = 2, /**< All valid packets have PE set to on */ } hdcd_pe; typedef enum { HDCD_PVER_NONE = 0, /**< No packets discovered */ HDCD_PVER_A = 1, /**< Packets of type A (8-bit control) discovered */ HDCD_PVER_B = 2, /**< Packets of type B (8-bit control, 8-bit XOR) discovered */ HDCD_PVER_MIX = 3, /**< Packets of type A and B discovered, most likely an error? */ } hdcd_pf; /** get a string describing the detection status */ const char* hdcd_str_detect(hdcd_dv v); /** get a string describing the PE status */ const char* hdcd_str_pe(hdcd_pe v); /** get a string describing the packet format found */ const char* hdcd_str_pformat(hdcd_pf v); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_libversion.c000066400000000000000000000034761516712004000267460ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "hdcd_libversion.h" int hdcd_lib_version(int* major, int* minor) { int match = 0; if (*major == HDCDLIB_VER_MAJOR && *minor == HDCDLIB_VER_MINOR) match = 1; *major = HDCDLIB_VER_MAJOR; *minor = HDCDLIB_VER_MINOR; return match; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_libversion.h000066400000000000000000000044311516712004000267430ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _HDCD_LIBVERSION_H_ #define _HDCD_LIBVERSION_H_ #ifdef __cplusplus extern "C" { #endif #define HDCDLIB_VER_MAJOR 1 /* used as libtool 'current' */ #define HDCDLIB_VER_MINOR 4 /* used as libtool 'revision' */ #define HDCDLIB_VER_AGE 0 /* used as libtool 'age' */ /* age is the difference between the 'current' and whatever * old 'current' version the library can still safely link against. * https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html */ /** fills major and minor with the version of the built library * * int major = HDCDLIB_VER_MAJOR, minor = HDCDLIB_VER_MINOR; * ver_match = hdcd_lib_version(&major, &minor); * */ int hdcd_lib_version(int* major, int* minor); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_simple.c000066400000000000000000000211451516712004000260540ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "hdcd_decode2.h" #include "hdcd_simple.h" struct hdcd_simple { hdcd_state_stereo state; hdcd_detection_data detect; hdcd_log logger; int smode; int rate; int bits; }; /** set stereo processing mode, only used internally */ static void hdcd_smode(hdcd_simple *s, int mode) { if (!s) return; if (mode != 0 && mode != 1) return; /* TODO: this could be more careful when switching in * the middle of processing, re: last valid tg, * but not critical. */ s->smode = mode; } /** create a new hdcd_simple context */ hdcd_simple *hdcd_new(void) { hdcd_simple *s = malloc(sizeof(*s)); if (s) { memset(s, 0, sizeof(*s)); _hdcd_log_init(&s->logger, NULL, NULL); _hdcd_log_disable(&s->logger); s->rate = 44100; s->bits = 16; hdcd_reset(s); } return s; } static void _hdcd_simple_reset_state(hdcd_state_stereo *state, int rate, int bits) { if (!state) return; _hdcd_reset_stereo(state, rate, bits, 0, HDCD_FLAG_TGM_LOG_OFF); } int hdcd_reset_ext(hdcd_simple *s, int rate, int bits) { if (!s) return 0; switch(rate) { case 0: rate = 44100; case 44100: case 88200: case 176400: case 48000: case 96000: case 192000: break; default: return 0; } switch(bits) { case 0: bits = 16; case 16: case 20: case 24: break; default: return 0; } s->rate = rate; s->bits = bits; _hdcd_simple_reset_state(&s->state, s->rate, s->bits); _hdcd_detect_reset(&s->detect); _hdcd_attach_logger(&s->state, &s->logger); hdcd_analyze_mode(s, 0); hdcd_smode(s, 1); return 1; } /** on a song change or something, reset the decoding state */ void hdcd_reset(hdcd_simple *s) { if (!s) return; hdcd_reset_ext(s, 0, 0); } /** process signed 16-bit samples (stored in 32-bit), interlaced stereo */ void hdcd_process(hdcd_simple *s, int *samples, int count) { if (!s) return; if (s->smode) /* process stereo channels together */ _hdcd_process_stereo(&s->state, samples, count); else { /* independently process each channel */ _hdcd_process(&s->state.channel[0], samples, count, 2); _hdcd_process(&s->state.channel[1], samples + 1, count, 2); } _hdcd_detect_stereo(&s->state, &s->detect); } /*hdcd_dv*/ int hdcd_scan(hdcd_simple *s, int *samples, int count, int ignore_state) { hdcd_state_stereo st; hdcd_detection_data d; int buf_size = sizeof(int) * count * 2; int *samp; if (!s) return 0; /* The simplest way to do this is to copy everything and process. * Perhaps later, a more efficient way can be implemented using * calls to _hdcd_scan_stereo() until the first effectual packet * is found */ if (ignore_state) { _hdcd_simple_reset_state(&st, s->rate, s->bits); _hdcd_detect_reset(&d); } else { memcpy(&st, &s->state, sizeof(hdcd_state_stereo)); memcpy(&d, &s->detect, sizeof(hdcd_detection_data)); } if (d.hdcd_detected == HDCD_EFFECTUAL) return d.hdcd_detected; /* easy peasy */ samp = malloc(buf_size); if (samp) { memcpy(samp, samples, buf_size); _hdcd_process_stereo(&st, samp, count); _hdcd_detect_stereo(&st, &d); free(samp); return d.hdcd_detected; } else return 0; /* possible alternate method: *samp = samples; int c = count; while (c) { c -= _hdcd_scan_stereo(&st, samp_scan, c); if (st.channel[0].count_peak_extend || st.channel[1].count_peak_extend || st.channel[0].max_gain || st.channel[1].max_gain) return HDCD_EFFECTUAL; } if (packets) return HDCD_NO_EFFECT; else return HDCD_NONE; */ } /** free the context when finished */ void hdcd_free(hdcd_simple *s) { if(s) free(s); } /** Is HDCD encoding detected? */ /*hdcd_dv*/ int hdcd_detected(hdcd_simple *s) { if (!s) return 0; return s->detect.hdcd_detected; } /*hdcd_pf*/ int hdcd_detect_packet_type(hdcd_simple *ctx) { if (ctx) return ctx->detect.packet_type; else return 0; } int hdcd_detect_total_packets(hdcd_simple *ctx) { if (ctx) return ctx->detect.total_packets; else return 0; } int hdcd_detect_errors(hdcd_simple *ctx) { if (ctx) return ctx->detect.errors; else return 0; } /*hdcd_pe*/ int hdcd_detect_peak_extend(hdcd_simple *ctx) { if (ctx) return ctx->detect.peak_extend; else return 0; } int hdcd_detect_uses_transient_filter(hdcd_simple *ctx) { if (ctx) return ctx->detect.uses_transient_filter; else return 0; } float hdcd_detect_max_gain_adjustment(hdcd_simple *ctx) { if (ctx) return ctx->detect.max_gain_adjustment; else return 0.0; } int hdcd_detect_cdt_expirations(hdcd_simple *ctx) { if (ctx) return ctx->detect.cdt_expirations; else return -1; } int hdcd_detect_lle_mismatch(hdcd_simple *ctx) { if (ctx) return ctx->state.count_tg_mismatch; else return 0; } /** get a string with an HDCD detection summary */ void hdcd_detect_str(hdcd_simple *s, char *str, int maxlen) { if (!s || !str) return; _hdcd_detect_str(&s->detect, str, maxlen); } int hdcd_logger_attach(hdcd_simple *s, hdcd_log_callback func, void *priv) { if (!s) return 0; if (!func) return 0; _hdcd_log_init(&s->logger, func, priv); _hdcd_attach_logger(&s->state, &s->logger); return 1; } void hdcd_logger_default(hdcd_simple *s) { if (!s) return; _hdcd_log_init(&s->logger, NULL, NULL); _hdcd_attach_logger(&s->state, &s->logger); } void hdcd_logger_detach(hdcd_simple *s) { if (!s) return; /* just reset to the default and then disable */ _hdcd_log_init(&s->logger, NULL, NULL); _hdcd_attach_logger(&s->state, &s->logger); _hdcd_log_disable(&s->logger); } int hdcd_analyze_mode(hdcd_simple *s, int mode) { if (!s) return 0; /* clear HDCD_FLAG_FORCE_PE for all, and set it * in the one mode that will use it */ s->state.channel[0].decoder_options &= ~HDCD_FLAG_FORCE_PE; s->state.channel[1].decoder_options &= ~HDCD_FLAG_FORCE_PE; switch(mode) { case HDCD_ANA_OFF: case HDCD_ANA_LLE: case HDCD_ANA_PE: case HDCD_ANA_CDT: case HDCD_ANA_TGM: hdcd_smode(s, 1); _hdcd_set_analyze_mode(&s->state, mode); return 1; case HDCD_ANA_PEL: /* HDCD_ANA_PE + HDCD_FLAG_FORCE_PE */ hdcd_smode(s, 1); s->state.channel[0].decoder_options |= HDCD_FLAG_FORCE_PE; s->state.channel[1].decoder_options |= HDCD_FLAG_FORCE_PE; _hdcd_set_analyze_mode(&s->state, HDCD_ANA_PE); return 1; case HDCD_ANA_LTGM: /* HDCD_ANA_LLE + stereo_mode off */ hdcd_smode(s, 0); _hdcd_set_analyze_mode(&s->state, HDCD_ANA_LLE); return 1; } return 0; } void hdcd_logger_dump_state(hdcd_simple *s) { int i; if (!s) return; for(i = 0; i < 2; i++) _hdcd_dump_state_to_log(&s->state.channel[i], i); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_simple.h000066400000000000000000000100351516712004000260550ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _HDCD_SIMPLE_H_ #define _HDCD_SIMPLE_H_ #include #include "hdcd_decode2.h" #ifdef __cplusplus extern "C" { #endif typedef struct hdcd_simple hdcd_simple; /** create a new hdcd_simple context */ hdcd_simple *hdcd_new(void); /** process 16-bit samples (stored in 32-bit), interlaced stereo. * the samples will be converted in place to 32-bit samples. */ void hdcd_process(hdcd_simple *ctx, int *samples, int count); /** on a song change or something, reset the decoding state */ void hdcd_reset(hdcd_simple *ctx); /** version of hdcd_reset when not 44100Hz or 16-bit */ int hdcd_reset_ext(hdcd_simple *ctx, int rate, int bits); /** free the context when finished */ void hdcd_free(hdcd_simple *ctx); /** as hdcd_process(), but only scan. samples remain unprocessed. * return expected value of hdcd_detected() after processing */ /*hdcd_dv*/ int hdcd_scan(hdcd_simple *ctx, int *samples, int count, int ignore_state); /** is HDCD encoding detected? */ /*hdcd_dv*/ int hdcd_detected(hdcd_simple *ctx); /**< see hdcd_dv in hdcd_detect.h */ /** get a string with an HDCD detection summary */ void hdcd_detect_str(hdcd_simple *ctx, char *str, int maxlen); /* [256] should be enough */ /** get individual detection values */ /*hdcd_pf*/ int hdcd_detect_packet_type(hdcd_simple *ctx); /**< see hdcd_pf in hdcd_detect.h */ int hdcd_detect_total_packets(hdcd_simple *ctx); /**< valid packets */ int hdcd_detect_errors(hdcd_simple *ctx); /**< detectable errors */ /*hdcd_pe*/ int hdcd_detect_peak_extend(hdcd_simple *ctx); /**< see hdcd_pe in hdcd_detect.h */ int hdcd_detect_uses_transient_filter(hdcd_simple *ctx); /**< bool, 1 if the tf flag was detected */ float hdcd_detect_max_gain_adjustment(hdcd_simple *ctx); /**< in dB, expected in the range -7.5 to 0.0 */ int hdcd_detect_cdt_expirations(hdcd_simple *ctx); /**< -1 for never set, 0 for set but never expired */ int hdcd_detect_lle_mismatch(hdcd_simple *ctx); /**< number of samples with a mismatch in gain values between channels */ /** set a logging callback or use the default (print to stderr) */ int hdcd_logger_attach(hdcd_simple *ctx, hdcd_log_callback func, void *priv); void hdcd_logger_default(hdcd_simple *ctx); void hdcd_logger_detach(hdcd_simple *ctx); void hdcd_logger_dump_state(hdcd_simple *s); /** set the analyze mode */ int hdcd_analyze_mode(hdcd_simple *ctx, int mode); #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_strings.c000066400000000000000000000051241516712004000262530ustar00rootroot00000000000000/* * Copyright (C) 2016, Burt P., * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "hdcd_analyze.h" #include "hdcd_detect.h" const char* hdcd_str_analyze_mode_desc(hdcd_ana_mode mode) { static const char * const ana_mode_str[] = { HDCD_ANA_OFF_DESC, HDCD_ANA_LLE_DESC, HDCD_ANA_PE_DESC, HDCD_ANA_CDT_DESC, HDCD_ANA_TGM_DESC, HDCD_ANA_PEL_DESC, HDCD_ANA_LTGM_DESC, }; if (mode < 0 || mode > 6) return ""; return ana_mode_str[mode]; } const char* hdcd_str_detect(hdcd_dv v) { static const char * const det_str[] = { "not detected", "detected (no effect)", "detected" }; if (v < 0 || v > 2) return ""; return det_str[v]; } const char* hdcd_str_pe(hdcd_pe v) { static const char * const pe_str[] = { "never enabled", "enabled intermittently", "enabled permanently" }; if (v < 0 || v > 2) return ""; return pe_str[v]; } const char* hdcd_str_pformat(hdcd_pf v) { static const char * const pf_str[] = { "?", "A", "B", "A+B" }; if (v < 0 || v > 3) return ""; return pf_str[v]; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/hdcd/libhdcd/hdcd_tables.c000066400000000000000000004316121516712004000260410ustar00rootroot00000000000000/* * Copyright (C) 2010, Chris Moeller, * All rights reserved. * Optimizations by Gumboot * Additional work by Burt P. * Original code reverse engineered from HDCD decoder library by Christopher Key, * which was likely reverse engineered from Windows Media Player. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* #included in hdcd_decode2.c */ static const int peak_ext_level = 0x5981; /* + sizeof(peaktab)-1 = 0x8000 */ static const uint32_t peaktab[0x2680] = { 0x2cc08300, 0x2cc10600, 0x2cc18900, 0x2cc20c00, 0x2cc28f00, 0x2cc31200, 0x2cc39500, 0x2cc41800, 0x2cc49b00, 0x2cc51e00, 0x2cc5a100, 0x2cc62400, 0x2cc6a700, 0x2cc72a00, 0x2cc7ad00, 0x2cc83000, 0x2cc8b300, 0x2cc93600, 0x2cc9b900, 0x2cca3c00, 0x2ccabf00, 0x2ccb4200, 0x2ccbc500, 0x2ccc4800, 0x2ccccb00, 0x2ccd4e00, 0x2ccdd100, 0x2cce5400, 0x2cced700, 0x2ccf5a00, 0x2ccfdd00, 0x2cd06000, 0x2cd0e300, 0x2cd16600, 0x2cd1e900, 0x2cd26c00, 0x2cd2ef00, 0x2cd37200, 0x2cd3f500, 0x2cd47800, 0x2cd4fb00, 0x2cd57e00, 0x2cd60100, 0x2cd68400, 0x2cd70700, 0x2cd78a00, 0x2cd80d00, 0x2cd89000, 0x2cd91300, 0x2cd99600, 0x2cda1900, 0x2cda9c00, 0x2cdb1f00, 0x2cdba200, 0x2cdc2500, 0x2cdca800, 0x2cdd2b00, 0x2cddae00, 0x2cde3100, 0x2cdeb400, 0x2cdf3700, 0x2cdfba00, 0x2ce03d00, 0x2ce0c000, 0x2ce14300, 0x2ce1c600, 0x2ce24900, 0x2ce2cc00, 0x2ce34f00, 0x2ce3d200, 0x2ce45500, 0x2ce4d800, 0x2ce55b00, 0x2ce5de00, 0x2ce66100, 0x2ce6e400, 0x2ce76700, 0x2ce7ea00, 0x2ce86d00, 0x2ce8f000, 0x2ce97300, 0x2ce9f600, 0x2cea7900, 0x2ceafc00, 0x2ceb7f00, 0x2cec0200, 0x2cec8500, 0x2ced0800, 0x2ced8b00, 0x2cee0e00, 0x2cee9100, 0x2cef1400, 0x2cef9700, 0x2cf01a00, 0x2cf09d00, 0x2cf12000, 0x2cf1a300, 0x2cf22600, 0x2cf2a900, 0x2cf32c00, 0x2cf3af00, 0x2cf43200, 0x2cf4b500, 0x2cf53800, 0x2cf5bb00, 0x2cf63e00, 0x2cf6c100, 0x2cf74400, 0x2cf7c700, 0x2cf84a00, 0x2cf8cd00, 0x2cf95000, 0x2cf9d300, 0x2cfa5600, 0x2cfad900, 0x2cfb5c00, 0x2cfbdf00, 0x2cfc6200, 0x2cfce500, 0x2cfd6800, 0x2cfdeb00, 0x2cfe6e00, 0x2cfef100, 0x2cff7400, 0x2cfff700, 0x2d007a00, 0x2d00fd00, 0x2d018000, 0x2d020300, 0x2d028600, 0x2d030900, 0x2d038c00, 0x2d040f00, 0x2d049200, 0x2d051500, 0x2d059800, 0x2d061b00, 0x2d069e00, 0x2d072100, 0x2d07a400, 0x2d082700, 0x2d08aa00, 0x2d092d00, 0x2d09b000, 0x2d0a3300, 0x2d0ab600, 0x2d0b3900, 0x2d0bbc00, 0x2d0c3f00, 0x2d0cc200, 0x2d0d4500, 0x2d0dc800, 0x2d0e4b00, 0x2d0ece00, 0x2d0f5100, 0x2d0fd400, 0x2d105700, 0x2d10da00, 0x2d115d00, 0x2d11e000, 0x2d126300, 0x2d12e600, 0x2d136900, 0x2d13ec00, 0x2d146f00, 0x2d14f200, 0x2d157500, 0x2d15f800, 0x2d167b00, 0x2d16fe00, 0x2d178100, 0x2d180400, 0x2d188700, 0x2d190a00, 0x2d198d00, 0x2d1a1000, 0x2d1a9300, 0x2d1b1600, 0x2d1b9900, 0x2d1c1c00, 0x2d1c9f00, 0x2d1d2200, 0x2d1da500, 0x2d1e2800, 0x2d1eab00, 0x2d1f2e00, 0x2d1fb100, 0x2d203400, 0x2d20b700, 0x2d213a00, 0x2d21bd00, 0x2d224000, 0x2d22c300, 0x2d234600, 0x2d23c900, 0x2d244c00, 0x2d24cf00, 0x2d255200, 0x2d25d500, 0x2d265800, 0x2d26db00, 0x2d275e00, 0x2d27e100, 0x2d286400, 0x2d28e700, 0x2d296a00, 0x2d29ed00, 0x2d2a7000, 0x2d2af300, 0x2d2b7600, 0x2d2bf900, 0x2d2c7c00, 0x2d2cff00, 0x2d2d8200, 0x2d2e0500, 0x2d2e8800, 0x2d2f0b00, 0x2d2f8e00, 0x2d301100, 0x2d309400, 0x2d311700, 0x2d319a00, 0x2d321d00, 0x2d32a000, 0x2d332300, 0x2d33a600, 0x2d342900, 0x2d34ac00, 0x2d352f00, 0x2d35b200, 0x2d363500, 0x2d36b800, 0x2d373b00, 0x2d37be00, 0x2d384100, 0x2d38c400, 0x2d394700, 0x2d39ca00, 0x2d3a4d00, 0x2d3ad000, 0x2d3b5300, 0x2d3bd600, 0x2d3c5900, 0x2d3cdc00, 0x2d3d5f00, 0x2d3de200, 0x2d3e6500, 0x2d3ee800, 0x2d3f6b00, 0x2d3fee00, 0x2d407100, 0x2d40f400, 0x2d417700, 0x2d41fa00, 0x2d427d00, 0x2d430000, 0x2d438300, 0x2d440600, 0x2d448900, 0x2d450c00, 0x2d458f00, 0x2d461200, 0x2d469500, 0x2d471800, 0x2d479b00, 0x2d481e00, 0x2d48a100, 0x2d492400, 0x2d49a700, 0x2d4a2a00, 0x2d4aad00, 0x2d4b3000, 0x2d4bb300, 0x2d4c3600, 0x2d4cb900, 0x2d4d3c00, 0x2d4dbf00, 0x2d4e4200, 0x2d4ec500, 0x2d4f4800, 0x2d4fcb00, 0x2d504e00, 0x2d50d100, 0x2d515400, 0x2d51d700, 0x2d525a00, 0x2d52dd00, 0x2d536000, 0x2d53e300, 0x2d546600, 0x2d54e900, 0x2d556c00, 0x2d55ef00, 0x2d567200, 0x2d56f500, 0x2d577800, 0x2d57fb00, 0x2d587e00, 0x2d590100, 0x2d598400, 0x2d5a0700, 0x2d5a8a00, 0x2d5b0d00, 0x2d5b9000, 0x2d5c1300, 0x2d5c9600, 0x2d5d1900, 0x2d5d9c00, 0x2d5e1f00, 0x2d5ea200, 0x2d5f2500, 0x2d5fa800, 0x2d602b00, 0x2d60ae00, 0x2d613100, 0x2d61b400, 0x2d623700, 0x2d62ba00, 0x2d633d00, 0x2d63c000, 0x2d644300, 0x2d64c600, 0x2d654900, 0x2d65cc00, 0x2d664f00, 0x2d66d200, 0x2d675500, 0x2d67d800, 0x2d685b00, 0x2d68de00, 0x2d696100, 0x2d69e400, 0x2d6a6700, 0x2d6aea00, 0x2d6b6d00, 0x2d6bf000, 0x2d6c7300, 0x2d6cf600, 0x2d6d7900, 0x2d6dfc00, 0x2d6e7f00, 0x2d6f0200, 0x2d6f8500, 0x2d700800, 0x2d708b00, 0x2d710e00, 0x2d719100, 0x2d721400, 0x2d729700, 0x2d731a00, 0x2d739d00, 0x2d742000, 0x2d74a300, 0x2d752600, 0x2d75a900, 0x2d762c00, 0x2d76af00, 0x2d773200, 0x2d77b500, 0x2d783800, 0x2d78bb00, 0x2d793e00, 0x2d79c100, 0x2d7a4400, 0x2d7ac700, 0x2d7b4a00, 0x2d7bcd00, 0x2d7c5000, 0x2d7cd300, 0x2d7d5600, 0x2d7dd900, 0x2d7e5c00, 0x2d7edf00, 0x2d7f6200, 0x2d7fe500, 0x2d806800, 0x2d80eb00, 0x2d816e00, 0x2d81f100, 0x2d827400, 0x2d82f700, 0x2d837a00, 0x2d83fd00, 0x2d848000, 0x2d850300, 0x2d858600, 0x2d860900, 0x2d868c00, 0x2d870f00, 0x2d879200, 0x2d881500, 0x2d889800, 0x2d891b00, 0x2d899e00, 0x2d8a2100, 0x2d8aa400, 0x2d8b2700, 0x2d8baa00, 0x2d8c2d00, 0x2d8cb000, 0x2d8d3300, 0x2d8db600, 0x2d8e3900, 0x2d8ebc00, 0x2d8f3f00, 0x2d8fc200, 0x2d904500, 0x2d90c800, 0x2d914b00, 0x2d91ce00, 0x2d925100, 0x2d92d400, 0x2d935700, 0x2d93da00, 0x2d945d00, 0x2d94e000, 0x2d956300, 0x2d95e600, 0x2d966900, 0x2d96ec00, 0x2d976f00, 0x2d97f200, 0x2d987500, 0x2d98f800, 0x2d997b00, 0x2d99fe00, 0x2d9a8100, 0x2d9b0400, 0x2d9b8700, 0x2d9c0a00, 0x2d9c8d00, 0x2d9d1000, 0x2d9d9300, 0x2d9e1600, 0x2d9e9900, 0x2d9f1c00, 0x2d9f9f00, 0x2da02200, 0x2da0a500, 0x2da12800, 0x2da1ab00, 0x2da22e00, 0x2da2b100, 0x2da33400, 0x2da3b700, 0x2da43a00, 0x2da4bd00, 0x2da54000, 0x2da5c300, 0x2da64600, 0x2da6c900, 0x2da74c00, 0x2da7cf00, 0x2da85200, 0x2da8d500, 0x2da95800, 0x2da9db00, 0x2daa5e00, 0x2daae100, 0x2dab6400, 0x2dabe700, 0x2dac6a00, 0x2daced00, 0x2dad7000, 0x2dadf300, 0x2dae7600, 0x2daef900, 0x2daf7c00, 0x2dafff00, 0x2db08200, 0x2db10500, 0x2db18800, 0x2db20b00, 0x2db28e00, 0x2db31100, 0x2db39400, 0x2db41700, 0x2db49a00, 0x2db51d00, 0x2db5a000, 0x2db62300, 0x2db6a600, 0x2db72900, 0x2db7ac00, 0x2db82f00, 0x2db8b200, 0x2db93500, 0x2db9b800, 0x2dba3b00, 0x2dbabe00, 0x2dbb4100, 0x2dbbc400, 0x2dbc4700, 0x2dbcca00, 0x2dbd4d00, 0x2dbdd000, 0x2dbe5300, 0x2dbed600, 0x2dbf5900, 0x2dbfdc00, 0x2dc05f00, 0x2dc0e200, 0x2dc16500, 0x2dc1e800, 0x2dc26b00, 0x2dc2ee00, 0x2dc37100, 0x2dc3f400, 0x2dc47700, 0x2dc4fa00, 0x2dc57d00, 0x2dc60000, 0x2dc68700, 0x2dc70e00, 0x2dc79500, 0x2dc81c00, 0x2dc8a300, 0x2dc92a00, 0x2dc9b100, 0x2dca3800, 0x2dcabf00, 0x2dcb4600, 0x2dcbcd00, 0x2dcc5400, 0x2dccdb00, 0x2dcd6200, 0x2dcde900, 0x2dce7000, 0x2dcef700, 0x2dcf7e00, 0x2dd00500, 0x2dd08c00, 0x2dd11300, 0x2dd19a00, 0x2dd22100, 0x2dd2a800, 0x2dd32f00, 0x2dd3b600, 0x2dd43d00, 0x2dd4c400, 0x2dd54b00, 0x2dd5d200, 0x2dd65900, 0x2dd6e000, 0x2dd76700, 0x2dd7ee00, 0x2dd87500, 0x2dd8fc00, 0x2dd98300, 0x2dda0a00, 0x2dda9100, 0x2ddb1800, 0x2ddb9f00, 0x2ddc2600, 0x2ddcad00, 0x2ddd3400, 0x2dddbb00, 0x2dde4200, 0x2ddec900, 0x2ddf5000, 0x2ddfd700, 0x2de05e00, 0x2de0e500, 0x2de16c00, 0x2de1f300, 0x2de27a00, 0x2de30100, 0x2de38800, 0x2de40f00, 0x2de49600, 0x2de51d00, 0x2de5a400, 0x2de62b00, 0x2de6b200, 0x2de73900, 0x2de7c000, 0x2de84700, 0x2de8ce00, 0x2de95500, 0x2de9dc00, 0x2dea6300, 0x2deaea00, 0x2deb7100, 0x2debf800, 0x2dec7f00, 0x2ded0600, 0x2ded8d00, 0x2dee1400, 0x2dee9b00, 0x2def2200, 0x2defa900, 0x2df03000, 0x2df0b700, 0x2df13e00, 0x2df1c500, 0x2df24c00, 0x2df2d300, 0x2df35a00, 0x2df3e100, 0x2df46800, 0x2df4ef00, 0x2df57600, 0x2df5fd00, 0x2df68400, 0x2df70b00, 0x2df79200, 0x2df81900, 0x2df8a000, 0x2df92700, 0x2df9ae00, 0x2dfa3500, 0x2dfabc00, 0x2dfb4300, 0x2dfbca00, 0x2dfc5100, 0x2dfcd800, 0x2dfd5f00, 0x2dfde600, 0x2dfe6d00, 0x2dfef400, 0x2dff7b00, 0x2e000200, 0x2e008900, 0x2e011000, 0x2e019700, 0x2e021e00, 0x2e02a500, 0x2e032c00, 0x2e03b300, 0x2e043a00, 0x2e04c100, 0x2e054800, 0x2e05cf00, 0x2e065600, 0x2e06dd00, 0x2e076400, 0x2e07eb00, 0x2e087200, 0x2e08f900, 0x2e098000, 0x2e0a0700, 0x2e0a8e00, 0x2e0b1500, 0x2e0b9c00, 0x2e0c2300, 0x2e0caa00, 0x2e0d3100, 0x2e0db800, 0x2e0e3f00, 0x2e0ec600, 0x2e0f4d00, 0x2e0fd400, 0x2e105b00, 0x2e10e200, 0x2e116900, 0x2e11f000, 0x2e127700, 0x2e12fe00, 0x2e138500, 0x2e140c00, 0x2e149300, 0x2e151a00, 0x2e15a100, 0x2e162800, 0x2e16af00, 0x2e173600, 0x2e17bd00, 0x2e184400, 0x2e18cb00, 0x2e195200, 0x2e19d900, 0x2e1a6000, 0x2e1ae700, 0x2e1b6e00, 0x2e1bf500, 0x2e1c7c00, 0x2e1d0300, 0x2e1d8a00, 0x2e1e1100, 0x2e1e9800, 0x2e1f1f00, 0x2e1fa600, 0x2e202d00, 0x2e20b400, 0x2e213b00, 0x2e21c200, 0x2e224900, 0x2e22d000, 0x2e235700, 0x2e23de00, 0x2e246500, 0x2e24ec00, 0x2e257300, 0x2e25fa00, 0x2e268100, 0x2e270800, 0x2e278f00, 0x2e281600, 0x2e289d00, 0x2e292400, 0x2e29ab00, 0x2e2a3200, 0x2e2ab900, 0x2e2b4000, 0x2e2bc700, 0x2e2c4e00, 0x2e2cd500, 0x2e2d5c00, 0x2e2de300, 0x2e2e6a00, 0x2e2ef100, 0x2e2f7800, 0x2e2fff00, 0x2e308600, 0x2e310d00, 0x2e319400, 0x2e321b00, 0x2e32a200, 0x2e332900, 0x2e33b000, 0x2e343700, 0x2e34be00, 0x2e354500, 0x2e35cc00, 0x2e365300, 0x2e36da00, 0x2e376100, 0x2e37e800, 0x2e386f00, 0x2e38f600, 0x2e397d00, 0x2e3a0400, 0x2e3a8b00, 0x2e3b1200, 0x2e3b9900, 0x2e3c2000, 0x2e3ca700, 0x2e3d2e00, 0x2e3db500, 0x2e3e3c00, 0x2e3ec300, 0x2e3f4a00, 0x2e3fd100, 0x2e405800, 0x2e40df00, 0x2e416600, 0x2e41ed00, 0x2e427400, 0x2e42fb00, 0x2e438200, 0x2e440900, 0x2e449000, 0x2e451700, 0x2e459e00, 0x2e462500, 0x2e46ac00, 0x2e473300, 0x2e47ba00, 0x2e484100, 0x2e48c800, 0x2e494f00, 0x2e49d600, 0x2e4a5d00, 0x2e4ae400, 0x2e4b6b00, 0x2e4bf200, 0x2e4c7900, 0x2e4d0000, 0x2e4d8700, 0x2e4e0e00, 0x2e4e9500, 0x2e4f1c00, 0x2e4fa300, 0x2e502a00, 0x2e50b100, 0x2e513800, 0x2e51bf00, 0x2e524600, 0x2e52cd00, 0x2e535400, 0x2e53db00, 0x2e546200, 0x2e54e900, 0x2e557000, 0x2e55f700, 0x2e567e00, 0x2e570500, 0x2e578c00, 0x2e581300, 0x2e589a00, 0x2e592100, 0x2e59a800, 0x2e5a2f00, 0x2e5ab600, 0x2e5b3d00, 0x2e5bc400, 0x2e5c4b00, 0x2e5cd200, 0x2e5d5900, 0x2e5de000, 0x2e5e6700, 0x2e5eee00, 0x2e5f7500, 0x2e5ffc00, 0x2e608300, 0x2e610a00, 0x2e619100, 0x2e621800, 0x2e629f00, 0x2e632600, 0x2e63ad00, 0x2e643400, 0x2e64bb00, 0x2e654200, 0x2e65c900, 0x2e665000, 0x2e66d700, 0x2e675e00, 0x2e67e500, 0x2e686c00, 0x2e68f300, 0x2e697a00, 0x2e6a0100, 0x2e6a8800, 0x2e6b0f00, 0x2e6b9600, 0x2e6c1d00, 0x2e6ca400, 0x2e6d2b00, 0x2e6db200, 0x2e6e3900, 0x2e6ec000, 0x2e6f4700, 0x2e6fce00, 0x2e705500, 0x2e70dc00, 0x2e716300, 0x2e71ea00, 0x2e727100, 0x2e72f800, 0x2e737f00, 0x2e740600, 0x2e748d00, 0x2e751400, 0x2e759b00, 0x2e762200, 0x2e76a900, 0x2e773000, 0x2e77b700, 0x2e783e00, 0x2e78c500, 0x2e794c00, 0x2e79d300, 0x2e7a5a00, 0x2e7ae100, 0x2e7b6800, 0x2e7bef00, 0x2e7c7600, 0x2e7cfd00, 0x2e7d8400, 0x2e7e0b00, 0x2e7e9200, 0x2e7f1900, 0x2e7fa000, 0x2e802700, 0x2e80ae00, 0x2e813500, 0x2e81bc00, 0x2e824300, 0x2e82ca00, 0x2e835100, 0x2e83d800, 0x2e845f00, 0x2e84e600, 0x2e856d00, 0x2e85f400, 0x2e867b00, 0x2e870200, 0x2e878900, 0x2e881000, 0x2e889700, 0x2e891e00, 0x2e89a500, 0x2e8a2c00, 0x2e8ab300, 0x2e8b3a00, 0x2e8bc100, 0x2e8c4800, 0x2e8ccf00, 0x2e8d5600, 0x2e8ddd00, 0x2e8e6400, 0x2e8eeb00, 0x2e8f7200, 0x2e8ff900, 0x2e908000, 0x2e910700, 0x2e918e00, 0x2e921500, 0x2e929c00, 0x2e932300, 0x2e93aa00, 0x2e943100, 0x2e94b800, 0x2e953f00, 0x2e95c600, 0x2e964d00, 0x2e96d400, 0x2e975b00, 0x2e97e200, 0x2e986900, 0x2e98f000, 0x2e997700, 0x2e99fe00, 0x2e9a8500, 0x2e9b0c00, 0x2e9b9300, 0x2e9c1a00, 0x2e9ca100, 0x2e9d2800, 0x2e9daf00, 0x2e9e3600, 0x2e9ebd00, 0x2e9f4400, 0x2e9fcb00, 0x2ea05200, 0x2ea0d900, 0x2ea16000, 0x2ea1e700, 0x2ea26e00, 0x2ea2f500, 0x2ea37c00, 0x2ea40300, 0x2ea48a00, 0x2ea51100, 0x2ea59800, 0x2ea61f00, 0x2ea6a600, 0x2ea72d00, 0x2ea7b400, 0x2ea83b00, 0x2ea8c200, 0x2ea94900, 0x2ea9d000, 0x2eaa5700, 0x2eaade00, 0x2eab6500, 0x2eabec00, 0x2eac7300, 0x2eacfa00, 0x2ead8100, 0x2eae0800, 0x2eae8f00, 0x2eaf1600, 0x2eaf9d00, 0x2eb02400, 0x2eb0ab00, 0x2eb13200, 0x2eb1b900, 0x2eb24000, 0x2eb2c700, 0x2eb34e00, 0x2eb3d500, 0x2eb45c00, 0x2eb4e300, 0x2eb56a00, 0x2eb5f100, 0x2eb67800, 0x2eb6ff00, 0x2eb78600, 0x2eb80d00, 0x2eb89400, 0x2eb91b00, 0x2eb9a200, 0x2eba2900, 0x2ebab000, 0x2ebb3700, 0x2ebbbe00, 0x2ebc4500, 0x2ebccc00, 0x2ebd5300, 0x2ebdda00, 0x2ebe6100, 0x2ebee800, 0x2ebf6f00, 0x2ebff600, 0x2ec07d00, 0x2ec10400, 0x2ec18b00, 0x2ec21200, 0x2ec29900, 0x2ec32000, 0x2ec3a700, 0x2ec42e00, 0x2ec4b500, 0x2ec53c00, 0x2ec5c300, 0x2ec64a00, 0x2ec6d100, 0x2ec75800, 0x2ec7df00, 0x2ec86600, 0x2ec8ed00, 0x2ec97400, 0x2ec9fb00, 0x2eca8200, 0x2ecb0900, 0x2ecb9000, 0x2ecc1700, 0x2ecc9e00, 0x2ecd2500, 0x2ecdac00, 0x2ece3300, 0x2eceba00, 0x2ecf4100, 0x2ecfc800, 0x2ed04f00, 0x2ed0d600, 0x2ed15d00, 0x2ed1e400, 0x2ed26b00, 0x2ed2f200, 0x2ed37900, 0x2ed40000, 0x2ed48700, 0x2ed50e00, 0x2ed59500, 0x2ed61c00, 0x2ed6a300, 0x2ed72a00, 0x2ed7b100, 0x2ed83800, 0x2ed8bf00, 0x2ed94600, 0x2ed9cd00, 0x2eda5400, 0x2edadb00, 0x2edb6200, 0x2edbe900, 0x2edc7000, 0x2edcf700, 0x2edd7e00, 0x2ede0500, 0x2ede8c00, 0x2edf1300, 0x2edf9a00, 0x2ee02100, 0x2ee0a800, 0x2ee12f00, 0x2ee1b600, 0x2ee23d00, 0x2ee2c400, 0x2ee34b00, 0x2ee3d200, 0x2ee45900, 0x2ee4e000, 0x2ee56700, 0x2ee5ee00, 0x2ee67500, 0x2ee6fc00, 0x2ee78300, 0x2ee80a00, 0x2ee89100, 0x2ee91800, 0x2ee99f00, 0x2eea2600, 0x2eeaad00, 0x2eeb3400, 0x2eebbb00, 0x2eec4200, 0x2eecc900, 0x2eed5000, 0x2eedd700, 0x2eee5e00, 0x2eeee500, 0x2eef6c00, 0x2eeff300, 0x2ef07a00, 0x2ef10100, 0x2ef18800, 0x2ef20f00, 0x2ef29600, 0x2ef31d00, 0x2ef3a400, 0x2ef42b00, 0x2ef4b200, 0x2ef53900, 0x2ef5c000, 0x2ef64700, 0x2ef6ce00, 0x2ef75500, 0x2ef7dc00, 0x2ef86300, 0x2ef8ea00, 0x2ef97100, 0x2ef9f800, 0x2efa7f00, 0x2efb0600, 0x2efb8d00, 0x2efc1400, 0x2efc9b00, 0x2efd2200, 0x2efda900, 0x2efe3000, 0x2efeb700, 0x2eff3e00, 0x2effc500, 0x2f004c00, 0x2f00d300, 0x2f015a00, 0x2f01e100, 0x2f026800, 0x2f02ef00, 0x2f037600, 0x2f03fd00, 0x2f048400, 0x2f050b00, 0x2f059200, 0x2f061900, 0x2f06a000, 0x2f072700, 0x2f07ae00, 0x2f083500, 0x2f08bc00, 0x2f094300, 0x2f09ca00, 0x2f0a5100, 0x2f0ad800, 0x2f0b5f00, 0x2f0be600, 0x2f0c6d00, 0x2f0cf400, 0x2f0d7b00, 0x2f0e0200, 0x2f0e8900, 0x2f0f1000, 0x2f0f9700, 0x2f101e00, 0x2f10a500, 0x2f112c00, 0x2f11b300, 0x2f123a00, 0x2f12c100, 0x2f134800, 0x2f13cf00, 0x2f145600, 0x2f14dd00, 0x2f156400, 0x2f15eb00, 0x2f167200, 0x2f16f900, 0x2f178000, 0x2f180700, 0x2f188e00, 0x2f191500, 0x2f199c00, 0x2f1a2300, 0x2f1aaa00, 0x2f1b3100, 0x2f1bb800, 0x2f1c3f00, 0x2f1cc600, 0x2f1d4d00, 0x2f1dd400, 0x2f1e5b00, 0x2f1ee200, 0x2f1f6900, 0x2f1ff000, 0x2f207700, 0x2f20fe00, 0x2f218500, 0x2f220c00, 0x2f229300, 0x2f231a00, 0x2f23a100, 0x2f242800, 0x2f24af00, 0x2f253600, 0x2f25bd00, 0x2f264400, 0x2f26cb00, 0x2f275200, 0x2f27d900, 0x2f286000, 0x2f28e700, 0x2f296e00, 0x2f29f500, 0x2f2a7c00, 0x2f2b0300, 0x2f2b8a00, 0x2f2c1100, 0x2f2c9800, 0x2f2d1f00, 0x2f2da600, 0x2f2e2d00, 0x2f2eb400, 0x2f2f3b00, 0x2f2fc200, 0x2f304900, 0x2f30d000, 0x2f315700, 0x2f31de00, 0x2f326500, 0x2f32ec00, 0x2f337300, 0x2f33fa00, 0x2f348100, 0x2f350800, 0x2f358f00, 0x2f361600, 0x2f369d00, 0x2f372400, 0x2f37ab00, 0x2f383200, 0x2f38b900, 0x2f394000, 0x2f39c700, 0x2f3a4e00, 0x2f3ad500, 0x2f3b5c00, 0x2f3be300, 0x2f3c6a00, 0x2f3cf100, 0x2f3d7800, 0x2f3dff00, 0x2f3e8600, 0x2f3f0d00, 0x2f3f9400, 0x2f401b00, 0x2f40a200, 0x2f412900, 0x2f41b000, 0x2f423700, 0x2f42be00, 0x2f434500, 0x2f43cc00, 0x2f445300, 0x2f44da00, 0x2f456100, 0x2f45e800, 0x2f466f00, 0x2f46f600, 0x2f477d00, 0x2f480400, 0x2f488b00, 0x2f491200, 0x2f499900, 0x2f4a2000, 0x2f4aa700, 0x2f4b2e00, 0x2f4bb500, 0x2f4c3c00, 0x2f4cc300, 0x2f4d4a00, 0x2f4dd100, 0x2f4e5800, 0x2f4edf00, 0x2f4f6600, 0x2f4fed00, 0x2f507400, 0x2f50fb00, 0x2f518200, 0x2f520900, 0x2f529000, 0x2f531700, 0x2f539e00, 0x2f542500, 0x2f54ac00, 0x2f553300, 0x2f55ba00, 0x2f564100, 0x2f56c800, 0x2f574f00, 0x2f57d600, 0x2f585d00, 0x2f58e400, 0x2f596b00, 0x2f59f200, 0x2f5a7900, 0x2f5b0000, 0x2f5b8700, 0x2f5c0e00, 0x2f5c9500, 0x2f5d1c00, 0x2f5da300, 0x2f5e2a00, 0x2f5eb100, 0x2f5f3800, 0x2f5fbf00, 0x2f604600, 0x2f60cd00, 0x2f615400, 0x2f61db00, 0x2f626200, 0x2f62e900, 0x2f637000, 0x2f63f700, 0x2f647e00, 0x2f650500, 0x2f658c00, 0x2f661300, 0x2f669a00, 0x2f672100, 0x2f67a800, 0x2f682f00, 0x2f68b600, 0x2f693d00, 0x2f69c400, 0x2f6a4b00, 0x2f6ad200, 0x2f6b5900, 0x2f6be000, 0x2f6c6700, 0x2f6cee00, 0x2f6d7500, 0x2f6dfc00, 0x2f6e8300, 0x2f6f0a00, 0x2f6f9100, 0x2f701800, 0x2f709f00, 0x2f712600, 0x2f71ad00, 0x2f723400, 0x2f72bb00, 0x2f734200, 0x2f73c900, 0x2f745000, 0x2f74d700, 0x2f755e00, 0x2f75e500, 0x2f766c00, 0x2f76f300, 0x2f777a00, 0x2f780100, 0x2f788800, 0x2f790f00, 0x2f799600, 0x2f7a1d00, 0x2f7aa400, 0x2f7b2b00, 0x2f7bb200, 0x2f7c3900, 0x2f7cc000, 0x2f7d4700, 0x2f7dce00, 0x2f7e5500, 0x2f7edc00, 0x2f7f6300, 0x2f7fea00, 0x2f807100, 0x2f80f800, 0x2f817f00, 0x2f820600, 0x2f828d00, 0x2f831400, 0x2f839b00, 0x2f842200, 0x2f84a900, 0x2f853000, 0x2f85b700, 0x2f863e00, 0x2f86c500, 0x2f874c00, 0x2f87d300, 0x2f885a00, 0x2f88e100, 0x2f896800, 0x2f89ef00, 0x2f8a7600, 0x2f8afd00, 0x2f8b8400, 0x2f8c0b00, 0x2f8c9200, 0x2f8d1900, 0x2f8da000, 0x2f8e2700, 0x2f8eae00, 0x2f8f3500, 0x2f8fbc00, 0x2f904300, 0x2f90ca00, 0x2f915100, 0x2f91d800, 0x2f925f00, 0x2f92e600, 0x2f936d00, 0x2f93f400, 0x2f947b00, 0x2f950200, 0x2f958900, 0x2f961000, 0x2f969700, 0x2f971e00, 0x2f97a500, 0x2f982c00, 0x2f98b300, 0x2f993a00, 0x2f99c100, 0x2f9a4800, 0x2f9acf00, 0x2f9b5600, 0x2f9bdd00, 0x2f9c6400, 0x2f9ceb00, 0x2f9d7200, 0x2f9df900, 0x2f9e8000, 0x2f9f0700, 0x2f9f8e00, 0x2fa01500, 0x2fa09c00, 0x2fa12300, 0x2fa1aa00, 0x2fa23100, 0x2fa2b800, 0x2fa33f00, 0x2fa3c600, 0x2fa44d00, 0x2fa4d400, 0x2fa55b00, 0x2fa5e200, 0x2fa66900, 0x2fa6f000, 0x2fa77700, 0x2fa7fe00, 0x2fa88500, 0x2fa90c00, 0x2fa99300, 0x2faa1a00, 0x2faaa100, 0x2fab2800, 0x2fabaf00, 0x2fac3600, 0x2facbd00, 0x2fad4400, 0x2fadcb00, 0x2fae5200, 0x2faed900, 0x2faf6000, 0x2fafe700, 0x2fb06e00, 0x2fb0f500, 0x2fb17c00, 0x2fb20300, 0x2fb28a00, 0x2fb31100, 0x2fb39800, 0x2fb41f00, 0x2fb4a600, 0x2fb52d00, 0x2fb5b400, 0x2fb63b00, 0x2fb6c200, 0x2fb74900, 0x2fb7d000, 0x2fb85700, 0x2fb8de00, 0x2fb96500, 0x2fb9ec00, 0x2fba7300, 0x2fbafa00, 0x2fbb8100, 0x2fbc0800, 0x2fbc8f00, 0x2fbd1600, 0x2fbd9d00, 0x2fbe2400, 0x2fbeab00, 0x2fbf3200, 0x2fbfb900, 0x2fc04000, 0x2fc0c700, 0x2fc14e00, 0x2fc1d500, 0x2fc25c00, 0x2fc2e300, 0x2fc36a00, 0x2fc3f100, 0x2fc47800, 0x2fc4ff00, 0x2fc58600, 0x2fc60d00, 0x2fc69400, 0x2fc71b00, 0x2fc7a200, 0x2fc82900, 0x2fc8b000, 0x2fc93700, 0x2fc9be00, 0x2fca4500, 0x2fcacc00, 0x2fcb5300, 0x2fcbda00, 0x2fcc6100, 0x2fcce800, 0x2fcd6f00, 0x2fcdf600, 0x2fce7d00, 0x2fcf0400, 0x2fcf8b00, 0x2fd01200, 0x2fd09900, 0x2fd12000, 0x2fd1a700, 0x2fd22e00, 0x2fd2b500, 0x2fd33c00, 0x2fd3c300, 0x2fd44a00, 0x2fd4d100, 0x2fd55800, 0x2fd5df00, 0x2fd66600, 0x2fd6ed00, 0x2fd77400, 0x2fd7fb00, 0x2fd88200, 0x2fd90900, 0x2fd99000, 0x2fda1700, 0x2fda9e00, 0x2fdb2500, 0x2fdbac00, 0x2fdc3300, 0x2fdcba00, 0x2fdd4100, 0x2fddc800, 0x2fde4f00, 0x2fded600, 0x2fdf5d00, 0x2fdfe400, 0x2fe06b00, 0x2fe0f200, 0x2fe17900, 0x2fe20000, 0x2fe29600, 0x2fe32c00, 0x2fe3c200, 0x2fe45800, 0x2fe4ee00, 0x2fe58400, 0x2fe61a00, 0x2fe6b000, 0x2fe74600, 0x2fe7dc00, 0x2fe87200, 0x2fe90800, 0x2fe99e00, 0x2fea3400, 0x2feaca00, 0x2feb6000, 0x2febf600, 0x2fec8c00, 0x2fed2200, 0x2fedb800, 0x2fee4e00, 0x2feee400, 0x2fef7a00, 0x2ff01000, 0x2ff0a600, 0x2ff13c00, 0x2ff1d200, 0x2ff26800, 0x2ff2fe00, 0x2ff39400, 0x2ff42a00, 0x2ff4c000, 0x2ff55600, 0x2ff5ec00, 0x2ff68200, 0x2ff71800, 0x2ff7ae00, 0x2ff84400, 0x2ff8da00, 0x2ff97000, 0x2ffa0600, 0x2ffa9c00, 0x2ffb3200, 0x2ffbc800, 0x2ffc5e00, 0x2ffcf400, 0x2ffd8a00, 0x2ffe2000, 0x2ffeb600, 0x2fff4c00, 0x2fffe200, 0x30007800, 0x30010e00, 0x3001a400, 0x30023a00, 0x3002d000, 0x30036600, 0x3003fc00, 0x30049200, 0x30052800, 0x3005be00, 0x30065400, 0x3006ea00, 0x30078000, 0x30081600, 0x3008ac00, 0x30094200, 0x3009d800, 0x300a6e00, 0x300b0400, 0x300b9a00, 0x300c3000, 0x300cc600, 0x300d5c00, 0x300df200, 0x300e8800, 0x300f1e00, 0x300fb400, 0x30104a00, 0x3010e000, 0x30117600, 0x30120c00, 0x3012a200, 0x30133800, 0x3013ce00, 0x30146400, 0x3014fa00, 0x30159000, 0x30162600, 0x3016bc00, 0x30175200, 0x3017e800, 0x30187e00, 0x30191400, 0x3019aa00, 0x301a4000, 0x301ad600, 0x301b6c00, 0x301c0200, 0x301c9800, 0x301d2e00, 0x301dc400, 0x301e5a00, 0x301ef000, 0x301f8600, 0x30201c00, 0x3020b200, 0x30214800, 0x3021de00, 0x30227400, 0x30230a00, 0x3023a000, 0x30243600, 0x3024cc00, 0x30256200, 0x3025f800, 0x30268e00, 0x30272400, 0x3027ba00, 0x30285000, 0x3028e600, 0x30297c00, 0x302a1200, 0x302aa800, 0x302b3e00, 0x302bd400, 0x302c6a00, 0x302d0000, 0x302d9600, 0x302e2c00, 0x302ec200, 0x302f5800, 0x302fee00, 0x30308400, 0x30311a00, 0x3031b000, 0x30324600, 0x3032dc00, 0x30337200, 0x30340800, 0x30349e00, 0x30353400, 0x3035ca00, 0x30366000, 0x3036f600, 0x30378c00, 0x30382200, 0x3038b800, 0x30394e00, 0x3039e400, 0x303a7a00, 0x303b1000, 0x303ba600, 0x303c3c00, 0x303cd200, 0x303d6800, 0x303dfe00, 0x303e9400, 0x303f2a00, 0x303fc000, 0x30405600, 0x3040ec00, 0x30418200, 0x30421800, 0x3042ae00, 0x30434400, 0x3043da00, 0x30447000, 0x30450600, 0x30459c00, 0x30463200, 0x3046c800, 0x30475e00, 0x3047f400, 0x30488a00, 0x30492000, 0x3049b600, 0x304a4c00, 0x304ae200, 0x304b7800, 0x304c0e00, 0x304ca400, 0x304d3a00, 0x304dd000, 0x304e6600, 0x304efc00, 0x304f9200, 0x30502800, 0x3050be00, 0x30515400, 0x3051ea00, 0x30528000, 0x30531600, 0x3053ac00, 0x30544200, 0x3054d800, 0x30556e00, 0x30560400, 0x30569a00, 0x30573000, 0x3057c600, 0x30585c00, 0x3058f200, 0x30598800, 0x305a1e00, 0x305ab400, 0x305b4a00, 0x305be000, 0x305c7600, 0x305d0c00, 0x305da200, 0x305e3800, 0x305ece00, 0x305f6400, 0x305ffa00, 0x30609000, 0x30612600, 0x3061bc00, 0x30625200, 0x3062e800, 0x30637e00, 0x30641400, 0x3064aa00, 0x30654000, 0x3065d600, 0x30666c00, 0x30670200, 0x30679800, 0x30682e00, 0x3068c400, 0x30695a00, 0x3069f000, 0x306a8600, 0x306b1c00, 0x306bb200, 0x306c4800, 0x306cde00, 0x306d7400, 0x306e0a00, 0x306ea000, 0x306f3600, 0x306fcc00, 0x30706200, 0x3070f800, 0x30718e00, 0x30722400, 0x3072ba00, 0x30735000, 0x3073e600, 0x30747c00, 0x30751200, 0x3075a800, 0x30763e00, 0x3076d400, 0x30776a00, 0x30780000, 0x30789600, 0x30792c00, 0x3079c200, 0x307a5800, 0x307aee00, 0x307b8400, 0x307c1a00, 0x307cb000, 0x307d4600, 0x307ddc00, 0x307e7200, 0x307f0800, 0x307f9e00, 0x30803400, 0x3080ca00, 0x30816000, 0x3081f600, 0x30828c00, 0x30832200, 0x3083b800, 0x30844e00, 0x3084e400, 0x30857a00, 0x30861000, 0x3086a600, 0x30873c00, 0x3087d200, 0x30886800, 0x3088fe00, 0x30899400, 0x308a2a00, 0x308ac000, 0x308b5600, 0x308bec00, 0x308c8200, 0x308d1800, 0x308dae00, 0x308e4400, 0x308eda00, 0x308f7000, 0x30900600, 0x30909c00, 0x30913200, 0x3091c800, 0x30925e00, 0x3092f400, 0x30938a00, 0x30942000, 0x3094b600, 0x30954c00, 0x3095e200, 0x30967800, 0x30970e00, 0x3097a400, 0x30983a00, 0x3098d000, 0x30996600, 0x3099fc00, 0x309a9200, 0x309b2800, 0x309bbe00, 0x309c5400, 0x309cea00, 0x309d8000, 0x309e1600, 0x309eac00, 0x309f4200, 0x309fd800, 0x30a06e00, 0x30a10400, 0x30a19a00, 0x30a23000, 0x30a2c600, 0x30a35c00, 0x30a3f200, 0x30a48800, 0x30a51e00, 0x30a5b400, 0x30a64a00, 0x30a6e000, 0x30a77600, 0x30a80c00, 0x30a8a200, 0x30a93800, 0x30a9ce00, 0x30aa6400, 0x30aafa00, 0x30ab9000, 0x30ac2600, 0x30acbc00, 0x30ad5200, 0x30ade800, 0x30ae7e00, 0x30af1400, 0x30afaa00, 0x30b04000, 0x30b0d600, 0x30b16c00, 0x30b20200, 0x30b29800, 0x30b32e00, 0x30b3c400, 0x30b45a00, 0x30b4f000, 0x30b58600, 0x30b61c00, 0x30b6b200, 0x30b74800, 0x30b7de00, 0x30b87400, 0x30b90a00, 0x30b9a000, 0x30ba3600, 0x30bacc00, 0x30bb6200, 0x30bbf800, 0x30bc8e00, 0x30bd2400, 0x30bdba00, 0x30be5000, 0x30bee600, 0x30bf7c00, 0x30c01200, 0x30c0a800, 0x30c13e00, 0x30c1d400, 0x30c26a00, 0x30c30000, 0x30c39600, 0x30c42c00, 0x30c4c200, 0x30c55800, 0x30c5ee00, 0x30c68400, 0x30c71a00, 0x30c7b000, 0x30c84600, 0x30c8dc00, 0x30c97200, 0x30ca0800, 0x30ca9e00, 0x30cb3400, 0x30cbca00, 0x30cc6000, 0x30ccf600, 0x30cd8c00, 0x30ce2200, 0x30ceb800, 0x30cf4e00, 0x30cfe400, 0x30d07a00, 0x30d11000, 0x30d1a600, 0x30d23c00, 0x30d2d200, 0x30d36800, 0x30d3fe00, 0x30d49400, 0x30d52a00, 0x30d5c000, 0x30d65600, 0x30d6ec00, 0x30d78200, 0x30d81800, 0x30d8ae00, 0x30d94400, 0x30d9da00, 0x30da7000, 0x30db0600, 0x30db9c00, 0x30dc3200, 0x30dcc800, 0x30dd5e00, 0x30ddf400, 0x30de8a00, 0x30df2000, 0x30dfb600, 0x30e04c00, 0x30e0e200, 0x30e17800, 0x30e20e00, 0x30e2a400, 0x30e33a00, 0x30e3d000, 0x30e46600, 0x30e4fc00, 0x30e59200, 0x30e62800, 0x30e6be00, 0x30e75400, 0x30e7ea00, 0x30e88000, 0x30e91600, 0x30e9ac00, 0x30ea4200, 0x30ead800, 0x30eb6e00, 0x30ec0400, 0x30ec9a00, 0x30ed3000, 0x30edc600, 0x30ee5c00, 0x30eef200, 0x30ef8800, 0x30f01e00, 0x30f0b400, 0x30f14a00, 0x30f1e000, 0x30f27600, 0x30f30c00, 0x30f3a200, 0x30f43800, 0x30f4ce00, 0x30f56400, 0x30f5fa00, 0x30f69000, 0x30f72600, 0x30f7bc00, 0x30f85200, 0x30f8e800, 0x30f97e00, 0x30fa1400, 0x30faaa00, 0x30fb4000, 0x30fbd600, 0x30fc6c00, 0x30fd0200, 0x30fd9800, 0x30fe2e00, 0x30fec400, 0x30ff5a00, 0x30fff000, 0x31008600, 0x31011c00, 0x3101b200, 0x31024800, 0x3102de00, 0x31037400, 0x31040a00, 0x3104a000, 0x31053600, 0x3105cc00, 0x31066200, 0x3106f800, 0x31078e00, 0x31082400, 0x3108ba00, 0x31095000, 0x3109e600, 0x310a7c00, 0x310b1200, 0x310ba800, 0x310c3e00, 0x310cd400, 0x310d6a00, 0x310e0000, 0x310e9600, 0x310f2c00, 0x310fc200, 0x31105800, 0x3110ee00, 0x31118400, 0x31121a00, 0x3112b000, 0x31134600, 0x3113dc00, 0x31147200, 0x31150800, 0x31159e00, 0x31163400, 0x3116ca00, 0x31176000, 0x3117f600, 0x31188c00, 0x31192200, 0x3119b800, 0x311a4e00, 0x311ae400, 0x311b7a00, 0x311c1000, 0x311ca600, 0x311d3c00, 0x311dd200, 0x311e6800, 0x311efe00, 0x311f9400, 0x31202a00, 0x3120c000, 0x31215600, 0x3121ec00, 0x31228200, 0x31231800, 0x3123ae00, 0x31244400, 0x3124da00, 0x31257000, 0x31260600, 0x31269c00, 0x31273200, 0x3127c800, 0x31285e00, 0x3128f400, 0x31298a00, 0x312a2000, 0x312ab600, 0x312b4c00, 0x312be200, 0x312c7800, 0x312d0e00, 0x312da400, 0x312e3a00, 0x312ed000, 0x312f6600, 0x312ffc00, 0x31309200, 0x31312800, 0x3131be00, 0x31325400, 0x3132ea00, 0x31338000, 0x31341600, 0x3134ac00, 0x31354200, 0x3135d800, 0x31366e00, 0x31370400, 0x31379a00, 0x31383000, 0x3138c600, 0x31395c00, 0x3139f200, 0x313a8800, 0x313b1e00, 0x313bb400, 0x313c4a00, 0x313ce000, 0x313d7600, 0x313e0c00, 0x313ea200, 0x313f3800, 0x313fce00, 0x31406300, 0x3140f900, 0x31418f00, 0x31422500, 0x3142bb00, 0x31435100, 0x3143e700, 0x31447d00, 0x31451300, 0x3145a900, 0x31463f00, 0x3146d500, 0x31476b00, 0x31480100, 0x31489700, 0x31492d00, 0x3149c300, 0x314a5900, 0x314aef00, 0x314b8500, 0x314c1b00, 0x314cb100, 0x314d4700, 0x314ddd00, 0x314e7300, 0x314f0900, 0x314f9f00, 0x31503500, 0x3150cb00, 0x31516100, 0x3151f700, 0x31528d00, 0x31532300, 0x3153b900, 0x31544f00, 0x3154e500, 0x31557b00, 0x31561100, 0x3156a700, 0x31573d00, 0x3157d300, 0x31586900, 0x3158ff00, 0x31599500, 0x315a2b00, 0x315ac100, 0x315b5700, 0x315bed00, 0x315c8300, 0x315d1900, 0x315daf00, 0x315e4500, 0x315edb00, 0x315f7100, 0x31600700, 0x31609d00, 0x31613300, 0x3161c900, 0x31625f00, 0x3162f500, 0x31638b00, 0x31642100, 0x3164b700, 0x31654d00, 0x3165e300, 0x31667900, 0x31670f00, 0x3167a500, 0x31683b00, 0x3168d100, 0x31696700, 0x3169fd00, 0x316a9300, 0x316b2900, 0x316bbf00, 0x316c5500, 0x316ceb00, 0x316d8100, 0x316e1700, 0x316ead00, 0x316f4300, 0x316fd900, 0x31706f00, 0x31710500, 0x31719b00, 0x31723100, 0x3172c700, 0x31735d00, 0x3173f300, 0x31748900, 0x31751f00, 0x3175b500, 0x31764b00, 0x3176e100, 0x31777700, 0x31780d00, 0x3178a300, 0x31793900, 0x3179cf00, 0x317a6500, 0x317afb00, 0x317b9100, 0x317c2700, 0x317cbd00, 0x317d5300, 0x317de900, 0x317e7f00, 0x317f1500, 0x317fab00, 0x31804100, 0x3180d700, 0x31816d00, 0x31820300, 0x31829900, 0x31832f00, 0x3183c500, 0x31845b00, 0x3184f100, 0x31858700, 0x31861d00, 0x3186b300, 0x31874900, 0x3187df00, 0x31887500, 0x31890b00, 0x3189a100, 0x318a3700, 0x318acd00, 0x318b6300, 0x318bf900, 0x318c8f00, 0x318d2500, 0x318dbb00, 0x318e5100, 0x318ee700, 0x318f7d00, 0x31901300, 0x3190a900, 0x31913f00, 0x3191d500, 0x31926b00, 0x31930100, 0x31939700, 0x31942d00, 0x3194c300, 0x31955900, 0x3195ef00, 0x31968500, 0x31971b00, 0x3197b100, 0x31984700, 0x3198dd00, 0x31997300, 0x319a0900, 0x319a9f00, 0x319b3500, 0x319bcb00, 0x319c6100, 0x319cf700, 0x319d8d00, 0x319e2300, 0x319eb900, 0x319f4f00, 0x319fe500, 0x31a07b00, 0x31a11100, 0x31a1a700, 0x31a23d00, 0x31a2d300, 0x31a36900, 0x31a3ff00, 0x31a49500, 0x31a52b00, 0x31a5c100, 0x31a65700, 0x31a6ed00, 0x31a78300, 0x31a81900, 0x31a8af00, 0x31a94500, 0x31a9db00, 0x31aa7100, 0x31ab0700, 0x31ab9d00, 0x31ac3300, 0x31acc900, 0x31ad5f00, 0x31adf500, 0x31ae8b00, 0x31af2100, 0x31afb700, 0x31b04d00, 0x31b0e300, 0x31b17900, 0x31b20f00, 0x31b2a500, 0x31b33b00, 0x31b3d100, 0x31b46700, 0x31b4fd00, 0x31b59300, 0x31b62900, 0x31b6bf00, 0x31b75500, 0x31b7eb00, 0x31b88100, 0x31b91700, 0x31b9ad00, 0x31ba4300, 0x31bad900, 0x31bb6f00, 0x31bc0500, 0x31bc9b00, 0x31bd3100, 0x31bdc700, 0x31be5d00, 0x31bef300, 0x31bf8900, 0x31c01f00, 0x31c0b500, 0x31c14b00, 0x31c1e100, 0x31c27700, 0x31c30d00, 0x31c3a300, 0x31c43900, 0x31c4cf00, 0x31c56500, 0x31c5fb00, 0x31c69100, 0x31c72700, 0x31c7bd00, 0x31c85300, 0x31c8e900, 0x31c97f00, 0x31ca1500, 0x31caab00, 0x31cb4100, 0x31cbd700, 0x31cc6d00, 0x31cd0300, 0x31cd9900, 0x31ce2f00, 0x31cec500, 0x31cf5b00, 0x31cff100, 0x31d08700, 0x31d11d00, 0x31d1b300, 0x31d24900, 0x31d2df00, 0x31d37500, 0x31d40b00, 0x31d4a100, 0x31d53700, 0x31d5cd00, 0x31d66300, 0x31d6f900, 0x31d78f00, 0x31d82500, 0x31d8bb00, 0x31d95100, 0x31d9e700, 0x31da7d00, 0x31db1300, 0x31dba900, 0x31dc3f00, 0x31dcd500, 0x31dd6b00, 0x31de0100, 0x31de9700, 0x31df2d00, 0x31dfc300, 0x31e05900, 0x31e0ef00, 0x31e18500, 0x31e21b00, 0x31e2b100, 0x31e34700, 0x31e3dd00, 0x31e47300, 0x31e50900, 0x31e59f00, 0x31e63500, 0x31e6cb00, 0x31e76100, 0x31e7f700, 0x31e88d00, 0x31e92300, 0x31e9b900, 0x31ea4f00, 0x31eae500, 0x31eb7b00, 0x31ec1100, 0x31eca700, 0x31ed3d00, 0x31edd300, 0x31ee6900, 0x31eeff00, 0x31ef9500, 0x31f02b00, 0x31f0c100, 0x31f15700, 0x31f1ed00, 0x31f28300, 0x31f31900, 0x31f3af00, 0x31f44500, 0x31f4db00, 0x31f57100, 0x31f60700, 0x31f69d00, 0x31f73300, 0x31f7c900, 0x31f85f00, 0x31f8f500, 0x31f98b00, 0x31fa2100, 0x31fab700, 0x31fb4d00, 0x31fbe300, 0x31fc7900, 0x31fd0f00, 0x31fda500, 0x31fe3b00, 0x31fed100, 0x31ff6700, 0x31fffd00, 0x32009300, 0x32012900, 0x3201bf00, 0x32025500, 0x3202eb00, 0x32038100, 0x32041700, 0x3204ad00, 0x32054300, 0x3205d900, 0x32066f00, 0x32070500, 0x32079b00, 0x32083100, 0x3208c700, 0x32095d00, 0x3209f300, 0x320a8900, 0x320b1f00, 0x320bb500, 0x320c4b00, 0x320ce100, 0x320d7700, 0x320e0d00, 0x320ea300, 0x320f3900, 0x320fcf00, 0x32106500, 0x3210fb00, 0x32119100, 0x32122700, 0x3212bd00, 0x32135300, 0x3213e900, 0x32147f00, 0x32151500, 0x3215ab00, 0x32164100, 0x3216d700, 0x32176d00, 0x32180300, 0x32189900, 0x32192f00, 0x3219c500, 0x321a5b00, 0x321af100, 0x321b8700, 0x321c1d00, 0x321cb300, 0x321d4900, 0x321ddf00, 0x321e7500, 0x321f0b00, 0x321fa100, 0x32203700, 0x3220cd00, 0x32216300, 0x3221f900, 0x32228f00, 0x32232500, 0x3223bb00, 0x32245100, 0x3224e700, 0x32257d00, 0x32261300, 0x3226a900, 0x32273f00, 0x3227d500, 0x32286b00, 0x32290100, 0x32299700, 0x322a2d00, 0x322ac300, 0x322b5900, 0x322bef00, 0x322c8500, 0x322d1b00, 0x322db100, 0x322e4700, 0x322edd00, 0x322f7300, 0x32300900, 0x32309f00, 0x32313500, 0x3231cb00, 0x32326100, 0x3232f700, 0x32338d00, 0x32342300, 0x3234b900, 0x32354f00, 0x3235e500, 0x32367b00, 0x32371100, 0x3237a700, 0x32383d00, 0x3238d300, 0x32396900, 0x3239ff00, 0x323aa400, 0x323b4900, 0x323bee00, 0x323c9300, 0x323d3800, 0x323ddd00, 0x323e8200, 0x323f2700, 0x323fcc00, 0x32407100, 0x32411600, 0x3241bb00, 0x32426000, 0x32430500, 0x3243aa00, 0x32444f00, 0x3244f400, 0x32459900, 0x32463e00, 0x3246e300, 0x32478800, 0x32482d00, 0x3248d200, 0x32497700, 0x324a1c00, 0x324ac100, 0x324b6600, 0x324c0b00, 0x324cb000, 0x324d5500, 0x324dfa00, 0x324e9f00, 0x324f4400, 0x324fe900, 0x32508e00, 0x32513300, 0x3251d800, 0x32527d00, 0x32532200, 0x3253c700, 0x32546c00, 0x32551100, 0x3255b600, 0x32565b00, 0x32570000, 0x3257a500, 0x32584a00, 0x3258ef00, 0x32599400, 0x325a3900, 0x325ade00, 0x325b8300, 0x325c2800, 0x325ccd00, 0x325d7200, 0x325e1700, 0x325ebc00, 0x325f6100, 0x32600600, 0x3260ab00, 0x32615000, 0x3261f500, 0x32629a00, 0x32633f00, 0x3263e400, 0x32648900, 0x32652e00, 0x3265d300, 0x32667800, 0x32671d00, 0x3267c200, 0x32686700, 0x32690c00, 0x3269b100, 0x326a5600, 0x326afb00, 0x326ba000, 0x326c4500, 0x326cea00, 0x326d8f00, 0x326e3400, 0x326ed900, 0x326f7e00, 0x32702300, 0x3270c800, 0x32716d00, 0x32721200, 0x3272b700, 0x32735c00, 0x32740100, 0x3274a600, 0x32754b00, 0x3275f000, 0x32769500, 0x32773a00, 0x3277df00, 0x32788400, 0x32792900, 0x3279ce00, 0x327a7300, 0x327b1800, 0x327bbd00, 0x327c6200, 0x327d0700, 0x327dac00, 0x327e5100, 0x327ef600, 0x327f9b00, 0x32804000, 0x3280e500, 0x32818a00, 0x32822f00, 0x3282d400, 0x32837900, 0x32841e00, 0x3284c300, 0x32856800, 0x32860d00, 0x3286b200, 0x32875700, 0x3287fc00, 0x3288a100, 0x32894600, 0x3289eb00, 0x328a9000, 0x328b3500, 0x328bda00, 0x328c7f00, 0x328d2400, 0x328dc900, 0x328e6e00, 0x328f1300, 0x328fb800, 0x32905d00, 0x32910200, 0x3291a700, 0x32924c00, 0x3292f100, 0x32939600, 0x32943b00, 0x3294e000, 0x32958500, 0x32962a00, 0x3296cf00, 0x32977400, 0x32981900, 0x3298be00, 0x32996300, 0x329a0800, 0x329aad00, 0x329b5200, 0x329bf700, 0x329c9c00, 0x329d4100, 0x329de600, 0x329e8b00, 0x329f3000, 0x329fd500, 0x32a07a00, 0x32a11f00, 0x32a1c400, 0x32a26900, 0x32a30e00, 0x32a3b300, 0x32a45800, 0x32a4fd00, 0x32a5a200, 0x32a64700, 0x32a6ec00, 0x32a79100, 0x32a83600, 0x32a8db00, 0x32a98000, 0x32aa2500, 0x32aaca00, 0x32ab6f00, 0x32ac1400, 0x32acb900, 0x32ad5e00, 0x32ae0300, 0x32aea800, 0x32af4d00, 0x32aff200, 0x32b09700, 0x32b13c00, 0x32b1e100, 0x32b28600, 0x32b32b00, 0x32b3d000, 0x32b47500, 0x32b51a00, 0x32b5bf00, 0x32b66400, 0x32b70900, 0x32b7ae00, 0x32b85300, 0x32b8f800, 0x32b99d00, 0x32ba4200, 0x32bae700, 0x32bb8c00, 0x32bc3100, 0x32bcd600, 0x32bd7b00, 0x32be2000, 0x32bec500, 0x32bf6a00, 0x32c00f00, 0x32c0b400, 0x32c15900, 0x32c1fe00, 0x32c2a300, 0x32c34800, 0x32c3ed00, 0x32c49200, 0x32c53700, 0x32c5dc00, 0x32c68100, 0x32c72600, 0x32c7cb00, 0x32c87000, 0x32c91500, 0x32c9ba00, 0x32ca5f00, 0x32cb0400, 0x32cba900, 0x32cc4e00, 0x32ccf300, 0x32cd9800, 0x32ce3d00, 0x32cee200, 0x32cf8700, 0x32d02c00, 0x32d0d100, 0x32d17600, 0x32d21b00, 0x32d2c000, 0x32d36500, 0x32d40a00, 0x32d4af00, 0x32d55400, 0x32d5f900, 0x32d69e00, 0x32d74300, 0x32d7e800, 0x32d88d00, 0x32d93200, 0x32d9d700, 0x32da7c00, 0x32db2100, 0x32dbc600, 0x32dc6b00, 0x32dd1000, 0x32ddb500, 0x32de5a00, 0x32deff00, 0x32dfa400, 0x32e04900, 0x32e0ee00, 0x32e19300, 0x32e23800, 0x32e2dd00, 0x32e38200, 0x32e42700, 0x32e4cc00, 0x32e57100, 0x32e61600, 0x32e6bb00, 0x32e76000, 0x32e80500, 0x32e8aa00, 0x32e94f00, 0x32e9f400, 0x32ea9900, 0x32eb3e00, 0x32ebe300, 0x32ec8800, 0x32ed2d00, 0x32edd200, 0x32ee7700, 0x32ef1c00, 0x32efc100, 0x32f06600, 0x32f10b00, 0x32f1b000, 0x32f25500, 0x32f2fa00, 0x32f39f00, 0x32f44400, 0x32f4e900, 0x32f58e00, 0x32f63300, 0x32f6d800, 0x32f77d00, 0x32f82200, 0x32f8c700, 0x32f96c00, 0x32fa1100, 0x32fab600, 0x32fb5b00, 0x32fc0000, 0x32fca500, 0x32fd4a00, 0x32fdef00, 0x32fe9400, 0x32ff3900, 0x32ffde00, 0x33008300, 0x33012800, 0x3301cd00, 0x33027200, 0x33031700, 0x3303bc00, 0x33046100, 0x33050600, 0x3305ab00, 0x33065000, 0x3306f500, 0x33079a00, 0x33083f00, 0x3308e400, 0x33098900, 0x330a2e00, 0x330ad300, 0x330b7800, 0x330c1d00, 0x330cc200, 0x330d6700, 0x330e0c00, 0x330eb100, 0x330f5600, 0x330ffb00, 0x3310a000, 0x33114500, 0x3311ea00, 0x33128f00, 0x33133400, 0x3313d900, 0x33147e00, 0x33152300, 0x3315c800, 0x33166d00, 0x33171200, 0x3317b700, 0x33185c00, 0x33190100, 0x3319a600, 0x331a4b00, 0x331af000, 0x331b9500, 0x331c3a00, 0x331cdf00, 0x331d8400, 0x331e2900, 0x331ece00, 0x331f7300, 0x33201800, 0x3320bd00, 0x33216200, 0x33220700, 0x3322ac00, 0x33235100, 0x3323f600, 0x33249b00, 0x33254000, 0x3325e500, 0x33268a00, 0x33272f00, 0x3327d400, 0x33287900, 0x33291e00, 0x3329c300, 0x332a6800, 0x332b0d00, 0x332bb200, 0x332c5700, 0x332cfc00, 0x332da100, 0x332e4600, 0x332eeb00, 0x332f9000, 0x33303500, 0x3330da00, 0x33317f00, 0x33322400, 0x3332c900, 0x33336e00, 0x33341300, 0x3334b800, 0x33355d00, 0x33360200, 0x3336a700, 0x33374c00, 0x3337f100, 0x33389600, 0x33393b00, 0x3339e000, 0x333a8500, 0x333b2a00, 0x333bcf00, 0x333c7400, 0x333d1900, 0x333dbe00, 0x333e6300, 0x333f0800, 0x333fad00, 0x33405200, 0x3340f700, 0x33419c00, 0x33424100, 0x3342e600, 0x33438b00, 0x33443000, 0x3344d500, 0x33457a00, 0x33461f00, 0x3346c400, 0x33476900, 0x33480e00, 0x3348b300, 0x33495800, 0x3349fd00, 0x334aa200, 0x334b4700, 0x334bec00, 0x334c9100, 0x334d3600, 0x334ddb00, 0x334e8000, 0x334f2500, 0x334fca00, 0x33506f00, 0x33511400, 0x3351b900, 0x33525e00, 0x33530300, 0x3353a800, 0x33544d00, 0x3354f200, 0x33559700, 0x33563c00, 0x3356e100, 0x33578600, 0x33582b00, 0x3358d000, 0x33597500, 0x335a1a00, 0x335abf00, 0x335b6400, 0x335c0900, 0x335cae00, 0x335d5300, 0x335df800, 0x335e9d00, 0x335f4200, 0x335fe700, 0x33608c00, 0x33613100, 0x3361d600, 0x33627b00, 0x33632000, 0x3363c500, 0x33646a00, 0x33650f00, 0x3365b400, 0x33665900, 0x3366fe00, 0x3367a300, 0x33684800, 0x3368ed00, 0x33699200, 0x336a3700, 0x336adc00, 0x336b8100, 0x336c2600, 0x336ccb00, 0x336d7000, 0x336e1500, 0x336eba00, 0x336f5f00, 0x33700400, 0x3370a900, 0x33714e00, 0x3371f300, 0x33729800, 0x33733d00, 0x3373e200, 0x33748700, 0x33752c00, 0x3375d100, 0x33767600, 0x33771b00, 0x3377c000, 0x33786500, 0x33790a00, 0x3379af00, 0x337a5400, 0x337af900, 0x337b9e00, 0x337c4300, 0x337ce800, 0x337d8d00, 0x337e3200, 0x337ed700, 0x337f7c00, 0x33802100, 0x3380c600, 0x33816b00, 0x33821000, 0x3382b500, 0x33835a00, 0x3383ff00, 0x3384a700, 0x33854f00, 0x3385f700, 0x33869f00, 0x33874700, 0x3387ef00, 0x33889700, 0x33893f00, 0x3389e700, 0x338a8f00, 0x338b3700, 0x338bdf00, 0x338c8700, 0x338d2f00, 0x338dd700, 0x338e7f00, 0x338f2700, 0x338fcf00, 0x33907700, 0x33911f00, 0x3391c700, 0x33926f00, 0x33931700, 0x3393bf00, 0x33946700, 0x33950f00, 0x3395b700, 0x33965f00, 0x33970700, 0x3397af00, 0x33985700, 0x3398ff00, 0x3399a700, 0x339a4f00, 0x339af700, 0x339b9f00, 0x339c4700, 0x339cef00, 0x339d9700, 0x339e3f00, 0x339ee700, 0x339f8f00, 0x33a03700, 0x33a0df00, 0x33a18700, 0x33a22f00, 0x33a2d700, 0x33a37f00, 0x33a42700, 0x33a4cf00, 0x33a57700, 0x33a61f00, 0x33a6c700, 0x33a76f00, 0x33a81700, 0x33a8bf00, 0x33a96700, 0x33aa0f00, 0x33aab700, 0x33ab5f00, 0x33ac0700, 0x33acaf00, 0x33ad5700, 0x33adff00, 0x33aea700, 0x33af4f00, 0x33aff700, 0x33b09f00, 0x33b14700, 0x33b1ef00, 0x33b29700, 0x33b33f00, 0x33b3e700, 0x33b48f00, 0x33b53700, 0x33b5df00, 0x33b68700, 0x33b72f00, 0x33b7d700, 0x33b87f00, 0x33b92700, 0x33b9cf00, 0x33ba7700, 0x33bb1f00, 0x33bbc700, 0x33bc6f00, 0x33bd1700, 0x33bdbf00, 0x33be6700, 0x33bf0f00, 0x33bfb700, 0x33c05f00, 0x33c10700, 0x33c1af00, 0x33c25700, 0x33c2ff00, 0x33c3a700, 0x33c44f00, 0x33c4f700, 0x33c59f00, 0x33c64700, 0x33c6ef00, 0x33c79700, 0x33c83f00, 0x33c8e700, 0x33c98f00, 0x33ca3700, 0x33cadf00, 0x33cb8700, 0x33cc2f00, 0x33ccd700, 0x33cd7f00, 0x33ce2700, 0x33cecf00, 0x33cf7700, 0x33d01f00, 0x33d0c700, 0x33d16f00, 0x33d21700, 0x33d2bf00, 0x33d36700, 0x33d40f00, 0x33d4b700, 0x33d55f00, 0x33d60700, 0x33d6af00, 0x33d75700, 0x33d80000, 0x33d8a800, 0x33d95000, 0x33d9f800, 0x33daa000, 0x33db4800, 0x33dbf000, 0x33dc9800, 0x33dd4000, 0x33dde800, 0x33de9000, 0x33df3800, 0x33dfe000, 0x33e08800, 0x33e13000, 0x33e1d800, 0x33e28000, 0x33e32800, 0x33e3d000, 0x33e47800, 0x33e52000, 0x33e5c800, 0x33e67000, 0x33e71800, 0x33e7c000, 0x33e86800, 0x33e91000, 0x33e9b800, 0x33ea6000, 0x33eb0800, 0x33ebb000, 0x33ec5800, 0x33ed0000, 0x33eda800, 0x33ee5000, 0x33eef800, 0x33efa000, 0x33f04800, 0x33f0f000, 0x33f19800, 0x33f24000, 0x33f2e800, 0x33f39000, 0x33f43800, 0x33f4e000, 0x33f58800, 0x33f63000, 0x33f6d800, 0x33f78000, 0x33f82800, 0x33f8d000, 0x33f97800, 0x33fa2000, 0x33fac800, 0x33fb7000, 0x33fc1800, 0x33fcc000, 0x33fd6800, 0x33fe1000, 0x33feb800, 0x33ff6000, 0x34000800, 0x3400b000, 0x34015800, 0x34020000, 0x3402a800, 0x34035000, 0x3403f800, 0x3404a000, 0x34054800, 0x3405f000, 0x34069800, 0x34074000, 0x3407e800, 0x34089000, 0x34093800, 0x3409e000, 0x340a8800, 0x340b3000, 0x340bd800, 0x340c8000, 0x340d2800, 0x340dd000, 0x340e7800, 0x340f2000, 0x340fc800, 0x34107000, 0x34111800, 0x3411c000, 0x34126800, 0x34131000, 0x3413b800, 0x34146000, 0x34150800, 0x3415b000, 0x34165800, 0x34170000, 0x3417a800, 0x34185000, 0x3418f800, 0x3419a000, 0x341a4800, 0x341af000, 0x341b9800, 0x341c4000, 0x341ce800, 0x341d9000, 0x341e3800, 0x341ee000, 0x341f8800, 0x34203000, 0x3420d800, 0x34218000, 0x34222800, 0x3422d000, 0x34237800, 0x34242000, 0x3424c800, 0x34257000, 0x34261800, 0x3426c000, 0x34276800, 0x34281000, 0x3428b800, 0x34296000, 0x342a0800, 0x342ab000, 0x342b5800, 0x342c0000, 0x342ca800, 0x342d5000, 0x342df800, 0x342ea000, 0x342f4800, 0x342ff000, 0x34309800, 0x34314000, 0x3431e800, 0x34329000, 0x34333800, 0x3433e000, 0x34348800, 0x34353000, 0x3435d800, 0x34368000, 0x34372800, 0x3437d000, 0x34387800, 0x34392000, 0x3439c800, 0x343a7000, 0x343b1800, 0x343bc000, 0x343c6800, 0x343d1000, 0x343db800, 0x343e6000, 0x343f0800, 0x343fb000, 0x34405800, 0x34410000, 0x3441a800, 0x34425000, 0x3442f800, 0x3443a000, 0x34444800, 0x3444f000, 0x34459800, 0x34464000, 0x3446e800, 0x34479000, 0x34483800, 0x3448e000, 0x34498800, 0x344a3000, 0x344ad800, 0x344b8000, 0x344c2800, 0x344cd000, 0x344d7800, 0x344e2000, 0x344ec800, 0x344f7000, 0x34501800, 0x3450c000, 0x34516800, 0x34521000, 0x3452b800, 0x34536000, 0x34540800, 0x3454b000, 0x34555800, 0x34560000, 0x3456a800, 0x34575000, 0x3457f800, 0x3458a000, 0x34594800, 0x3459f000, 0x345a9800, 0x345b4000, 0x345be800, 0x345c9000, 0x345d3800, 0x345de000, 0x345e8800, 0x345f3000, 0x345fd800, 0x34608000, 0x34612800, 0x3461d000, 0x34627800, 0x34632000, 0x3463c800, 0x34647000, 0x34651800, 0x3465c000, 0x34666800, 0x34671000, 0x3467b800, 0x34686000, 0x34690800, 0x3469b000, 0x346a5800, 0x346b0000, 0x346ba800, 0x346c5000, 0x346cf800, 0x346da000, 0x346e4800, 0x346ef000, 0x346f9800, 0x34704000, 0x3470e800, 0x34719000, 0x34723800, 0x3472e000, 0x34738800, 0x34743000, 0x3474d800, 0x34758000, 0x34762800, 0x3476d000, 0x34777800, 0x34782000, 0x3478c800, 0x34797000, 0x347a1800, 0x347ac000, 0x347b6800, 0x347c1000, 0x347cb800, 0x347d6000, 0x347e0800, 0x347eb000, 0x347f5800, 0x34800000, 0x3480a800, 0x34815000, 0x3481f800, 0x3482a000, 0x34834800, 0x3483f000, 0x34849800, 0x34854000, 0x3485e800, 0x34869000, 0x34873800, 0x3487e000, 0x34888800, 0x34893000, 0x3489d800, 0x348a8000, 0x348b2800, 0x348bd000, 0x348c7800, 0x348d2000, 0x348dc800, 0x348e7000, 0x348f1800, 0x348fc000, 0x34906800, 0x34911000, 0x3491b800, 0x34926000, 0x34930800, 0x3493b000, 0x34945800, 0x34950000, 0x3495a800, 0x34965000, 0x3496f800, 0x3497a000, 0x34984800, 0x3498f000, 0x34999800, 0x349a4000, 0x349ae800, 0x349b9000, 0x349c3800, 0x349ce000, 0x349d8800, 0x349e3000, 0x349ed800, 0x349f8000, 0x34a02800, 0x34a0d000, 0x34a17800, 0x34a22000, 0x34a2c800, 0x34a37000, 0x34a41800, 0x34a4c000, 0x34a56800, 0x34a61000, 0x34a6b800, 0x34a76000, 0x34a80800, 0x34a8b000, 0x34a95800, 0x34aa0000, 0x34aaa800, 0x34ab5000, 0x34abf800, 0x34aca000, 0x34ad4800, 0x34adf000, 0x34ae9800, 0x34af4000, 0x34afe800, 0x34b09000, 0x34b13800, 0x34b1e000, 0x34b28800, 0x34b33000, 0x34b3d800, 0x34b48000, 0x34b52800, 0x34b5d000, 0x34b67800, 0x34b72000, 0x34b7c800, 0x34b87000, 0x34b91800, 0x34b9c000, 0x34ba6800, 0x34bb1000, 0x34bbb800, 0x34bc6000, 0x34bd0800, 0x34bdb000, 0x34be5800, 0x34bf0000, 0x34bfa800, 0x34c05000, 0x34c0f800, 0x34c1a000, 0x34c24800, 0x34c2f000, 0x34c39800, 0x34c44000, 0x34c4e800, 0x34c59000, 0x34c63800, 0x34c6e000, 0x34c78800, 0x34c83000, 0x34c8d800, 0x34c98000, 0x34ca2800, 0x34cad000, 0x34cb7800, 0x34cc2000, 0x34ccc800, 0x34cd7000, 0x34ce1800, 0x34cec000, 0x34cf6800, 0x34d01000, 0x34d0b800, 0x34d16000, 0x34d20800, 0x34d2b000, 0x34d35800, 0x34d40000, 0x34d4bb00, 0x34d57600, 0x34d63100, 0x34d6ec00, 0x34d7a700, 0x34d86200, 0x34d91d00, 0x34d9d800, 0x34da9300, 0x34db4e00, 0x34dc0900, 0x34dcc400, 0x34dd7f00, 0x34de3a00, 0x34def500, 0x34dfb000, 0x34e06b00, 0x34e12600, 0x34e1e100, 0x34e29c00, 0x34e35700, 0x34e41200, 0x34e4cd00, 0x34e58800, 0x34e64300, 0x34e6fe00, 0x34e7b900, 0x34e87400, 0x34e92f00, 0x34e9ea00, 0x34eaa500, 0x34eb6000, 0x34ec1b00, 0x34ecd600, 0x34ed9100, 0x34ee4c00, 0x34ef0700, 0x34efc200, 0x34f07d00, 0x34f13800, 0x34f1f300, 0x34f2ae00, 0x34f36900, 0x34f42400, 0x34f4df00, 0x34f59a00, 0x34f65500, 0x34f71000, 0x34f7cb00, 0x34f88600, 0x34f94100, 0x34f9fc00, 0x34fab700, 0x34fb7200, 0x34fc2d00, 0x34fce800, 0x34fda300, 0x34fe5e00, 0x34ff1900, 0x34ffd400, 0x35008f00, 0x35014a00, 0x35020500, 0x3502c000, 0x35037b00, 0x35043600, 0x3504f100, 0x3505ac00, 0x35066700, 0x35072200, 0x3507dd00, 0x35089800, 0x35095300, 0x350a0e00, 0x350ac900, 0x350b8400, 0x350c3f00, 0x350cfa00, 0x350db500, 0x350e7000, 0x350f2b00, 0x350fe600, 0x3510a100, 0x35115c00, 0x35121700, 0x3512d200, 0x35138d00, 0x35144800, 0x35150300, 0x3515be00, 0x35167900, 0x35173400, 0x3517ef00, 0x3518aa00, 0x35196500, 0x351a2000, 0x351adb00, 0x351b9600, 0x351c5100, 0x351d0c00, 0x351dc700, 0x351e8200, 0x351f3d00, 0x351ff800, 0x3520b300, 0x35216e00, 0x35222900, 0x3522e400, 0x35239f00, 0x35245a00, 0x35251500, 0x3525d000, 0x35268b00, 0x35274600, 0x35280100, 0x3528bc00, 0x35297700, 0x352a3200, 0x352aed00, 0x352ba800, 0x352c6300, 0x352d1e00, 0x352dd900, 0x352e9400, 0x352f4f00, 0x35300a00, 0x3530c500, 0x35318000, 0x35323b00, 0x3532f600, 0x3533b100, 0x35346c00, 0x35352700, 0x3535e200, 0x35369d00, 0x35375800, 0x35381300, 0x3538ce00, 0x35398900, 0x353a4400, 0x353aff00, 0x353bba00, 0x353c7500, 0x353d3000, 0x353deb00, 0x353ea600, 0x353f6100, 0x35401c00, 0x3540d700, 0x35419200, 0x35424d00, 0x35430800, 0x3543c300, 0x35447e00, 0x35453900, 0x3545f400, 0x3546af00, 0x35476a00, 0x35482500, 0x3548e000, 0x35499b00, 0x354a5600, 0x354b1100, 0x354bcc00, 0x354c8700, 0x354d4200, 0x354dfd00, 0x354eb800, 0x354f7300, 0x35502e00, 0x3550e900, 0x3551a400, 0x35525f00, 0x35531a00, 0x3553d500, 0x35549000, 0x35554b00, 0x35560600, 0x3556c100, 0x35577c00, 0x35583700, 0x3558f200, 0x3559ad00, 0x355a6800, 0x355b2300, 0x355bde00, 0x355c9900, 0x355d5400, 0x355e0f00, 0x355eca00, 0x355f8500, 0x35604000, 0x3560fb00, 0x3561b600, 0x35627100, 0x35632c00, 0x3563e700, 0x3564a200, 0x35655d00, 0x35661800, 0x3566d300, 0x35678e00, 0x35684900, 0x35690400, 0x3569bf00, 0x356a7a00, 0x356b3500, 0x356bf000, 0x356cab00, 0x356d6600, 0x356e2100, 0x356edc00, 0x356f9700, 0x35705200, 0x35710d00, 0x3571c800, 0x35728300, 0x35733e00, 0x3573f900, 0x3574b400, 0x35756f00, 0x35762a00, 0x3576e500, 0x3577a000, 0x35785b00, 0x35791600, 0x3579d100, 0x357a8c00, 0x357b4700, 0x357c0200, 0x357cbd00, 0x357d7800, 0x357e3300, 0x357eee00, 0x357fa900, 0x35806400, 0x35811f00, 0x3581da00, 0x35829500, 0x35835000, 0x35840b00, 0x3584c600, 0x35858100, 0x35863c00, 0x3586f700, 0x3587b200, 0x35886d00, 0x35892800, 0x3589e300, 0x358a9e00, 0x358b5900, 0x358c1400, 0x358ccf00, 0x358d8a00, 0x358e4500, 0x358f0000, 0x358fbb00, 0x35907600, 0x35913100, 0x3591ec00, 0x3592a700, 0x35936200, 0x35941d00, 0x3594d800, 0x35959300, 0x35964e00, 0x35970900, 0x3597c400, 0x35987f00, 0x35993a00, 0x3599f500, 0x359ab000, 0x359b6b00, 0x359c2600, 0x359ce100, 0x359d9c00, 0x359e5700, 0x359f1200, 0x359fcd00, 0x35a08800, 0x35a14300, 0x35a1fe00, 0x35a2b900, 0x35a37400, 0x35a42f00, 0x35a4ea00, 0x35a5a500, 0x35a66000, 0x35a71b00, 0x35a7d600, 0x35a89100, 0x35a94c00, 0x35aa0700, 0x35aac200, 0x35ab7d00, 0x35ac3800, 0x35acf300, 0x35adae00, 0x35ae6900, 0x35af2400, 0x35afdf00, 0x35b09a00, 0x35b15500, 0x35b21000, 0x35b2cb00, 0x35b38600, 0x35b44100, 0x35b4fc00, 0x35b5b700, 0x35b67200, 0x35b72d00, 0x35b7e800, 0x35b8a300, 0x35b95e00, 0x35ba1900, 0x35bad400, 0x35bb8f00, 0x35bc4a00, 0x35bd0500, 0x35bdc000, 0x35be7b00, 0x35bf3600, 0x35bff100, 0x35c0ac00, 0x35c16700, 0x35c22200, 0x35c2dd00, 0x35c39800, 0x35c45300, 0x35c50e00, 0x35c5c900, 0x35c68400, 0x35c73f00, 0x35c7fa00, 0x35c8b500, 0x35c97000, 0x35ca2b00, 0x35cae600, 0x35cba100, 0x35cc5c00, 0x35cd1700, 0x35cdd200, 0x35ce8d00, 0x35cf4800, 0x35d00300, 0x35d0be00, 0x35d17900, 0x35d23400, 0x35d2ef00, 0x35d3aa00, 0x35d46500, 0x35d52000, 0x35d5db00, 0x35d69600, 0x35d75100, 0x35d80c00, 0x35d8c700, 0x35d98200, 0x35da3d00, 0x35daf800, 0x35dbb300, 0x35dc6e00, 0x35dd2900, 0x35dde400, 0x35de9f00, 0x35df5a00, 0x35e01500, 0x35e0d000, 0x35e18b00, 0x35e24600, 0x35e30100, 0x35e3bc00, 0x35e47700, 0x35e53200, 0x35e5ed00, 0x35e6a800, 0x35e76300, 0x35e81e00, 0x35e8d900, 0x35e99400, 0x35ea4f00, 0x35eb0a00, 0x35ebc500, 0x35ec8000, 0x35ed3b00, 0x35edf600, 0x35eeb100, 0x35ef6c00, 0x35f02700, 0x35f0e200, 0x35f19d00, 0x35f25800, 0x35f31300, 0x35f3ce00, 0x35f48900, 0x35f54400, 0x35f5ff00, 0x35f6ba00, 0x35f77500, 0x35f83000, 0x35f8eb00, 0x35f9a600, 0x35fa6100, 0x35fb1c00, 0x35fbd700, 0x35fc9200, 0x35fd4d00, 0x35fe0800, 0x35fec300, 0x35ff7e00, 0x36003900, 0x3600f400, 0x3601af00, 0x36026a00, 0x36032500, 0x3603e000, 0x36049b00, 0x36055600, 0x36061100, 0x3606cc00, 0x36078700, 0x36084200, 0x3608fd00, 0x3609b800, 0x360a7300, 0x360b2e00, 0x360be900, 0x360ca400, 0x360d5f00, 0x360e1a00, 0x360ed500, 0x360f9000, 0x36104b00, 0x36110600, 0x3611c100, 0x36127c00, 0x36133700, 0x3613f200, 0x3614ad00, 0x36156800, 0x36162300, 0x3616de00, 0x36179900, 0x36185400, 0x36190f00, 0x3619ca00, 0x361a8500, 0x361b4000, 0x361bfb00, 0x361cb600, 0x361d7100, 0x361e2c00, 0x361ee700, 0x361fa200, 0x36205d00, 0x36211800, 0x3621d300, 0x36228e00, 0x36234900, 0x36240400, 0x3624bf00, 0x36257a00, 0x36263500, 0x3626f000, 0x3627ab00, 0x36286600, 0x36292100, 0x3629dc00, 0x362a9700, 0x362b5200, 0x362c0d00, 0x362cc800, 0x362d8300, 0x362e3e00, 0x362ef900, 0x362fb400, 0x36306f00, 0x36312a00, 0x3631e500, 0x3632a000, 0x36335b00, 0x36341600, 0x3634d100, 0x36358c00, 0x36364700, 0x36370200, 0x3637bd00, 0x36387800, 0x36393300, 0x3639ee00, 0x363aa900, 0x363b6400, 0x363c1f00, 0x363cda00, 0x363d9500, 0x363e5000, 0x363f0b00, 0x363fc600, 0x36408100, 0x36413c00, 0x3641f700, 0x3642b200, 0x36436d00, 0x36442800, 0x3644e300, 0x36459e00, 0x36465900, 0x36471400, 0x3647cf00, 0x36488a00, 0x36494500, 0x364a0000, 0x364ac000, 0x364b8000, 0x364c4000, 0x364d0000, 0x364dc000, 0x364e8000, 0x364f4000, 0x36500000, 0x3650c000, 0x36518000, 0x36524000, 0x36530000, 0x3653c000, 0x36548000, 0x36554000, 0x36560000, 0x3656c000, 0x36578000, 0x36584000, 0x36590000, 0x3659c000, 0x365a8000, 0x365b4000, 0x365c0000, 0x365cc000, 0x365d8000, 0x365e4000, 0x365f0000, 0x365fc000, 0x36608000, 0x36614000, 0x36620000, 0x3662c000, 0x36638000, 0x36644000, 0x36650000, 0x3665c000, 0x36668000, 0x36674000, 0x36680000, 0x3668c000, 0x36698000, 0x366a4000, 0x366b0000, 0x366bc000, 0x366c8000, 0x366d4000, 0x366e0000, 0x366ec000, 0x366f8000, 0x36704000, 0x36710000, 0x3671c000, 0x36728000, 0x36734000, 0x36740000, 0x3674c000, 0x36758000, 0x36764000, 0x36770000, 0x3677c000, 0x36788000, 0x36794000, 0x367a0000, 0x367ac000, 0x367b8000, 0x367c4000, 0x367d0000, 0x367dc000, 0x367e8000, 0x367f4000, 0x36800000, 0x3680c000, 0x36818000, 0x36824000, 0x36830000, 0x3683c000, 0x36848000, 0x36854000, 0x36860000, 0x3686c000, 0x36878000, 0x36884000, 0x36890000, 0x3689c000, 0x368a8000, 0x368b4000, 0x368c0000, 0x368cc000, 0x368d8000, 0x368e4000, 0x368f0000, 0x368fc000, 0x36908000, 0x36914000, 0x36920000, 0x3692c000, 0x36938000, 0x36944000, 0x36950000, 0x3695c000, 0x36968000, 0x36974000, 0x36980000, 0x3698c000, 0x36998000, 0x369a4000, 0x369b0000, 0x369bc000, 0x369c8000, 0x369d4000, 0x369e0000, 0x369ec000, 0x369f8000, 0x36a04000, 0x36a10000, 0x36a1c000, 0x36a28000, 0x36a34000, 0x36a40000, 0x36a4c000, 0x36a58000, 0x36a64000, 0x36a70000, 0x36a7c000, 0x36a88000, 0x36a94000, 0x36aa0000, 0x36aac000, 0x36ab8000, 0x36ac4000, 0x36ad0000, 0x36adc000, 0x36ae8000, 0x36af4000, 0x36b00000, 0x36b0c000, 0x36b18000, 0x36b24000, 0x36b30000, 0x36b3c000, 0x36b48000, 0x36b54000, 0x36b60000, 0x36b6c000, 0x36b78000, 0x36b84000, 0x36b90000, 0x36b9c000, 0x36ba8000, 0x36bb4000, 0x36bc0000, 0x36bcc000, 0x36bd8000, 0x36be4000, 0x36bf0000, 0x36bfc000, 0x36c08000, 0x36c14000, 0x36c20000, 0x36c2c000, 0x36c38000, 0x36c44000, 0x36c50000, 0x36c5c000, 0x36c68000, 0x36c74000, 0x36c80000, 0x36c8c000, 0x36c98000, 0x36ca4000, 0x36cb0000, 0x36cbc000, 0x36cc8000, 0x36cd4000, 0x36ce0000, 0x36cec000, 0x36cf8000, 0x36d04000, 0x36d10000, 0x36d1c000, 0x36d28000, 0x36d34000, 0x36d40000, 0x36d4c000, 0x36d58000, 0x36d64000, 0x36d70000, 0x36d7c000, 0x36d88000, 0x36d94000, 0x36da0000, 0x36dac000, 0x36db8000, 0x36dc4000, 0x36dd0000, 0x36ddc000, 0x36de8000, 0x36df4000, 0x36e00000, 0x36e0c000, 0x36e18000, 0x36e24000, 0x36e30000, 0x36e3c000, 0x36e48000, 0x36e54000, 0x36e60000, 0x36e6c000, 0x36e78000, 0x36e84000, 0x36e90000, 0x36e9c000, 0x36ea8000, 0x36eb4000, 0x36ec0000, 0x36ecc000, 0x36ed8000, 0x36ee4000, 0x36ef0000, 0x36efc000, 0x36f08000, 0x36f14000, 0x36f20000, 0x36f2c000, 0x36f38000, 0x36f44000, 0x36f50000, 0x36f5c000, 0x36f68000, 0x36f74000, 0x36f80000, 0x36f8c000, 0x36f98000, 0x36fa4000, 0x36fb0000, 0x36fbc000, 0x36fc8000, 0x36fd4000, 0x36fe0000, 0x36fec000, 0x36ff8000, 0x37004000, 0x37010000, 0x3701c000, 0x37028000, 0x37034000, 0x37040000, 0x3704c000, 0x37058000, 0x37064000, 0x37070000, 0x3707c000, 0x37088000, 0x37094000, 0x370a0000, 0x370ac000, 0x370b8000, 0x370c4000, 0x370d0000, 0x370dc000, 0x370e8000, 0x370f4000, 0x37100000, 0x3710c000, 0x37118000, 0x37124000, 0x37130000, 0x3713c000, 0x37148000, 0x37154000, 0x37160000, 0x3716c000, 0x37178000, 0x37184000, 0x37190000, 0x3719c000, 0x371a8000, 0x371b4000, 0x371c0000, 0x371cc000, 0x371d8000, 0x371e4000, 0x371f0000, 0x371fc000, 0x37208000, 0x37214000, 0x37220000, 0x3722c000, 0x37238000, 0x37244000, 0x37250000, 0x3725c000, 0x37268000, 0x37274000, 0x37280000, 0x3728c000, 0x37298000, 0x372a4000, 0x372b0000, 0x372bc000, 0x372c8000, 0x372d4000, 0x372e0000, 0x372ec000, 0x372f8000, 0x37304000, 0x37310000, 0x3731c000, 0x37328000, 0x37334000, 0x37340000, 0x3734c000, 0x37358000, 0x37364000, 0x37370000, 0x3737c000, 0x37388000, 0x37394000, 0x373a0000, 0x373ac000, 0x373b8000, 0x373c4000, 0x373d0000, 0x373dc000, 0x373e8000, 0x373f4000, 0x37400000, 0x3740c000, 0x37418000, 0x37424000, 0x37430000, 0x3743c000, 0x37448000, 0x37454000, 0x37460000, 0x3746c000, 0x37478000, 0x37484000, 0x37490000, 0x3749c000, 0x374a8000, 0x374b4000, 0x374c0000, 0x374cc000, 0x374d8000, 0x374e4000, 0x374f0000, 0x374fc000, 0x37508000, 0x37514000, 0x37520000, 0x3752c000, 0x37538000, 0x37544000, 0x37550000, 0x3755c000, 0x37568000, 0x37574000, 0x37580000, 0x3758c000, 0x37598000, 0x375a4000, 0x375b0000, 0x375bc000, 0x375c8000, 0x375d4000, 0x375e0000, 0x375ec000, 0x375f8000, 0x37604000, 0x37610000, 0x3761c000, 0x37628000, 0x37634000, 0x37640000, 0x3764c000, 0x37658000, 0x37664000, 0x37670000, 0x3767c000, 0x37688000, 0x37694000, 0x376a0000, 0x376ac000, 0x376b8000, 0x376c4000, 0x376d0000, 0x376dc000, 0x376e8000, 0x376f4000, 0x37700000, 0x3770c000, 0x37718000, 0x37724000, 0x37730000, 0x3773c000, 0x37748000, 0x37754000, 0x37760000, 0x3776c000, 0x37778000, 0x37784000, 0x37790000, 0x3779c000, 0x377a8000, 0x377b4000, 0x377c0000, 0x377cc000, 0x377d8000, 0x377e4000, 0x377f0000, 0x377fc000, 0x37808000, 0x37814000, 0x37820000, 0x3782c000, 0x37838000, 0x37844000, 0x37850000, 0x3785c000, 0x37868000, 0x37874000, 0x37880000, 0x3788c000, 0x37898000, 0x378a4000, 0x378b0000, 0x378bc000, 0x378c8000, 0x378d4000, 0x378e0000, 0x378ec000, 0x378f8000, 0x37904000, 0x37910000, 0x3791c000, 0x37928000, 0x37934000, 0x37940000, 0x3794c000, 0x37958000, 0x37964000, 0x37970000, 0x3797c000, 0x37988000, 0x37994000, 0x379a0000, 0x379ac000, 0x379b8000, 0x379c4000, 0x379d0000, 0x379dc000, 0x379e8000, 0x379f4000, 0x37a00000, 0x37a0c000, 0x37a18000, 0x37a24000, 0x37a30000, 0x37a3c000, 0x37a48000, 0x37a54000, 0x37a60000, 0x37a6c000, 0x37a78000, 0x37a84000, 0x37a90000, 0x37a9c000, 0x37aa8000, 0x37ab4000, 0x37ac0000, 0x37acc000, 0x37ad8000, 0x37ae4000, 0x37af0000, 0x37afc000, 0x37b08000, 0x37b14000, 0x37b20000, 0x37b2c000, 0x37b38000, 0x37b44000, 0x37b50000, 0x37b5c000, 0x37b68000, 0x37b74000, 0x37b80000, 0x37b8c000, 0x37b98000, 0x37ba4000, 0x37bb0000, 0x37bbc000, 0x37bc8000, 0x37bd4000, 0x37be0000, 0x37bec000, 0x37bf8000, 0x37c04000, 0x37c10000, 0x37c1c000, 0x37c28000, 0x37c34000, 0x37c40000, 0x37c4c000, 0x37c58000, 0x37c64000, 0x37c70000, 0x37c7c000, 0x37c88000, 0x37c94000, 0x37ca0000, 0x37cad800, 0x37cbb000, 0x37cc8800, 0x37cd6000, 0x37ce3800, 0x37cf1000, 0x37cfe800, 0x37d0c000, 0x37d19800, 0x37d27000, 0x37d34800, 0x37d42000, 0x37d4f800, 0x37d5d000, 0x37d6a800, 0x37d78000, 0x37d85800, 0x37d93000, 0x37da0800, 0x37dae000, 0x37dbb800, 0x37dc9000, 0x37dd6800, 0x37de4000, 0x37df1800, 0x37dff000, 0x37e0c800, 0x37e1a000, 0x37e27800, 0x37e35000, 0x37e42800, 0x37e50000, 0x37e5d800, 0x37e6b000, 0x37e78800, 0x37e86000, 0x37e93800, 0x37ea1000, 0x37eae800, 0x37ebc000, 0x37ec9800, 0x37ed7000, 0x37ee4800, 0x37ef2000, 0x37eff800, 0x37f0d000, 0x37f1a800, 0x37f28000, 0x37f35800, 0x37f43000, 0x37f50800, 0x37f5e000, 0x37f6b800, 0x37f79000, 0x37f86800, 0x37f94000, 0x37fa1800, 0x37faf000, 0x37fbc800, 0x37fca000, 0x37fd7800, 0x37fe5000, 0x37ff2800, 0x38000000, 0x3800d800, 0x3801b000, 0x38028800, 0x38036000, 0x38043800, 0x38051000, 0x3805e800, 0x3806c000, 0x38079800, 0x38087000, 0x38094800, 0x380a2000, 0x380af800, 0x380bd000, 0x380ca800, 0x380d8000, 0x380e5800, 0x380f3000, 0x38100800, 0x3810e000, 0x3811b800, 0x38129000, 0x38136800, 0x38144000, 0x38151800, 0x3815f000, 0x3816c800, 0x3817a000, 0x38187800, 0x38195000, 0x381a2800, 0x381b0000, 0x381bd800, 0x381cb000, 0x381d8800, 0x381e6000, 0x381f3800, 0x38201000, 0x3820e800, 0x3821c000, 0x38229800, 0x38237000, 0x38244800, 0x38252000, 0x3825f800, 0x3826d000, 0x3827a800, 0x38288000, 0x38295800, 0x382a3000, 0x382b0800, 0x382be000, 0x382cb800, 0x382d9000, 0x382e6800, 0x382f4000, 0x38301800, 0x3830f000, 0x3831c800, 0x3832a000, 0x38337800, 0x38345000, 0x38352800, 0x38360000, 0x3836d800, 0x3837b000, 0x38388800, 0x38396000, 0x383a3800, 0x383b1000, 0x383be800, 0x383cc000, 0x383d9800, 0x383e7000, 0x383f4800, 0x38402000, 0x3840f800, 0x3841d000, 0x3842a800, 0x38438000, 0x38445800, 0x38453000, 0x38460800, 0x3846e000, 0x3847b800, 0x38489000, 0x38496800, 0x384a4000, 0x384b1800, 0x384bf000, 0x384cc800, 0x384da000, 0x384e7800, 0x384f5000, 0x38502800, 0x38510000, 0x3851d800, 0x3852b000, 0x38538800, 0x38546000, 0x38553800, 0x38561000, 0x3856e800, 0x3857c000, 0x38589800, 0x38597000, 0x385a4800, 0x385b2000, 0x385bf800, 0x385cd000, 0x385da800, 0x385e8000, 0x385f5800, 0x38603000, 0x38610800, 0x3861e000, 0x3862b800, 0x38639000, 0x38646800, 0x38654000, 0x38661800, 0x3866f000, 0x3867c800, 0x3868a000, 0x38697800, 0x386a5000, 0x386b2800, 0x386c0000, 0x386cd700, 0x386daf00, 0x386e8700, 0x386f5f00, 0x38703700, 0x38710f00, 0x3871e700, 0x3872bf00, 0x38739700, 0x38746f00, 0x38754700, 0x38761f00, 0x3876f700, 0x3877cf00, 0x3878a700, 0x38797f00, 0x387a5700, 0x387b2f00, 0x387c0700, 0x387cdf00, 0x387db700, 0x387e8f00, 0x387f6700, 0x38803f00, 0x38811700, 0x3881ef00, 0x3882c700, 0x38839f00, 0x38847700, 0x38854f00, 0x38862700, 0x3886ff00, 0x3887d700, 0x3888af00, 0x38898700, 0x388a5f00, 0x388b3700, 0x388c0f00, 0x388ce700, 0x388dbf00, 0x388e9700, 0x388f6f00, 0x38904700, 0x38911f00, 0x3891f700, 0x3892cf00, 0x3893a700, 0x38947f00, 0x38955700, 0x38962f00, 0x38970700, 0x3897df00, 0x3898b700, 0x38998f00, 0x389a6700, 0x389b3f00, 0x389c1700, 0x389cef00, 0x389dc700, 0x389e9f00, 0x389f7700, 0x38a04f00, 0x38a12700, 0x38a1ff00, 0x38a2d700, 0x38a3af00, 0x38a48700, 0x38a55f00, 0x38a63700, 0x38a70f00, 0x38a7e700, 0x38a8bf00, 0x38a99700, 0x38aa6f00, 0x38ab4700, 0x38ac1f00, 0x38acf700, 0x38adcf00, 0x38aea700, 0x38af7f00, 0x38b05700, 0x38b12f00, 0x38b20700, 0x38b2df00, 0x38b3b700, 0x38b48f00, 0x38b56700, 0x38b63f00, 0x38b71700, 0x38b7ef00, 0x38b8c700, 0x38b99f00, 0x38ba7700, 0x38bb4f00, 0x38bc2700, 0x38bcff00, 0x38bdd700, 0x38beaf00, 0x38bf8700, 0x38c05f00, 0x38c13700, 0x38c20f00, 0x38c2e700, 0x38c3bf00, 0x38c49700, 0x38c56f00, 0x38c64700, 0x38c71f00, 0x38c7f700, 0x38c8cf00, 0x38c9a700, 0x38ca7f00, 0x38cb5700, 0x38cc2f00, 0x38cd0700, 0x38cddf00, 0x38ceb700, 0x38cf8f00, 0x38d06700, 0x38d13f00, 0x38d21700, 0x38d2ef00, 0x38d3c700, 0x38d49f00, 0x38d57700, 0x38d64f00, 0x38d72700, 0x38d7ff00, 0x38d8d700, 0x38d9af00, 0x38da8700, 0x38db5f00, 0x38dc3700, 0x38dd0f00, 0x38dde700, 0x38debf00, 0x38df9700, 0x38e06f00, 0x38e14700, 0x38e21f00, 0x38e2f700, 0x38e3cf00, 0x38e4a700, 0x38e57f00, 0x38e65700, 0x38e72f00, 0x38e80700, 0x38e8df00, 0x38e9b700, 0x38ea8f00, 0x38eb6700, 0x38ec3f00, 0x38ed1700, 0x38edef00, 0x38eec700, 0x38ef9f00, 0x38f07700, 0x38f14f00, 0x38f22700, 0x38f2ff00, 0x38f3d700, 0x38f4af00, 0x38f58700, 0x38f65f00, 0x38f73700, 0x38f80f00, 0x38f8e700, 0x38f9bf00, 0x38fa9700, 0x38fb6f00, 0x38fc4700, 0x38fd1f00, 0x38fdf700, 0x38fecf00, 0x38ffa700, 0x39007f00, 0x39015700, 0x39022f00, 0x39030700, 0x3903df00, 0x3904b700, 0x39058f00, 0x39066700, 0x39073f00, 0x39081700, 0x3908ef00, 0x3909c700, 0x390a9f00, 0x390b7700, 0x390c4f00, 0x390d2700, 0x390dff00, 0x390ed700, 0x390faf00, 0x39108700, 0x39115f00, 0x39123700, 0x39130f00, 0x3913e700, 0x3914bf00, 0x39159700, 0x39166f00, 0x39174700, 0x39181f00, 0x3918f700, 0x3919cf00, 0x391aa700, 0x391b7f00, 0x391c5700, 0x391d2f00, 0x391e0700, 0x391edf00, 0x391fb700, 0x39208f00, 0x39216700, 0x39223f00, 0x39231700, 0x3923ef00, 0x3924c700, 0x39259f00, 0x39267700, 0x39274f00, 0x39282700, 0x3928ff00, 0x3929d700, 0x392aaf00, 0x392b8700, 0x392c5f00, 0x392d3700, 0x392e0f00, 0x392ee700, 0x392fbf00, 0x39309700, 0x39316f00, 0x39324700, 0x39331f00, 0x3933f700, 0x3934cf00, 0x3935a700, 0x39367f00, 0x39375700, 0x39382f00, 0x39390700, 0x3939df00, 0x393ab700, 0x393b8f00, 0x393c6700, 0x393d3f00, 0x393e1700, 0x393eef00, 0x393fc700, 0x39409f00, 0x39417700, 0x39424f00, 0x39432700, 0x3943ff00, 0x3944d700, 0x3945af00, 0x39468700, 0x39475f00, 0x39483700, 0x39490f00, 0x3949e700, 0x394abf00, 0x394b9700, 0x394c6f00, 0x394d4700, 0x394e1f00, 0x394ef700, 0x394fcf00, 0x3950a700, 0x39517f00, 0x39525700, 0x39532f00, 0x39540700, 0x3954df00, 0x3955b700, 0x39568f00, 0x39576700, 0x39583f00, 0x39591700, 0x3959ef00, 0x395ac700, 0x395b9f00, 0x395c7700, 0x395d4f00, 0x395e2700, 0x395eff00, 0x395fd700, 0x3960af00, 0x39618700, 0x39625f00, 0x39633700, 0x39640f00, 0x3964e700, 0x3965bf00, 0x39669700, 0x39676f00, 0x39684700, 0x39691f00, 0x3969f700, 0x396acf00, 0x396ba700, 0x396c7f00, 0x396d5700, 0x396e2f00, 0x396f0700, 0x396fdf00, 0x3970b700, 0x39718f00, 0x39726700, 0x39733f00, 0x39741700, 0x3974ef00, 0x3975c700, 0x39769f00, 0x39777700, 0x39784f00, 0x39792700, 0x3979ff00, 0x397ae900, 0x397bd300, 0x397cbd00, 0x397da700, 0x397e9100, 0x397f7b00, 0x39806500, 0x39814f00, 0x39823900, 0x39832300, 0x39840d00, 0x3984f700, 0x3985e100, 0x3986cb00, 0x3987b500, 0x39889f00, 0x39898900, 0x398a7300, 0x398b5d00, 0x398c4700, 0x398d3100, 0x398e1b00, 0x398f0500, 0x398fef00, 0x3990d900, 0x3991c300, 0x3992ad00, 0x39939700, 0x39948100, 0x39956b00, 0x39965500, 0x39973f00, 0x39982900, 0x39991300, 0x3999fd00, 0x399ae700, 0x399bd100, 0x399cbb00, 0x399da500, 0x399e8f00, 0x399f7900, 0x39a06300, 0x39a14d00, 0x39a23700, 0x39a32100, 0x39a40b00, 0x39a4f500, 0x39a5df00, 0x39a6c900, 0x39a7b300, 0x39a89d00, 0x39a98700, 0x39aa7100, 0x39ab5b00, 0x39ac4500, 0x39ad2f00, 0x39ae1900, 0x39af0300, 0x39afed00, 0x39b0d700, 0x39b1c100, 0x39b2ab00, 0x39b39500, 0x39b47f00, 0x39b56900, 0x39b65300, 0x39b73d00, 0x39b82700, 0x39b91100, 0x39b9fb00, 0x39bae500, 0x39bbcf00, 0x39bcb900, 0x39bda300, 0x39be8d00, 0x39bf7700, 0x39c06100, 0x39c14b00, 0x39c23500, 0x39c31f00, 0x39c40900, 0x39c4f300, 0x39c5dd00, 0x39c6c700, 0x39c7b100, 0x39c89b00, 0x39c98500, 0x39ca6f00, 0x39cb5900, 0x39cc4300, 0x39cd2d00, 0x39ce1700, 0x39cf0100, 0x39cfeb00, 0x39d0d500, 0x39d1bf00, 0x39d2a900, 0x39d39300, 0x39d47d00, 0x39d56700, 0x39d65100, 0x39d73b00, 0x39d82500, 0x39d90f00, 0x39d9f900, 0x39dae300, 0x39dbcd00, 0x39dcb700, 0x39dda100, 0x39de8b00, 0x39df7500, 0x39e05f00, 0x39e14900, 0x39e23300, 0x39e31d00, 0x39e40700, 0x39e4f100, 0x39e5db00, 0x39e6c500, 0x39e7af00, 0x39e89900, 0x39e98300, 0x39ea6d00, 0x39eb5700, 0x39ec4100, 0x39ed2b00, 0x39ee1500, 0x39eeff00, 0x39efe900, 0x39f0d300, 0x39f1bd00, 0x39f2a700, 0x39f39100, 0x39f47b00, 0x39f56500, 0x39f64f00, 0x39f73900, 0x39f82300, 0x39f90d00, 0x39f9f700, 0x39fae100, 0x39fbcb00, 0x39fcb500, 0x39fd9f00, 0x39fe8900, 0x39ff7300, 0x3a005d00, 0x3a014700, 0x3a023100, 0x3a031b00, 0x3a040500, 0x3a04ef00, 0x3a05d900, 0x3a06c300, 0x3a07ad00, 0x3a089700, 0x3a098100, 0x3a0a6b00, 0x3a0b5500, 0x3a0c3f00, 0x3a0d2900, 0x3a0e1300, 0x3a0efd00, 0x3a0fe700, 0x3a10d100, 0x3a11bb00, 0x3a12a500, 0x3a138f00, 0x3a147900, 0x3a156300, 0x3a164d00, 0x3a173700, 0x3a182100, 0x3a190b00, 0x3a19f500, 0x3a1adf00, 0x3a1bc900, 0x3a1cb300, 0x3a1d9d00, 0x3a1e8700, 0x3a1f7100, 0x3a205b00, 0x3a214500, 0x3a222f00, 0x3a231900, 0x3a240300, 0x3a24ed00, 0x3a25d700, 0x3a26c100, 0x3a27ab00, 0x3a289500, 0x3a297f00, 0x3a2a6900, 0x3a2b5300, 0x3a2c3d00, 0x3a2d2700, 0x3a2e1100, 0x3a2efb00, 0x3a2fe500, 0x3a30cf00, 0x3a31b900, 0x3a32a300, 0x3a338d00, 0x3a347700, 0x3a356100, 0x3a364b00, 0x3a373500, 0x3a381f00, 0x3a390900, 0x3a39f300, 0x3a3add00, 0x3a3bc700, 0x3a3cb100, 0x3a3d9b00, 0x3a3e8500, 0x3a3f6f00, 0x3a405900, 0x3a414300, 0x3a422d00, 0x3a431700, 0x3a440100, 0x3a44eb00, 0x3a45d500, 0x3a46bf00, 0x3a47a900, 0x3a489300, 0x3a497d00, 0x3a4a6700, 0x3a4b5100, 0x3a4c3b00, 0x3a4d2500, 0x3a4e0f00, 0x3a4ef900, 0x3a4fe300, 0x3a50cd00, 0x3a51b700, 0x3a52a100, 0x3a538b00, 0x3a547500, 0x3a555f00, 0x3a564900, 0x3a573300, 0x3a581d00, 0x3a590700, 0x3a59f100, 0x3a5adb00, 0x3a5bc500, 0x3a5caf00, 0x3a5d9900, 0x3a5e8300, 0x3a5f6d00, 0x3a605700, 0x3a614100, 0x3a622b00, 0x3a631500, 0x3a63ff00, 0x3a64e900, 0x3a65d300, 0x3a66bd00, 0x3a67a700, 0x3a689100, 0x3a697b00, 0x3a6a6500, 0x3a6b4f00, 0x3a6c3900, 0x3a6d2300, 0x3a6e0d00, 0x3a6ef700, 0x3a6fe100, 0x3a70cb00, 0x3a71b500, 0x3a729f00, 0x3a738900, 0x3a747300, 0x3a755d00, 0x3a764700, 0x3a773100, 0x3a781b00, 0x3a790500, 0x3a79ef00, 0x3a7ad900, 0x3a7bc300, 0x3a7cad00, 0x3a7d9700, 0x3a7e8100, 0x3a7f6b00, 0x3a805500, 0x3a813f00, 0x3a822900, 0x3a831300, 0x3a83fd00, 0x3a84e700, 0x3a85d100, 0x3a86bb00, 0x3a87a500, 0x3a888f00, 0x3a897900, 0x3a8a6300, 0x3a8b4d00, 0x3a8c3700, 0x3a8d2100, 0x3a8e0b00, 0x3a8ef500, 0x3a8fdf00, 0x3a90c900, 0x3a91b300, 0x3a929d00, 0x3a938700, 0x3a947100, 0x3a955b00, 0x3a964500, 0x3a972f00, 0x3a981900, 0x3a990300, 0x3a99ed00, 0x3a9ad700, 0x3a9bc100, 0x3a9cab00, 0x3a9d9500, 0x3a9e7f00, 0x3a9f6900, 0x3aa05300, 0x3aa13d00, 0x3aa22700, 0x3aa31100, 0x3aa3fb00, 0x3aa4e500, 0x3aa5cf00, 0x3aa6b900, 0x3aa7a300, 0x3aa88d00, 0x3aa97700, 0x3aaa6100, 0x3aab4b00, 0x3aac3500, 0x3aad1f00, 0x3aae0900, 0x3aaef300, 0x3aafdd00, 0x3ab0c700, 0x3ab1b100, 0x3ab29b00, 0x3ab38500, 0x3ab46f00, 0x3ab55900, 0x3ab64300, 0x3ab72d00, 0x3ab81700, 0x3ab90100, 0x3ab9eb00, 0x3abad500, 0x3abbbf00, 0x3abca900, 0x3abd9300, 0x3abe7d00, 0x3abf6700, 0x3ac05100, 0x3ac13b00, 0x3ac22500, 0x3ac30f00, 0x3ac3f900, 0x3ac4e300, 0x3ac5cd00, 0x3ac6b700, 0x3ac7a100, 0x3ac88b00, 0x3ac97500, 0x3aca5f00, 0x3acb4900, 0x3acc3300, 0x3acd1d00, 0x3ace0700, 0x3acef100, 0x3acfdb00, 0x3ad0c500, 0x3ad1af00, 0x3ad29900, 0x3ad38300, 0x3ad46d00, 0x3ad55700, 0x3ad64100, 0x3ad72b00, 0x3ad81500, 0x3ad8ff00, 0x3ad9e900, 0x3adad300, 0x3adbbd00, 0x3adca700, 0x3add9100, 0x3ade7b00, 0x3adf6500, 0x3ae04f00, 0x3ae13900, 0x3ae22300, 0x3ae30d00, 0x3ae3f700, 0x3ae4e100, 0x3ae5cb00, 0x3ae6b500, 0x3ae79f00, 0x3ae88900, 0x3ae97300, 0x3aea5d00, 0x3aeb4700, 0x3aec3100, 0x3aed1b00, 0x3aee0500, 0x3aeeef00, 0x3aefd900, 0x3af0c300, 0x3af1ad00, 0x3af29700, 0x3af38100, 0x3af46b00, 0x3af55500, 0x3af63f00, 0x3af72900, 0x3af81300, 0x3af8fd00, 0x3af9e700, 0x3afad100, 0x3afbbb00, 0x3afca500, 0x3afd8f00, 0x3afe7900, 0x3aff6300, 0x3b004e00, 0x3b013800, 0x3b022200, 0x3b030c00, 0x3b03f600, 0x3b04e000, 0x3b05ca00, 0x3b06b400, 0x3b079e00, 0x3b088800, 0x3b097200, 0x3b0a5c00, 0x3b0b4600, 0x3b0c3000, 0x3b0d1a00, 0x3b0e0400, 0x3b0eee00, 0x3b0fd800, 0x3b10c200, 0x3b11ac00, 0x3b129600, 0x3b138000, 0x3b146a00, 0x3b155400, 0x3b163e00, 0x3b172800, 0x3b181200, 0x3b18fc00, 0x3b19e600, 0x3b1ad000, 0x3b1bba00, 0x3b1ca400, 0x3b1d8e00, 0x3b1e7800, 0x3b1f6200, 0x3b204c00, 0x3b213600, 0x3b222000, 0x3b230a00, 0x3b23f400, 0x3b24de00, 0x3b25c800, 0x3b26b200, 0x3b279c00, 0x3b288600, 0x3b297000, 0x3b2a5a00, 0x3b2b4400, 0x3b2c2e00, 0x3b2d1800, 0x3b2e0200, 0x3b2eec00, 0x3b2fd600, 0x3b30c000, 0x3b31aa00, 0x3b329400, 0x3b337e00, 0x3b346800, 0x3b355200, 0x3b363c00, 0x3b372600, 0x3b381000, 0x3b38fa00, 0x3b39e400, 0x3b3ace00, 0x3b3bb800, 0x3b3ca200, 0x3b3d8c00, 0x3b3e7600, 0x3b3f6000, 0x3b404a00, 0x3b413400, 0x3b421e00, 0x3b430800, 0x3b43f200, 0x3b44dc00, 0x3b45c600, 0x3b46b000, 0x3b479a00, 0x3b488400, 0x3b496e00, 0x3b4a5800, 0x3b4b4200, 0x3b4c2c00, 0x3b4d1600, 0x3b4e0000, 0x3b4f0000, 0x3b500000, 0x3b510000, 0x3b520000, 0x3b530000, 0x3b540000, 0x3b550000, 0x3b560000, 0x3b570000, 0x3b580000, 0x3b590000, 0x3b5a0000, 0x3b5b0000, 0x3b5c0000, 0x3b5d0000, 0x3b5e0000, 0x3b5f0000, 0x3b600000, 0x3b610000, 0x3b620000, 0x3b630000, 0x3b640000, 0x3b650000, 0x3b660000, 0x3b670000, 0x3b680000, 0x3b690000, 0x3b6a0000, 0x3b6b0000, 0x3b6c0000, 0x3b6d0000, 0x3b6e0000, 0x3b6f0000, 0x3b700000, 0x3b710000, 0x3b720000, 0x3b730000, 0x3b740000, 0x3b750000, 0x3b760000, 0x3b770000, 0x3b780000, 0x3b790000, 0x3b7a0000, 0x3b7b0000, 0x3b7c0000, 0x3b7d0000, 0x3b7e0000, 0x3b7f0000, 0x3b800000, 0x3b810000, 0x3b820000, 0x3b830000, 0x3b840000, 0x3b850000, 0x3b860000, 0x3b870000, 0x3b880000, 0x3b890000, 0x3b8a0000, 0x3b8b0000, 0x3b8c0000, 0x3b8d0000, 0x3b8e0000, 0x3b8f0000, 0x3b900000, 0x3b910000, 0x3b920000, 0x3b930000, 0x3b940000, 0x3b950000, 0x3b960000, 0x3b970000, 0x3b980000, 0x3b990000, 0x3b9a0000, 0x3b9b0000, 0x3b9c0000, 0x3b9d0000, 0x3b9e0000, 0x3b9f0000, 0x3ba00000, 0x3ba10000, 0x3ba20000, 0x3ba30000, 0x3ba40000, 0x3ba50000, 0x3ba60000, 0x3ba70000, 0x3ba80000, 0x3ba90000, 0x3baa0000, 0x3bab0000, 0x3bac0000, 0x3bad0000, 0x3bae0000, 0x3baf0000, 0x3bb00000, 0x3bb10000, 0x3bb20000, 0x3bb30000, 0x3bb40000, 0x3bb50000, 0x3bb60000, 0x3bb70000, 0x3bb80000, 0x3bb90000, 0x3bba0000, 0x3bbb0000, 0x3bbc0000, 0x3bbd0000, 0x3bbe0000, 0x3bbf0000, 0x3bc00000, 0x3bc10000, 0x3bc20000, 0x3bc30000, 0x3bc40000, 0x3bc50000, 0x3bc60000, 0x3bc70000, 0x3bc80000, 0x3bc90000, 0x3bca0000, 0x3bcb0000, 0x3bcc0000, 0x3bcd0000, 0x3bce0000, 0x3bcf0000, 0x3bd00000, 0x3bd10000, 0x3bd20000, 0x3bd30000, 0x3bd40000, 0x3bd50000, 0x3bd60000, 0x3bd70000, 0x3bd80000, 0x3bd90000, 0x3bda0000, 0x3bdb0000, 0x3bdc0000, 0x3bdd0000, 0x3bde0000, 0x3bdf0000, 0x3be00000, 0x3be10000, 0x3be20000, 0x3be30000, 0x3be40000, 0x3be50000, 0x3be60000, 0x3be70000, 0x3be80000, 0x3be90000, 0x3bea0000, 0x3beb0000, 0x3bec0000, 0x3bed0000, 0x3bee0000, 0x3bef0000, 0x3bf00000, 0x3bf10000, 0x3bf20000, 0x3bf30000, 0x3bf40000, 0x3bf50000, 0x3bf60000, 0x3bf70000, 0x3bf80000, 0x3bf90000, 0x3bfa0000, 0x3bfb0000, 0x3bfc0000, 0x3bfd0000, 0x3bfe0000, 0x3bff0000, 0x3c000000, 0x3c010000, 0x3c020000, 0x3c030000, 0x3c040000, 0x3c050000, 0x3c060000, 0x3c070000, 0x3c080000, 0x3c090000, 0x3c0a0000, 0x3c0b0000, 0x3c0c0000, 0x3c0d0000, 0x3c0e0000, 0x3c0f0000, 0x3c100000, 0x3c110000, 0x3c120000, 0x3c130000, 0x3c140000, 0x3c150000, 0x3c160000, 0x3c170000, 0x3c180000, 0x3c190000, 0x3c1a0000, 0x3c1b0000, 0x3c1c0000, 0x3c1d0000, 0x3c1e0000, 0x3c1f0000, 0x3c200000, 0x3c210000, 0x3c220000, 0x3c230000, 0x3c240000, 0x3c250000, 0x3c260000, 0x3c270000, 0x3c280000, 0x3c290000, 0x3c2a0000, 0x3c2b0000, 0x3c2c0000, 0x3c2d0000, 0x3c2e0000, 0x3c2f0000, 0x3c300000, 0x3c310000, 0x3c320000, 0x3c330000, 0x3c340000, 0x3c350000, 0x3c360000, 0x3c370000, 0x3c380000, 0x3c390000, 0x3c3a0000, 0x3c3b0000, 0x3c3c0000, 0x3c3d0000, 0x3c3e0000, 0x3c3f0000, 0x3c400000, 0x3c410000, 0x3c420000, 0x3c430000, 0x3c440000, 0x3c450000, 0x3c460000, 0x3c470000, 0x3c480000, 0x3c490000, 0x3c4a0000, 0x3c4b0000, 0x3c4c0000, 0x3c4d0000, 0x3c4e0000, 0x3c4f0000, 0x3c500000, 0x3c510000, 0x3c520000, 0x3c530000, 0x3c540000, 0x3c550000, 0x3c560000, 0x3c570000, 0x3c580000, 0x3c590000, 0x3c5a0000, 0x3c5b0000, 0x3c5c0000, 0x3c5d0000, 0x3c5e0000, 0x3c5f0000, 0x3c600000, 0x3c610000, 0x3c620000, 0x3c630000, 0x3c640000, 0x3c650000, 0x3c660000, 0x3c670000, 0x3c680000, 0x3c690000, 0x3c6a0000, 0x3c6b0000, 0x3c6c0000, 0x3c6d0000, 0x3c6e0000, 0x3c6f0000, 0x3c700000, 0x3c710000, 0x3c720000, 0x3c730000, 0x3c740000, 0x3c750000, 0x3c760000, 0x3c770000, 0x3c780000, 0x3c790000, 0x3c7a0000, 0x3c7b0000, 0x3c7c0000, 0x3c7d0000, 0x3c7e0000, 0x3c7f0000, 0x3c800000, 0x3c810000, 0x3c820000, 0x3c830000, 0x3c840000, 0x3c850000, 0x3c860000, 0x3c870000, 0x3c880000, 0x3c890000, 0x3c8a0000, 0x3c8b0000, 0x3c8c0000, 0x3c8d0000, 0x3c8e0000, 0x3c8f0000, 0x3c900000, 0x3c910000, 0x3c920000, 0x3c930000, 0x3c940000, 0x3c950000, 0x3c960000, 0x3c970000, 0x3c980000, 0x3c990000, 0x3c9a0000, 0x3c9b0000, 0x3c9c0000, 0x3c9d0000, 0x3c9e0000, 0x3c9f0000, 0x3ca00000, 0x3ca10000, 0x3ca20000, 0x3ca30000, 0x3ca40000, 0x3ca50000, 0x3ca60000, 0x3ca70000, 0x3ca80000, 0x3ca90000, 0x3caa0000, 0x3cab0000, 0x3cac0000, 0x3cad0000, 0x3cae0000, 0x3caf0000, 0x3cb00000, 0x3cb10000, 0x3cb20000, 0x3cb30000, 0x3cb40000, 0x3cb50000, 0x3cb60000, 0x3cb70000, 0x3cb80000, 0x3cb90000, 0x3cba0000, 0x3cbb0000, 0x3cbc0000, 0x3cbd0000, 0x3cbe0000, 0x3cbf0000, 0x3cc00000, 0x3cc10000, 0x3cc20000, 0x3cc30000, 0x3cc40000, 0x3cc50000, 0x3cc60000, 0x3cc70000, 0x3cc80000, 0x3cc90000, 0x3cca0000, 0x3ccb0000, 0x3ccc0000, 0x3ccd0000, 0x3cce0000, 0x3ccf0000, 0x3cd00000, 0x3cd10000, 0x3cd20000, 0x3cd30000, 0x3cd40000, 0x3cd50000, 0x3cd60000, 0x3cd70000, 0x3cd80000, 0x3cd90000, 0x3cda0000, 0x3cdb0000, 0x3cdc0000, 0x3cdd0000, 0x3cde0000, 0x3cdf0000, 0x3ce00000, 0x3ce10000, 0x3ce20000, 0x3ce30000, 0x3ce40000, 0x3ce50000, 0x3ce60000, 0x3ce70000, 0x3ce80000, 0x3ce90000, 0x3cea0000, 0x3ceb0000, 0x3cec0000, 0x3ced0000, 0x3cee0000, 0x3cef0000, 0x3cf00000, 0x3cf10000, 0x3cf20000, 0x3cf30000, 0x3cf40000, 0x3cf50000, 0x3cf60000, 0x3cf70000, 0x3cf80000, 0x3cf90000, 0x3cfa0000, 0x3cfb0000, 0x3cfc0000, 0x3cfd0000, 0x3cfe0000, 0x3cff0000, 0x3d000000, 0x3d010000, 0x3d020000, 0x3d030000, 0x3d040000, 0x3d050000, 0x3d060000, 0x3d070000, 0x3d080000, 0x3d090000, 0x3d0a0000, 0x3d0b0000, 0x3d0c0000, 0x3d0d0000, 0x3d0e0000, 0x3d0f0000, 0x3d100000, 0x3d110000, 0x3d120000, 0x3d130000, 0x3d140000, 0x3d150000, 0x3d160000, 0x3d170000, 0x3d180000, 0x3d190000, 0x3d1a0000, 0x3d1b0000, 0x3d1c0000, 0x3d1d0000, 0x3d1e0000, 0x3d1f0000, 0x3d200000, 0x3d210000, 0x3d220000, 0x3d230000, 0x3d240000, 0x3d250000, 0x3d260000, 0x3d270000, 0x3d280000, 0x3d290000, 0x3d2a0000, 0x3d2b0000, 0x3d2c0000, 0x3d2d0000, 0x3d2e0000, 0x3d2f0000, 0x3d300000, 0x3d310000, 0x3d320000, 0x3d330000, 0x3d340000, 0x3d350000, 0x3d360000, 0x3d370000, 0x3d380000, 0x3d390000, 0x3d3a0000, 0x3d3b0000, 0x3d3c0000, 0x3d3d0000, 0x3d3e0000, 0x3d3f0000, 0x3d400000, 0x3d410000, 0x3d420000, 0x3d430000, 0x3d440000, 0x3d450000, 0x3d460000, 0x3d470000, 0x3d480000, 0x3d490000, 0x3d4a0000, 0x3d4b0000, 0x3d4c0000, 0x3d4d0000, 0x3d4e0000, 0x3d4f2200, 0x3d504400, 0x3d516600, 0x3d528800, 0x3d53aa00, 0x3d54cc00, 0x3d55ee00, 0x3d571000, 0x3d583200, 0x3d595400, 0x3d5a7600, 0x3d5b9800, 0x3d5cba00, 0x3d5ddc00, 0x3d5efe00, 0x3d602000, 0x3d614200, 0x3d626400, 0x3d638600, 0x3d64a800, 0x3d65ca00, 0x3d66ec00, 0x3d680e00, 0x3d693000, 0x3d6a5200, 0x3d6b7400, 0x3d6c9600, 0x3d6db800, 0x3d6eda00, 0x3d6ffc00, 0x3d711e00, 0x3d724000, 0x3d736200, 0x3d748400, 0x3d75a600, 0x3d76c800, 0x3d77ea00, 0x3d790c00, 0x3d7a2e00, 0x3d7b5000, 0x3d7c7200, 0x3d7d9400, 0x3d7eb600, 0x3d7fd800, 0x3d80fa00, 0x3d821c00, 0x3d833e00, 0x3d846000, 0x3d858200, 0x3d86a400, 0x3d87c600, 0x3d88e800, 0x3d8a0a00, 0x3d8b2c00, 0x3d8c4e00, 0x3d8d7000, 0x3d8e9200, 0x3d8fb400, 0x3d90d600, 0x3d91f800, 0x3d931a00, 0x3d943c00, 0x3d955e00, 0x3d968000, 0x3d97a200, 0x3d98c400, 0x3d99e600, 0x3d9b0800, 0x3d9c2a00, 0x3d9d4c00, 0x3d9e6e00, 0x3d9f9000, 0x3da0b200, 0x3da1d400, 0x3da2f600, 0x3da41800, 0x3da53a00, 0x3da65c00, 0x3da77e00, 0x3da8a000, 0x3da9c200, 0x3daae400, 0x3dac0600, 0x3dad2800, 0x3dae4a00, 0x3daf6c00, 0x3db08e00, 0x3db1b000, 0x3db2d200, 0x3db3f400, 0x3db51600, 0x3db63800, 0x3db75a00, 0x3db87c00, 0x3db99e00, 0x3dbac000, 0x3dbbe200, 0x3dbd0400, 0x3dbe2600, 0x3dbf4800, 0x3dc06a00, 0x3dc18c00, 0x3dc2ae00, 0x3dc3d000, 0x3dc4f200, 0x3dc61400, 0x3dc73600, 0x3dc85800, 0x3dc97a00, 0x3dca9c00, 0x3dcbbe00, 0x3dcce000, 0x3dce0200, 0x3dcf2400, 0x3dd04600, 0x3dd16800, 0x3dd28a00, 0x3dd3ac00, 0x3dd4ce00, 0x3dd5f000, 0x3dd71200, 0x3dd83400, 0x3dd95600, 0x3dda7800, 0x3ddb9a00, 0x3ddcbc00, 0x3dddde00, 0x3ddf0000, 0x3de02200, 0x3de14400, 0x3de26600, 0x3de38800, 0x3de4aa00, 0x3de5cc00, 0x3de6ee00, 0x3de81000, 0x3de93200, 0x3dea5400, 0x3deb7600, 0x3dec9800, 0x3dedba00, 0x3deedc00, 0x3deffe00, 0x3df12000, 0x3df24200, 0x3df36400, 0x3df48600, 0x3df5a800, 0x3df6ca00, 0x3df7ec00, 0x3df90e00, 0x3dfa3000, 0x3dfb5200, 0x3dfc7400, 0x3dfd9600, 0x3dfeb800, 0x3dffda00, 0x3e00fc00, 0x3e021e00, 0x3e034000, 0x3e046200, 0x3e058400, 0x3e06a600, 0x3e07c800, 0x3e08ea00, 0x3e0a0c00, 0x3e0b2e00, 0x3e0c5000, 0x3e0d7200, 0x3e0e9400, 0x3e0fb600, 0x3e10d800, 0x3e11fa00, 0x3e131c00, 0x3e143e00, 0x3e156000, 0x3e168200, 0x3e17a400, 0x3e18c600, 0x3e19e800, 0x3e1b0a00, 0x3e1c2c00, 0x3e1d4e00, 0x3e1e7000, 0x3e1f9200, 0x3e20b400, 0x3e21d600, 0x3e22f800, 0x3e241a00, 0x3e253c00, 0x3e265e00, 0x3e278000, 0x3e28a200, 0x3e29c400, 0x3e2ae600, 0x3e2c0800, 0x3e2d2a00, 0x3e2e4c00, 0x3e2f6e00, 0x3e309000, 0x3e31b200, 0x3e32d400, 0x3e33f600, 0x3e351800, 0x3e363a00, 0x3e375c00, 0x3e387e00, 0x3e39a000, 0x3e3ac200, 0x3e3be400, 0x3e3d0600, 0x3e3e2800, 0x3e3f4a00, 0x3e406c00, 0x3e418e00, 0x3e42b000, 0x3e43d200, 0x3e44f400, 0x3e461600, 0x3e473800, 0x3e485a00, 0x3e497c00, 0x3e4a9e00, 0x3e4bc000, 0x3e4ce200, 0x3e4e0400, 0x3e4f2600, 0x3e504800, 0x3e516a00, 0x3e528c00, 0x3e53ae00, 0x3e54d000, 0x3e55f200, 0x3e571400, 0x3e583600, 0x3e595800, 0x3e5a7a00, 0x3e5b9c00, 0x3e5cbe00, 0x3e5de000, 0x3e5f0200, 0x3e602400, 0x3e614600, 0x3e626800, 0x3e638a00, 0x3e64ac00, 0x3e65ce00, 0x3e66f000, 0x3e681200, 0x3e693400, 0x3e6a5600, 0x3e6b7800, 0x3e6c9a00, 0x3e6dbc00, 0x3e6ede00, 0x3e700000, 0x3e712100, 0x3e724300, 0x3e736500, 0x3e748700, 0x3e75a900, 0x3e76cb00, 0x3e77ed00, 0x3e790f00, 0x3e7a3100, 0x3e7b5300, 0x3e7c7500, 0x3e7d9700, 0x3e7eb900, 0x3e7fdb00, 0x3e80fd00, 0x3e821f00, 0x3e834100, 0x3e846300, 0x3e858500, 0x3e86a700, 0x3e87c900, 0x3e88eb00, 0x3e8a0d00, 0x3e8b2f00, 0x3e8c5100, 0x3e8d7300, 0x3e8e9500, 0x3e8fb700, 0x3e90d900, 0x3e91fb00, 0x3e931d00, 0x3e943f00, 0x3e956100, 0x3e968300, 0x3e97a500, 0x3e98c700, 0x3e99e900, 0x3e9b0b00, 0x3e9c2d00, 0x3e9d4f00, 0x3e9e7100, 0x3e9f9300, 0x3ea0b500, 0x3ea1d700, 0x3ea2f900, 0x3ea41b00, 0x3ea53d00, 0x3ea65f00, 0x3ea78100, 0x3ea8a300, 0x3ea9c500, 0x3eaae700, 0x3eac0900, 0x3ead2b00, 0x3eae4d00, 0x3eaf6f00, 0x3eb09100, 0x3eb1b300, 0x3eb2d500, 0x3eb3f700, 0x3eb51900, 0x3eb63b00, 0x3eb75d00, 0x3eb87f00, 0x3eb9a100, 0x3ebac300, 0x3ebbe500, 0x3ebd0700, 0x3ebe2900, 0x3ebf4b00, 0x3ec06d00, 0x3ec18f00, 0x3ec2b100, 0x3ec3d300, 0x3ec4f500, 0x3ec61700, 0x3ec73900, 0x3ec85b00, 0x3ec97d00, 0x3eca9f00, 0x3ecbc100, 0x3ecce300, 0x3ece0500, 0x3ecf2700, 0x3ed04900, 0x3ed16b00, 0x3ed28d00, 0x3ed3af00, 0x3ed4d100, 0x3ed5f300, 0x3ed71500, 0x3ed83700, 0x3ed95900, 0x3eda7b00, 0x3edb9d00, 0x3edcbf00, 0x3edde100, 0x3edf0300, 0x3ee02500, 0x3ee14700, 0x3ee26900, 0x3ee38b00, 0x3ee4ad00, 0x3ee5cf00, 0x3ee6f100, 0x3ee81300, 0x3ee93500, 0x3eea5700, 0x3eeb7900, 0x3eec9b00, 0x3eedbd00, 0x3eeedf00, 0x3ef00100, 0x3ef12300, 0x3ef24500, 0x3ef36700, 0x3ef48900, 0x3ef5ab00, 0x3ef6cd00, 0x3ef7ef00, 0x3ef91100, 0x3efa3300, 0x3efb5500, 0x3efc7700, 0x3efd9900, 0x3efebb00, 0x3effdd00, 0x3f00ff00, 0x3f022100, 0x3f034300, 0x3f046500, 0x3f058700, 0x3f06a900, 0x3f07cb00, 0x3f08ed00, 0x3f0a0f00, 0x3f0b3100, 0x3f0c5300, 0x3f0d7500, 0x3f0e9700, 0x3f0fb900, 0x3f10db00, 0x3f11fd00, 0x3f131f00, 0x3f144100, 0x3f156300, 0x3f168500, 0x3f17a700, 0x3f18c900, 0x3f19eb00, 0x3f1b0d00, 0x3f1c2f00, 0x3f1d5100, 0x3f1e7300, 0x3f1f9500, 0x3f20b700, 0x3f21d900, 0x3f22fb00, 0x3f241d00, 0x3f253f00, 0x3f266100, 0x3f278300, 0x3f28a500, 0x3f29c700, 0x3f2ae900, 0x3f2c0b00, 0x3f2d2d00, 0x3f2e4f00, 0x3f2f7100, 0x3f309300, 0x3f31b500, 0x3f32d700, 0x3f33f900, 0x3f351b00, 0x3f363d00, 0x3f375f00, 0x3f388100, 0x3f39a300, 0x3f3ac500, 0x3f3be700, 0x3f3d0900, 0x3f3e2b00, 0x3f3f4d00, 0x3f406f00, 0x3f419100, 0x3f42b300, 0x3f43d500, 0x3f44f700, 0x3f461900, 0x3f473b00, 0x3f485d00, 0x3f497f00, 0x3f4aa100, 0x3f4bc300, 0x3f4ce500, 0x3f4e0700, 0x3f4f2900, 0x3f504b00, 0x3f516d00, 0x3f528f00, 0x3f53b100, 0x3f54d300, 0x3f55f500, 0x3f571700, 0x3f583900, 0x3f595b00, 0x3f5a7d00, 0x3f5b9f00, 0x3f5cc100, 0x3f5de300, 0x3f5f0500, 0x3f602700, 0x3f614900, 0x3f626b00, 0x3f638d00, 0x3f64af00, 0x3f65d100, 0x3f66f300, 0x3f681500, 0x3f693700, 0x3f6a5900, 0x3f6b7b00, 0x3f6c9d00, 0x3f6dbf00, 0x3f6ee100, 0x3f700300, 0x3f712500, 0x3f724700, 0x3f736900, 0x3f748b00, 0x3f75ad00, 0x3f76cf00, 0x3f77f100, 0x3f791300, 0x3f7a3500, 0x3f7b5700, 0x3f7c7900, 0x3f7d9b00, 0x3f7ebd00, 0x3f7fdf00, 0x3f810100, 0x3f822300, 0x3f834500, 0x3f846700, 0x3f858900, 0x3f86ab00, 0x3f87cd00, 0x3f88ef00, 0x3f8a1100, 0x3f8b3300, 0x3f8c5500, 0x3f8d7700, 0x3f8e9900, 0x3f8fbb00, 0x3f90dd00, 0x3f91ff00, 0x3f935300, 0x3f94a700, 0x3f95fb00, 0x3f974f00, 0x3f98a300, 0x3f99f700, 0x3f9b4b00, 0x3f9c9f00, 0x3f9df300, 0x3f9f4700, 0x3fa09b00, 0x3fa1ef00, 0x3fa34300, 0x3fa49700, 0x3fa5eb00, 0x3fa73f00, 0x3fa89300, 0x3fa9e700, 0x3fab3b00, 0x3fac8f00, 0x3fade300, 0x3faf3700, 0x3fb08b00, 0x3fb1df00, 0x3fb33300, 0x3fb48700, 0x3fb5db00, 0x3fb72f00, 0x3fb88300, 0x3fb9d700, 0x3fbb2b00, 0x3fbc7f00, 0x3fbdd300, 0x3fbf2700, 0x3fc07b00, 0x3fc1cf00, 0x3fc32300, 0x3fc47700, 0x3fc5cb00, 0x3fc71f00, 0x3fc87300, 0x3fc9c700, 0x3fcb1b00, 0x3fcc6f00, 0x3fcdc300, 0x3fcf1700, 0x3fd06b00, 0x3fd1bf00, 0x3fd31300, 0x3fd46700, 0x3fd5bb00, 0x3fd70f00, 0x3fd86300, 0x3fd9b700, 0x3fdb0b00, 0x3fdc5f00, 0x3fddb300, 0x3fdf0700, 0x3fe05b00, 0x3fe1af00, 0x3fe30300, 0x3fe45700, 0x3fe5ab00, 0x3fe6ff00, 0x3fe85300, 0x3fe9a700, 0x3feafb00, 0x3fec4f00, 0x3feda300, 0x3feef700, 0x3ff04b00, 0x3ff19f00, 0x3ff2f300, 0x3ff44700, 0x3ff59b00, 0x3ff6ef00, 0x3ff84300, 0x3ff99700, 0x3ffaeb00, 0x3ffc3f00, 0x3ffd9300, 0x3ffee700, 0x40003b00, 0x40018f00, 0x4002e300, 0x40043700, 0x40058b00, 0x4006df00, 0x40083300, 0x40098700, 0x400adb00, 0x400c2f00, 0x400d8300, 0x400ed700, 0x40102b00, 0x40117f00, 0x4012d300, 0x40142700, 0x40157b00, 0x4016cf00, 0x40182300, 0x40197700, 0x401acb00, 0x401c1f00, 0x401d7300, 0x401ec700, 0x40201b00, 0x40216f00, 0x4022c300, 0x40241700, 0x40256b00, 0x4026bf00, 0x40281300, 0x40296700, 0x402abb00, 0x402c0f00, 0x402d6300, 0x402eb700, 0x40300b00, 0x40315f00, 0x4032b300, 0x40340700, 0x40355b00, 0x4036af00, 0x40380300, 0x40395700, 0x403aab00, 0x403bff00, 0x403d5300, 0x403ea700, 0x403ffb00, 0x40414f00, 0x4042a300, 0x4043f700, 0x40454b00, 0x40469f00, 0x4047f300, 0x40494700, 0x404a9b00, 0x404bef00, 0x404d4300, 0x404e9700, 0x404feb00, 0x40513f00, 0x40529300, 0x4053e700, 0x40553b00, 0x40568f00, 0x4057e300, 0x40593700, 0x405a8b00, 0x405bdf00, 0x405d3300, 0x405e8700, 0x405fdb00, 0x40612f00, 0x40628300, 0x4063d700, 0x40652b00, 0x40667f00, 0x4067d300, 0x40692700, 0x406a7b00, 0x406bcf00, 0x406d2300, 0x406e7700, 0x406fcb00, 0x40711f00, 0x40727300, 0x4073c700, 0x40751b00, 0x40766f00, 0x4077c300, 0x40791700, 0x407a6b00, 0x407bbf00, 0x407d1300, 0x407e6700, 0x407fbb00, 0x40810f00, 0x40826300, 0x4083b700, 0x40850b00, 0x40865f00, 0x4087b300, 0x40890700, 0x408a5b00, 0x408baf00, 0x408d0300, 0x408e5700, 0x408fab00, 0x4090ff00, 0x40925300, 0x4093a700, 0x4094fb00, 0x40964f00, 0x4097a300, 0x4098f700, 0x409a4b00, 0x409b9f00, 0x409cf300, 0x409e4700, 0x409f9b00, 0x40a0ef00, 0x40a24300, 0x40a39700, 0x40a4eb00, 0x40a63f00, 0x40a79300, 0x40a8e700, 0x40aa3b00, 0x40ab8f00, 0x40ace300, 0x40ae3700, 0x40af8b00, 0x40b0df00, 0x40b23300, 0x40b38700, 0x40b4db00, 0x40b62f00, 0x40b78300, 0x40b8d700, 0x40ba2b00, 0x40bb7f00, 0x40bcd300, 0x40be2700, 0x40bf7b00, 0x40c0cf00, 0x40c22300, 0x40c37700, 0x40c4cb00, 0x40c61f00, 0x40c77300, 0x40c8c700, 0x40ca1b00, 0x40cb6f00, 0x40ccc300, 0x40ce1700, 0x40cf6b00, 0x40d0bf00, 0x40d21300, 0x40d36700, 0x40d4bb00, 0x40d60f00, 0x40d76300, 0x40d8b700, 0x40da0b00, 0x40db5f00, 0x40dcb300, 0x40de0700, 0x40df5b00, 0x40e0af00, 0x40e20300, 0x40e35700, 0x40e4ab00, 0x40e5ff00, 0x40e75300, 0x40e8a700, 0x40e9fb00, 0x40eb4f00, 0x40eca300, 0x40edf700, 0x40ef4b00, 0x40f09f00, 0x40f1f300, 0x40f34700, 0x40f49b00, 0x40f5ef00, 0x40f74300, 0x40f89700, 0x40f9eb00, 0x40fb3f00, 0x40fc9300, 0x40fde700, 0x40ff3b00, 0x41008f00, 0x4101e300, 0x41033700, 0x41048b00, 0x4105df00, 0x41073300, 0x41088700, 0x4109db00, 0x410b2f00, 0x410c8300, 0x410dd700, 0x410f2b00, 0x41107f00, 0x4111d300, 0x41132700, 0x41147b00, 0x4115cf00, 0x41172300, 0x41187700, 0x4119cb00, 0x411b1f00, 0x411c7300, 0x411dc700, 0x411f1b00, 0x41206f00, 0x4121c300, 0x41231700, 0x41246b00, 0x4125bf00, 0x41271300, 0x41286700, 0x4129bb00, 0x412b0f00, 0x412c6300, 0x412db700, 0x412f0b00, 0x41305f00, 0x4131b300, 0x41330700, 0x41345b00, 0x4135af00, 0x41370300, 0x41385700, 0x4139ab00, 0x413aff00, 0x413c5300, 0x413da700, 0x413efb00, 0x41404f00, 0x4141a300, 0x4142f700, 0x41444b00, 0x41459f00, 0x4146f300, 0x41484700, 0x41499b00, 0x414aef00, 0x414c4300, 0x414d9700, 0x414eeb00, 0x41503f00, 0x41519300, 0x4152e700, 0x41543b00, 0x41558f00, 0x4156e300, 0x41583700, 0x41598b00, 0x415adf00, 0x415c3300, 0x415d8700, 0x415edb00, 0x41602f00, 0x41618300, 0x4162d700, 0x41642b00, 0x41657f00, 0x4166d300, 0x41682700, 0x41697b00, 0x416acf00, 0x416c2300, 0x416d7700, 0x416ecb00, 0x41701f00, 0x41717300, 0x4172c700, 0x41741b00, 0x41756f00, 0x4176c300, 0x41781700, 0x41796b00, 0x417abf00, 0x417c1300, 0x417d6700, 0x417ebb00, 0x41800f00, 0x41816300, 0x4182b700, 0x41840b00, 0x41855f00, 0x4186b300, 0x41880700, 0x41895b00, 0x418aaf00, 0x418c0300, 0x418d5700, 0x418eab00, 0x418fff00, 0x41915300, 0x4192a700, 0x4193fb00, 0x41954f00, 0x4196a300, 0x4197f700, 0x41994b00, 0x419a9f00, 0x419bf300, 0x419d4700, 0x419e9b00, 0x419fef00, 0x41a14300, 0x41a29700, 0x41a3eb00, 0x41a53f00, 0x41a69300, 0x41a7e700, 0x41a93b00, 0x41aa8f00, 0x41abe300, 0x41ad3700, 0x41ae8b00, 0x41afdf00, 0x41b13300, 0x41b28700, 0x41b3db00, 0x41b52f00, 0x41b68300, 0x41b7d700, 0x41b92b00, 0x41ba7f00, 0x41bbd300, 0x41bd2700, 0x41be7b00, 0x41bfcf00, 0x41c12300, 0x41c27700, 0x41c3cb00, 0x41c51f00, 0x41c67300, 0x41c7c700, 0x41c91b00, 0x41ca6f00, 0x41cbc300, 0x41cd1700, 0x41ce6b00, 0x41cfbf00, 0x41d11300, 0x41d26700, 0x41d3bb00, 0x41d50f00, 0x41d66300, 0x41d7b700, 0x41d90b00, 0x41da5f00, 0x41dbb300, 0x41dd0700, 0x41de5b00, 0x41dfaf00, 0x41e10300, 0x41e25700, 0x41e3ab00, 0x41e4ff00, 0x41e65300, 0x41e7a700, 0x41e8fb00, 0x41ea4f00, 0x41eba300, 0x41ecf700, 0x41ee4b00, 0x41ef9f00, 0x41f0f300, 0x41f24700, 0x41f39b00, 0x41f4ef00, 0x41f64300, 0x41f79700, 0x41f8eb00, 0x41fa3f00, 0x41fb9300, 0x41fce700, 0x41fe3b00, 0x41ff8f00, 0x4200e300, 0x42023700, 0x42038b00, 0x4204df00, 0x42063300, 0x42078700, 0x4208db00, 0x420a2f00, 0x420b8300, 0x420cd700, 0x420e2b00, 0x420f7f00, 0x4210d300, 0x42122700, 0x42137b00, 0x4214cf00, 0x42162300, 0x42177700, 0x4218cb00, 0x421a1f00, 0x421b7300, 0x421cc700, 0x421e1b00, 0x421f6f00, 0x4220c300, 0x42221700, 0x42236b00, 0x4224bf00, 0x42261300, 0x42276700, 0x4228bb00, 0x422a0f00, 0x422b6300, 0x422cb700, 0x422e0b00, 0x422f5f00, 0x4230b300, 0x42320700, 0x42335b00, 0x4234af00, 0x42360300, 0x42375700, 0x4238ab00, 0x4239ff00, 0x423b9d00, 0x423d3b00, 0x423ed900, 0x42407700, 0x42421500, 0x4243b300, 0x42455100, 0x4246ef00, 0x42488d00, 0x424a2b00, 0x424bc900, 0x424d6700, 0x424f0500, 0x4250a300, 0x42524100, 0x4253df00, 0x42557d00, 0x42571b00, 0x4258b900, 0x425a5700, 0x425bf500, 0x425d9300, 0x425f3100, 0x4260cf00, 0x42626d00, 0x42640b00, 0x4265a900, 0x42674700, 0x4268e500, 0x426a8300, 0x426c2100, 0x426dbf00, 0x426f5d00, 0x4270fb00, 0x42729900, 0x42743700, 0x4275d500, 0x42777300, 0x42791100, 0x427aaf00, 0x427c4d00, 0x427deb00, 0x427f8900, 0x42812700, 0x4282c500, 0x42846300, 0x42860100, 0x42879f00, 0x42893d00, 0x428adb00, 0x428c7900, 0x428e1700, 0x428fb500, 0x42915300, 0x4292f100, 0x42948f00, 0x42962d00, 0x4297cb00, 0x42996900, 0x429b0700, 0x429ca500, 0x429e4300, 0x429fe100, 0x42a17f00, 0x42a31d00, 0x42a4bb00, 0x42a65900, 0x42a7f700, 0x42a99500, 0x42ab3300, 0x42acd100, 0x42ae6f00, 0x42b00d00, 0x42b1ab00, 0x42b34900, 0x42b4e700, 0x42b68500, 0x42b82300, 0x42b9c100, 0x42bb5f00, 0x42bcfd00, 0x42be9b00, 0x42c03900, 0x42c1d700, 0x42c37500, 0x42c51300, 0x42c6b100, 0x42c84f00, 0x42c9ed00, 0x42cb8b00, 0x42cd2900, 0x42cec700, 0x42d06500, 0x42d20300, 0x42d3a100, 0x42d53f00, 0x42d6dd00, 0x42d87b00, 0x42da1900, 0x42dbb700, 0x42dd5500, 0x42def300, 0x42e09100, 0x42e22f00, 0x42e3cd00, 0x42e56b00, 0x42e70900, 0x42e8a700, 0x42ea4500, 0x42ebe300, 0x42ed8100, 0x42ef1f00, 0x42f0bd00, 0x42f25b00, 0x42f3f900, 0x42f59700, 0x42f73500, 0x42f8d300, 0x42fa7100, 0x42fc0f00, 0x42fdad00, 0x42ff4b00, 0x4300e900, 0x43028700, 0x43042500, 0x4305c300, 0x43076100, 0x4308ff00, 0x430a9d00, 0x430c3b00, 0x430dd900, 0x430f7700, 0x43111500, 0x4312b300, 0x43145100, 0x4315ef00, 0x43178d00, 0x43192b00, 0x431ac900, 0x431c6700, 0x431e0500, 0x431fa300, 0x43214100, 0x4322df00, 0x43247d00, 0x43261b00, 0x4327b900, 0x43295700, 0x432af500, 0x432c9300, 0x432e3100, 0x432fcf00, 0x43316d00, 0x43330b00, 0x4334a900, 0x43364700, 0x4337e500, 0x43398300, 0x433b2100, 0x433cbf00, 0x433e5d00, 0x433ffb00, 0x43419900, 0x43433700, 0x4344d500, 0x43467300, 0x43481100, 0x4349af00, 0x434b4d00, 0x434ceb00, 0x434e8900, 0x43502700, 0x4351c500, 0x43536300, 0x43550100, 0x43569f00, 0x43583d00, 0x4359db00, 0x435b7900, 0x435d1700, 0x435eb500, 0x43605300, 0x4361f100, 0x43638f00, 0x43652d00, 0x4366cb00, 0x43686900, 0x436a0700, 0x436ba500, 0x436d4300, 0x436ee100, 0x43707f00, 0x43721d00, 0x4373bb00, 0x43755900, 0x4376f700, 0x43789500, 0x437a3300, 0x437bd100, 0x437d6f00, 0x437f0d00, 0x4380ab00, 0x43824900, 0x4383e700, 0x43858500, 0x43872300, 0x4388c100, 0x438a5f00, 0x438bfd00, 0x438d9b00, 0x438f3900, 0x4390d700, 0x43927500, 0x43941300, 0x4395b100, 0x43974f00, 0x4398ed00, 0x439a8b00, 0x439c2900, 0x439dc700, 0x439f6500, 0x43a10300, 0x43a2a100, 0x43a43f00, 0x43a5dd00, 0x43a77b00, 0x43a91900, 0x43aab700, 0x43ac5500, 0x43adf300, 0x43af9100, 0x43b12f00, 0x43b2cd00, 0x43b46b00, 0x43b60900, 0x43b7a700, 0x43b94500, 0x43bae300, 0x43bc8100, 0x43be1f00, 0x43bfbd00, 0x43c15b00, 0x43c2f900, 0x43c49700, 0x43c63500, 0x43c7d300, 0x43c97100, 0x43cb0f00, 0x43ccad00, 0x43ce4b00, 0x43cfe900, 0x43d18700, 0x43d32500, 0x43d4c300, 0x43d66100, 0x43d7ff00, 0x43d99d00, 0x43db3b00, 0x43dcd900, 0x43de7700, 0x43e01500, 0x43e1b300, 0x43e35100, 0x43e4ef00, 0x43e68d00, 0x43e82b00, 0x43e9c900, 0x43eb6700, 0x43ed0500, 0x43eea300, 0x43f04100, 0x43f1df00, 0x43f37d00, 0x43f51b00, 0x43f6b900, 0x43f85700, 0x43f9f500, 0x43fb9300, 0x43fd3100, 0x43fecf00, 0x44006d00, 0x44020b00, 0x4403a900, 0x44054700, 0x4406e500, 0x44088300, 0x440a2100, 0x440bbf00, 0x440d5d00, 0x440efb00, 0x44109900, 0x44123700, 0x4413d500, 0x44157300, 0x44171100, 0x4418af00, 0x441a4d00, 0x441beb00, 0x441d8900, 0x441f2700, 0x4420c500, 0x44226300, 0x44240100, 0x44259f00, 0x44273d00, 0x4428db00, 0x442a7900, 0x442c1700, 0x442db500, 0x442f5300, 0x4430f100, 0x44328f00, 0x44342d00, 0x4435cb00, 0x44376900, 0x44390700, 0x443aa500, 0x443c4300, 0x443de100, 0x443f7f00, 0x44411d00, 0x4442bb00, 0x44445900, 0x4445f700, 0x44479500, 0x44493300, 0x444ad100, 0x444c6f00, 0x444e0d00, 0x444fab00, 0x44514900, 0x4452e700, 0x44548500, 0x44562300, 0x4457c100, 0x44595f00, 0x445afd00, 0x445c9b00, 0x445e3900, 0x445fd700, 0x44617500, 0x44631300, 0x4464b100, 0x44664f00, 0x4467ed00, 0x44698b00, 0x446b2900, 0x446cc700, 0x446e6500, 0x44700300, 0x4471a100, 0x44733f00, 0x4474dd00, 0x44767b00, 0x44781900, 0x4479b700, 0x447b5500, 0x447cf300, 0x447e9100, 0x44802f00, 0x4481cd00, 0x44836b00, 0x44850900, 0x4486a700, 0x44884500, 0x4489e300, 0x448b8100, 0x448d1f00, 0x448ebd00, 0x44905b00, 0x4491f900, 0x44939700, 0x44953500, 0x4496d300, 0x44987100, 0x449a0f00, 0x449bad00, 0x449d4b00, 0x449ee900, 0x44a08700, 0x44a22500, 0x44a3c300, 0x44a56100, 0x44a6ff00, 0x44a89d00, 0x44aa3b00, 0x44abd900, 0x44ad7700, 0x44af1500, 0x44b0b300, 0x44b25100, 0x44b3ef00, 0x44b58d00, 0x44b72b00, 0x44b8c900, 0x44ba6700, 0x44bc0500, 0x44bda300, 0x44bf4100, 0x44c0df00, 0x44c27d00, 0x44c41b00, 0x44c5b900, 0x44c75700, 0x44c8f500, 0x44ca9300, 0x44cc3100, 0x44cdcf00, 0x44cf6d00, 0x44d10b00, 0x44d2a900, 0x44d44700, 0x44d5e500, 0x44d78300, 0x44d92100, 0x44dabf00, 0x44dc5d00, 0x44ddfb00, 0x44df9900, 0x44e13700, 0x44e2d500, 0x44e47300, 0x44e61100, 0x44e7af00, 0x44e94d00, 0x44eaeb00, 0x44ec8900, 0x44ee2700, 0x44efc500, 0x44f16300, 0x44f30100, 0x44f49f00, 0x44f63d00, 0x44f7db00, 0x44f97900, 0x44fb1700, 0x44fcb500, 0x44fe5300, 0x44fff100, 0x45018f00, 0x45032d00, 0x4504cb00, 0x45066900, 0x45080700, 0x4509a500, 0x450b4300, 0x450ce100, 0x450e7f00, 0x45101d00, 0x4511bb00, 0x45135900, 0x4514f700, 0x45169500, 0x45183300, 0x4519d100, 0x451b6f00, 0x451d0d00, 0x451eab00, 0x45204900, 0x4521e700, 0x45238500, 0x45252300, 0x4526c100, 0x45285f00, 0x4529fd00, 0x452b9b00, 0x452d3900, 0x452ed700, 0x45307500, 0x45321300, 0x4533b100, 0x45354f00, 0x4536ed00, 0x45388b00, 0x453a2900, 0x453bc700, 0x453d6500, 0x453f0300, 0x4540a100, 0x45423f00, 0x4543dd00, 0x45457b00, 0x45471900, 0x4548b700, 0x454a5500, 0x454bf300, 0x454d9100, 0x454f2f00, 0x4550cd00, 0x45526b00, 0x45540900, 0x4555a700, 0x45574500, 0x4558e300, 0x455a8100, 0x455c1f00, 0x455dbd00, 0x455f5b00, 0x4560f900, 0x45629700, 0x45643500, 0x4565d300, 0x45677100, 0x45690f00, 0x456aad00, 0x456c4b00, 0x456de900, 0x456f8700, 0x45712500, 0x4572c300, 0x45746100, 0x4575ff00, 0x4577e300, 0x4579c700, 0x457bab00, 0x457d8f00, 0x457f7300, 0x45815700, 0x45833b00, 0x45851f00, 0x45870300, 0x4588e700, 0x458acb00, 0x458caf00, 0x458e9300, 0x45907700, 0x45925b00, 0x45943f00, 0x45962300, 0x45980700, 0x4599eb00, 0x459bcf00, 0x459db300, 0x459f9700, 0x45a17b00, 0x45a35f00, 0x45a54300, 0x45a72700, 0x45a90b00, 0x45aaef00, 0x45acd300, 0x45aeb700, 0x45b09b00, 0x45b27f00, 0x45b46300, 0x45b64700, 0x45b82b00, 0x45ba0f00, 0x45bbf300, 0x45bdd700, 0x45bfbb00, 0x45c19f00, 0x45c38300, 0x45c56700, 0x45c74b00, 0x45c92f00, 0x45cb1300, 0x45ccf700, 0x45cedb00, 0x45d0bf00, 0x45d2a300, 0x45d48700, 0x45d66b00, 0x45d84f00, 0x45da3300, 0x45dc1700, 0x45ddfb00, 0x45dfdf00, 0x45e1c300, 0x45e3a700, 0x45e58b00, 0x45e76f00, 0x45e95300, 0x45eb3700, 0x45ed1b00, 0x45eeff00, 0x45f0e300, 0x45f2c700, 0x45f4ab00, 0x45f68f00, 0x45f87300, 0x45fa5700, 0x45fc3b00, 0x45fe1f00, 0x46000300, 0x4601e700, 0x4603cb00, 0x4605af00, 0x46079300, 0x46097700, 0x460b5b00, 0x460d3f00, 0x460f2300, 0x46110700, 0x4612eb00, 0x4614cf00, 0x4616b300, 0x46189700, 0x461a7b00, 0x461c5f00, 0x461e4300, 0x46202700, 0x46220b00, 0x4623ef00, 0x4625d300, 0x4627b700, 0x46299b00, 0x462b7f00, 0x462d6300, 0x462f4700, 0x46312b00, 0x46330f00, 0x4634f300, 0x4636d700, 0x4638bb00, 0x463a9f00, 0x463c8300, 0x463e6700, 0x46404b00, 0x46422f00, 0x46441300, 0x4645f700, 0x4647db00, 0x4649bf00, 0x464ba300, 0x464d8700, 0x464f6b00, 0x46514f00, 0x46533300, 0x46551700, 0x4656fb00, 0x4658df00, 0x465ac300, 0x465ca700, 0x465e8b00, 0x46606f00, 0x46625300, 0x46643700, 0x46661b00, 0x4667ff00, 0x4669e300, 0x466bc700, 0x466dab00, 0x466f8f00, 0x46717300, 0x46735700, 0x46753b00, 0x46771f00, 0x46790300, 0x467ae700, 0x467ccb00, 0x467eaf00, 0x46809300, 0x46827700, 0x46845b00, 0x46863f00, 0x46882300, 0x468a0700, 0x468beb00, 0x468dcf00, 0x468fb300, 0x46919700, 0x46937b00, 0x46955f00, 0x46974300, 0x46992700, 0x469b0b00, 0x469cef00, 0x469ed300, 0x46a0b700, 0x46a29b00, 0x46a47f00, 0x46a66300, 0x46a84700, 0x46aa2b00, 0x46ac0f00, 0x46adf300, 0x46afd700, 0x46b1bb00, 0x46b39f00, 0x46b58300, 0x46b76700, 0x46b94b00, 0x46bb2f00, 0x46bd1300, 0x46bef700, 0x46c0db00, 0x46c2bf00, 0x46c4a300, 0x46c68700, 0x46c86b00, 0x46ca4f00, 0x46cc3300, 0x46ce1700, 0x46cffb00, 0x46d1df00, 0x46d3c300, 0x46d5a700, 0x46d78b00, 0x46d96f00, 0x46db5300, 0x46dd3700, 0x46df1b00, 0x46e0ff00, 0x46e2e300, 0x46e4c700, 0x46e6ab00, 0x46e88f00, 0x46ea7300, 0x46ec5700, 0x46ee3b00, 0x46f01f00, 0x46f20300, 0x46f3e700, 0x46f5cb00, 0x46f7af00, 0x46f99300, 0x46fb7700, 0x46fd5b00, 0x46ff3f00, 0x47012300, 0x47030700, 0x4704eb00, 0x4706cf00, 0x4708b300, 0x470a9700, 0x470c7b00, 0x470e5f00, 0x47104300, 0x47122700, 0x47140b00, 0x4715ef00, 0x4717d300, 0x4719b700, 0x471b9b00, 0x471d7f00, 0x471f6300, 0x47214700, 0x47232b00, 0x47250f00, 0x4726f300, 0x4728d700, 0x472abb00, 0x472c9f00, 0x472e8300, 0x47306700, 0x47324b00, 0x47342f00, 0x47361300, 0x4737f700, 0x4739db00, 0x473bbf00, 0x473da300, 0x473f8700, 0x47416b00, 0x47434f00, 0x47453300, 0x47471700, 0x4748fb00, 0x474adf00, 0x474cc300, 0x474ea700, 0x47508b00, 0x47526f00, 0x47545300, 0x47563700, 0x47581b00, 0x4759ff00, 0x475c3f00, 0x475e7f00, 0x4760bf00, 0x4762ff00, 0x47653f00, 0x47677f00, 0x4769bf00, 0x476bff00, 0x476e3f00, 0x47707f00, 0x4772bf00, 0x4774ff00, 0x47773f00, 0x47797f00, 0x477bbf00, 0x477dff00, 0x47803f00, 0x47827f00, 0x4784bf00, 0x4786ff00, 0x47893f00, 0x478b7f00, 0x478dbf00, 0x478fff00, 0x47923f00, 0x47947f00, 0x4796bf00, 0x4798ff00, 0x479b3f00, 0x479d7f00, 0x479fbf00, 0x47a1ff00, 0x47a43f00, 0x47a67f00, 0x47a8bf00, 0x47aaff00, 0x47ad3f00, 0x47af7f00, 0x47b1bf00, 0x47b3ff00, 0x47b63f00, 0x47b87f00, 0x47babf00, 0x47bcff00, 0x47bf3f00, 0x47c17f00, 0x47c3bf00, 0x47c5ff00, 0x47c83f00, 0x47ca7f00, 0x47ccbf00, 0x47ceff00, 0x47d13f00, 0x47d37f00, 0x47d5bf00, 0x47d7ff00, 0x47da3f00, 0x47dc7f00, 0x47debf00, 0x47e0ff00, 0x47e33f00, 0x47e57f00, 0x47e7bf00, 0x47e9ff00, 0x47ec3f00, 0x47ee7f00, 0x47f0bf00, 0x47f2ff00, 0x47f53f00, 0x47f77f00, 0x47f9bf00, 0x47fbff00, 0x47fe3f00, 0x48007f00, 0x4802bf00, 0x4804ff00, 0x48073f00, 0x48097f00, 0x480bbf00, 0x480dff00, 0x48103f00, 0x48127f00, 0x4814bf00, 0x4816ff00, 0x48193f00, 0x481b7f00, 0x481dbf00, 0x481fff00, 0x48223f00, 0x48247f00, 0x4826bf00, 0x4828ff00, 0x482b3f00, 0x482d7f00, 0x482fbf00, 0x4831ff00, 0x48343f00, 0x48367f00, 0x4838bf00, 0x483aff00, 0x483d3f00, 0x483f7f00, 0x4841bf00, 0x4843ff00, 0x48463f00, 0x48487f00, 0x484abf00, 0x484cff00, 0x484f3f00, 0x48517f00, 0x4853bf00, 0x4855ff00, 0x48583f00, 0x485a7f00, 0x485cbf00, 0x485eff00, 0x48613f00, 0x48637f00, 0x4865bf00, 0x4867ff00, 0x486a3f00, 0x486c7f00, 0x486ebf00, 0x4870ff00, 0x48733f00, 0x48757f00, 0x4877bf00, 0x4879ff00, 0x487c3f00, 0x487e7f00, 0x4880bf00, 0x4882ff00, 0x48853f00, 0x48877f00, 0x4889bf00, 0x488bff00, 0x488e3f00, 0x48907f00, 0x4892bf00, 0x4894ff00, 0x48973f00, 0x48997f00, 0x489bbf00, 0x489dff00, 0x48a03f00, 0x48a27f00, 0x48a4bf00, 0x48a6ff00, 0x48a93f00, 0x48ab7f00, 0x48adbf00, 0x48afff00, 0x48b23f00, 0x48b47f00, 0x48b6bf00, 0x48b8ff00, 0x48bb3f00, 0x48bd7f00, 0x48bfbf00, 0x48c1ff00, 0x48c43f00, 0x48c67f00, 0x48c8bf00, 0x48caff00, 0x48cd3f00, 0x48cf7f00, 0x48d1bf00, 0x48d3ff00, 0x48d63f00, 0x48d87f00, 0x48dabf00, 0x48dcff00, 0x48df3f00, 0x48e17f00, 0x48e3bf00, 0x48e5ff00, 0x48e83f00, 0x48ea7f00, 0x48ecbf00, 0x48eeff00, 0x48f13f00, 0x48f37f00, 0x48f5bf00, 0x48f7ff00, 0x48fa3f00, 0x48fc7f00, 0x48febf00, 0x4900ff00, 0x49033f00, 0x49057f00, 0x4907bf00, 0x4909ff00, 0x490c3f00, 0x490e7f00, 0x4910bf00, 0x4912ff00, 0x49153f00, 0x49177f00, 0x4919bf00, 0x491bff00, 0x491e3f00, 0x49207f00, 0x4922bf00, 0x4924ff00, 0x49273f00, 0x49297f00, 0x492bbf00, 0x492dff00, 0x49303f00, 0x49327f00, 0x4934bf00, 0x4936ff00, 0x49393f00, 0x493b7f00, 0x493dbf00, 0x493fff00, 0x49423f00, 0x49447f00, 0x4946bf00, 0x4948ff00, 0x494b3f00, 0x494d7f00, 0x494fbf00, 0x4951ff00, 0x49543f00, 0x49567f00, 0x4958bf00, 0x495aff00, 0x495d3f00, 0x495f7f00, 0x4961bf00, 0x4963ff00, 0x49663f00, 0x49687f00, 0x496abf00, 0x496cff00, 0x496f3f00, 0x49717f00, 0x4973bf00, 0x4975ff00, 0x49783f00, 0x497a7f00, 0x497cbf00, 0x497eff00, 0x49813f00, 0x49837f00, 0x4985bf00, 0x4987ff00, 0x498a3f00, 0x498c7f00, 0x498ebf00, 0x4990ff00, 0x49933f00, 0x49957f00, 0x4997bf00, 0x4999ff00, 0x499cb300, 0x499f6700, 0x49a21b00, 0x49a4cf00, 0x49a78300, 0x49aa3700, 0x49aceb00, 0x49af9f00, 0x49b25300, 0x49b50700, 0x49b7bb00, 0x49ba6f00, 0x49bd2300, 0x49bfd700, 0x49c28b00, 0x49c53f00, 0x49c7f300, 0x49caa700, 0x49cd5b00, 0x49d00f00, 0x49d2c300, 0x49d57700, 0x49d82b00, 0x49dadf00, 0x49dd9300, 0x49e04700, 0x49e2fb00, 0x49e5af00, 0x49e86300, 0x49eb1700, 0x49edcb00, 0x49f07f00, 0x49f33300, 0x49f5e700, 0x49f89b00, 0x49fb4f00, 0x49fe0300, 0x4a00b700, 0x4a036b00, 0x4a061f00, 0x4a08d300, 0x4a0b8700, 0x4a0e3b00, 0x4a10ef00, 0x4a13a300, 0x4a165700, 0x4a190b00, 0x4a1bbf00, 0x4a1e7300, 0x4a212700, 0x4a23db00, 0x4a268f00, 0x4a294300, 0x4a2bf700, 0x4a2eab00, 0x4a315f00, 0x4a341300, 0x4a36c700, 0x4a397c00, 0x4a3c3000, 0x4a3ee400, 0x4a419800, 0x4a444c00, 0x4a470000, 0x4a49b400, 0x4a4c6800, 0x4a4f1c00, 0x4a51d000, 0x4a548400, 0x4a573800, 0x4a59ec00, 0x4a5ca000, 0x4a5f5400, 0x4a620800, 0x4a64bc00, 0x4a677000, 0x4a6a2400, 0x4a6cd800, 0x4a6f8c00, 0x4a724000, 0x4a74f400, 0x4a77a800, 0x4a7a5c00, 0x4a7d1000, 0x4a7fc400, 0x4a827800, 0x4a852c00, 0x4a87e000, 0x4a8a9400, 0x4a8d4800, 0x4a8ffc00, 0x4a92b000, 0x4a956400, 0x4a981800, 0x4a9acc00, 0x4a9d8000, 0x4aa03400, 0x4aa2e800, 0x4aa59c00, 0x4aa85000, 0x4aab0400, 0x4aadb800, 0x4ab06c00, 0x4ab32000, 0x4ab5d400, 0x4ab88800, 0x4abb3c00, 0x4abdf000, 0x4ac0a400, 0x4ac35800, 0x4ac60c00, 0x4ac8c000, 0x4acb7400, 0x4ace2800, 0x4ad0dc00, 0x4ad39000, 0x4ad64400, 0x4ad8f800, 0x4adbac00, 0x4ade6000, 0x4ae11400, 0x4ae3c800, 0x4ae67c00, 0x4ae93000, 0x4aebe400, 0x4aee9800, 0x4af14c00, 0x4af40000, 0x4af6cc00, 0x4af99800, 0x4afc6400, 0x4aff3000, 0x4b01fc00, 0x4b04c800, 0x4b079400, 0x4b0a6000, 0x4b0d2c00, 0x4b0ff800, 0x4b12c400, 0x4b159000, 0x4b185c00, 0x4b1b2800, 0x4b1df400, 0x4b20c000, 0x4b238c00, 0x4b265800, 0x4b292400, 0x4b2bf000, 0x4b2ebc00, 0x4b318800, 0x4b345400, 0x4b372000, 0x4b39ec00, 0x4b3cb800, 0x4b3f8400, 0x4b425000, 0x4b451c00, 0x4b47e800, 0x4b4ab400, 0x4b4d8000, 0x4b504c00, 0x4b531800, 0x4b55e400, 0x4b58b000, 0x4b5b7c00, 0x4b5e4800, 0x4b611400, 0x4b63e000, 0x4b66ac00, 0x4b697800, 0x4b6c4400, 0x4b6f1000, 0x4b71dc00, 0x4b74a800, 0x4b777400, 0x4b7a4000, 0x4b7d0c00, 0x4b7fd800, 0x4b82a400, 0x4b857000, 0x4b883c00, 0x4b8b0800, 0x4b8dd400, 0x4b90a000, 0x4b936c00, 0x4b963800, 0x4b990400, 0x4b9bd000, 0x4b9e9c00, 0x4ba16800, 0x4ba43400, 0x4ba70000, 0x4ba9cc00, 0x4bac9800, 0x4baf6400, 0x4bb23000, 0x4bb4fc00, 0x4bb7c700, 0x4bba9300, 0x4bbd5f00, 0x4bc02b00, 0x4bc2f700, 0x4bc5c300, 0x4bc88f00, 0x4bcb5b00, 0x4bce2700, 0x4bd0f300, 0x4bd3bf00, 0x4bd68b00, 0x4bd95700, 0x4bdc2300, 0x4bdeef00, 0x4be1bb00, 0x4be48700, 0x4be75300, 0x4bea1f00, 0x4beceb00, 0x4befb700, 0x4bf28300, 0x4bf54f00, 0x4bf81b00, 0x4bfae700, 0x4bfdb300, 0x4c007f00, 0x4c034b00, 0x4c061700, 0x4c08e300, 0x4c0baf00, 0x4c0e7b00, 0x4c114700, 0x4c141300, 0x4c16df00, 0x4c19ab00, 0x4c1c7700, 0x4c1f4300, 0x4c220f00, 0x4c24db00, 0x4c27a700, 0x4c2a7300, 0x4c2d3f00, 0x4c300b00, 0x4c32d700, 0x4c35a300, 0x4c386f00, 0x4c3b3b00, 0x4c3e0700, 0x4c40d300, 0x4c439f00, 0x4c466b00, 0x4c493700, 0x4c4c0300, 0x4c4ecf00, 0x4c519b00, 0x4c546700, 0x4c573300, 0x4c59ff00, 0x4c5d7700, 0x4c60ef00, 0x4c646700, 0x4c67df00, 0x4c6b5700, 0x4c6ecf00, 0x4c724700, 0x4c75bf00, 0x4c793700, 0x4c7caf00, 0x4c802700, 0x4c839f00, 0x4c871700, 0x4c8a8f00, 0x4c8e0700, 0x4c917f00, 0x4c94f700, 0x4c986f00, 0x4c9be700, 0x4c9f5f00, 0x4ca2d700, 0x4ca64f00, 0x4ca9c700, 0x4cad3f00, 0x4cb0b700, 0x4cb42f00, 0x4cb7a700, 0x4cbb1f00, 0x4cbe9700, 0x4cc20f00, 0x4cc58700, 0x4cc8ff00, 0x4ccc7700, 0x4ccfef00, 0x4cd36700, 0x4cd6df00, 0x4cda5700, 0x4cddcf00, 0x4ce14700, 0x4ce4bf00, 0x4ce83700, 0x4cebaf00, 0x4cef2700, 0x4cf29f00, 0x4cf61700, 0x4cf98f00, 0x4cfd0700, 0x4d007f00, 0x4d03f700, 0x4d076f00, 0x4d0ae700, 0x4d0e5f00, 0x4d11d700, 0x4d154f00, 0x4d18c700, 0x4d1c3f00, 0x4d1fb700, 0x4d232f00, 0x4d26a700, 0x4d2a1f00, 0x4d2d9700, 0x4d310f00, 0x4d348700, 0x4d37ff00, 0x4d3b7700, 0x4d3eef00, 0x4d426700, 0x4d45df00, 0x4d495700, 0x4d4ccf00, 0x4d504700, 0x4d53bf00, 0x4d573700, 0x4d5aaf00, 0x4d5e2700, 0x4d619f00, 0x4d651700, 0x4d688f00, 0x4d6c0700, 0x4d6f7f00, 0x4d72f700, 0x4d766f00, 0x4d79e700, 0x4d7d5f00, 0x4d80d700, 0x4d844f00, 0x4d87c700, 0x4d8b3f00, 0x4d8eb700, 0x4d922f00, 0x4d95a700, 0x4d991f00, 0x4d9c9700, 0x4da00f00, 0x4da38700, 0x4da6ff00, 0x4daa7700, 0x4dadef00, 0x4db16700, 0x4db4df00, 0x4db85700, 0x4dbbcf00, 0x4dbf4700, 0x4dc2bf00, 0x4dc63700, 0x4dc9af00, 0x4dcd2700, 0x4dd09f00, 0x4dd41700, 0x4dd78f00, 0x4ddb0700, 0x4dde7f00, 0x4de1f700, 0x4de56f00, 0x4de8e700, 0x4dec5f00, 0x4defd700, 0x4df34f00, 0x4df6c700, 0x4dfa3f00, 0x4dfdb700, 0x4e012f00, 0x4e04a700, 0x4e081f00, 0x4e0b9700, 0x4e0f0f00, 0x4e128700, 0x4e15ff00, 0x4e19ff00, 0x4e1dff00, 0x4e21ff00, 0x4e25ff00, 0x4e29ff00, 0x4e2dff00, 0x4e31ff00, 0x4e35ff00, 0x4e39ff00, 0x4e3dff00, 0x4e41ff00, 0x4e45ff00, 0x4e49ff00, 0x4e4dff00, 0x4e51ff00, 0x4e55ff00, 0x4e59ff00, 0x4e5dff00, 0x4e61ff00, 0x4e65ff00, 0x4e69ff00, 0x4e6dff00, 0x4e71ff00, 0x4e75ff00, 0x4e79ff00, 0x4e7dff00, 0x4e81ff00, 0x4e85ff00, 0x4e89ff00, 0x4e8dff00, 0x4e91ff00, 0x4e95ff00, 0x4e99ff00, 0x4e9dff00, 0x4ea1ff00, 0x4ea5ff00, 0x4ea9ff00, 0x4eadff00, 0x4eb1ff00, 0x4eb5ff00, 0x4eb9ff00, 0x4ebdff00, 0x4ec1ff00, 0x4ec5ff00, 0x4ec9ff00, 0x4ecdff00, 0x4ed1ff00, 0x4ed5ff00, 0x4ed9ff00, 0x4eddff00, 0x4ee1ff00, 0x4ee5ff00, 0x4ee9ff00, 0x4eedff00, 0x4ef1ff00, 0x4ef5ff00, 0x4ef9ff00, 0x4efdff00, 0x4f01ff00, 0x4f05ff00, 0x4f09ff00, 0x4f0dff00, 0x4f11ff00, 0x4f15ff00, 0x4f19ff00, 0x4f1dff00, 0x4f21ff00, 0x4f25ff00, 0x4f29ff00, 0x4f2dff00, 0x4f31ff00, 0x4f35ff00, 0x4f39ff00, 0x4f3dff00, 0x4f41ff00, 0x4f45ff00, 0x4f49ff00, 0x4f4dff00, 0x4f51ff00, 0x4f55ff00, 0x4f59ff00, 0x4f5dff00, 0x4f61ff00, 0x4f65ff00, 0x4f69ff00, 0x4f6dff00, 0x4f71ff00, 0x4f75ff00, 0x4f79ff00, 0x4f7dff00, 0x4f81ff00, 0x4f85ff00, 0x4f89ff00, 0x4f8dff00, 0x4f91ff00, 0x4f95ff00, 0x4f99ff00, 0x4f9dff00, 0x4fa1ff00, 0x4fa5ff00, 0x4fa9ff00, 0x4fadff00, 0x4fb1ff00, 0x4fb5ff00, 0x4fb9ff00, 0x4fbdff00, 0x4fc1ff00, 0x4fc5ff00, 0x4fc9ff00, 0x4fcdff00, 0x4fd1ff00, 0x4fd5ff00, 0x4fd9ff00, 0x4fddff00, 0x4fe1ff00, 0x4fe5ff00, 0x4fe9ff00, 0x4fedff00, 0x4ff1ff00, 0x4ff5ff00, 0x4ff9ff00, 0x4ffdff00, 0x5001ff00, 0x5005ff00, 0x5009ff00, 0x500dff00, 0x5011ff00, 0x5015ff00, 0x501a7700, 0x501eef00, 0x50236700, 0x5027df00, 0x502c5700, 0x5030cf00, 0x50354700, 0x5039bf00, 0x503e3700, 0x5042af00, 0x50472700, 0x504b9f00, 0x50501700, 0x50548f00, 0x50590700, 0x505d7f00, 0x5061f700, 0x50666f00, 0x506ae700, 0x506f5f00, 0x5073d700, 0x50785000, 0x507cc800, 0x50814000, 0x5085b800, 0x508a3000, 0x508ea800, 0x50932000, 0x50979800, 0x509c1000, 0x50a08800, 0x50a50000, 0x50a97800, 0x50adf000, 0x50b26800, 0x50b6e000, 0x50bb5800, 0x50bfd000, 0x50c44800, 0x50c8c000, 0x50cd3800, 0x50d1b000, 0x50d62800, 0x50daa000, 0x50df1800, 0x50e39000, 0x50e80800, 0x50ec8000, 0x50f0f800, 0x50f57000, 0x50f9e800, 0x50fe6000, 0x5102d800, 0x51075000, 0x510bc800, 0x51104000, 0x5114b800, 0x51193000, 0x511da800, 0x51222000, 0x51269800, 0x512b1000, 0x512f8800, 0x51340000, 0x51396800, 0x513ed000, 0x51443800, 0x5149a000, 0x514f0800, 0x51547000, 0x5159d800, 0x515f4000, 0x5164a800, 0x516a1000, 0x516f7800, 0x5174e000, 0x517a4800, 0x517fb000, 0x51851800, 0x518a8000, 0x518fe800, 0x51955000, 0x519ab800, 0x51a02000, 0x51a58800, 0x51aaf000, 0x51b05800, 0x51b5c000, 0x51bb2800, 0x51c09000, 0x51c5f800, 0x51cb6000, 0x51d0c800, 0x51d63000, 0x51db9800, 0x51e10000, 0x51e66800, 0x51ebd000, 0x51f13800, 0x51f6a000, 0x51fc0800, 0x52017000, 0x5206d800, 0x520c4000, 0x5211a800, 0x52171000, 0x521c7800, 0x5221e000, 0x52274800, 0x522cb000, 0x52321800, 0x52378000, 0x523ce800, 0x52425000, 0x5247b800, 0x524d2000, 0x52528800, 0x5257f000, 0x525d5800, 0x5262c000, 0x52682800, 0x526d9000, 0x5272f800, 0x52786000, 0x527dc800, 0x52833000, 0x52889800, 0x528e0000, 0x5293c000, 0x52998000, 0x529f4000, 0x52a50000, 0x52aac000, 0x52b08000, 0x52b64000, 0x52bc0000, 0x52c1bf00, 0x52c77f00, 0x52cd3f00, 0x52d2ff00, 0x52d8bf00, 0x52de7f00, 0x52e43f00, 0x52e9ff00, 0x52efbf00, 0x52f57f00, 0x52fb3f00, 0x5300ff00, 0x5306bf00, 0x530c7f00, 0x53123f00, 0x5317ff00, 0x531dbf00, 0x53237f00, 0x53293f00, 0x532eff00, 0x5334bf00, 0x533a7f00, 0x53403f00, 0x5345ff00, 0x534bbf00, 0x53517f00, 0x53573f00, 0x535cff00, 0x5362bf00, 0x53687f00, 0x536e3f00, 0x5373ff00, 0x5379bf00, 0x537f7f00, 0x53853f00, 0x538aff00, 0x5390bf00, 0x53967f00, 0x539c3f00, 0x53a1ff00, 0x53a7bf00, 0x53ad7f00, 0x53b33f00, 0x53b8ff00, 0x53bebf00, 0x53c47f00, 0x53ca3f00, 0x53cfff00, 0x53d5bf00, 0x53db7f00, 0x53e13f00, 0x53e6ff00, 0x53ecbf00, 0x53f27f00, 0x53f83f00, 0x53fdff00, 0x54055f00, 0x540cbf00, 0x54141f00, 0x541b7f00, 0x5422df00, 0x542a3f00, 0x54319f00, 0x5438ff00, 0x54405f00, 0x5447bf00, 0x544f1f00, 0x54567f00, 0x545ddf00, 0x54653f00, 0x546c9f00, 0x5473ff00, 0x547b5f00, 0x5482bf00, 0x548a1f00, 0x54917f00, 0x5498df00, 0x54a03f00, 0x54a79f00, 0x54aeff00, 0x54b65f00, 0x54bdbf00, 0x54c51f00, 0x54cc7f00, 0x54d3df00, 0x54db3f00, 0x54e29f00, 0x54e9ff00, 0x54f15f00, 0x54f8bf00, 0x55001f00, 0x55077f00, 0x550edf00, 0x55163f00, 0x551d9f00, 0x5524ff00, 0x552c5f00, 0x5533bf00, 0x553b1f00, 0x55427f00, 0x5549df00, 0x55513f00, 0x55589f00, 0x555fff00, 0x55675f00, 0x556ebf00, 0x55761f00, 0x557d7f00, 0x5584df00, 0x558c3f00, 0x55939f00, 0x559aff00, 0x55a25f00, 0x55a9bf00, 0x55b11f00, 0x55b87f00, 0x55bfdf00, 0x55c73f00, 0x55ce9f00, 0x55d5ff00, 0x55de9f00, 0x55e73f00, 0x55efdf00, 0x55f87f00, 0x56011f00, 0x5609bf00, 0x56125f00, 0x561aff00, 0x56239f00, 0x562c3f00, 0x5634df00, 0x563d7f00, 0x56461f00, 0x564ebf00, 0x56575f00, 0x565fff00, 0x56689f00, 0x56713f00, 0x5679df00, 0x56827f00, 0x568b1f00, 0x5693bf00, 0x569c5f00, 0x56a4ff00, 0x56ad9f00, 0x56b63f00, 0x56bedf00, 0x56c77f00, 0x56d01f00, 0x56d8bf00, 0x56e15f00, 0x56e9ff00, 0x56f29f00, 0x56fb3f00, 0x5703df00, 0x570c7f00, 0x57151f00, 0x571dbf00, 0x57265f00, 0x572eff00, 0x57379f00, 0x57403f00, 0x5748df00, 0x57517f00, 0x575a1f00, 0x5762bf00, 0x576b5f00, 0x5773ff00, 0x577c9f00, 0x57853f00, 0x578ddf00, 0x57967f00, 0x579f1f00, 0x57a7bf00, 0x57b05f00, 0x57b8ff00, 0x57c19f00, 0x57ca3f00, 0x57d2df00, 0x57db7f00, 0x57e41f00, 0x57ecbf00, 0x57f55f00, 0x57fdff00, 0x58087f00, 0x5812ff00, 0x581d7f00, 0x5827ff00, 0x58327f00, 0x583cff00, 0x58477f00, 0x5851ff00, 0x585c7f00, 0x5866ff00, 0x58717f00, 0x587bff00, 0x58867f00, 0x5890ff00, 0x589b7f00, 0x58a5ff00, 0x58b07f00, 0x58baff00, 0x58c57f00, 0x58cfff00, 0x58da7f00, 0x58e4ff00, 0x58ef7f00, 0x58f9ff00, 0x59047f00, 0x590eff00, 0x59197f00, 0x5923ff00, 0x592e7f00, 0x5938ff00, 0x59437f00, 0x594dff00, 0x59587f00, 0x5962ff00, 0x596d7f00, 0x5977ff00, 0x59827f00, 0x598cff00, 0x59977f00, 0x59a1ff00, 0x59ac7f00, 0x59b6ff00, 0x59c17f00, 0x59cbff00, 0x59d67f00, 0x59e0ff00, 0x59eb7f00, 0x59f5ff00, 0x5a007f00, 0x5a0aff00, 0x5a157f00, 0x5a1fff00, 0x5a2a7f00, 0x5a34ff00, 0x5a3f7f00, 0x5a49ff00, 0x5a547f00, 0x5a5eff00, 0x5a697f00, 0x5a73ff00, 0x5a7e7f00, 0x5a88ff00, 0x5a937f00, 0x5a9dff00, 0x5aaa0700, 0x5ab60f00, 0x5ac21700, 0x5ace1f00, 0x5ada2700, 0x5ae62f00, 0x5af23700, 0x5afe3f00, 0x5b0a4700, 0x5b164f00, 0x5b225700, 0x5b2e5f00, 0x5b3a6700, 0x5b466f00, 0x5b527700, 0x5b5e7f00, 0x5b6a8700, 0x5b768f00, 0x5b829700, 0x5b8e9f00, 0x5b9aa700, 0x5ba6af00, 0x5bb2b700, 0x5bbebf00, 0x5bcac700, 0x5bd6cf00, 0x5be2d700, 0x5beedf00, 0x5bfae700, 0x5c06ef00, 0x5c12f700, 0x5c1eff00, 0x5c2b0700, 0x5c370f00, 0x5c431700, 0x5c4f1f00, 0x5c5b2700, 0x5c672f00, 0x5c733700, 0x5c7f3f00, 0x5c8b4700, 0x5c974f00, 0x5ca35700, 0x5caf5f00, 0x5cbb6700, 0x5cc76f00, 0x5cd37700, 0x5cdf7f00, 0x5ceb8700, 0x5cf78f00, 0x5d039700, 0x5d0f9f00, 0x5d1ba700, 0x5d27af00, 0x5d33b700, 0x5d3fbf00, 0x5d4bc700, 0x5d57cf00, 0x5d63d700, 0x5d6fdf00, 0x5d7be700, 0x5d87ef00, 0x5d93f700, 0x5da00000, 0x5dac8000, 0x5db90000, 0x5dc58000, 0x5dd20000, 0x5dde8000, 0x5deb0000, 0x5df78000, 0x5e040000, 0x5e108000, 0x5e1d0000, 0x5e298000, 0x5e360000, 0x5e428000, 0x5e4f0000, 0x5e5b8000, 0x5e680000, 0x5e748000, 0x5e810000, 0x5e8d8000, 0x5e9a0000, 0x5ea68000, 0x5eb30000, 0x5ebf8000, 0x5ecc0000, 0x5ed88000, 0x5ee50000, 0x5ef18000, 0x5efe0000, 0x5f0a8000, 0x5f170000, 0x5f238000, 0x5f300000, 0x5f3c8000, 0x5f490000, 0x5f558000, 0x5f620000, 0x5f6e8000, 0x5f7b0000, 0x5f878000, 0x5f940000, 0x5fa08000, 0x5fad0000, 0x5fb98000, 0x5fc60000, 0x5fd28000, 0x5fdf0000, 0x5feb8000, 0x5ff80000, 0x60048000, 0x60110000, 0x601d8000, 0x602a0000, 0x60368000, 0x60430000, 0x604f8000, 0x605c0000, 0x60688000, 0x60750000, 0x60818000, 0x608e0000, 0x609a8000, 0x60a70000, 0x60b38000, 0x60c00000, 0x60cc8000, 0x60d90000, 0x60e58000, 0x60f20000, 0x60fe8000, 0x610b0000, 0x61178000, 0x61240000, 0x61308000, 0x613d0000, 0x61498000, 0x61560000, 0x61628000, 0x616f0000, 0x617b8000, 0x61880000, 0x61948000, 0x61a10000, 0x61ad8000, 0x61ba0000, 0x61c68000, 0x61d30000, 0x61df8000, 0x61ec0000, 0x61f88000, 0x62050000, 0x62118000, 0x621e0000, 0x622a8000, 0x62370000, 0x62438000, 0x62500000, 0x625c8000, 0x62690000, 0x62758000, 0x62820000, 0x628e8000, 0x629b0000, 0x62a78000, 0x62b40000, 0x62c08000, 0x62cd0000, 0x62d98000, 0x62e60000, 0x62f28000, 0x62ff0000, 0x630b8000, 0x63180000, 0x63248000, 0x63310000, 0x633d8000, 0x634a0000, 0x63568000, 0x63630000, 0x636f8000, 0x637c0000, 0x63888000, 0x63950000, 0x63a18000, 0x63ae0000, 0x63ba8000, 0x63c70000, 0x63d38000, 0x63e00000, 0x63ec8000, 0x63f90000, 0x64058000, 0x64120000, 0x641e8000, 0x642b0000, 0x64378000, 0x64440000, 0x64508000, 0x645d0000, 0x64698000, 0x64760000, 0x64828000, 0x648f0000, 0x649b8000, 0x64a80000, 0x64b48000, 0x64c10000, 0x64cd8000, 0x64da0000, 0x64e68000, 0x64f30000, 0x64ff8000, 0x650c0000, 0x65188000, 0x65250000, 0x65318000, 0x653e0000, 0x654a8000, 0x65570000, 0x65638000, 0x65700000, 0x657c8000, 0x65890000, 0x65958000, 0x65a20000, 0x65ae8000, 0x65bb0000, 0x65c78000, 0x65d40000, 0x65e08000, 0x65ed0000, 0x65f98000, 0x66060000, 0x66128000, 0x661f0000, 0x662b8000, 0x66380000, 0x66448000, 0x66510000, 0x665d8000, 0x666a0000, 0x66768000, 0x66830000, 0x668f8000, 0x669c0000, 0x66a88000, 0x66b50000, 0x66c18000, 0x66ce0000, 0x66da8000, 0x66e70000, 0x66f38000, 0x67000000, 0x670c8000, 0x67190000, 0x67258000, 0x67320000, 0x673e8000, 0x674b0000, 0x67578000, 0x67640000, 0x67708000, 0x677d0000, 0x67898000, 0x67960000, 0x67a28000, 0x67af0000, 0x67bb8000, 0x67c80000, 0x67d48000, 0x67e10000, 0x67ed8000, 0x67fa0000, 0x68068000, 0x68130000, 0x681f8000, 0x682c0000, 0x68388000, 0x68450000, 0x68518000, 0x685e0000, 0x686a8000, 0x68770000, 0x68838000, 0x68900000, 0x689c8000, 0x68a90000, 0x68b58000, 0x68c20000, 0x68ce8000, 0x68db0000, 0x68e78000, 0x68f40000, 0x69008000, 0x690d0000, 0x69198000, 0x69260000, 0x69328000, 0x693f0000, 0x694b8000, 0x69580000, 0x69648000, 0x69710000, 0x697d8000, 0x698a0000, 0x69968000, 0x69a30000, 0x69af8000, 0x69bc0000, 0x69c88000, 0x69d50000, 0x69e18000, 0x69ee0000, 0x69fa8000, 0x6a070000, 0x6a138000, 0x6a200000, 0x6a2c8000, 0x6a390000, 0x6a458000, 0x6a520000, 0x6a5e8000, 0x6a6b0000, 0x6a778000, 0x6a840000, 0x6a908000, 0x6a9d0000, 0x6aa98000, 0x6ab60000, 0x6ac28000, 0x6acf0000, 0x6adb8000, 0x6ae80000, 0x6af48000, 0x6b010000, 0x6b0d8000, 0x6b1a0000, 0x6b268000, 0x6b330000, 0x6b3f8000, 0x6b4c0000, 0x6b588000, 0x6b650000, 0x6b718000, 0x6b7e0000, 0x6b8a8000, 0x6b970000, 0x6ba38000, 0x6bb00000, 0x6bbc8000, 0x6bc90000, 0x6bd58000, 0x6be20000, 0x6bee8000, 0x6bfb0000, 0x6c078000, 0x6c140000, 0x6c208000, 0x6c2d0000, 0x6c398000, 0x6c460000, 0x6c528000, 0x6c5f0000, 0x6c6b8000, 0x6c780000, 0x6c848000, 0x6c910000, 0x6c9d8000, 0x6caa0000, 0x6cb68000, 0x6cc30000, 0x6ccf8000, 0x6cdc0000, 0x6ce88000, 0x6cf50000, 0x6d018000, 0x6d0e0000, 0x6d1a8000, 0x6d270000, 0x6d338000, 0x6d400000, 0x6d4c8000, 0x6d590000, 0x6d658000, 0x6d720000, 0x6d7e8000, 0x6d8b0000, 0x6d978000, 0x6da40000, 0x6db08000, 0x6dbd0000, 0x6dc98000, 0x6dd60000, 0x6de28000, 0x6def0000, 0x6dfb8000, 0x6e080000, 0x6e148000, 0x6e210000, 0x6e2d8000, 0x6e3a0000, 0x6e468000, 0x6e530000, 0x6e5f8000, 0x6e6c0000, 0x6e788000, 0x6e850000, 0x6e918000, 0x6e9e0000, 0x6eaa8000, 0x6eb70000, 0x6ec38000, 0x6ed00000, 0x6edc8000, 0x6ee90000, 0x6ef58000, 0x6f020000, 0x6f0e8000, 0x6f1b0000, 0x6f278000, 0x6f340000, 0x6f408000, 0x6f4d0000, 0x6f598000, 0x6f660000, 0x6f728000, 0x6f7f0000, 0x6f8b8000, 0x6f980000, 0x6fa48000, 0x6fb10000, 0x6fbd8000, 0x6fca0000, 0x6fd68000, 0x6fe30000, 0x6fef8000, 0x6ffc0000, 0x70088000, 0x70150000, 0x70218000, 0x702e0000, 0x703a8000, 0x70470000, 0x70538000, 0x70600000, 0x706c8000, 0x70790000, 0x70858000, 0x70920000, 0x709e8000, 0x70ab0000, 0x70b78000, 0x70c40000, 0x70d08000, 0x70dd0000, 0x70e98000, 0x70f60000, 0x71028000, 0x710f0000, 0x711b8000, 0x71280000, 0x71348000, 0x71410000, 0x714d8000, 0x715a0000, 0x71668000, 0x71730000, 0x717f8000, 0x718c0000, 0x71988000, 0x71a50000, 0x71b18000, 0x71be0000, 0x71ca8000, 0x71d70000, 0x71e38000, 0x71f00000, 0x71fc8000, 0x72090000, 0x72158000, 0x72220000, 0x722e8000, 0x723b0000, 0x72478000, 0x72540000, 0x72608000, 0x726d0000, 0x72798000, 0x72860000, 0x72928000, 0x729f0000, 0x72ab8000, 0x72b80000, 0x72c48000, 0x72d10000, 0x72dd8000, 0x72ea0000, 0x72f68000, 0x73030000, 0x730f8000, 0x731c0000, 0x73288000, 0x73350000, 0x73418000, 0x734e0000, 0x735a8000, 0x73670000, 0x73738000, 0x73800000, 0x738c8000, 0x73990000, 0x73a58000, 0x73b20000, 0x73be8000, 0x73cb0000, 0x73d78000, 0x73e40000, 0x73f08000, 0x73fd0000, 0x74098000, 0x74160000, 0x74228000, 0x742f0000, 0x743b8000, 0x74480000, 0x74548000, 0x74610000, 0x746d8000, 0x747a0000, 0x74868000, 0x74930000, 0x749f8000, 0x74ac0000, 0x74b88000, 0x74c50000, 0x74d18000, 0x74de0000, 0x74ea8000, 0x74f70000, 0x75038000, 0x75100000, 0x751c8000, 0x75290000, 0x75358000, 0x75420000, 0x754e8000, 0x755b0000, 0x75678000, 0x75740000, 0x75808000, 0x758d0000, 0x75998000, 0x75a60000, 0x75b28000, 0x75bf0000, 0x75cb8000, 0x75d80000, 0x75e48000, 0x75f10000, 0x75fd8000, 0x760a0000, 0x76168000, 0x76230000, 0x762f8000, 0x763c0000, 0x76488000, 0x76550000, 0x76618000, 0x766e0000, 0x767a8000, 0x76870000, 0x76938000, 0x76a00000, 0x76ac8000, 0x76b90000, 0x76c58000, 0x76d20000, 0x76de8000, 0x76eb0000, 0x76f78000, 0x77040000, 0x77108000, 0x771d0000, 0x77298000, 0x77360000, 0x77428000, 0x774f0000, 0x775b8000, 0x77680000, 0x77748000, 0x77810000, 0x778d8000, 0x779a0000, 0x77a68000, 0x77b30000, 0x77bf8000, 0x77cc0000, 0x77d88000, 0x77e50000, 0x77f18000, 0x77fe0000, 0x780a8000, 0x78170000, 0x78238000, 0x78300000, 0x783c8000, 0x78490000, 0x78558000, 0x78620000, 0x786e8000, 0x787b0000, 0x78878000, 0x78940000, 0x78a08000, 0x78ad0000, 0x78b98000, 0x78c60000, 0x78d28000, 0x78df0000, 0x78eb8000, 0x78f80000, 0x79048000, 0x79110000, 0x791d8000, 0x792a0000, 0x79368000, 0x79430000, 0x794f8000, 0x795c0000, 0x79688000, 0x79750000, 0x79818000, 0x798e0000, 0x799a8000, 0x79a70000, 0x79b38000, 0x79c00000, 0x79cc8000, 0x79d90000, 0x79e58000, 0x79f20000, 0x79fe8000, 0x7a0b0000, 0x7a178000, 0x7a240000, 0x7a308000, 0x7a3d0000, 0x7a498000, 0x7a560000, 0x7a628000, 0x7a6f0000, 0x7a7b8000, 0x7a880000, 0x7a948000, 0x7aa10000, 0x7aad8000, 0x7aba0000, 0x7ac68000, 0x7ad30000, 0x7adf8000, 0x7aec0000, 0x7af88000, 0x7b050000, 0x7b118000, 0x7b1e0000, 0x7b2a8000, 0x7b370000, 0x7b438000, 0x7b500000, 0x7b5c8000, 0x7b690000, 0x7b758000, 0x7b820000, 0x7b8e8000, 0x7b9b0000, 0x7ba78000, 0x7bb40000, 0x7bc08000, 0x7bcd0000, 0x7bd98000, 0x7be60000, 0x7bf28000, 0x7bff0000, 0x7c0b8000, 0x7c180000, 0x7c248000, 0x7c310000, 0x7c3d8000, 0x7c4a0000, 0x7c568000, 0x7c630000, 0x7c6f8000, 0x7c7c0000, 0x7c888000, 0x7c950000, 0x7ca18000, 0x7cae0000, 0x7cba8000, 0x7cc70000, 0x7cd38000, 0x7ce00000, 0x7cec8000, 0x7cf90000, 0x7d058000, 0x7d120000, 0x7d1e8000, 0x7d2b0000, 0x7d378000, 0x7d440000, 0x7d508000, 0x7d5d0000, 0x7d698000, 0x7d760000, 0x7d828000, 0x7d8f0000, 0x7d9b8000, 0x7da80000, 0x7db48000, 0x7dc10000, 0x7dcd8000, 0x7dda0000, 0x7de68000, 0x7df30000, 0x7dff8000, 0x7e0c0000, 0x7e188000, 0x7e250000, 0x7e318000, 0x7e3e0000, 0x7e4a8000, 0x7e570000, 0x7e638000, 0x7e700000, 0x7e7c8000, 0x7e890000, 0x7e958000, 0x7ea20000, 0x7eae8000, 0x7ebb0000, 0x7ec78000, 0x7ed40000, 0x7ee08000, 0x7eed0000, 0x7ef98000, 0x7f060000, 0x7f128000, 0x7f1f0000, 0x7f2b8000, 0x7f380000, 0x7f448000, 0x7f510000, 0x7f5d8000, 0x7f6a0000, 0x7f768000, 0x7f830000, 0x7f8f8000, 0x7f9c0000, 0x7fa88000, 0x7fb50000, 0x7fc18000, 0x7fce0000, 0x7fda8000, 0x7fe70000, 0x7ff38000, 0x80000000 }; static const int pe_max_asample = sizeof(peaktab) / sizeof(peaktab[0]) - 1; static const uint8_t readaheadtab[] = { 0x03, 0x02, 0x01, 0x01, 0x1f, 0x1e, 0x1f, 0x11, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x10, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x0f, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x0e, 0x19, 0x07, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1a, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x0d, 0x18, 0x20, 0x06, 0x1e, 0x1f, 0x12, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1a, 0x08, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x19, 0x1f, 0x13, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x09, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x1f, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1a, 0x14, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1c, 0x0a, 0x1e, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1b, 0x15, 0x1e, 0x1f, 0x1d, 0x0b, 0x1e, 0x1f, 0x1c, 0x16, 0x1e, 0x0c, 0x1d, 0x17, 0x1e, 0x1f, 0x20 }; // values between 0 and 1 multiplied by 2^23 to avoid floating point numbers. static const int32_t gaintab[] = { 0x800000, 0x7ff144, 0x7fe28a, 0x7fd3d2, 0x7fc51b, 0x7fb666, 0x7fa7b3, 0x7f9901, 0x7f8a52, 0x7f7ba3, 0x7f6cf7, 0x7f5e4c, 0x7f4fa3, 0x7f40fc, 0x7f3256, 0x7f23b2, 0x7f1510, 0x7f066f, 0x7ef7d0, 0x7ee933, 0x7eda97, 0x7ecbfd, 0x7ebd65, 0x7eaece, 0x7ea039, 0x7e91a6, 0x7e8315, 0x7e7485, 0x7e65f6, 0x7e576a, 0x7e48df, 0x7e3a56, 0x7e2bce, 0x7e1d49, 0x7e0ec5, 0x7e0042, 0x7df1c1, 0x7de342, 0x7dd4c5, 0x7dc649, 0x7db7cf, 0x7da956, 0x7d9adf, 0x7d8c6a, 0x7d7df7, 0x7d6f85, 0x7d6115, 0x7d52a6, 0x7d443a, 0x7d35ce, 0x7d2765, 0x7d18fd, 0x7d0a97, 0x7cfc32, 0x7cedd0, 0x7cdf6e, 0x7cd10f, 0x7cc2b1, 0x7cb455, 0x7ca5fa, 0x7c97a1, 0x7c894a, 0x7c7af4, 0x7c6ca0, 0x7c5e4e, 0x7c4ffd, 0x7c41ae, 0x7c3361, 0x7c2515, 0x7c16cb, 0x7c0882, 0x7bfa3b, 0x7bebf6, 0x7bddb3, 0x7bcf71, 0x7bc131, 0x7bb2f2, 0x7ba4b5, 0x7b967a, 0x7b8840, 0x7b7a08, 0x7b6bd2, 0x7b5d9d, 0x7b4f6a, 0x7b4138, 0x7b3308, 0x7b24da, 0x7b16ad, 0x7b0882, 0x7afa59, 0x7aec31, 0x7ade0b, 0x7acfe7, 0x7ac1c4, 0x7ab3a3, 0x7aa583, 0x7a9765, 0x7a8949, 0x7a7b2e, 0x7a6d15, 0x7a5efd, 0x7a50e8, 0x7a42d3, 0x7a34c1, 0x7a26b0, 0x7a18a0, 0x7a0a93, 0x79fc87, 0x79ee7c, 0x79e073, 0x79d26c, 0x79c466, 0x79b662, 0x79a860, 0x799a5f, 0x798c60, 0x797e62, 0x797066, 0x79626c, 0x795473, 0x79467c, 0x793886, 0x792a92, 0x791ca0, 0x790eaf, 0x7900c0, 0x78f2d3, 0x78e4e7, 0x78d6fc, 0x78c914, 0x78bb2d, 0x78ad47, 0x789f63, 0x789181, 0x7883a0, 0x7875c1, 0x7867e3, 0x785a07, 0x784c2d, 0x783e54, 0x78307d, 0x7822a8, 0x7814d4, 0x780701, 0x77f931, 0x77eb61, 0x77dd94, 0x77cfc8, 0x77c1fd, 0x77b434, 0x77a66d, 0x7798a8, 0x778ae3, 0x777d21, 0x776f60, 0x7761a1, 0x7753e3, 0x774627, 0x77386c, 0x772ab3, 0x771cfc, 0x770f46, 0x770192, 0x76f3df, 0x76e62e, 0x76d87e, 0x76cad0, 0x76bd24, 0x76af79, 0x76a1d0, 0x769428, 0x768682, 0x7678de, 0x766b3b, 0x765d99, 0x764ffa, 0x76425b, 0x7634bf, 0x762723, 0x76198a, 0x760bf2, 0x75fe5c, 0x75f0c7, 0x75e333, 0x75d5a2, 0x75c811, 0x75ba83, 0x75acf6, 0x759f6a, 0x7591e0, 0x758458, 0x7576d1, 0x75694c, 0x755bc8, 0x754e46, 0x7540c6, 0x753347, 0x7525c9, 0x75184d, 0x750ad3, 0x74fd5a, 0x74efe3, 0x74e26d, 0x74d4f9, 0x74c786, 0x74ba15, 0x74aca6, 0x749f38, 0x7491cb, 0x748460, 0x7476f7, 0x74698f, 0x745c29, 0x744ec4, 0x744161, 0x7433ff, 0x74269f, 0x741941, 0x740be4, 0x73fe88, 0x73f12e, 0x73e3d6, 0x73d67f, 0x73c92a, 0x73bbd6, 0x73ae84, 0x73a133, 0x7393e4, 0x738696, 0x73794a, 0x736bff, 0x735eb6, 0x73516f, 0x734429, 0x7336e4, 0x7329a1, 0x731c60, 0x730f20, 0x7301e1, 0x72f4a5, 0x72e769, 0x72da2f, 0x72ccf7, 0x72bfc0, 0x72b28b, 0x72a557, 0x729825, 0x728af4, 0x727dc5, 0x727098, 0x72636c, 0x725641, 0x724918, 0x723bf0, 0x722eca, 0x7221a6, 0x721482, 0x720761, 0x71fa41, 0x71ed22, 0x71e005, 0x71d2ea, 0x71c5d0, 0x71b8b7, 0x71aba0, 0x719e8b, 0x719177, 0x718465, 0x717754, 0x716a44, 0x715d36, 0x71502a, 0x71431f, 0x713615, 0x71290e, 0x711c07, 0x710f02, 0x7101ff, 0x70f4fd, 0x70e7fc, 0x70dafd, 0x70ce00, 0x70c104, 0x70b40a, 0x70a711, 0x709a19, 0x708d23, 0x70802f, 0x70733c, 0x70664a, 0x70595a, 0x704c6c, 0x703f7f, 0x703293, 0x7025a9, 0x7018c0, 0x700bd9, 0x6ffef4, 0x6ff20f, 0x6fe52d, 0x6fd84c, 0x6fcb6c, 0x6fbe8e, 0x6fb1b1, 0x6fa4d6, 0x6f97fc, 0x6f8b24, 0x6f7e4d, 0x6f7178, 0x6f64a4, 0x6f57d2, 0x6f4b01, 0x6f3e31, 0x6f3163, 0x6f2497, 0x6f17cc, 0x6f0b02, 0x6efe3a, 0x6ef174, 0x6ee4af, 0x6ed7eb, 0x6ecb29, 0x6ebe68, 0x6eb1a9, 0x6ea4eb, 0x6e982f, 0x6e8b74, 0x6e7ebb, 0x6e7203, 0x6e654c, 0x6e5897, 0x6e4be4, 0x6e3f32, 0x6e3281, 0x6e25d2, 0x6e1924, 0x6e0c78, 0x6dffcd, 0x6df324, 0x6de67c, 0x6dd9d6, 0x6dcd31, 0x6dc08e, 0x6db3ec, 0x6da74b, 0x6d9aac, 0x6d8e0e, 0x6d8172, 0x6d74d7, 0x6d683e, 0x6d5ba6, 0x6d4f10, 0x6d427b, 0x6d35e7, 0x6d2955, 0x6d1cc5, 0x6d1036, 0x6d03a8, 0x6cf71c, 0x6cea91, 0x6cde07, 0x6cd17f, 0x6cc4f9, 0x6cb874, 0x6cabf0, 0x6c9f6e, 0x6c92ed, 0x6c866e, 0x6c79f0, 0x6c6d74, 0x6c60f9, 0x6c547f, 0x6c4807, 0x6c3b91, 0x6c2f1b, 0x6c22a8, 0x6c1635, 0x6c09c4, 0x6bfd55, 0x6bf0e7, 0x6be47a, 0x6bd80f, 0x6bcba5, 0x6bbf3d, 0x6bb2d6, 0x6ba670, 0x6b9a0c, 0x6b8daa, 0x6b8148, 0x6b74e9, 0x6b688a, 0x6b5c2d, 0x6b4fd2, 0x6b4378, 0x6b371f, 0x6b2ac8, 0x6b1e72, 0x6b121d, 0x6b05ca, 0x6af979, 0x6aed29, 0x6ae0da, 0x6ad48d, 0x6ac841, 0x6abbf6, 0x6aafad, 0x6aa365, 0x6a971f, 0x6a8ada, 0x6a7e97, 0x6a7255, 0x6a6614, 0x6a59d5, 0x6a4d97, 0x6a415b, 0x6a3520, 0x6a28e6, 0x6a1cae, 0x6a1078, 0x6a0442, 0x69f80e, 0x69ebdc, 0x69dfab, 0x69d37b, 0x69c74d, 0x69bb20, 0x69aef4, 0x69a2ca, 0x6996a1, 0x698a7a, 0x697e54, 0x697230, 0x69660c, 0x6959eb, 0x694dca, 0x6941ab, 0x69358e, 0x692972, 0x691d57, 0x69113e, 0x690526, 0x68f90f, 0x68ecfa, 0x68e0e6, 0x68d4d4, 0x68c8c3, 0x68bcb3, 0x68b0a5, 0x68a498, 0x68988d, 0x688c83, 0x68807a, 0x687473, 0x68686d, 0x685c68, 0x685065, 0x684463, 0x683863, 0x682c64, 0x682066, 0x68146a, 0x68086f, 0x67fc76, 0x67f07d, 0x67e487, 0x67d891, 0x67cc9d, 0x67c0ab, 0x67b4ba, 0x67a8ca, 0x679cdb, 0x6790ee, 0x678502, 0x677918, 0x676d2f, 0x676147, 0x675561, 0x67497c, 0x673d99, 0x6731b7, 0x6725d6, 0x6719f7, 0x670e19, 0x67023c, 0x66f661, 0x66ea87, 0x66deae, 0x66d2d7, 0x66c701, 0x66bb2d, 0x66af59, 0x66a388, 0x6697b7, 0x668be8, 0x66801a, 0x66744e, 0x666883, 0x665cba, 0x6650f1, 0x66452a, 0x663965, 0x662da1, 0x6621de, 0x66161c, 0x660a5c, 0x65fe9e, 0x65f2e0, 0x65e724, 0x65db69, 0x65cfb0, 0x65c3f8, 0x65b841, 0x65ac8c, 0x65a0d8, 0x659525, 0x658974, 0x657dc4, 0x657216, 0x656668, 0x655abc, 0x654f12, 0x654369, 0x6537c1, 0x652c1a, 0x652075, 0x6514d1, 0x65092f, 0x64fd8d, 0x64f1ee, 0x64e64f, 0x64dab2, 0x64cf16, 0x64c37c, 0x64b7e3, 0x64ac4b, 0x64a0b4, 0x64951f, 0x64898b, 0x647df9, 0x647268, 0x6466d8, 0x645b49, 0x644fbc, 0x644430, 0x6438a6, 0x642d1d, 0x642195, 0x64160e, 0x640a89, 0x63ff05, 0x63f383, 0x63e802, 0x63dc82, 0x63d103, 0x63c586, 0x63ba0a, 0x63ae8f, 0x63a316, 0x63979e, 0x638c28, 0x6380b2, 0x63753e, 0x6369cc, 0x635e5a, 0x6352ea, 0x63477b, 0x633c0e, 0x6330a2, 0x632537, 0x6319ce, 0x630e66, 0x6302ff, 0x62f799, 0x62ec35, 0x62e0d2, 0x62d571, 0x62ca10, 0x62beb1, 0x62b354, 0x62a7f7, 0x629c9c, 0x629142, 0x6285ea, 0x627a93, 0x626f3d, 0x6263e9, 0x625895, 0x624d43, 0x6241f3, 0x6236a4, 0x622b56, 0x622009, 0x6214bd, 0x620973, 0x61fe2b, 0x61f2e3, 0x61e79d, 0x61dc58, 0x61d114, 0x61c5d2, 0x61ba91, 0x61af51, 0x61a413, 0x6198d6, 0x618d9a, 0x61825f, 0x617726, 0x616bee, 0x6160b7, 0x615582, 0x614a4e, 0x613f1b, 0x6133ea, 0x6128b9, 0x611d8a, 0x61125d, 0x610730, 0x60fc05, 0x60f0dc, 0x60e5b3, 0x60da8c, 0x60cf66, 0x60c441, 0x60b91e, 0x60adfc, 0x60a2db, 0x6097bc, 0x608c9d, 0x608180, 0x607665, 0x606b4a, 0x606031, 0x605519, 0x604a03, 0x603eed, 0x6033d9, 0x6028c7, 0x601db5, 0x6012a5, 0x600796, 0x5ffc88, 0x5ff17c, 0x5fe671, 0x5fdb67, 0x5fd05e, 0x5fc557, 0x5fba51, 0x5faf4c, 0x5fa449, 0x5f9947, 0x5f8e46, 0x5f8346, 0x5f7848, 0x5f6d4a, 0x5f624e, 0x5f5754, 0x5f4c5a, 0x5f4162, 0x5f366c, 0x5f2b76, 0x5f2082, 0x5f158f, 0x5f0a9d, 0x5effac, 0x5ef4bd, 0x5ee9cf, 0x5edee2, 0x5ed3f7, 0x5ec90c, 0x5ebe23, 0x5eb33c, 0x5ea855, 0x5e9d70, 0x5e928c, 0x5e87a9, 0x5e7cc8, 0x5e71e8, 0x5e6709, 0x5e5c2b, 0x5e514f, 0x5e4673, 0x5e3b99, 0x5e30c1, 0x5e25e9, 0x5e1b13, 0x5e103e, 0x5e056a, 0x5dfa98, 0x5defc7, 0x5de4f7, 0x5dda28, 0x5dcf5a, 0x5dc48e, 0x5db9c3, 0x5daef9, 0x5da431, 0x5d996a, 0x5d8ea4, 0x5d83df, 0x5d791b, 0x5d6e59, 0x5d6398, 0x5d58d8, 0x5d4e19, 0x5d435c, 0x5d38a0, 0x5d2de5, 0x5d232b, 0x5d1873, 0x5d0dbc, 0x5d0306, 0x5cf851, 0x5ced9d, 0x5ce2eb, 0x5cd83a, 0x5ccd8a, 0x5cc2dc, 0x5cb82e, 0x5cad82, 0x5ca2d7, 0x5c982e, 0x5c8d85, 0x5c82de, 0x5c7838, 0x5c6d93, 0x5c62f0, 0x5c584e, 0x5c4dad, 0x5c430d, 0x5c386e, 0x5c2dd1, 0x5c2334, 0x5c1899, 0x5c0e00, 0x5c0367, 0x5bf8d0, 0x5bee3a, 0x5be3a5, 0x5bd911, 0x5bce7f, 0x5bc3ee, 0x5bb95e, 0x5baecf, 0x5ba441, 0x5b99b5, 0x5b8f2a, 0x5b84a0, 0x5b7a17, 0x5b6f90, 0x5b6509, 0x5b5a84, 0x5b5000, 0x5b457e, 0x5b3afc, 0x5b307c, 0x5b25fd, 0x5b1b7f, 0x5b1103, 0x5b0687, 0x5afc0d, 0x5af194, 0x5ae71c, 0x5adca6, 0x5ad230, 0x5ac7bc, 0x5abd49, 0x5ab2d7, 0x5aa867, 0x5a9df7, 0x5a9389, 0x5a891c, 0x5a7eb1, 0x5a7446, 0x5a69dd, 0x5a5f74, 0x5a550d, 0x5a4aa8, 0x5a4043, 0x5a35e0, 0x5a2b7e, 0x5a211d, 0x5a16bd, 0x5a0c5e, 0x5a0201, 0x59f7a5, 0x59ed4a, 0x59e2f0, 0x59d897, 0x59ce40, 0x59c3e9, 0x59b994, 0x59af40, 0x59a4ee, 0x599a9c, 0x59904c, 0x5985fd, 0x597baf, 0x597162, 0x596717, 0x595ccc, 0x595283, 0x59483b, 0x593df4, 0x5933ae, 0x59296a, 0x591f27, 0x5914e5, 0x590aa4, 0x590064, 0x58f625, 0x58ebe8, 0x58e1ac, 0x58d771, 0x58cd37, 0x58c2fe, 0x58b8c7, 0x58ae90, 0x58a45b, 0x589a27, 0x588ff5, 0x5885c3, 0x587b93, 0x587163, 0x586735, 0x585d08, 0x5852dc, 0x5848b2, 0x583e88, 0x583460, 0x582a39, 0x582013, 0x5815ee, 0x580bcb, 0x5801a9, 0x57f787, 0x57ed67, 0x57e348, 0x57d92b, 0x57cf0e, 0x57c4f3, 0x57bad8, 0x57b0bf, 0x57a6a7, 0x579c91, 0x57927b, 0x578866, 0x577e53, 0x577441, 0x576a30, 0x576020, 0x575612, 0x574c04, 0x5741f8, 0x5737ed, 0x572de3, 0x5723da, 0x5719d2, 0x570fcc, 0x5705c6, 0x56fbc2, 0x56f1bf, 0x56e7bd, 0x56ddbc, 0x56d3bc, 0x56c9be, 0x56bfc1, 0x56b5c4, 0x56abc9, 0x56a1cf, 0x5697d7, 0x568ddf, 0x5683e9, 0x5679f3, 0x566fff, 0x56660c, 0x565c1a, 0x56522a, 0x56483a, 0x563e4c, 0x56345e, 0x562a72, 0x562087, 0x56169d, 0x560cb5, 0x5602cd, 0x55f8e7, 0x55ef01, 0x55e51d, 0x55db3a, 0x55d158, 0x55c777, 0x55bd98, 0x55b3b9, 0x55a9dc, 0x55a000, 0x559625, 0x558c4b, 0x558272, 0x55789a, 0x556ec4, 0x5564ee, 0x555b1a, 0x555147, 0x554775, 0x553da4, 0x5533d4, 0x552a06, 0x552038, 0x55166c, 0x550ca1, 0x5502d7, 0x54f90e, 0x54ef46, 0x54e57f, 0x54dbba, 0x54d1f5, 0x54c832, 0x54be6f, 0x54b4ae, 0x54aaee, 0x54a130, 0x549772, 0x548db5, 0x5483fa, 0x547a3f, 0x547086, 0x5466ce, 0x545d17, 0x545361, 0x5449ac, 0x543ff9, 0x543646, 0x542c95, 0x5422e4, 0x541935, 0x540f87, 0x5405da, 0x53fc2e, 0x53f283, 0x53e8da, 0x53df31, 0x53d58a, 0x53cbe4, 0x53c23e, 0x53b89a, 0x53aef7, 0x53a555, 0x539bb5, 0x539215, 0x538877, 0x537ed9, 0x53753d, 0x536ba2, 0x536208, 0x53586f, 0x534ed7, 0x534540, 0x533baa, 0x533216, 0x532882, 0x531ef0, 0x53155e, 0x530bce, 0x53023f, 0x52f8b1, 0x52ef24, 0x52e599, 0x52dc0e, 0x52d284, 0x52c8fc, 0x52bf74, 0x52b5ee, 0x52ac69, 0x52a2e5, 0x529962, 0x528fe0, 0x52865f, 0x527cdf, 0x527361, 0x5269e3, 0x526067, 0x5256eb, 0x524d71, 0x5243f8, 0x523a80, 0x523109, 0x522793, 0x521e1e, 0x5214ab, 0x520b38, 0x5201c6, 0x51f856, 0x51eee7, 0x51e578, 0x51dc0b, 0x51d29f, 0x51c934, 0x51bfca, 0x51b661, 0x51acf9, 0x51a393, 0x519a2d, 0x5190c9, 0x518765, 0x517e03, 0x5174a1, 0x516b41, 0x5161e2, 0x515884, 0x514f27, 0x5145cb, 0x513c70, 0x513317, 0x5129be, 0x512066, 0x511710, 0x510dba, 0x510466, 0x50fb13, 0x50f1c1, 0x50e86f, 0x50df1f, 0x50d5d0, 0x50cc82, 0x50c336, 0x50b9ea, 0x50b09f, 0x50a755, 0x509e0d, 0x5094c5, 0x508b7f, 0x50823a, 0x5078f5, 0x506fb2, 0x506670, 0x505d2f, 0x5053ef, 0x504ab0, 0x504172, 0x503835, 0x502ef9, 0x5025be, 0x501c85, 0x50134c, 0x500a15, 0x5000de, 0x4ff7a9, 0x4fee74, 0x4fe541, 0x4fdc0f, 0x4fd2de, 0x4fc9ae, 0x4fc07e, 0x4fb750, 0x4fae23, 0x4fa4f8, 0x4f9bcd, 0x4f92a3, 0x4f897a, 0x4f8053, 0x4f772c, 0x4f6e06, 0x4f64e2, 0x4f5bbe, 0x4f529c, 0x4f497b, 0x4f405a, 0x4f373b, 0x4f2e1d, 0x4f2500, 0x4f1be4, 0x4f12c9, 0x4f09af, 0x4f0096, 0x4ef77e, 0x4eee67, 0x4ee551, 0x4edc3c, 0x4ed328, 0x4eca16, 0x4ec104, 0x4eb7f3, 0x4eaee4, 0x4ea5d5, 0x4e9cc8, 0x4e93bc, 0x4e8ab0, 0x4e81a6, 0x4e789c, 0x4e6f94, 0x4e668d, 0x4e5d87, 0x4e5482, 0x4e4b7e, 0x4e427a, 0x4e3978, 0x4e3077, 0x4e2777, 0x4e1e79, 0x4e157b, 0x4e0c7e, 0x4e0382, 0x4dfa87, 0x4df18d, 0x4de895, 0x4ddf9d, 0x4dd6a6, 0x4dcdb1, 0x4dc4bc, 0x4dbbc9, 0x4db2d6, 0x4da9e5, 0x4da0f4, 0x4d9805, 0x4d8f16, 0x4d8629, 0x4d7d3c, 0x4d7451, 0x4d6b67, 0x4d627e, 0x4d5995, 0x4d50ae, 0x4d47c8, 0x4d3ee3, 0x4d35ff, 0x4d2d1b, 0x4d2439, 0x4d1b58, 0x4d1278, 0x4d0999, 0x4d00bb, 0x4cf7de, 0x4cef02, 0x4ce627, 0x4cdd4d, 0x4cd474, 0x4ccb9c, 0x4cc2c5, 0x4cb9f0, 0x4cb11b, 0x4ca847, 0x4c9f74, 0x4c96a2, 0x4c8dd1, 0x4c8502, 0x4c7c33, 0x4c7365, 0x4c6a98, 0x4c61cd, 0x4c5902, 0x4c5038, 0x4c4770, 0x4c3ea8, 0x4c35e1, 0x4c2d1c, 0x4c2457, 0x4c1b93, 0x4c12d1, 0x4c0a0f, 0x4c014f, 0x4bf88f, 0x4befd0, 0x4be713, 0x4bde56, 0x4bd59b, 0x4bcce0, 0x4bc426, 0x4bbb6e, 0x4bb2b6, 0x4baa00, 0x4ba14a, 0x4b9896, 0x4b8fe2, 0x4b8730, 0x4b7e7e, 0x4b75cd, 0x4b6d1e, 0x4b646f, 0x4b5bc2, 0x4b5315, 0x4b4a6a, 0x4b41bf, 0x4b3916, 0x4b306d, 0x4b27c6, 0x4b1f1f, 0x4b1679, 0x4b0dd5, 0x4b0531, 0x4afc8f, 0x4af3ed, 0x4aeb4c, 0x4ae2ad, 0x4ada0e, 0x4ad171, 0x4ac8d4, 0x4ac038, 0x4ab79e, 0x4aaf04, 0x4aa66b, 0x4a9dd4, 0x4a953d, 0x4a8ca7, 0x4a8413, 0x4a7b7f, 0x4a72ec, 0x4a6a5a, 0x4a61ca, 0x4a593a, 0x4a50ab, 0x4a481d, 0x4a3f91, 0x4a3705, 0x4a2e7a, 0x4a25f0, 0x4a1d67, 0x4a14df, 0x4a0c58, 0x4a03d2, 0x49fb4d, 0x49f2c9, 0x49ea46, 0x49e1c4, 0x49d943, 0x49d0c3, 0x49c844, 0x49bfc6, 0x49b749, 0x49aecd, 0x49a652, 0x499dd7, 0x49955e, 0x498ce6, 0x49846f, 0x497bf8, 0x497383, 0x496b0f, 0x49629b, 0x495a29, 0x4951b8, 0x494947, 0x4940d8, 0x493869, 0x492ffc, 0x49278f, 0x491f23, 0x4916b9, 0x490e4f, 0x4905e6, 0x48fd7f, 0x48f518, 0x48ecb2, 0x48e44d, 0x48dbe9, 0x48d386, 0x48cb25, 0x48c2c4, 0x48ba64, 0x48b205, 0x48a9a6, 0x48a149, 0x4898ed, 0x489092, 0x488838, 0x487fdf, 0x487786, 0x486f2f, 0x4866d8, 0x485e83, 0x48562f, 0x484ddb, 0x484589, 0x483d37, 0x4834e6, 0x482c97, 0x482448, 0x481bfa, 0x4813ad, 0x480b62, 0x480317, 0x47facd, 0x47f284, 0x47ea3c, 0x47e1f5, 0x47d9ae, 0x47d169, 0x47c925, 0x47c0e2, 0x47b89f, 0x47b05e, 0x47a81e, 0x479fde, 0x4797a0, 0x478f62, 0x478725, 0x477eea, 0x4776af, 0x476e75, 0x47663c, 0x475e05, 0x4755ce, 0x474d98, 0x474563, 0x473d2f, 0x4734fb, 0x472cc9, 0x472498, 0x471c68, 0x471438, 0x470c0a, 0x4703dc, 0x46fbb0, 0x46f384, 0x46eb59, 0x46e330, 0x46db07, 0x46d2df, 0x46cab8, 0x46c292, 0x46ba6d, 0x46b249, 0x46aa26, 0x46a203, 0x4699e2, 0x4691c2, 0x4689a2, 0x468184, 0x467966, 0x46714a, 0x46692e, 0x466113, 0x4658f9, 0x4650e0, 0x4648c9, 0x4640b1, 0x46389b, 0x463086, 0x462872, 0x46205f, 0x46184c, 0x46103b, 0x46082a, 0x46001b, 0x45f80c, 0x45effe, 0x45e7f2, 0x45dfe6, 0x45d7db, 0x45cfd1, 0x45c7c8, 0x45bfbf, 0x45b7b8, 0x45afb2, 0x45a7ac, 0x459fa8, 0x4597a4, 0x458fa2, 0x4587a0, 0x457f9f, 0x45779f, 0x456fa0, 0x4567a2, 0x455fa5, 0x4557a9, 0x454fae, 0x4547b3, 0x453fba, 0x4537c1, 0x452fca, 0x4527d3, 0x451fdd, 0x4517e8, 0x450ff5, 0x450802, 0x45000f, 0x44f81e, 0x44f02e, 0x44e83f, 0x44e050, 0x44d863, 0x44d076, 0x44c88a, 0x44c09f, 0x44b8b6, 0x44b0cd, 0x44a8e4, 0x44a0fd, 0x449917, 0x449132, 0x44894d, 0x44816a, 0x447987, 0x4471a5, 0x4469c5, 0x4461e5, 0x445a06, 0x445228, 0x444a4b, 0x44426e, 0x443a93, 0x4432b8, 0x442adf, 0x442306, 0x441b2e, 0x441358, 0x440b82, 0x4403ad, 0x43fbd8, 0x43f405, 0x43ec33, 0x43e461, 0x43dc91, 0x43d4c1, 0x43ccf3, 0x43c525, 0x43bd58, 0x43b58c, 0x43adc1, 0x43a5f6, 0x439e2d, 0x439664, 0x438e9d, 0x4386d6, 0x437f10, 0x43774c, 0x436f88, 0x4367c5, 0x436002, 0x435841, 0x435081, 0x4348c1, 0x434102, 0x433945, 0x433188, 0x4329cc, 0x432211, 0x431a57, 0x43129d, 0x430ae5, 0x43032e, 0x42fb77, 0x42f3c1, 0x42ec0c, 0x42e458, 0x42dca5, 0x42d4f3, 0x42cd42, 0x42c591, 0x42bde2, 0x42b633, 0x42ae85, 0x42a6d9, 0x429f2d, 0x429781, 0x428fd7, 0x42882e, 0x428085, 0x4278de, 0x427137, 0x426991, 0x4261ec, 0x425a48, 0x4252a5, 0x424b03, 0x424361, 0x423bc1, 0x423421, 0x422c82, 0x4224e5, 0x421d48, 0x4215ab, 0x420e10, 0x420676, 0x41fedc, 0x41f744, 0x41efac, 0x41e815, 0x41e07f, 0x41d8ea, 0x41d155, 0x41c9c2, 0x41c22f, 0x41ba9e, 0x41b30d, 0x41ab7d, 0x41a3ee, 0x419c60, 0x4194d2, 0x418d46, 0x4185ba, 0x417e30, 0x4176a6, 0x416f1d, 0x416795, 0x41600d, 0x415887, 0x415102, 0x41497d, 0x4141f9, 0x413a76, 0x4132f4, 0x412b73, 0x4123f3, 0x411c73, 0x4114f5, 0x410d77, 0x4105fa, 0x40fe7e, 0x40f703, 0x40ef89, 0x40e80f, 0x40e097, 0x40d91f, 0x40d1a8, 0x40ca32, 0x40c2bd, 0x40bb49, 0x40b3d5, 0x40ac63, 0x40a4f1, 0x409d80, 0x409610, 0x408ea1, 0x408733, 0x407fc5, 0x407859, 0x4070ed, 0x406982, 0x406218, 0x405aaf, 0x405347, 0x404bdf, 0x404479, 0x403d13, 0x4035ae, 0x402e4a, 0x4026e7, 0x401f85, 0x401823, 0x4010c3, 0x400963, 0x400204, 0x3ffaa6, 0x3ff348, 0x3febec, 0x3fe490, 0x3fdd36, 0x3fd5dc, 0x3fce83, 0x3fc72b, 0x3fbfd3, 0x3fb87d, 0x3fb127, 0x3fa9d3, 0x3fa27f, 0x3f9b2c, 0x3f93d9, 0x3f8c88, 0x3f8537, 0x3f7de8, 0x3f7699, 0x3f6f4b, 0x3f67fd, 0x3f60b1, 0x3f5966, 0x3f521b, 0x3f4ad1, 0x3f4388, 0x3f3c40, 0x3f34f9, 0x3f2db2, 0x3f266c, 0x3f1f28, 0x3f17e4, 0x3f10a1, 0x3f095e, 0x3f021d, 0x3efadc, 0x3ef39c, 0x3eec5d, 0x3ee51f, 0x3edde2, 0x3ed6a6, 0x3ecf6a, 0x3ec82f, 0x3ec0f5, 0x3eb9bc, 0x3eb284, 0x3eab4c, 0x3ea416, 0x3e9ce0, 0x3e95ab, 0x3e8e77, 0x3e8743, 0x3e8011, 0x3e78df, 0x3e71ae, 0x3e6a7e, 0x3e634f, 0x3e5c21, 0x3e54f3, 0x3e4dc7, 0x3e469b, 0x3e3f70, 0x3e3845, 0x3e311c, 0x3e29f3, 0x3e22cc, 0x3e1ba5, 0x3e147f, 0x3e0d59, 0x3e0635, 0x3dff11, 0x3df7ef, 0x3df0cd, 0x3de9ab, 0x3de28b, 0x3ddb6b, 0x3dd44d, 0x3dcd2f, 0x3dc612, 0x3dbef6, 0x3db7da, 0x3db0c0, 0x3da9a6, 0x3da28d, 0x3d9b75, 0x3d945d, 0x3d8d47, 0x3d8631, 0x3d7f1c, 0x3d7808, 0x3d70f5, 0x3d69e2, 0x3d62d1, 0x3d5bc0, 0x3d54b0, 0x3d4da1, 0x3d4692, 0x3d3f85, 0x3d3878, 0x3d316c, 0x3d2a61, 0x3d2356, 0x3d1c4d, 0x3d1544, 0x3d0e3c, 0x3d0735, 0x3d002f, 0x3cf929, 0x3cf225, 0x3ceb21, 0x3ce41e, 0x3cdd1c, 0x3cd61a, 0x3ccf1a, 0x3cc81a, 0x3cc11b, 0x3cba1c, 0x3cb31f, 0x3cac22, 0x3ca527, 0x3c9e2c, 0x3c9731, 0x3c9038, 0x3c893f, 0x3c8248, 0x3c7b51, 0x3c745b, 0x3c6d65, 0x3c6671, 0x3c5f7d, 0x3c588a, 0x3c5198, 0x3c4aa6, 0x3c43b6, 0x3c3cc6, 0x3c35d7, 0x3c2ee9, 0x3c27fb, 0x3c210f, 0x3c1a23, 0x3c1338, 0x3c0c4e, 0x3c0564, 0x3bfe7c, 0x3bf794, 0x3bf0ad, 0x3be9c7, 0x3be2e1, 0x3bdbfd, 0x3bd519, 0x3bce36, 0x3bc753, 0x3bc072, 0x3bb991, 0x3bb2b1, 0x3babd2, 0x3ba4f4, 0x3b9e17, 0x3b973a, 0x3b905e, 0x3b8983, 0x3b82a8, 0x3b7bcf, 0x3b74f6, 0x3b6e1e, 0x3b6747, 0x3b6070, 0x3b599b, 0x3b52c6, 0x3b4bf2, 0x3b451f, 0x3b3e4c, 0x3b377b, 0x3b30aa, 0x3b29da, 0x3b230a, 0x3b1c3c, 0x3b156e, 0x3b0ea1, 0x3b07d5, 0x3b0109, 0x3afa3f, 0x3af375, 0x3aecac, 0x3ae5e3, 0x3adf1c, 0x3ad855, 0x3ad18f, 0x3acaca, 0x3ac406, 0x3abd42, 0x3ab67f, 0x3aafbd, 0x3aa8fc, 0x3aa23b, 0x3a9b7c, 0x3a94bd, 0x3a8dfe, 0x3a8741, 0x3a8084, 0x3a79c9, 0x3a730d, 0x3a6c53, 0x3a659a, 0x3a5ee1, 0x3a5829, 0x3a5172, 0x3a4abb, 0x3a4406, 0x3a3d51, 0x3a369d, 0x3a2fe9, 0x3a2937, 0x3a2285, 0x3a1bd4, 0x3a1524, 0x3a0e74, 0x3a07c5, 0x3a0118, 0x39fa6a, 0x39f3be, 0x39ed12, 0x39e667, 0x39dfbd, 0x39d914, 0x39d26b, 0x39cbc4, 0x39c51d, 0x39be76, 0x39b7d1, 0x39b12c, 0x39aa88, 0x39a3e5, 0x399d42, 0x3996a1, 0x399000, 0x398960, 0x3982c0, 0x397c22, 0x397584, 0x396ee7, 0x39684a, 0x3961af, 0x395b14, 0x39547a, 0x394de0, 0x394748, 0x3940b0, 0x393a19, 0x393383, 0x392ced, 0x392658, 0x391fc4, 0x391931, 0x39129f, 0x390c0d, 0x39057c, 0x38feec, 0x38f85c, 0x38f1ce, 0x38eb40, 0x38e4b2, 0x38de26, 0x38d79a, 0x38d10f, 0x38ca85, 0x38c3fc, 0x38bd73, 0x38b6eb, 0x38b064, 0x38a9de, 0x38a358, 0x389cd3, 0x38964f, 0x388fcb, 0x388949, 0x3882c7, 0x387c46, 0x3875c5, 0x386f45, 0x3868c7, 0x386248, 0x385bcb, 0x38554e, 0x384ed2, 0x384857, 0x3841dd, 0x383b63, 0x3834ea, 0x382e72, 0x3827fa, 0x382184, 0x381b0e, 0x381498, 0x380e24, 0x3807b0, 0x38013d, 0x37facb, 0x37f459, 0x37ede9, 0x37e778, 0x37e109, 0x37da9b, 0x37d42d, 0x37cdc0, 0x37c753, 0x37c0e8, 0x37ba7d, 0x37b413, 0x37ada9, 0x37a741, 0x37a0d9, 0x379a72, 0x37940b, 0x378da6, 0x378741, 0x3780dc, 0x377a79, 0x377416, 0x376db4, 0x376753, 0x3760f2, 0x375a93, 0x375433, 0x374dd5, 0x374777, 0x37411b, 0x373abe, 0x373463, 0x372e08, 0x3727ae, 0x372155, 0x371afd, 0x3714a5, 0x370e4e, 0x3707f8, 0x3701a2, 0x36fb4d, 0x36f4f9, 0x36eea6, 0x36e853, 0x36e201, 0x36dbb0, 0x36d55f, 0x36cf10, 0x36c8c1, 0x36c272, 0x36bc25, 0x36b5d8, 0x36af8c, 0x36a940, 0x36a2f6, 0x369cac, 0x369663, 0x36901a, 0x3689d2, 0x36838b, 0x367d45, 0x3676ff, 0x3670ba, 0x366a76, 0x366433, 0x365df0, 0x3657ae, 0x36516d, 0x364b2c, 0x3644ec, 0x363ead, 0x36386f, 0x363231, 0x362bf4, 0x3625b8, 0x361f7c, 0x361942, 0x361308, 0x360cce, 0x360695, 0x36005e, 0x35fa26 }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/000077500000000000000000000000001516712004000227475ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/Makefile000077500000000000000000000012271516712004000244140ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = resample TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o resample.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/config.cpp000077500000000000000000000074131516712004000247300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureResample::ConfigID = "Resample"; BoCA::ConfigureResample::ConfigureResample() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Resample"); group_converter = new GroupBox(i18n->TranslateString("Converter"), Point(7, 11), Size(480, 59)); group_samplerate = new GroupBox(i18n->TranslateString("Output sampling rate"), Point(7, 82), Size(480, 43)); text_converter = new Text(i18n->AddColon(i18n->TranslateString("Converter")), Point(17, 27)); combo_converter = new ComboBox(Point(24 + text_converter->GetUnscaledTextWidth(), 24), Size(453 - text_converter->GetUnscaledTextWidth(), 0)); for (Int i = 0; true; i++) { String name = ex_src_get_name(i); if (name == NIL) break; combo_converter->AddEntry(name); } combo_converter->SelectNthEntry(config->GetIntValue(ConfigID, "Converter", SRC_SINC_MEDIUM_QUALITY) - SRC_SINC_BEST_QUALITY); combo_converter->onSelectEntry.Connect(&ConfigureResample::SetConverter, this); text_description = new Text(NIL, Point(24 + text_converter->GetUnscaledTextWidth(), 49)); text_samplerate = new Text(i18n->AddColon(i18n->TranslateString("Sampling rate")), Point(17, 98)); edit_samplerate = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "Samplerate", 44100)), Point(24 + text_samplerate->GetUnscaledTextWidth(), 95), Size(70, 0), 6); edit_samplerate->SetFlags(EDB_NUMERIC); list_samplerate = new ListBox(Point(24 + text_samplerate->GetUnscaledTextWidth(), 95), Size(70, 0)); list_samplerate->AddEntry( "8000"); list_samplerate->AddEntry( "11025"); list_samplerate->AddEntry( "12000"); list_samplerate->AddEntry( "16000"); list_samplerate->AddEntry( "22050"); list_samplerate->AddEntry( "24000"); list_samplerate->AddEntry( "32000"); list_samplerate->AddEntry( "44100"); list_samplerate->AddEntry( "48000"); list_samplerate->AddEntry( "64000"); list_samplerate->AddEntry( "88200"); list_samplerate->AddEntry( "96000"); list_samplerate->AddEntry("128000"); list_samplerate->AddEntry("176400"); list_samplerate->AddEntry("192000"); list_samplerate->AddEntry("256000"); list_samplerate->AddEntry("352800"); list_samplerate->AddEntry("384000"); edit_samplerate->SetDropDownList(list_samplerate); SetConverter(); Add(group_converter); Add(text_converter); Add(combo_converter); Add(text_description); Add(group_samplerate); Add(text_samplerate); Add(edit_samplerate); SetSize(Size(494, 132)); } BoCA::ConfigureResample::~ConfigureResample() { DeleteObject(group_converter); DeleteObject(text_converter); DeleteObject(combo_converter); DeleteObject(text_description); DeleteObject(group_samplerate); DeleteObject(text_samplerate); DeleteObject(edit_samplerate); DeleteObject(list_samplerate); } Int BoCA::ConfigureResample::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Converter", combo_converter->GetSelectedEntryNumber() + SRC_SINC_BEST_QUALITY); config->SetIntValue(ConfigID, "Samplerate", edit_samplerate->GetText().ToInt()); return Success(); } Void BoCA::ConfigureResample::SetConverter() { text_description->SetText(ex_src_get_description(combo_converter->GetSelectedEntryNumber())); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/config.h000077500000000000000000000023321516712004000243700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_RESAMPLECONFIG #define H_RESAMPLECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureResample : public ConfigLayer { private: GroupBox *group_converter; Text *text_converter; ComboBox *combo_converter; Text *text_description; GroupBox *group_samplerate; Text *text_samplerate; EditBox *edit_samplerate; List *list_samplerate; slots: Void SetConverter(); public: static const String ConfigID; ConfigureResample(); ~ConfigureResample(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/dllinterface.cpp000077500000000000000000000033711516712004000261160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" SRC_NEW ex_src_new = NIL; SRC_DELETE ex_src_delete = NIL; SRC_PROCESS ex_src_process = NIL; SRC_GET_NAME ex_src_get_name = NIL; SRC_GET_DESCRIPTION ex_src_get_description = NIL; SRC_STRERROR ex_src_strerror = NIL; DynamicLoader *srcdll = NIL; Bool LoadSRCDLL() { srcdll = BoCA::Utilities::LoadCodecDLL("samplerate"); if (srcdll == NIL) return False; ex_src_new = (SRC_NEW) srcdll->GetFunctionAddress("src_new"); ex_src_delete = (SRC_DELETE) srcdll->GetFunctionAddress("src_delete"); ex_src_process = (SRC_PROCESS) srcdll->GetFunctionAddress("src_process"); ex_src_get_name = (SRC_GET_NAME) srcdll->GetFunctionAddress("src_get_name"); ex_src_get_description = (SRC_GET_DESCRIPTION) srcdll->GetFunctionAddress("src_get_description"); ex_src_strerror = (SRC_STRERROR) srcdll->GetFunctionAddress("src_strerror"); if (ex_src_new == NIL || ex_src_delete == NIL || ex_src_process == NIL || ex_src_get_name == NIL || ex_src_get_description == NIL || ex_src_strerror == NIL) { FreeSRCDLL(); return False; } return True; } Void FreeSRCDLL() { BoCA::Utilities::FreeCodecDLL(srcdll); srcdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/dllinterface.h000077500000000000000000000024121516712004000255560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *srcdll; Bool LoadSRCDLL(); Void FreeSRCDLL(); typedef SRC_STATE * (*SRC_NEW) (int, int, int *); typedef SRC_STATE * (*SRC_DELETE) (SRC_STATE *); typedef int (*SRC_PROCESS) (SRC_STATE *, SRC_DATA *); typedef const char * (*SRC_GET_NAME) (int); typedef const char * (*SRC_GET_DESCRIPTION) (int); typedef const char * (*SRC_STRERROR) (int); extern SRC_NEW ex_src_new; extern SRC_DELETE ex_src_delete; extern SRC_PROCESS ex_src_process; extern SRC_GET_NAME ex_src_get_name; extern SRC_GET_DESCRIPTION ex_src_get_description; extern SRC_STRERROR ex_src_strerror; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/resample.cpp000066400000000000000000000113171516712004000252660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "resample.h" #include "config.h" const String &BoCA::DSPResample::GetComponentSpecs() { static String componentSpecs; if (srcdll != NIL) { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Sample Rate Converter")).Append(" \ 1.0 \ resample-dsp \ dsp \ \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadSRCDLL(); } Void smooth::DetachDLL() { FreeSRCDLL(); } BoCA::DSPResample::DSPResample() { configLayer = NIL; converter = NIL; ratio = 1; state = NIL; } BoCA::DSPResample::~DSPResample() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPResample::Activate() { const Config *config = GetConfiguration(); const Format &format = track.GetFormat(); this->format = format; this->format.rate = config->GetIntValue(ConfigureResample::ConfigID, "Samplerate", 44100); if (this->format.rate == format.rate) return True; this->format.fp = True; this->format.bits = 32; this->format.sign = True; /* Create and init format converter component. */ Format converterFormat = format; converterFormat.fp = True; converterFormat.bits = 32; converterFormat.sign = True; converter = new FormatConverter(format, converterFormat); if (converter->GetErrorState() == True) { errorState = True; errorString = converter->GetErrorString(); delete converter; return False; } /* Setup the resampler. */ int error; ratio = Float(this->format.rate) / Float(format.rate); state = ex_src_new(config->GetIntValue(ConfigureResample::ConfigID, "Converter", SRC_SINC_MEDIUM_QUALITY), format.channels, &error); if (state == NIL) { errorState = True; errorString = ex_src_strerror(error); delete converter; return False; } return True; } Bool BoCA::DSPResample::Deactivate() { if (state == NIL) return True; ex_src_delete(state); state = NIL; delete converter; return True; } Int BoCA::DSPResample::TransformData(Buffer &data) { if (state == NIL) return data.Size(); /* Perform format conversion. */ converter->Transform(data); /* Setup resampler data. */ SRC_DATA src_data = { 0 }; src_data.end_of_input = 0; src_data.src_ratio = ratio; src_data.input_frames = data.Size() / sizeof(float) / format.channels; src_data.output_frames = src_data.input_frames * src_data.src_ratio + 2; output.Resize(src_data.output_frames * format.channels); src_data.data_in = (float *) (UnsignedByte *) data; src_data.data_out = output; /* Process input and copy to output. */ ex_src_process(state, &src_data); data.Resize(src_data.output_frames_gen * sizeof(float) * format.channels); memcpy(data, src_data.data_out, data.Size()); return data.Size(); } Int BoCA::DSPResample::Flush(Buffer &data) { if (state == NIL) return 0; /* Flush format converter. */ converter->Finish(data); /* Setup resampler data. */ SRC_DATA src_data = { 0 }; src_data.end_of_input = 1; src_data.src_ratio = ratio; src_data.input_frames = data.Size() / sizeof(float) / format.channels; src_data.output_frames = format.rate; output.Resize(src_data.output_frames * format.channels); src_data.data_in = (float *) (UnsignedByte *) data; src_data.data_out = output; if (src_data.data_in == NIL) src_data.data_in = (float *) NIL + 1; // Library needs a non-NULL pointer even if input_frames is 0. /* Flush input and copy to output. */ ex_src_process(state, &src_data); data.Resize(src_data.output_frames_gen * sizeof(float) * format.channels); memcpy(data, src_data.data_out, data.Size()); return data.Size(); } ConfigLayer *BoCA::DSPResample::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureResample(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/resample/resample.h000066400000000000000000000023221516712004000247270ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DSPResample) namespace BoCA { class DSPResample : public CS::DSPComponent { private: ConfigLayer *configLayer; FormatConverter *converter; Float ratio; SRC_STATE *state; Buffer output; public: static const String &GetComponentSpecs(); DSPResample(); ~DSPResample(); Bool Activate(); Bool Deactivate(); Int TransformData(Buffer &); Int Flush(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPResample) BoCA_END_COMPONENT(DSPResample) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/000077500000000000000000000000001516712004000226145ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/Makefile000066400000000000000000000015071516712004000242570ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = rnnoise TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o rnnoise.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = cp -r "$(SRCDIR)"/boca.dsp.rnnoise "$(DESTDIR)"$(libdir)/boca INSTCMD2 = chmod -R a=rX,u=rwX "$(DESTDIR)"$(libdir)/boca/boca.dsp.rnnoise UINSTCMD1 = rm -f -r "$(DESTDIR)"$(libdir)/boca/boca.dsp.rnnoise UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/000077500000000000000000000000001516712004000257615ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/Readme.md000066400000000000000000000002701516712004000274770ustar00rootroot00000000000000## RNNoise Model Files These RNNoise model files have been trained by Gregor Richards and kindly made available in the public domain at https://github.com/GregorR/rnnoise-models. boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/bd.rnnn000066400000000000000000011112551516712004000272510ustar00rootroot00000000000000rnnoise-nu model file version 1 42 24 0 3 -3 3 4 20 1 1 4 4 6 2 -9 2 8 2 -3 8 0 -11 4 9 12 -4 3 -31 -2 17 -3 21 -9 -4 -26 18 -6 1 -16 -4 34 -2 15 14 -5 -18 -20 0 7 -63 -21 37 -58 36 6 49 -19 16 -31 -10 -1 1 -40 -43 24 -3 12 -10 6 -18 -47 -10 -21 23 -19 9 -40 6 4 27 5 -24 -36 40 65 6 -52 -21 4 -31 -71 -63 7 -11 11 7 21 50 11 20 121 37 12 -106 17 37 -12 -16 59 17 17 49 -6 16 -57 -97 40 8 14 1 11 -78 9 -68 61 -4 -1 59 -12 1 10 44 7 1 -7 24 -16 -4 49 -30 17 -8 34 33 -10 19 23 -111 -98 -114 40 -104 -81 119 88 -54 -64 71 -118 -30 -127 -34 127 -16 83 -35 -90 116 -14 -51 -8 -106 107 -116 -15 101 23 -128 9 100 40 95 2 29 -126 12 -76 -43 -30 -14 80 80 45 14 -119 -99 2 -111 4 -83 41 69 -21 -107 11 127 47 11 -125 -27 -20 -62 -75 -32 6 113 51 127 -126 29 -24 -122 39 -55 22 -26 59 127 -20 23 -33 -73 -128 -84 12 -46 7 -8 -24 32 116 -83 16 -27 88 -81 83 93 -8 98 61 -40 91 -54 83 -124 -2 -39 -40 123 -9 24 -3 38 -25 -124 42 -24 -9 -37 -76 -122 -58 -11 127 26 -13 -92 87 63 127 -66 -50 57 -80 5 -77 65 106 -11 -124 45 -43 67 127 -40 89 122 78 -122 25 -60 28 -23 65 0 124 6 -50 36 -30 -34 -21 55 -70 -15 113 88 -28 38 -1 113 75 100 -20 15 -22 -93 78 41 68 -59 -71 -18 125 -36 -66 -5 -97 -27 55 20 81 67 80 -54 36 -69 -24 126 38 26 65 63 2 120 -35 66 -62 31 -125 54 111 31 -84 61 80 9 71 -109 62 26 73 123 41 -68 43 -20 -99 116 -75 -19 7 -30 -48 -59 106 127 85 9 91 127 23 19 38 -28 -29 127 105 -102 -100 127 28 -23 -26 -30 50 -85 -127 -128 -32 -26 -128 97 127 -115 127 32 121 32 114 -119 -126 -43 -23 93 54 -120 9 -109 10 -128 -51 38 127 28 77 -60 117 -26 -24 126 11 -45 21 114 38 -119 -51 68 118 -118 -45 -19 -69 75 103 33 23 88 -122 -45 -11 127 -107 -126 -15 -2 -20 127 -6 -32 -61 -79 -101 0 -68 84 -101 118 92 -41 -34 -127 -124 92 107 -97 -117 8 -110 -46 -54 8 2 -6 8 -31 21 -120 -111 37 -44 96 -98 -126 -66 124 127 78 -44 127 -18 -40 4 13 -128 15 20 -128 -107 110 118 -51 79 -112 62 -32 -96 -128 -32 -103 -100 36 4 -116 33 -11 117 24 127 -31 -127 85 35 127 -78 -24 -119 -116 127 -32 47 61 127 23 114 81 -70 34 -79 16 -128 11 89 72 -127 -7 75 127 -65 85 -128 -60 127 -126 -24 -54 68 19 -82 127 45 -78 -120 -8 -38 0 -2 -94 -128 -94 44 101 -120 -17 -20 -127 -47 7 -18 -22 -52 74 -127 70 27 -121 -13 -88 36 18 63 -57 -123 64 -51 -67 -116 -128 113 -24 -6 11 27 -45 93 -123 120 51 64 -64 -51 33 -72 1 35 127 -19 74 -14 125 -117 -54 26 -92 -119 -34 105 -28 -22 106 -26 -35 -33 7 99 -15 4 2 -34 100 -41 62 -83 -33 120 75 127 -21 12 31 -46 52 9 88 26 16 44 96 -127 18 -117 1 -121 -77 50 112 31 -29 -5 14 68 -13 49 43 -8 -106 107 11 -67 43 -30 -5 -68 34 0 -20 7 2 -89 13 44 65 -44 -10 -45 -38 122 22 45 -80 -51 -116 96 59 10 71 83 9 -104 -15 19 -127 -27 -11 25 -45 -17 -52 8 37 -10 -30 -50 -8 -5 -17 -91 4 -54 -42 76 60 -103 53 -41 -47 -33 8 27 -106 -18 -25 58 16 67 -66 19 30 56 110 4 16 73 -27 -55 8 -95 -105 75 108 -8 48 -29 26 80 79 34 63 -23 49 -77 -123 37 -128 -12 32 -35 -106 18 50 -102 14 7 -81 -98 71 -38 -17 -21 -62 -30 1 -118 31 95 -33 58 -79 -102 84 -4 -49 127 -126 59 -65 74 -20 -7 127 127 -90 127 124 80 -128 125 -128 -45 127 26 -100 -119 107 100 8 127 -113 103 -104 57 -124 -128 108 110 -65 127 122 -79 -128 125 -128 -77 17 122 -46 -119 127 17 -5 -1 50 92 53 5 53 -31 -81 -23 73 -35 -65 -78 -6 42 -34 -100 -95 120 -55 68 94 -43 98 -55 -7 -32 -28 21 109 22 127 7 119 -128 -116 76 -62 -111 -23 -58 33 -74 52 102 96 58 -58 27 -85 47 -36 -51 3 -36 127 48 37 -65 -62 64 -50 -38 -54 -34 -20 -9 77 -25 -4 66 10 -34 81 -3 60 -64 27 10 44 -120 19 -122 -44 -28 97 -7 111 127 -101 -56 101 85 -55 -48 12 -25 25 -21 25 -50 27 -82 -47 -35 -10 -37 -2 -22 2 51 29 10 76 -39 94 -6 -47 61 77 43 -19 4 -27 70 9 71 86 -16 1 -33 -62 -50 -23 -51 14 -26 -15 108 -56 125 -87 -127 -85 -91 -20 -124 120 68 -125 -68 2 21 -43 -27 -80 -13 -3 34 -33 -108 46 63 24 24 0 -6 96 -13 -69 77 84 21 -48 21 22 -4 -128 35 -47 39 37 -69 79 35 -35 -31 42 100 -108 20 29 46 -18 2 40 42 -82 -40 -42 51 -30 -36 72 -39 -25 -28 -76 -18 -13 51 10 1 -84 66 55 20 11 25 -9 -42 -3 49 -48 -18 -6 -28 -9 38 -8 59 -4 -35 57 12 -39 27 -25 105 -41 59 -34 35 52 -22 46 126 119 -46 77 67 48 10 -95 -87 -73 66 -39 -73 -97 -60 -128 41 78 119 109 97 10 -2 -50 -9 0 34 -79 -27 39 -30 11 72 40 15 -3 27 20 83 42 8 -52 -81 51 32 80 -20 -34 11 72 -23 -51 23 -18 23 -8 32 -7 -1 -75 -14 60 -39 56 -86 72 -31 41 69 -8 -38 -104 -69 69 63 67 -101 -35 -69 -1 41 38 107 127 -25 -39 -9 27 -19 -48 -5 -102 -125 29 -67 -54 25 102 -13 55 54 62 -13 37 8 -113 -10 -113 45 -24 -41 -30 41 75 125 -69 45 -82 -3 -38 -40 -15 108 -53 66 -1 -24 101 97 28 -83 62 125 -116 -36 10 -123 109 37 -53 -12 54 -12 -123 -37 5 100 -106 -118 -62 30 92 -83 87 73 28 42 -24 -108 -9 -85 65 -28 -2 -76 32 3 -84 -97 92 57 -8 -66 0 -72 -33 -120 -2 19 88 8 -40 27 -101 6 -45 116 -59 107 16 -89 51 -18 7 32 54 19 -54 -94 73 -10 96 19 90 48 3 -29 -24 -71 114 -41 115 105 96 42 -84 -37 66 -57 46 -13 -2 -56 88 -109 -14 81 30 50 5 62 29 -4 -6 -25 -55 -33 12 96 -58 -105 57 64 -54 -7 57 49 75 -24 45 -28 -32 32 -1 -58 -11 0 65 -6 27 -19 -38 -68 12 17 8 10 -55 -33 -77 18 91 -11 -2 -12 26 59 49 -17 28 -128 70 -64 -31 -83 127 -76 -45 -44 112 -67 -116 -115 -19 -39 -69 -111 -128 -118 -94 -3 57 -112 -98 -115 68 12 -26 54 -26 21 82 -67 40 -67 -87 -84 -45 -65 -73 -100 -43 -105 93 44 28 5 -95 -8 9 9 -106 -45 34 -59 77 1 74 -51 25 41 28 -30 32 56 69 -17 19 -36 -56 -17 60 16 -13 42 -7 -5 -54 -38 -30 -26 73 49 -26 -60 -103 78 123 114 122 114 105 61 66 -53 62 93 -31 9 92 32 -1 12 -98 94 51 98 109 -59 55 -29 -46 -5 18 76 66 99 -16 19 75 -18 -37 -51 58 61 41 -11 -25 -57 98 -105 -25 -13 43 -7 -75 -67 -87 37 -110 -57 19 20 -87 -66 114 77 -31 28 -65 -15 71 -28 118 124 -81 -44 -90 5 15 -52 -62 25 24 37 -39 -34 17 35 76 -78 -33 2 19 2 -53 37 -52 82 20 -29 94 92 -26 -68 31 86 73 69 -88 51 -11 20 11 1 20 -14 -49 -22 88 -19 7 9 83 52 15 -26 54 -14 105 -79 58 65 -69 7 -8 67 118 9 -47 79 82 127 -109 102 -26 -64 -31 127 47 39 -44 -82 80 41 -94 -101 7 24 41 40 46 -27 -22 -74 118 112 -42 -22 127 21 -3 38 -60 75 99 -65 97 41 17 26 18 -50 -45 50 30 89 0 -14 12 0 38 26 -58 54 0 -31 24 -20 63 -4 81 -127 120 89 -85 -34 -5 89 -29 -125 5 21 37 -23 41 -12 9 -116 -65 -100 -55 -61 -127 88 -124 -24 -108 -87 -5 14 85 -1 -72 -91 -78 -76 0 -4 47 71 38 -128 -60 24 -46 -60 -85 12 -123 -23 -95 -51 -29 43 -67 -15 96 51 -118 9 -9 52 65 36 -43 46 16 -36 -47 -40 50 -24 -39 8 41 122 -72 -66 57 -128 101 127 82 -21 25 76 47 40 50 -65 18 98 31 112 116 35 117 119 86 68 127 -51 -32 -17 49 10 109 -15 35 58 -91 -34 59 104 76 52 106 -125 54 -45 -40 -19 12 8 43 -10 -64 62 -21 -40 -43 -21 97 4 12 30 52 -22 3 -69 -37 57 -22 59 7 -21 0 -55 20 63 51 -23 -120 47 -112 -108 16 14 -82 -100 68 -128 -101 40 -9 87 33 64 18 -128 66 2 80 60 35 -14 -128 -47 35 92 -120 -121 15 9 -117 -39 -64 -103 9 54 -121 -123 19 -108 -28 46 -75 23 -63 10 -4 -73 -13 -27 33 -8 -35 29 -27 -52 -22 -38 -18 -13 -26 -67 51 81 -15 13 34 7 20 -63 -119 116 -48 46 17 -78 0 -36 -31 87 45 -127 -124 2 79 -25 54 -46 -71 126 -72 -27 -68 -23 -117 -77 20 13 -61 11 40 73 -28 -106 -72 -12 45 127 66 -35 13 11 -56 44 28 81 85 -17 127 -25 -86 -67 -70 52 -49 -12 -110 89 -9 28 14 -118 38 25 71 37 19 21 0 -57 82 -44 -40 -5 37 95 -38 -17 -68 -120 -82 3 42 -98 -58 -128 -67 -69 -120 -64 -19 50 29 7 -128 -30 -96 -38 -128 -2 127 -47 -18 -68 113 -85 -60 24 -43 -60 -70 -98 -101 -96 -121 -57 -103 -48 66 -5 67 109 -105 -17 -27 15 -14 -4 -77 125 -54 0 -56 -91 73 107 106 -55 71 88 -95 -28 42 -56 96 3 81 27 -81 94 116 -6 -29 -78 110 127 -12 80 125 94 0 127 6 60 65 51 -26 7 88 -124 29 -63 16 -57 -78 55 13 -35 103 80 8 58 106 68 79 67 -78 -18 -8 -33 -15 58 -71 1 -10 48 -61 1 73 -7 -20 27 60 35 -33 29 -35 54 -20 -11 -8 46 11 69 63 -116 118 99 60 101 1 -74 -61 -115 102 125 -88 -112 -36 -112 -30 -125 -127 19 78 57 -55 117 -96 8 -50 -110 -38 30 43 -44 -40 -128 55 21 27 -42 -22 43 -61 -127 -31 11 -74 8 -33 -20 -4 -15 -58 32 -113 16 -54 -14 -56 7 66 0 9 62 16 -51 61 52 74 13 115 45 -103 29 60 -50 -55 127 120 1 -117 -70 88 -100 -8 42 -56 -56 26 -117 -22 36 -5 -13 77 119 36 75 -46 -70 -61 -36 -128 70 -105 -35 -57 -14 -65 23 -44 -128 4 -52 7 -55 -45 2 -55 5 -20 7 -37 44 -16 -7 -78 -59 -5 -4 -45 -23 -33 124 65 -27 -91 -65 84 28 86 -37 23 26 0 22 54 46 4 -126 -49 44 59 -8 -4 -3 117 81 -46 -95 9 64 -49 -27 6 127 118 -54 -64 -23 -12 56 105 5 126 -46 32 8 -74 -24 0 42 28 87 -17 39 87 -114 46 -90 21 -31 -32 -10 -92 29 -11 14 -58 -87 -32 37 -42 -64 53 35 -1 62 51 46 -29 -18 76 -10 69 27 -85 -44 -84 96 119 91 -44 -24 -13 75 -13 47 81 -56 -38 108 27 48 -67 56 -18 -34 -36 -113 102 52 17 76 4 -76 107 106 -60 -118 61 -26 -117 52 85 -18 -38 -59 -30 -95 -26 -64 50 -53 -9 66 25 -59 -124 -43 -63 -51 -42 35 -112 21 108 -47 34 -57 58 75 -46 -114 -66 -14 -1 27 -18 -75 -54 13 33 33 -66 6 11 24 23 115 -21 -27 29 -85 -95 -120 -8 -24 -125 -11 -127 -106 17 -98 -128 48 94 -10 -56 119 28 -41 -60 -54 67 17 -31 14 -115 110 60 -62 -47 73 -2 2 -26 -19 8 0 10 41 -120 14 -71 1 -25 -49 -18 90 91 13 79 -55 26 31 42 -86 77 38 -27 48 64 33 0 29 -13 -57 -28 28 -127 37 14 91 -101 93 -2 85 127 24 127 80 -26 110 22 -12 119 -18 83 20 127 -117 -112 59 -94 -40 -124 48 111 88 97 83 11 -115 51 -29 70 -35 106 -39 -92 52 39 -81 30 40 48 -7 51 41 -15 0 22 -76 -6 37 5 -127 30 4 11 -100 92 -9 -67 -92 18 96 -122 36 12 127 -37 26 53 110 -85 4 -99 -31 97 -17 -25 18 16 118 124 -75 -5 5 127 -108 99 3 15 69 -98 -3 -39 66 26 125 -52 -3 36 -122 -38 -15 88 78 6 1 46 48 81 -10 -79 -42 -13 -29 55 -7 -31 27 62 46 -26 -63 20 -74 -36 -119 23 25 32 24 -48 40 113 -86 48 78 87 46 79 -11 0 -75 -26 -60 40 -10 -51 -126 -67 64 -88 -119 -94 21 -42 68 36 49 -62 -19 -47 5 -44 31 -70 -33 -29 43 -52 12 -15 37 97 -1 55 39 -20 -60 58 -20 1 -15 37 -62 37 -12 -53 -34 67 -29 41 24 47 -45 -54 -19 -25 -28 -93 -3 5 12 56 -46 -105 -87 -84 70 -54 43 32 11 -97 -87 -36 95 -20 8 -79 63 -54 -111 -119 -86 -77 89 36 -100 -112 -122 -125 -65 0 -85 127 106 -74 -127 114 -76 3 19 -38 -68 -106 115 -127 -57 -73 4 -79 -29 60 118 -112 23 -51 13 47 -31 -47 120 67 -83 8 4 118 -22 9 96 102 115 -67 -11 35 122 19 -128 -30 127 33 127 39 -112 96 -21 -106 7 14 -28 -109 -90 -57 39 -128 -96 -125 105 -29 75 -28 57 89 63 -36 -113 118 -29 -18 -72 37 -108 -99 -113 79 115 94 119 70 -25 -27 111 -6 47 -127 -117 127 -117 24 -82 -126 115 101 -82 -98 10 -47 58 -37 -126 -110 121 -128 -94 105 -120 -121 42 -103 61 127 -26 48 67 -22 -61 -115 34 -15 73 104 72 73 61 76 114 65 87 46 -22 93 76 -37 -32 -36 -117 65 113 -105 -33 60 -5 -48 45 32 43 -8 38 -21 -31 -12 -87 -1 -88 -36 107 127 25 -33 -77 -128 -82 13 101 -128 50 -77 -14 -65 46 -36 -25 -60 -36 8 -40 -28 -13 -103 -79 47 -59 31 -79 -12 -127 21 -103 -10 2 -10 -127 2 20 -6 25 -8 -128 15 -2 10 -40 32 36 -26 68 -2 7 52 -68 53 -11 -10 29 4 33 13 -46 11 62 8 4 -11 -18 32 96 37 -7 81 2 -100 -40 -84 101 -20 2 -22 35 69 111 -33 -20 -1 16 107 -5 60 88 -53 -7 31 122 -108 -127 -101 72 42 125 11 123 9 -106 99 118 -20 -60 -65 -103 -128 -26 -113 -121 -126 60 -70 34 -43 -47 -31 -33 0 99 -17 75 -20 -80 -7 118 -62 15 28 93 -25 -49 29 32 77 -60 20 31 -25 -128 72 57 127 6 10 18 56 -125 6 5 58 -3 -118 -24 -95 38 -128 -87 53 -63 10 -126 51 -85 -44 -61 124 -127 -77 17 126 -33 -55 -127 -109 -115 -16 22 17 -70 30 -32 -128 30 -59 -7 -55 -68 -24 37 43 -14 21 6 34 -76 35 -42 63 56 -67 -35 -87 -98 -127 51 39 -21 101 -75 -27 40 0 29 14 -92 50 50 30 0 -25 -66 10 -79 -23 12 -6 -10 -1 117 -128 77 88 -55 -63 -115 -92 88 123 -127 -74 -13 36 -107 62 -25 -92 -121 -128 -89 -117 -88 -106 -116 -54 -44 -1 19 -14 23 -54 9 51 25 -100 -25 83 -26 -33 -16 -13 63 -71 1 -120 -89 -59 -65 33 39 41 -41 -16 66 -29 102 -4 30 67 30 53 -22 -80 44 112 -89 -8 65 -19 -39 15 102 -11 15 97 127 -103 -53 5 -26 -100 126 -115 62 -128 -128 37 124 107 -30 -125 7 -20 -23 -125 -120 51 4 53 41 -103 -5 9 -37 7 84 -43 15 -67 -83 -26 64 5 -83 -25 -6 -32 91 105 -63 -6 35 38 49 24 52 -105 -108 37 46 29 22 18 91 74 77 119 -21 120 46 86 -123 103 76 -58 -63 -3 -128 112 77 97 -89 56 -78 -37 -18 -34 -22 -92 95 -60 -122 -31 -41 49 -60 -96 5 24 -110 -80 -71 70 15 12 -102 19 29 -36 -121 123 10 -55 3 -24 14 -123 -117 -119 -73 -16 -127 -36 -98 -7 -18 121 119 -117 15 57 -80 118 -51 -106 127 117 -28 27 -77 120 101 76 -119 127 108 -128 99 105 -106 14 -97 -127 119 113 127 99 64 118 -114 93 -42 -62 -28 -103 85 -36 37 -91 -95 -74 61 -23 3 -100 27 40 -81 11 -30 113 44 -12 -118 16 21 -1 16 37 112 54 117 -10 46 74 -15 55 118 -2 -96 80 -113 -37 -82 -81 -2 -19 -91 -30 -75 -114 76 -115 -35 -18 21 -88 -86 127 -128 -39 19 -20 -126 -126 51 109 -42 -118 46 22 -108 -8 -21 -101 -85 -124 -119 -128 -110 -128 -127 -126 16 -79 40 -16 29 -82 22 5 67 -38 -68 23 23 13 -7 -53 -3 -88 -37 -73 -74 -21 50 -2 56 83 -127 30 97 -69 68 -41 52 26 -13 48 89 -23 -17 15 -108 88 29 17 5 82 45 -69 -84 95 57 49 -41 31 25 -114 -22 7 -102 -105 40 -57 42 34 -41 127 9 -6 -46 39 -70 16 -42 -47 -8 32 60 1 -17 0 -78 -8 -55 -11 3 39 4 -16 -13 -18 66 82 -4 59 -51 30 -18 99 3 63 2 -52 11 -32 78 -33 45 -101 36 -34 28 -66 24 87 43 38 28 46 127 44 -26 -5 81 -18 -55 -16 -124 -120 -27 -44 27 -128 -55 -38 127 -37 126 -41 -127 -30 -103 -75 4 65 -118 52 -26 52 5 -62 20 -27 61 6 -57 15 42 26 -23 -11 -99 -17 -52 -90 85 33 -22 10 -101 -94 7 58 127 -108 -54 -32 14 69 -53 -68 126 40 42 13 -30 125 24 99 -122 125 125 -52 -67 107 127 -70 -128 -91 -10 -125 120 -121 67 -127 -128 -46 127 52 112 -45 -113 -123 -120 -127 -119 -90 -82 -39 125 3 88 -52 -9 18 -34 55 3 47 16 23 82 50 34 -5 -42 60 127 126 -8 66 20 0 -43 20 31 -3 -46 17 116 13 -50 90 31 107 28 112 -71 125 20 42 -75 51 44 -67 -63 -28 127 -102 -116 16 -87 -42 -35 6 115 -114 -109 64 115 84 101 -72 -99 -88 -64 -94 -118 99 -53 16 61 -128 3 37 -11 -11 51 -75 -6 3 -113 66 77 -9 19 43 -47 6 -28 88 -31 82 -32 31 -28 62 29 -7 30 -62 78 50 -98 -1 72 71 32 62 11 58 58 66 -116 82 65 -11 -34 45 -41 12 -126 -100 34 50 98 -74 61 109 11 108 102 34 -71 114 -22 107 127 102 -25 -113 127 14 -98 -18 33 29 21 36 9 -35 -48 85 35 -5 36 -64 12 13 55 -17 -106 -63 -70 -70 -27 -10 -80 -80 -88 94 -18 127 -77 17 80 125 -105 -70 -83 -84 103 -37 -8 -87 94 -101 -32 124 61 -64 20 -2 -27 12 -58 -111 -1 -39 -59 -114 16 47 26 71 12 123 -35 -63 -14 -11 -31 -10 -77 -19 22 75 22 20 26 -25 -38 -27 -62 86 21 -8 82 7 -34 -64 33 11 39 33 -25 33 19 -12 25 44 97 33 -27 67 28 20 -8 -52 127 -19 111 -26 -9 63 -44 -12 3 9 75 -110 -54 44 -118 62 127 89 -44 69 -127 -29 -124 9 85 41 -126 -63 -96 120 59 121 -58 127 124 122 -33 31 -26 -48 99 -41 32 -11 -17 -6 -102 44 92 -23 -19 19 -1 77 42 25 -51 -23 -31 -27 4 61 57 75 115 -122 -38 -66 14 47 -124 -116 127 71 48 -5 -83 62 124 123 -108 127 8 -72 -10 110 51 0 126 117 -114 -45 -69 -18 -115 19 112 1 -127 46 38 117 124 55 -22 118 120 119 -37 124 -90 9 -5 32 -10 -93 -58 -9 -14 -64 77 -5 -51 -2 -14 -4 -4 121 46 61 -47 6 -13 10 42 103 127 -120 -80 -66 102 4 -93 -94 126 48 36 20 2 120 47 50 -76 127 101 -37 -6 9 -123 -119 -78 -118 -39 57 -99 -23 4 51 -94 127 -104 -114 -77 -73 -20 -25 -75 -66 -47 -31 1 -98 -38 -59 -40 -43 -23 12 -50 36 -6 1 -5 24 -68 21 -39 -91 37 -26 3 1 -59 -42 32 49 29 -116 -125 111 123 91 -14 47 30 84 -118 -90 -90 22 15 -127 -81 -43 122 -74 -126 14 66 -74 40 59 83 59 -59 -112 51 -29 -46 -11 28 -22 -7 105 -6 4 17 31 -69 60 77 118 5 25 38 3 37 -7 -4 -43 41 32 -74 74 -9 -28 23 70 75 10 14 61 89 32 -10 -31 -4 -47 11 82 70 -58 -20 -122 49 6 -57 -84 124 -2 105 -53 20 127 -4 55 -45 42 127 -75 -15 3 -1 66 13 -27 -16 -26 -104 -16 -26 -66 38 3 8 -5 -34 -42 0 -28 -20 10 -5 -32 -4 32 37 14 24 -5 70 21 -123 70 -30 84 37 -43 -34 6 -7 -23 -33 63 64 -3 -32 53 72 102 -49 -22 75 -25 5 -17 -12 -43 -30 13 43 -37 48 21 -103 19 36 37 74 -24 53 -9 -38 45 -9 -83 -42 14 65 -55 126 32 100 41 -33 58 100 -23 -34 -55 8 95 94 -38 -67 -44 48 -33 -39 17 -58 -6 26 -8 39 -27 19 -6 14 30 -6 -59 -19 16 -4 30 -10 40 -88 46 17 -125 19 -72 -63 40 18 96 -36 -41 108 13 -128 -39 -118 50 100 -9 -13 -90 25 -104 -126 110 19 -43 -128 103 88 118 32 102 -127 -40 13 126 69 18 -123 -58 -26 124 106 122 73 127 120 -11 -33 -23 -85 45 -6 62 -36 46 -83 -62 24 101 22 -90 -38 -20 -40 -95 -24 -60 -126 -87 -14 -111 -38 -120 -32 -27 44 34 51 30 -123 103 -13 -46 25 -9 3 -13 37 36 65 -37 74 -52 68 -26 65 40 -75 -10 58 -10 -37 -30 -127 35 -48 -29 -128 115 -102 -64 -29 -9 -9 -41 -118 9 -64 117 -80 44 -19 -68 54 12 72 -48 49 6 7 86 -27 -54 -92 26 -29 -105 27 -12 -53 -24 124 56 -69 -2 17 127 106 -127 -46 -39 71 66 -80 13 127 88 34 53 -9 45 112 112 -113 71 40 -86 -117 66 123 19 -128 -127 119 3 125 67 125 -23 -128 98 127 49 -25 -123 -100 -121 -103 -127 -128 -123 78 -97 121 42 -13 -24 61 40 95 36 118 27 -19 102 115 51 67 22 6 34 78 36 -14 88 75 31 6 40 27 5 -65 -59 80 13 39 -15 34 26 21 31 -20 48 -12 44 -50 32 24 3 -127 25 90 48 2 42 35 23 3 6 -38 61 47 45 37 31 -16 -31 58 -75 35 -4 -13 84 47 25 20 0 -67 32 -40 48 -60 14 25 -10 -17 -21 -2 -12 17 -16 -78 16 31 -70 -12 -2 -34 42 32 102 -85 77 -61 -63 91 -33 35 50 25 -66 -15 16 5 1 21 -38 19 -43 -14 35 -18 29 -70 13 45 3 -40 -12 -10 5 21 -2 -57 32 12 -8 -17 51 51 83 -16 29 13 25 -57 38 32 -49 -27 51 -33 -51 23 -14 19 9 -15 15 25 11 -20 -11 12 -66 9 -14 -22 -24 30 -11 4 -4 -23 52 -27 21 23 2 24 24 80 1 -7 -2 12 10 33 22 -31 -18 37 47 4 -19 46 61 -37 -83 61 -34 29 28 -123 -2 -25 96 57 83 -9 -27 -32 -4 -78 -85 26 -89 106 14 -61 26 -22 38 94 -41 -12 0 -59 13 17 55 47 -47 114 28 87 31 84 123 -72 -1 1 14 -26 6 -76 1 -54 7 -60 -16 -87 -22 -73 -41 5 -92 7 -15 -82 65 -88 5 -48 1 -24 45 -42 -26 33 9 124 -103 -105 121 64 18 -25 4 22 5 -21 21 -13 24 25 -14 75 2 28 53 -15 16 30 31 30 29 36 -2 14 18 -26 4 0 -27 44 43 -64 29 19 -77 27 -98 -10 -125 13 29 -13 -91 22 47 34 8 70 -10 -35 -33 -84 53 -11 37 17 1 -7 11 36 -1 13 42 -9 15 2 77 110 63 -38 7 -20 -16 -27 -38 -14 4 45 -127 -45 -100 -3 43 -86 -17 27 -4 -1 -71 -21 37 -125 6 50 41 -2 -42 -11 -10 27 -3 -50 13 57 36 -127 -17 12 -5 41 -97 54 -8 96 31 -2 26 24 -38 35 -39 15 -84 -12 84 31 28 -40 125 -56 -4 -45 20 -29 -42 -18 0 70 -20 -33 66 22 -33 42 15 54 70 43 39 20 55 42 20 -10 -58 -27 -22 9 -49 15 20 -51 -19 41 11 -34 -20 37 6 17 -1 -50 9 -47 -78 -39 -16 6 11 -16 43 23 6 -19 -26 18 -35 -64 -31 41 -43 22 -38 -57 54 -73 -51 -74 -54 -32 -42 -12 -34 46 20 -14 -59 13 -9 -11 -42 39 -6 -4 30 -32 -38 -36 -101 -27 -6 -20 -69 -75 60 18 -63 -11 -29 -56 -49 71 31 -35 13 -25 6 -41 -62 2 -61 -61 -1 18 10 -18 -60 -81 62 18 -11 -8 1 10 45 -19 14 39 15 17 -20 30 51 62 -92 15 -1 -31 86 -49 -11 -10 -23 7 -24 -54 20 -20 47 8 -23 -69 -103 -1 21 -15 1 -50 72 -34 -5 -8 4 -62 -3 11 66 -2 -8 20 -8 28 12 68 -48 -71 -1 -35 -7 -47 -20 -6 8 -23 34 -22 59 -6 -10 11 -59 -29 -2 19 -27 45 -60 3 -16 26 -1 38 -3 -45 -27 9 6 -43 47 -31 10 34 -9 24 -32 -9 -23 -35 11 0 11 -27 37 -19 -11 17 -27 -26 31 13 20 20 -33 9 -29 -79 -52 83 80 -43 -30 62 -20 -8 -38 99 -42 -94 -41 2 -3 -11 -17 -78 -42 -41 22 -2 -61 70 -11 -4 10 92 12 -8 88 14 79 -30 39 -22 21 1 -54 98 15 2 -103 1 76 -61 40 -24 -19 -17 -38 23 -27 -50 54 -28 10 -79 9 -33 -20 -25 -13 -11 -4 19 0 -58 -47 -6 53 -37 15 26 28 -26 -19 -8 13 60 23 44 9 30 -4 -7 24 10 25 -46 47 10 30 19 -7 -38 8 -2 -62 -6 8 57 16 -5 -86 -10 -17 8 9 -28 15 -17 49 51 16 12 -3 -31 9 9 -15 -4 7 -37 31 21 10 -57 -6 -29 55 -16 32 5 72 43 50 -80 -48 -7 100 26 -15 13 20 -31 78 1 -56 -32 -43 -52 -43 64 -92 0 -68 -35 3 90 -43 -11 89 -77 46 -21 -18 -59 -102 -63 -24 -51 -63 63 47 40 -54 27 -8 -58 -36 38 -4 6 -11 64 12 50 26 -26 31 -21 29 36 -1 -41 -20 -59 -69 -25 88 29 56 62 -63 46 31 45 -69 18 24 -38 82 -28 11 14 -91 -11 -45 24 6 6 -57 -25 34 5 -41 -92 50 32 -14 -11 -23 21 -29 -28 -19 8 42 -4 -43 -24 -55 -73 32 64 -20 62 18 30 29 31 47 42 0 -41 10 37 5 -50 11 -47 -59 -60 65 26 12 54 8 17 -8 -63 49 16 -42 -15 -7 -113 25 -8 -12 19 -18 12 72 23 8 22 58 -81 -56 37 29 -33 -12 92 -47 5 37 108 31 15 -40 -23 3 34 10 -20 1 17 22 -85 80 -65 19 -57 -2 92 -117 -10 -25 12 85 59 -28 -38 50 -23 -28 90 6 36 -39 31 15 -2 20 -37 37 -33 -21 8 90 -13 65 22 -9 3 86 11 95 32 -12 -5 -14 67 87 47 27 31 5 -27 24 53 -12 -47 17 -20 -13 2 -1 -16 42 -11 33 15 -1 -4 -51 27 25 -36 -59 36 23 32 -7 70 26 -14 -12 -19 26 -3 -13 -39 31 23 16 58 34 2 7 -18 -39 52 -66 59 -9 12 3 -34 -29 -30 38 29 10 18 8 -2 21 -76 54 -79 -41 -7 24 67 23 39 -43 -92 77 50 -109 -31 10 8 34 23 -31 44 -49 6 -38 -52 -3 -9 11 3 0 -120 87 39 -38 -7 -30 -35 17 -40 49 -18 58 -38 -73 -8 -67 -21 116 52 4 22 12 37 -2 63 34 52 33 -21 16 59 35 -5 -36 -77 8 75 9 -35 -70 -22 18 46 37 -51 65 -51 40 44 -7 -46 -16 -17 12 -49 50 -58 25 40 -22 -16 80 39 15 41 -16 -61 -18 -33 -22 25 5 -15 36 -23 18 -36 -20 6 37 17 42 34 -23 8 -16 -54 -27 51 38 30 -2 -52 -1 -29 2 -29 -20 30 24 -1 14 -10 7 51 18 -9 10 19 16 -69 57 19 8 70 -9 70 -10 -35 91 51 -39 33 4 38 -5 26 -97 49 86 63 -20 109 93 46 -4 16 -13 50 7 18 14 51 -22 -29 -27 78 -12 -9 4 53 29 20 57 -124 45 55 110 22 11 -47 26 25 -10 76 39 -40 -1 5 63 -20 -69 -2 32 -4 24 42 54 -33 -30 -22 -13 25 -10 -61 -3 37 -31 21 -5 -14 -19 4 14 4 -8 49 34 21 -16 -65 -102 46 -78 58 37 -10 37 14 36 -9 -15 -64 -4 -24 2 21 2 -4 -38 -42 -9 52 -51 -17 -26 -32 -22 -73 -34 -24 0 -1 40 -24 13 -10 20 45 -17 -36 17 18 -29 -20 59 10 36 23 23 34 -13 -15 -12 28 0 8 -13 -88 -75 30 -17 29 -85 34 -35 -61 -58 -13 -65 -125 52 20 32 -49 82 -42 -33 7 6 -105 -61 13 -5 23 29 83 -21 -63 110 50 -5 -109 -122 -68 39 -126 -119 57 48 60 -48 -102 -7 42 -63 27 33 23 17 -14 14 57 6 9 16 -30 -33 -25 -3 -70 39 -55 -49 -79 -9 -116 75 -19 49 24 25 80 -25 -33 32 78 26 -125 48 37 -89 -91 -2 29 -81 56 -35 10 -114 -67 15 19 -5 -7 26 -31 -27 16 -39 -34 40 15 17 13 0 -24 -9 65 22 -34 39 21 33 -13 -67 -25 -20 16 -29 30 -15 -125 5 20 47 -19 -78 38 24 -44 58 32 75 10 -10 -29 13 47 -35 -31 39 -53 30 24 -6 -13 -56 -7 115 -21 20 -14 80 -35 91 52 53 -36 -32 -70 -53 91 30 59 -71 -52 -19 41 36 9 -82 -62 39 -12 42 53 -105 -46 -114 -55 21 -52 -20 -6 53 88 33 -39 -88 -57 -54 44 105 -18 -8 -41 55 -64 88 -1 9 24 36 87 -5 -35 115 44 -5 71 17 21 43 82 23 -14 -6 47 -13 -78 -1 -28 56 -57 -75 50 19 65 95 46 70 55 52 3 14 -92 15 21 -15 39 66 34 7 15 15 -22 65 23 34 61 -51 -26 -16 -9 -5 -24 -34 -37 34 -65 25 19 43 -8 44 -29 25 -42 41 -18 -5 1 22 37 -24 -65 8 -18 26 -34 -12 13 -24 -23 -87 -48 -8 -26 22 -19 -2 -37 -30 8 -46 23 -74 43 -27 -1 35 30 83 -8 20 -38 -40 17 22 28 -2 23 36 -50 -59 15 -85 79 9 -81 0 -27 1 57 -4 43 -31 -1 -55 97 5 32 44 -6 2 -43 26 22 58 99 -99 -29 15 -53 -47 -25 -27 19 2 -51 47 -5 -42 -3 27 55 -64 37 -66 -34 28 49 -2 21 -42 65 -110 42 43 43 -1 -35 5 -4 -16 51 -22 56 26 11 43 -58 5 -40 9 -52 -17 -29 9 -40 26 35 -3 9 25 -32 -57 49 -5 -49 22 21 -9 3 12 -2 -2 14 -51 -2 29 -13 -23 7 21 1 -37 14 -16 -7 6 25 -66 7 6 -68 55 -24 -94 -104 -46 23 -5 -24 11 -88 -7 26 26 60 -25 -46 -6 14 24 -22 58 50 -63 -7 8 -25 -66 23 31 11 -5 -15 58 -125 -20 13 22 -39 -11 47 64 56 -123 -3 19 60 -105 54 -49 48 -22 35 35 -40 26 -19 68 33 -11 56 -35 -78 22 7 126 -35 91 10 3 29 -121 -29 0 73 -60 -4 12 0 -71 -28 115 72 15 -27 -110 34 -7 -18 69 -7 -81 78 2 69 -31 -11 -21 -94 -9 -37 -7 -82 -26 2 14 -31 -3 -28 -28 29 9 -11 -27 69 -80 13 6 25 -29 11 -18 2 -77 10 -46 127 45 -28 -62 -3 -14 14 13 -38 -12 14 68 79 12 -24 19 -12 10 -16 -73 -53 -56 32 20 1 -7 -50 35 -13 -38 51 -31 53 -78 17 -84 -121 97 -11 -13 -18 -76 -28 -117 31 54 -108 -60 74 -5 -2 23 -19 -107 45 84 -126 55 34 93 -71 -33 -23 2 -20 -63 58 -104 41 26 50 47 57 2 -38 6 -10 -89 25 1 90 1 -109 74 -71 -29 -55 -47 -23 -92 25 7 118 -67 -107 -70 -11 32 33 -10 83 46 56 2 51 22 65 41 -24 -55 -1 73 41 56 37 14 -29 7 56 67 -26 -10 49 101 -32 16 8 31 4 -7 -64 -16 -13 -56 91 17 20 74 23 -52 29 -84 -72 -14 37 -2 38 -29 84 86 -58 -15 -89 -67 -31 -69 -4 -63 89 82 -20 11 7 7 -26 6 67 -23 -3 57 -17 -18 49 73 27 -2 -3 64 19 14 48 52 20 -55 -4 52 32 -49 21 -26 -11 55 -27 28 37 25 -69 80 38 8 101 31 8 51 34 10 31 92 5 32 82 20 -35 51 -37 6 39 32 -2 -70 50 -120 -54 75 1 1 38 -21 93 -5 -12 -67 -45 25 4 51 34 84 80 10 66 3 -29 -16 54 -16 -9 39 27 -4 -94 89 20 9 -33 -72 79 30 -43 33 -37 -38 -51 -4 -66 -37 5 56 9 66 -33 31 -46 23 -39 -18 44 41 22 8 -62 -19 38 34 -13 -2 24 17 40 -31 -14 6 13 22 -16 40 28 18 -2 -31 9 -6 40 27 1 -9 -10 -1 34 -7 -27 30 -14 -47 4 -58 -5 126 -21 -28 20 -49 -55 27 -80 43 -36 -43 -83 -95 31 -70 18 48 -118 -22 70 24 59 32 5 -1 65 12 -127 -35 18 63 76 -91 -105 -2 -29 32 -51 -31 -63 -38 -37 -27 17 -43 15 78 33 28 -15 64 38 39 30 -47 7 -49 -5 18 -39 29 -12 -107 -50 -9 -60 -24 -16 -2 -3 44 2 30 32 38 -75 -19 19 37 -100 -39 24 -35 -19 18 -3 -72 22 -4 -29 59 -48 -16 -19 48 44 11 0 -15 33 8 68 2 -24 -25 18 32 71 22 -75 -56 2 -45 4 -25 14 0 -9 -16 -54 5 27 -92 -69 -36 22 44 -45 -19 45 17 -25 -59 43 -67 -62 95 49 -14 -14 14 41 -31 94 -12 34 -16 -106 -4 -9 -41 -61 -4 -50 -3 -9 -58 3 17 13 53 -117 -41 -48 5 54 -32 38 79 16 53 41 19 -87 5 15 11 79 2 74 -82 31 53 78 -24 -29 -3 87 2 0 31 -56 11 -18 19 66 7 -41 -68 -60 -78 -20 -5 -123 -18 -45 -96 47 -9 34 35 -75 31 5 -3 -27 5 41 -35 -17 116 29 22 -39 -63 -10 28 52 127 -82 -60 -10 2 -17 21 -50 -45 20 -4 57 47 -12 22 35 41 -26 15 -3 -67 8 10 26 57 -49 -46 28 -113 25 -45 -16 39 -31 -60 -44 39 11 26 -100 -36 48 -20 49 13 51 26 -37 -2 -10 -49 -76 17 -45 79 41 12 -27 -19 16 -32 -109 -40 57 45 -22 11 16 11 -71 -70 25 -24 33 -22 14 31 28 -72 -70 6 56 -25 51 -113 24 10 72 80 58 -67 44 59 -56 -47 19 28 26 -34 -21 -9 31 -11 39 33 10 -62 30 85 29 -42 -108 -89 25 74 -9 12 72 32 40 -32 -34 8 20 -13 52 -40 3 -44 69 -39 -68 36 27 -5 -47 -27 73 6 -48 29 -73 7 -30 -31 -20 -33 83 -67 59 -1 61 34 7 13 14 -26 24 1 -33 -29 87 3 -35 -8 -50 -12 25 -90 -61 -38 15 35 15 -78 -90 0 20 -8 16 21 -48 -76 -88 -39 24 87 1 51 32 -50 -6 -64 78 32 18 47 4 44 -31 25 -60 6 115 24 -6 75 122 23 88 -16 -43 25 20 -93 47 -30 5 67 -7 80 10 105 -20 65 -2 -10 56 -127 47 -31 30 65 5 -47 118 127 -41 16 -16 -12 -44 106 -19 7 -99 -35 -25 104 -12 11 6 -40 -39 1 -77 -37 22 -15 -19 53 5 -29 -1 -6 105 -6 -42 -61 109 -16 -79 -53 61 15 -63 -96 30 -42 81 -15 27 54 57 29 -55 22 -54 -67 9 6 16 26 21 -30 40 40 -56 -10 -14 49 19 -22 -32 -19 -40 -12 -26 36 28 -41 -23 -25 34 30 -57 -12 -32 71 -6 -10 50 24 14 15 56 10 64 4 -8 -8 5 -52 14 9 -38 33 -12 58 29 120 -105 78 -25 68 -31 112 -39 -66 92 -19 -61 -13 18 -123 21 -86 -49 -35 -45 -3 -124 13 -95 -17 27 34 -36 37 -25 -69 -71 123 56 6 52 94 32 1 17 -84 -77 93 -51 -80 6 -21 -39 13 28 -43 -24 56 -45 -21 66 -41 -72 -26 44 -3 26 37 -65 35 -33 -9 -89 18 -87 -38 8 -90 -70 -43 98 90 -55 2 -14 122 -4 -71 2 -18 -82 -1 -77 -74 2 -2 -29 25 39 -55 -19 -55 1 -44 -23 4 34 -110 -50 -26 -42 29 11 14 -58 16 33 25 50 36 53 86 -34 -99 52 53 -50 -37 67 19 29 -2 25 -1 17 3 14 -40 25 50 7 1 11 50 -31 -23 46 -10 12 -54 -53 -26 -32 -54 41 -43 -49 0 -10 6 23 70 18 -72 19 -11 24 36 53 62 66 91 16 61 70 25 -60 29 -29 -39 4 -2 -17 -14 34 66 19 -24 29 113 -21 26 12 22 -39 118 56 -24 -9 38 1 14 -72 -25 -15 66 26 -13 -13 -37 25 -88 -22 -59 13 14 52 44 -76 -50 -67 6 45 53 -59 54 78 -2 -65 -128 -25 -20 9 2 11 -49 36 12 -5 -10 -44 58 -71 33 -27 -15 -55 -36 21 48 -19 3 27 -52 -28 -14 8 -55 100 8 -49 -12 5 -13 -16 -51 -25 -13 -24 3 -32 92 25 -12 -1 -35 -15 7 13 32 62 -8 86 -39 -3 12 -35 -7 -12 -11 -39 14 -11 -38 -101 60 -29 56 39 -19 18 52 6 -16 40 -50 18 -48 25 -38 -11 -21 -44 -11 -71 60 -70 -79 29 12 -5 20 14 22 -29 4 8 24 9 4 -56 -64 95 -24 -60 23 -2 -26 33 -12 -29 109 -42 54 -11 109 31 -5 6 24 28 61 -32 49 29 34 43 81 -79 -6 36 -120 -13 7 5 -41 -4 10 -12 90 21 43 -14 -66 -36 -25 -33 29 -24 97 -17 30 3 -34 19 -63 89 15 -23 -25 -35 -44 -59 21 -15 21 -46 15 -49 -6 -6 -42 1 20 -26 6 -14 -9 2 -49 -48 -24 -25 -18 27 25 -7 1 14 18 7 59 -43 -9 -4 -14 51 -5 22 52 3 41 -18 -44 18 -13 -10 -26 -6 40 -31 -39 -6 29 -16 -33 49 8 16 9 14 -61 -61 11 17 -24 25 -8 -13 -41 -3 4 56 17 -6 58 48 -84 -55 25 30 53 -47 -19 -93 -8 -18 -3 29 -3 -75 -54 -23 5 -14 -48 67 -26 18 -34 16 -21 62 -49 -29 -51 48 9 -33 23 68 29 122 -6 -45 27 14 -58 25 33 36 -17 -75 48 -35 1 -42 12 -48 39 51 -55 -53 23 49 -108 6 -64 35 -10 -17 -111 -7 -7 23 -2 18 -5 60 30 23 -33 2 0 -49 -26 -9 -9 21 -9 48 -20 -1 -72 17 -12 -32 20 -16 13 -32 -53 7 35 70 14 -39 20 38 -37 32 98 8 54 -8 -10 -27 -91 8 -6 6 -52 -57 15 -48 -26 -24 13 -122 -126 8 21 -111 -25 -126 -99 71 -77 -122 -24 53 49 27 13 62 -80 -124 116 -28 -99 3 31 -111 104 38 44 1 27 -14 116 9 -124 58 10 -60 -18 -11 -4 8 73 1 14 -7 -31 41 43 -47 -74 34 -91 24 21 66 68 -86 56 71 -15 -38 34 -16 26 126 -75 26 30 14 -30 -79 -126 77 -103 -21 -121 127 24 -122 27 -90 -115 88 -10 17 100 33 -15 -21 105 -32 68 -13 -65 -4 -12 1 26 -28 0 -38 59 -66 16 98 -20 66 11 13 45 4 -55 -1 19 19 -63 111 -4 9 -12 29 -21 31 45 -27 -6 2 68 -7 -18 -5 16 10 11 -43 -6 -20 62 58 -28 88 -85 10 -66 44 -11 54 -38 -38 -91 75 -21 -29 5 71 -106 76 30 -16 89 -21 -2 36 -18 -26 79 51 12 -71 32 11 -84 -55 79 23 32 39 -11 -19 89 122 78 -25 124 -25 1 -26 -90 27 15 8 82 28 10 24 -5 19 -7 -19 42 56 -22 -18 68 -51 -58 -14 -40 11 -14 23 -13 14 -52 -38 11 16 -60 9 17 20 24 6 -19 -44 -73 10 1 46 19 44 -13 16 26 -17 -57 29 0 67 55 -10 14 -28 13 -40 0 -74 -39 20 -15 -3 32 -15 -29 -6 8 -28 -32 -49 7 -4 36 -94 52 -48 -5 -25 23 -57 84 -5 -18 -17 2 -67 -14 4 -122 12 -14 75 -45 1 35 17 122 8 22 -35 -13 -18 -24 -36 -23 26 18 55 65 -40 72 62 124 48 -7 11 -72 11 -10 55 -25 -14 12 -59 9 -26 35 3 -8 -51 -32 43 -52 17 15 7 -9 -33 -42 4 32 9 -58 -26 21 -26 -80 51 3 -55 -9 -29 -24 -3 -71 -25 -15 3 -34 60 -30 -33 -2 -45 43 -40 45 50 35 33 31 -17 -47 -33 7 -25 24 -8 -2 -34 -35 -31 -52 18 -31 -19 -40 -27 3 13 -26 30 -44 23 32 1 0 -16 -3 5 3 54 -4 -9 41 -15 20 26 14 13 30 1 -7 -9 0 31 33 10 -62 -4 3 0 -7 -15 65 0 -34 -9 36 -26 -50 36 5 -17 -5 -3 -2 4 -25 24 62 -31 -42 -46 -62 10 1 -23 33 4 -55 34 6 -13 -59 -24 26 28 1 13 24 -17 -19 -27 20 -14 -17 7 26 -50 6 -17 -42 14 -19 -65 -53 11 -30 -26 -2 12 -31 0 57 34 -69 39 -11 -32 -27 -21 -35 27 31 -2 18 -24 -48 7 56 -33 -14 -10 -76 2 60 26 18 -33 -22 -5 -3 -40 -20 25 33 -8 -22 -48 25 45 -34 20 -7 15 14 -8 -33 2 -76 -43 -53 2 21 7 21 26 -26 34 -22 32 -32 20 -22 8 4 -34 -1 -14 20 30 3 28 -21 -21 40 86 26 -15 14 31 -1 14 -14 9 6 13 27 -18 -13 -33 1 12 -31 10 -76 0 -20 17 28 -14 -52 -1 56 -2 -24 16 -23 -29 3 -32 14 -17 -59 -23 7 -41 39 -73 5 -12 -60 37 -32 32 -59 -19 52 11 -60 -32 -34 33 37 53 16 31 14 11 37 22 69 -52 73 -37 12 -48 -18 23 -5 13 12 12 16 18 28 -44 16 10 41 19 -5 4 -10 32 -40 -12 18 11 -20 -7 6 -15 25 -11 31 -3 37 -8 10 -16 35 51 2 14 -22 24 -10 -41 -32 -22 12 -12 -13 30 -34 13 1 17 -43 0 37 16 -38 -8 31 5 -42 -22 42 -3 19 -8 27 -15 -12 30 21 -12 45 8 -1 27 -36 13 54 11 -9 6 12 7 28 -50 -40 -13 -7 1 26 6 12 -1 -6 23 -7 -77 -17 -24 -6 23 -32 -5 -21 -6 -12 -12 2 -100 36 -60 -45 2 -14 -74 23 63 29 -30 11 24 73 44 -29 0 -48 -21 37 -31 -50 36 23 -47 44 -21 21 -24 8 -18 -64 45 -64 -5 41 -7 43 14 -28 -10 23 50 -30 -5 -31 19 50 -5 16 -60 40 7 38 -13 26 -33 -31 -25 -16 -30 57 13 34 -6 -30 -2 -39 -5 4 9 -28 -70 -27 73 46 17 -10 32 -30 52 14 9 -17 20 -30 25 -8 16 25 0 27 -2 -15 16 1 -26 4 3 27 -23 53 -13 28 21 13 2 -14 -9 -3 -5 -5 21 12 11 20 18 16 10 -45 -23 -38 25 21 -3 26 18 -13 -26 -27 8 -86 32 25 1 20 46 -30 -78 -14 54 10 -38 72 -27 15 -4 55 24 -3 -39 13 -16 19 33 8 88 107 -4 51 3 -44 8 -33 35 21 16 79 -33 -8 -41 -2 -5 13 11 -33 2 7 10 -55 -26 27 5 -24 15 3 0 -38 -28 17 -5 44 34 1 -18 -5 22 3 -14 12 20 -13 -15 -24 25 25 2 -12 64 23 5 -15 1 32 31 -5 -16 -52 -19 24 -25 -38 32 -25 -23 -9 -85 -1 -6 12 -13 -7 -17 -38 -8 -1 -16 14 -40 -27 -13 -31 9 -6 -61 -2 16 -15 -17 15 14 -48 52 -9 -4 -3 35 -10 -24 -21 9 23 23 -26 5 8 -19 -7 -22 14 7 -46 -43 1 -12 41 48 -54 61 34 -14 -19 6 -37 22 10 21 34 -76 29 41 35 11 107 -1 35 26 39 10 24 32 36 38 -5 31 -15 -23 -23 6 -5 91 0 -45 11 -16 48 19 3 66 -11 -80 -24 8 24 -1 -22 22 37 7 -45 2 -37 34 24 -25 -9 -106 -43 17 -26 1 -85 -72 -34 -5 46 31 84 -40 -51 -45 24 30 -36 43 39 -17 4 18 4 -19 -13 9 8 -33 -20 -35 5 -38 3 69 53 12 8 -42 2 -33 -30 0 -42 25 19 47 17 13 -25 -16 20 -22 16 -33 -12 -17 20 3 -20 13 -24 16 16 13 -33 -11 -30 21 -3 -4 7 -50 -57 -32 -36 33 19 -3 30 -12 -10 -72 -18 -58 -28 15 -53 0 34 77 -5 -31 15 -18 35 -30 49 -62 -21 -74 -17 0 -27 38 14 -111 -49 2 60 -44 -31 -33 -43 -42 119 -33 -20 1 -48 16 -39 -72 74 32 6 -11 -109 71 -52 -50 20 -19 37 -21 -67 -37 52 53 8 -47 43 -26 47 -1 -8 -7 30 -36 63 -21 -11 -74 27 -40 1 -74 52 66 -1 19 16 45 54 -12 12 -50 27 -27 -36 -20 80 45 -111 -60 56 -29 -69 -47 25 17 35 -10 -2 16 5 11 19 20 8 -30 29 37 4 29 -15 -20 -7 -4 16 -9 1 5 -40 0 -18 36 51 -15 10 46 -48 6 -30 25 -53 4 11 -19 30 -42 -3 -14 50 -10 20 26 -28 2 70 -16 -43 -47 -94 -43 -65 -16 -15 -69 41 -53 11 -29 51 31 13 -82 64 5 89 51 -18 7 -31 52 45 -72 -15 -14 -61 21 -8 -60 20 98 -50 20 -120 18 -74 127 62 32 98 -35 75 37 -38 8 11 -90 56 24 -63 0 -45 -2 -19 -5 -12 -12 0 14 -60 45 23 19 -15 47 -69 58 8 -16 -27 -66 -13 38 -122 -38 1 -16 -29 97 36 -38 -33 23 -4 90 -12 36 22 -62 0 -46 -31 -22 -34 -3 -9 -31 15 -34 57 -17 6 6 -45 -12 -53 1 32 62 -47 -26 -26 28 3 -63 3 9 8 -21 -13 -39 -7 -19 12 -44 15 -27 -4 -9 20 -14 10 10 0 9 -79 23 -21 39 34 -10 37 -2 12 26 -60 23 -19 -11 2 -43 -7 -74 20 0 -8 -42 -41 38 6 -57 55 -50 66 11 35 6 -51 -48 -18 39 -19 -10 -20 22 -34 20 15 13 4 -67 -28 -4 -10 -36 -5 -38 -12 -1 8 34 24 -10 -38 -12 -12 -58 12 26 -5 21 -12 34 32 -34 33 -21 -41 11 -25 42 -43 -22 22 72 45 11 14 -47 24 42 -3 0 33 17 12 3 30 -58 -17 -5 -4 -23 -2 -24 -19 -22 -50 6 -43 16 16 7 36 -3 25 17 -54 -46 -15 -21 -19 43 -29 9 -30 -10 20 5 -45 -10 -47 18 9 -37 -2 -12 -24 4 7 -5 7 6 18 -17 32 9 -12 12 -49 5 21 -29 1 -25 -8 -7 0 -24 3 28 28 -30 19 18 -43 -51 9 25 49 5 16 -32 40 32 -9 25 -14 -9 19 11 14 39 -34 -14 14 -36 28 -1 -23 17 41 0 1 16 11 6 40 8 41 36 -67 -7 1 -38 -46 21 32 15 -30 -15 17 -14 -27 -55 4 6 -1 4 29 13 -1 44 -13 26 0 -44 13 -33 -19 8 32 4 -32 4 38 31 -11 6 9 13 46 14 -12 -11 0 21 13 -17 13 -29 -26 -9 -34 -11 27 1 6 34 26 -14 7 29 -17 -28 13 -9 27 -25 2 1 -13 -5 -11 28 21 -5 14 -38 -23 -1 27 28 -26 14 -6 37 13 -27 20 6 -1 -25 1 22 -28 109 -59 -21 -60 42 26 41 28 55 6 15 76 36 -54 17 35 -11 -55 79 37 -15 11 53 17 19 112 29 41 -2 24 61 -43 11 -12 -34 13 29 9 -52 27 31 -26 -30 -40 26 16 -21 15 -65 3 0 11 9 6 6 -2 40 -16 27 25 39 -22 -36 18 -44 -24 21 43 -19 -5 -26 67 -11 35 -55 -2 35 30 0 32 -23 15 17 12 25 5 -22 71 -26 -109 -86 17 -42 -43 -11 44 -49 5 28 -20 -17 31 30 -12 -4 1 14 -8 14 27 -60 -19 37 3 -34 26 26 -30 -8 39 46 -11 12 -34 15 -51 32 35 67 -31 -46 -1 -14 -31 25 12 -4 -10 6 -40 -25 4 8 60 46 26 -24 -37 -4 15 -4 44 18 80 44 -1 25 -16 8 -8 91 -21 25 -2 -42 -26 -2 54 5 -30 -3 57 8 -23 -52 30 73 -11 -33 79 -51 78 -4 90 25 -2 -31 20 9 -4 -39 -82 -1 -16 -27 -50 21 -47 -15 30 4 -14 -34 -42 -22 -24 -24 -41 -40 20 11 -24 -86 -7 71 5 43 28 20 -29 -4 67 79 23 -57 59 -43 36 -74 25 -89 -2 -16 -24 2 6 28 11 -7 -27 53 -12 -9 -14 -19 42 -5 40 1 14 7 -35 -4 -11 27 4 -2 -15 23 -21 24 4 -20 -31 6 -26 27 7 -15 46 -7 7 8 -25 -5 -34 -2 15 -49 0 -6 -2 4 4 28 -5 -30 -109 50 -13 9 -56 95 8 33 17 1 56 24 73 -30 23 -11 -79 -83 77 -31 -40 -125 -21 -13 34 -3 57 19 99 -59 82 -14 -11 9 58 -22 47 -53 -71 -32 -14 84 18 -3 -28 11 -69 36 81 49 45 -12 14 32 82 8 -13 41 -4 -71 -48 -23 -3 -8 45 28 -39 -46 59 -20 52 20 30 -47 -20 -33 37 15 -29 -46 68 -41 -25 93 24 -46 -59 12 14 31 9 -55 66 -54 -7 -31 14 44 -5 25 4 -20 -73 -29 35 23 -45 36 28 65 -41 -11 -12 -10 8 6 -2 -18 11 -22 5 -22 0 -28 -7 23 18 -2 -9 35 -12 -4 27 -15 52 -2 6 43 -8 3 21 18 -72 -63 20 13 41 7 -57 -57 55 0 10 65 33 65 46 -2 57 -36 -49 41 -65 28 2 64 94 -46 43 56 30 -40 51 23 -7 46 121 13 -86 -24 51 28 8 -26 124 3 2 -25 30 -52 13 -61 -85 -90 7 1 -62 67 23 -25 -74 -18 -71 79 39 23 -24 20 -44 36 67 18 70 3 25 -13 0 23 16 34 -10 55 -91 25 8 -10 -82 61 -97 7 -5 -60 33 25 90 1 6 14 -9 27 1 -30 -49 52 52 26 -12 -1 -23 -21 -32 10 27 -1 1 12 -14 -10 6 12 -21 -8 -11 54 -35 27 34 31 6 36 -24 22 34 -1 1 14 -25 25 -2 19 0 -40 23 21 -27 0 11 -36 -8 16 -7 40 -56 -13 -28 9 -42 -10 -20 26 2 -32 32 2 -61 8 0 -18 -15 33 49 -21 0 -3 -15 6 -60 -4 -37 1 -16 -16 -39 12 7 2 1 9 -1 7 19 19 29 51 -11 5 -11 26 -26 21 -26 7 4 9 3 -29 1 -21 -10 21 -5 -26 35 4 55 9 -11 11 -1 -24 -2 48 -14 -21 45 34 11 -38 -23 25 -3 -43 7 -20 -78 -29 -21 -17 -22 -4 17 -30 -35 -12 -31 -26 -30 12 -38 5 23 24 -16 -25 1 -12 -15 11 -23 -45 -28 4 9 31 35 29 16 25 -18 -18 -18 8 -7 39 39 -15 -28 -34 -33 9 -36 -24 6 22 -1 -23 19 8 -16 16 17 28 -31 51 -67 6 52 -72 -13 43 120 18 -15 58 -30 -60 41 -12 26 -65 -28 48 -4 25 -87 -12 18 -61 -40 -11 -30 -39 24 24 -31 -40 42 -49 -120 24 -5 -34 -94 56 -16 5 -42 75 -120 9 -21 -35 -6 -14 -5 18 -2 -22 -17 -13 25 -5 -5 -56 6 1 -2 10 7 -11 -26 -12 51 -9 -12 -16 12 0 -27 -5 13 17 58 5 15 16 11 69 4 -17 34 28 68 -57 39 0 -19 -42 36 71 27 38 24 44 54 3 1 -24 16 -6 19 2 37 -2 45 -44 -29 -49 -42 -23 -9 -6 -10 26 -20 -31 25 16 26 -27 30 33 -19 24 -34 -32 -25 24 -9 35 18 -7 41 -24 13 -51 -29 27 -14 -60 75 73 -14 3 37 -19 -29 -46 -43 43 45 -19 -5 -29 -33 58 -33 72 -35 -17 -45 -31 -3 -28 11 -3 0 -4 -35 -28 86 -14 -13 -17 11 74 -42 17 -27 62 -12 27 -2 62 -2 16 25 46 38 33 5 -22 33 5 25 -12 -44 7 32 -17 -5 -14 92 31 -28 23 -36 29 -14 41 24 5 40 -8 -17 -60 48 25 -40 -62 -51 38 5 -26 22 -24 -18 -10 56 -51 -51 -20 6 28 -16 -21 -35 -22 -25 12 8 -15 2 25 -23 21 -34 -17 -5 -40 -38 -11 11 -7 -30 10 2 -47 -17 -19 -10 35 11 21 -23 -20 -55 -20 -1 -34 -18 -15 -32 -1 26 -11 23 3 -13 6 -42 -2 -5 -61 19 50 9 10 -11 -18 -14 -11 4 -40 64 32 -118 15 28 -24 6 17 -65 5 58 -18 16 -10 41 65 -57 8 -1 -10 -11 21 21 39 -41 -53 55 2 -31 35 64 25 42 55 -13 -6 36 -41 -49 19 37 -16 -52 11 -21 5 -4 -32 45 15 -20 -6 99 -13 23 13 -39 -14 -15 -9 33 -12 -19 -15 -18 22 27 0 -26 -19 -14 -14 5 -8 23 -6 22 63 -21 32 -11 -27 9 40 -24 -14 -6 -31 58 -7 -8 -29 6 -39 -17 34 -7 -27 10 -17 -4 22 14 38 37 -15 4 65 -13 21 -8 23 51 -43 19 40 1 10 -32 12 8 -24 25 -25 -5 -11 -24 7 -27 5 18 25 26 -60 -36 -69 23 75 2 22 24 -2 -13 -6 -16 -20 20 10 22 20 8 68 -36 15 -32 16 42 0 25 -7 73 17 6 -3 2 -11 16 -38 26 40 -10 -14 35 48 26 1 30 -28 -6 14 -16 -31 6 -26 -38 -48 30 44 -22 -5 12 43 -16 -31 -30 3 -16 18 0 -42 -40 33 -35 -33 44 42 22 22 45 14 8 -18 -25 -6 -33 53 -8 2 -31 38 -10 24 -6 29 22 -9 -24 25 2 -33 -26 32 -3 -17 0 14 -24 -16 -6 17 23 14 -60 8 -2 1 28 -29 -9 -32 25 12 -39 29 32 10 8 -6 -24 -23 -19 -12 7 27 2 -6 23 -30 22 6 60 -7 -8 0 1 9 6 47 -3 -25 -18 3 -19 4 14 -33 4 -57 -29 -20 16 1 -27 -21 -5 15 -14 -3 4 -13 -33 5 20 -1 3 0 -6 -43 35 12 5 -37 -34 -22 -1 -45 24 25 9 3 34 9 45 12 -4 16 26 -6 -3 -11 -2 4 10 -25 -2 -19 -36 -18 18 -12 18 43 -63 -35 10 41 -11 24 -30 23 42 -11 -50 -35 1 0 24 30 43 -9 0 22 -38 17 0 61 -5 37 -17 -47 -27 -18 -20 23 -2 53 -36 -39 27 -33 39 -7 -23 -25 -7 17 -6 -34 -19 -16 -55 26 6 -2 -6 64 -7 -15 24 15 43 -8 -12 22 14 26 15 26 -39 -12 -19 16 18 -15 -15 -2 22 -12 -19 -12 -26 14 -26 50 12 -16 17 48 24 -43 -50 0 9 -11 -44 -32 38 3 -7 -27 8 48 -23 -10 39 -32 5 -44 24 -8 10 33 -74 43 -3 25 57 64 12 31 42 16 17 -32 -13 19 -2 51 24 -1 -14 -27 -10 -2 -6 -51 -6 -2 4 1 -5 8 -44 38 -10 -12 56 -36 11 38 20 27 36 49 24 30 16 -27 -4 -2 -37 21 -30 -24 16 -30 63 -35 3 -8 -37 -11 10 -2 -19 -25 4 -3 -21 -21 -5 -7 -25 -17 3 6 -25 -8 -5 -10 -37 -14 -11 11 47 17 -16 28 -9 5 28 19 16 30 41 -23 -26 -25 -44 -16 -8 20 -5 -30 -25 -52 4 -14 43 19 -1 35 1 -51 -14 -10 106 9 -54 48 15 35 -62 18 50 -80 -47 4 -14 35 9 -35 16 -25 48 18 12 -5 -43 -25 -45 2 -15 24 58 -4 -57 -8 -26 -54 -73 -2 -33 32 -30 -60 -46 9 -33 -36 -30 0 28 27 5 15 56 28 4 10 27 42 58 25 -43 53 10 27 11 1 46 -43 16 -76 -26 -70 67 40 33 -35 -60 16 38 9 -70 0 0 6 -17 6 113 -23 44 33 8 55 -13 -58 -44 38 25 5 25 20 -19 2 -45 22 -18 59 32 -13 -8 -2 -45 -29 -30 36 60 38 -4 17 11 17 48 -23 -29 30 0 27 13 47 2 12 2 4 44 -8 -29 0 3 -32 9 26 27 -28 -93 -12 -99 -53 95 -50 9 -60 -25 -28 3 -18 16 -92 53 5 8 -69 38 -20 -21 -8 -113 -40 -44 36 -80 -5 -86 -6 -25 4 -38 -20 11 -52 -95 -45 -52 24 -31 8 -7 -5 -25 100 -40 3 21 19 47 -15 32 31 37 15 -65 18 16 -45 2 -76 61 -18 41 -52 -38 31 12 2 7 -29 39 28 -30 -30 -50 21 -10 8 37 25 8 54 15 4 65 3 33 -26 -46 -12 58 -14 -9 -43 41 49 -1 -30 4 -18 -62 -27 -13 -25 17 -9 25 40 -4 13 -6 -11 -76 17 -33 -14 22 37 56 -8 47 -28 35 -40 33 -12 21 -42 -25 -10 12 2 15 -14 -42 39 41 -32 73 11 5 -23 -45 -22 -5 -5 -3 14 1 7 11 9 4 13 22 -10 2 4 0 -21 6 9 10 -1 -20 3 0 4 57 -1 8 -32 6 10 -13 -9 12 11 -24 -21 59 2 17 16 -28 -7 -47 -9 -28 20 -14 -39 18 -7 1 16 -15 -15 -3 13 -18 34 -14 -23 -1 -15 -4 34 -12 15 9 8 16 6 11 13 -2 -14 22 1 -1 10 -50 10 -5 18 -9 -10 17 21 15 5 -4 53 3 -10 17 6 12 14 0 13 9 -8 -17 2 1 10 -16 11 11 9 10 -2 8 -22 8 -13 15 3 6 -4 9 7 -8 -3 10 -1 4 16 -6 27 -5 10 -11 -8 -7 -4 -12 12 8 4 20 -11 -4 -2 76 -17 -5 1 -51 -23 -24 -4 23 -15 -3 38 -53 -12 1 -5 -17 -21 12 9 21 33 -2 -36 32 24 -33 -3 -22 20 12 10 25 36 32 -10 -19 41 -8 -7 -7 11 62 -21 -28 -23 -13 -5 -37 15 6 2 -38 2 33 5 24 -18 -24 31 24 19 17 62 -1 -54 11 22 -31 17 -33 -40 9 -18 -42 36 26 -15 10 25 -2 41 52 -16 -24 -1 -26 -45 -31 -41 4 -33 2 -40 83 13 16 29 41 -22 -18 -19 38 10 -6 34 -18 -16 -19 -22 -25 5 -39 -25 -36 15 -25 28 -11 17 21 20 18 -3 25 39 -11 -32 4 38 -22 13 -1 -22 2 -8 -10 5 -13 -13 2 -29 24 -13 -5 32 -18 0 -40 1 -31 17 43 -42 -29 -37 -59 2 -59 -2 -20 -4 44 -1 25 110 6 -13 16 15 -16 37 -35 41 -49 95 38 41 21 7 19 31 37 -29 -37 11 0 -6 33 -19 18 13 13 -20 -25 112 -54 -50 -18 -43 53 7 -14 33 12 -46 17 64 5 65 -108 -15 0 11 -10 18 22 -77 31 -21 24 8 14 51 16 5 86 -17 -16 -38 5 19 -16 -26 -1 20 5 -91 -21 -14 -24 29 0 8 6 -14 60 -18 3 35 -3 -24 57 -35 30 -16 -47 2 4 45 -1 47 -20 -24 0 16 34 26 19 18 20 44 44 23 -12 -25 10 -46 -9 -45 3 -11 7 39 -22 -29 -31 -1 12 -6 48 -8 20 28 12 16 -29 11 43 -14 -38 -42 -103 14 -42 21 -16 -19 -20 -65 -33 -33 -14 -37 21 0 47 -37 19 -82 -49 -26 23 -18 -4 41 2 -11 25 5 41 -14 -22 -51 38 46 12 25 44 -46 -18 51 35 -18 49 -13 6 22 -27 22 -62 -1 26 -34 51 -4 17 -42 69 26 -26 -41 87 -31 -14 53 35 11 23 -37 5 -35 24 -30 -38 -22 -4 9 31 -89 -69 47 17 -4 -45 27 -28 -4 27 -18 -54 -54 -5 -46 23 20 36 -18 -19 -11 20 -15 37 4 -3 -9 10 4 -7 -8 -28 -5 -6 18 68 -34 21 -12 -36 -19 -12 -7 -1 -19 -39 10 -19 -31 -44 -11 -22 36 -69 8 -12 -78 40 -11 -3 -17 53 52 22 31 -3 -8 -6 7 24 47 55 -23 -21 -8 -31 -2 33 -82 58 14 23 44 -33 65 31 5 28 -34 -1 -9 -47 16 60 -17 -57 56 -84 48 -22 28 -9 -5 28 -39 63 37 -1 12 73 -49 42 -23 -25 -47 117 -120 53 -20 47 28 -53 -30 2 -3 -73 6 27 -41 -8 -20 54 63 -22 -31 -21 -61 27 2 -9 22 116 35 -22 -52 -77 39 49 15 8 -10 26 -21 37 -40 30 -71 5 -56 54 4 -33 -1 49 -13 20 24 28 -4 -69 31 -10 28 -2 -1 -70 -23 -18 -4 -33 -7 -9 -45 2 40 9 -24 -10 -3 -9 38 -35 72 7 -22 1 -11 19 -33 -28 26 -22 -58 -40 19 1 -23 2 7 24 -36 66 -4 -1 29 22 2 -61 42 11 -125 68 -42 27 -1 27 44 62 -79 35 -26 -80 -2 6 13 86 49 -9 -29 -10 126 -54 71 -4 -26 -80 -20 56 9 -27 -68 2 -43 48 -36 38 -22 -11 -62 56 -31 -51 52 -61 -44 61 -70 -122 -67 -93 11 -50 64 15 0 -33 -61 -23 -34 -12 30 -97 -16 -47 38 -41 43 0 -27 5 -16 28 -71 -43 3 -5 -8 17 20 23 -11 -40 29 12 -54 12 51 25 -15 -24 1 -49 -26 -52 -13 6 41 -11 7 -28 -29 16 41 -75 20 -21 8 -55 -17 55 -11 29 32 -18 -8 -2 -70 15 -9 -17 -23 -54 -87 95 127 -125 17 -118 -127 61 -77 -12 6 -42 -30 -114 111 -83 69 -102 -45 -125 -14 110 -53 -2 -15 -17 -25 42 71 97 51 127 -74 -51 116 9 -63 -80 -32 99 41 -6 15 57 47 -19 3 -125 -26 82 -127 -101 126 95 121 123 121 123 -88 -78 125 -26 104 -126 3 125 17 94 21 -123 -73 127 83 126 127 -91 72 -40 -125 -20 -16 105 -59 64 -55 79 -64 85 -35 -22 13 -112 -38 107 28 -77 26 -83 109 115 126 -25 127 -120 -8 38 106 13 127 126 7 15 53 62 -85 88 38 -7 -116 103 126 111 -22 -38 -74 27 -76 35 54 -100 75 33 24 82 -56 30 -127 -68 126 -46 -83 62 5 11 -3 -1 60 -115 -61 -9 -116 92 -73 50 32 -34 91 111 125 -42 121 -122 70 127 -35 -10 74 10 72 -57 -78 53 34 -24 4 62 -33 -92 39 9 16 117 -27 112 12 15 -83 82 -104 6 81 -31 64 1 124 3 -121 -128 -41 125 -98 127 -32 6 7 -84 53 -66 9 -112 62 -12 -111 -69 -127 126 105 64 21 -41 -101 127 -17 66 47 -119 -88 -128 -9 -49 79 -88 -31 37 113 -37 -51 -45 -46 -66 -81 -112 116 36 -30 -128 124 -126 -70 22 -46 -85 125 127 -68 64 -90 -10 99 72 -124 76 48 71 114 103 -2 5 5 19 17 13 9 -53 45 -3 -45 123 127 -18 -87 12 -126 50 24 115 125 105 -128 -102 72 -19 124 -88 -77 127 -5 -21 -121 -40 -117 53 127 -70 -49 120 -119 48 -60 76 8 60 56 125 -47 -37 71 -4 98 -67 -87 -29 5 38 -64 -75 21 51 37 -90 39 70 -47 31 124 -27 -7 49 -126 -20 12 -63 -125 115 -42 126 42 -82 122 1 39 25 16 112 68 16 100 9 -104 29 35 26 -124 1 -63 69 -125 123 -72 60 66 69 -24 -106 19 127 -127 -15 -58 -91 -100 33 -128 36 19 -12 -40 125 -2 45 -127 -27 -43 64 -29 -36 124 17 -84 34 65 -60 53 -98 58 122 -18 70 85 61 -18 -73 -28 93 -2 86 101 -14 72 24 -39 13 75 53 45 10 57 -20 -49 42 -19 16 -11 -109 -70 -103 55 22 126 -41 62 -61 -71 -83 -95 0 127 40 -56 127 94 -65 -3 -99 -79 -117 105 33 -5 -117 -44 54 63 98 124 -99 -123 14 -99 -127 97 -53 16 119 59 -128 -103 42 -48 120 17 127 -119 127 -63 -45 -98 127 124 32 126 126 102 -16 -35 127 -22 -128 -84 23 108 -30 -121 -127 116 -57 -128 24 -127 -16 -125 -117 47 125 12 -126 120 -107 -7 -90 -102 -30 69 -46 -59 73 -128 22 16 16 -28 94 -62 -69 -128 -61 -38 6 50 -125 126 125 -127 127 29 -72 -48 8 123 -36 -127 -124 78 33 -25 58 -24 -3 -48 -21 -13 -128 -84 36 127 30 -41 43 -128 57 39 -80 -64 86 -123 48 65 -52 30 79 127 67 67 -118 72 -125 -4 -127 -86 -120 84 12 12 -26 -52 -4 -62 -21 127 16 -111 -112 7 117 46 -114 127 99 -28 5 -54 -67 -33 33 125 127 12 6 -109 -64 -108 99 65 -26 13 100 -102 38 -11 17 100 8 -2 63 -75 46 -123 3 -122 -20 -37 -27 -125 100 -8 -126 25 -8 123 95 -126 127 73 -128 56 -121 -88 23 102 69 26 -128 -61 -15 98 11 18 127 127 125 -88 -38 27 90 -51 124 49 -64 51 48 52 -18 76 84 83 3 -125 80 54 12 -91 92 -61 17 117 -101 -106 117 20 -55 -67 -97 -91 -128 74 126 -25 -10 53 -105 14 -126 -3 54 12 93 30 20 -101 -128 -98 -111 -59 -5 15 4 -43 127 4 -65 49 49 -107 -44 -128 14 102 84 -32 -62 41 -2 -73 46 13 -58 93 -4 -24 -109 -50 -128 -43 -23 -90 34 -43 8 -60 75 -15 -50 127 -114 -128 120 119 63 41 127 87 -127 -121 120 -64 30 64 116 10 55 -125 57 -116 -117 42 101 96 109 127 -128 80 8 -122 85 126 -78 -6 127 126 -126 -128 -14 35 21 -63 24 -37 -107 122 -123 -46 126 -56 106 125 -90 -127 71 25 -11 -29 -113 121 -80 110 15 -125 -18 71 -116 127 -124 63 98 -43 -9 -66 -37 -63 -35 -4 120 2 -124 82 8 75 -128 -50 52 69 -8 -74 -127 -13 55 92 84 127 0 12 -54 69 -95 -69 74 -128 -29 -10 -91 127 -94 59 -33 127 77 -35 67 -82 -121 52 18 62 45 1 -128 -84 57 -50 64 88 -108 -13 -80 -26 -20 18 92 -81 -10 -92 13 -75 34 1 -127 -128 -58 -24 127 -26 11 17 -47 -103 -127 68 -127 53 -126 19 127 65 39 -1 -87 70 121 -110 -90 -38 44 -29 -65 -15 69 123 127 68 10 -127 120 126 70 44 76 124 -127 50 117 11 -121 77 65 -34 -125 -42 -36 69 -46 -39 109 -42 -20 -125 43 -37 11 -33 -37 -127 40 127 8 127 101 101 -115 13 83 -118 -47 -68 127 -69 36 -10 27 -5 125 -2 -126 102 -128 -3 50 -103 124 30 -87 -126 76 -121 12 -53 -24 127 -123 -124 108 -125 88 88 0 -77 -126 127 -23 124 127 36 -68 -106 -78 127 125 78 82 -128 -48 127 -43 127 -41 60 13 -4 -128 -97 38 85 -73 -84 -38 41 115 2 -41 -119 105 -128 30 -128 -32 91 127 104 -102 43 92 126 19 -123 44 -30 118 -27 127 8 -7 123 124 -59 126 -127 44 -119 90 -121 94 -10 122 -40 69 2 93 95 -21 104 122 -53 48 119 51 117 -127 -42 -28 127 -52 68 -83 127 48 38 74 116 90 -128 10 56 127 -97 88 -128 -126 122 9 -111 113 -108 53 34 75 126 64 77 127 -10 127 -38 -50 -35 124 103 -75 15 -126 88 -89 -126 -6 6 6 -56 -104 127 -71 -53 70 31 88 -65 2 -54 -12 30 -20 -60 -127 124 124 21 125 115 13 -4 10 105 -29 -126 -103 -105 -40 127 -13 -127 -46 90 -60 23 126 -127 -71 3 -14 56 -63 -125 78 -78 -55 -127 86 72 -82 -85 39 16 -31 62 -102 37 114 -90 127 -14 -50 -21 16 9 94 84 56 -62 91 1 9 -63 99 -2 -76 83 -117 -48 -93 -89 110 124 -110 119 99 82 -13 -51 -111 125 18 102 -49 49 -68 5 125 -91 77 94 3 2 5 12 95 124 -93 126 125 -120 0 -98 -70 -46 -85 -117 -75 57 79 -52 100 94 -84 16 -104 -83 64 96 22 69 -126 -39 109 -124 94 29 -55 125 -118 -71 -72 -125 120 -116 104 -98 61 -127 127 -30 125 -110 127 70 62 126 -120 -73 -28 -40 118 -13 -90 69 51 81 -127 -107 -128 -44 127 122 42 -128 0 -33 56 76 29 -79 18 -103 100 -35 -108 -125 108 -12 -74 48 126 49 -86 20 51 102 5 -51 -91 -126 127 -89 -128 52 120 -90 69 46 66 -99 119 -122 -38 -66 -109 -126 65 127 -49 64 -116 -49 -127 -128 123 59 -115 53 -50 -40 -13 126 -113 -68 127 -72 -91 125 -55 -74 126 -125 96 -1 -96 52 53 -114 123 127 30 71 4 -36 55 -118 42 94 -45 -103 2 -21 -117 24 35 82 -123 25 -102 -125 126 -63 -120 -8 -126 76 127 70 125 126 -18 126 -128 -3 -126 -6 67 121 125 -127 18 -83 117 -45 120 14 76 71 127 122 -72 80 -60 -104 49 -106 31 8 -56 -26 43 -58 126 -76 63 49 36 -128 -62 -103 46 -122 84 -53 -124 103 -57 127 127 7 117 -128 -12 -128 60 16 127 33 5 127 50 31 11 69 4 33 -32 -121 17 -105 51 19 -18 115 -127 -42 -124 20 66 -32 127 127 26 124 59 25 -8 102 -128 -27 -11 106 -38 -23 -81 10 -116 73 32 -122 123 120 -50 116 69 4 114 44 32 66 62 127 80 38 42 -55 100 -46 124 111 -67 119 28 65 -13 46 127 -51 108 123 47 -93 60 -118 23 -123 -114 109 126 -124 -124 11 79 7 -26 -67 -13 -116 -7 117 -102 -117 57 -128 22 -68 -124 17 -83 -79 36 125 -61 7 -125 -16 56 75 50 -122 -18 107 -13 126 123 36 126 -82 -85 -20 89 122 2 127 -128 -87 127 25 -125 69 8 90 56 -29 -48 -17 125 19 -104 49 -29 -24 -56 -70 30 -14 66 -128 -69 120 79 126 -116 64 15 -39 -66 -6 -127 117 57 63 -123 19 126 63 127 -4 98 -124 28 -104 20 -113 125 123 23 127 118 125 -128 -66 84 -32 91 47 28 -78 -128 -36 -2 38 -86 127 36 -49 121 -116 -127 -22 53 -106 109 -92 -53 118 73 -43 118 -3 -76 39 -29 126 50 -42 70 -27 89 119 40 -115 -97 -39 -74 51 -59 123 23 -31 126 -7 -127 -24 -60 99 11 -92 19 29 -104 123 46 20 124 122 -128 -1 -23 -124 127 53 -91 -51 106 5 110 31 121 -111 -33 -55 -61 83 -128 127 -11 124 -36 -68 52 -128 127 54 111 123 -123 -44 92 -100 -82 3 -109 38 126 58 -26 44 89 20 8 -127 -48 126 -48 120 -58 -70 93 -96 116 -60 -54 -83 20 -21 -127 30 -54 108 46 26 -26 -7 4 -128 -60 127 26 67 -56 40 69 30 -61 120 -4 -16 81 23 72 -47 104 55 84 -13 56 -80 6 117 116 -6 -62 -68 -59 -114 16 -50 -31 20 -9 -122 -122 24 -52 -1 -125 127 -78 127 116 51 -7 -52 -3 114 -127 121 56 108 55 2 90 127 -34 87 72 9 124 -105 126 79 -24 44 11 97 65 46 51 -117 -127 125 -126 -7 -123 -109 -93 79 126 -25 71 -58 -35 -22 -102 112 127 -62 -125 -126 -52 11 24 -113 -101 -9 -16 -15 -120 44 123 -35 -2 -115 -92 14 118 -19 127 127 124 -127 56 -122 59 -34 127 40 -47 -127 126 -89 127 80 -63 82 -37 -12 -127 1 10 -57 -79 120 -60 109 -121 15 60 -96 2 127 -68 13 53 90 119 15 115 102 -125 111 112 124 123 -102 -93 -16 119 -117 76 -18 3 -95 127 126 -94 -91 -87 -37 97 125 -39 -42 127 -120 127 -84 96 -126 -1 97 37 17 -97 106 50 -85 30 -3 -72 -101 127 32 125 -4 -68 68 -119 2 -49 120 54 36 126 -128 -33 -112 -110 124 79 -2 55 79 -17 20 -125 -128 -69 -127 -67 74 -11 -23 -2 -126 16 113 -128 -124 -3 -109 100 63 48 124 -16 -4 81 127 -100 73 24 -48 13 126 10 -21 -84 -51 30 124 105 48 63 111 48 -73 -6 -43 103 -49 -23 66 -103 -6 127 34 -127 -80 81 98 69 -19 -123 21 -3 -17 -13 -102 -4 -102 15 -38 125 67 -5 65 -33 -39 -75 -113 80 -5 -103 103 91 -106 117 -117 -122 -8 10 63 127 -127 -100 47 78 -20 -58 33 62 -33 103 127 56 -22 -116 5 -55 -15 55 -17 90 -19 -104 58 105 -12 109 74 -12 111 -53 114 29 -58 40 36 -26 87 -83 -122 -108 16 29 -38 -99 51 -115 36 -84 -111 49 -103 -128 97 -20 -109 1 -48 -61 -76 125 115 112 127 -112 -105 -44 95 -66 -123 -109 -85 86 47 -80 -8 112 127 1 78 127 -110 -98 103 -75 124 47 -16 -120 37 -41 39 38 -127 -77 -88 127 18 -19 -30 -128 61 -14 -80 -90 -53 -99 106 -10 124 -69 127 -127 13 124 122 26 -126 -116 -127 88 -26 126 -9 32 -126 48 127 -32 -86 -52 -125 -119 -5 13 -46 94 -42 32 -26 -11 17 -14 126 31 125 55 -24 -126 -124 -119 125 75 -123 -79 22 63 -47 -128 127 -41 -6 127 116 122 -100 62 -40 127 -45 121 -50 -122 29 125 86 -128 -18 -115 64 127 -128 126 -10 -78 -122 13 -48 89 127 -27 125 -16 -10 1 2 46 53 15 -76 -22 -10 -40 18 50 -22 -78 -26 -31 -53 31 -6 87 8 -53 9 -91 -57 -51 -53 2 19 -51 40 46 50 -23 7 -67 13 -66 -126 -106 49 9 -26 30 -11 -77 -47 -18 16 34 -63 -18 45 -84 68 -46 54 23 -29 -22 14 -9 10 27 80 18 74 -77 -53 16 -16 12 -119 56 66 -24 -50 3 125 30 -126 -56 72 23 -128 19 -23 -84 103 -89 -5 27 62 -28 26 -32 -32 50 -126 -128 10 29 -29 -121 -128 5 59 10 30 57 101 10 -40 -30 -21 69 62 -26 41 57 71 -16 15 -31 -33 12 -13 -34 -14 39 40 -19 -52 -20 27 5 -125 -4 6 51 -48 -34 61 95 15 -6 -7 43 -10 -99 90 -36 4 33 49 -85 -79 -5 44 32 -20 -6 16 -69 -3 -61 -5 81 -3 43 -85 -26 -31 -26 -83 126 -24 -40 5 -23 49 4 -23 -127 -46 -15 -10 -1 24 94 -27 87 -128 -33 -1 -25 -12 -10 -4 -10 -5 13 90 115 -118 75 56 78 -123 9 50 118 38 -47 -17 127 51 -19 43 83 -101 127 -28 44 114 40 95 83 8 92 64 -110 115 75 2 47 -69 26 18 121 22 83 -2 -77 -72 76 55 53 69 27 44 94 -57 -24 66 -84 -85 -7 103 -87 61 119 -73 -56 102 18 30 -37 -19 38 -125 -58 -41 -105 2 17 -89 9 -14 19 -4 115 -29 20 40 46 67 -33 10 -63 -29 -50 -103 -48 -99 22 103 -68 -26 -71 47 12 -42 24 -124 56 -49 -13 36 -25 7 -34 12 -26 9 5 -105 4 7 -84 43 40 73 -34 1 9 -43 40 -2 66 106 -55 -25 26 67 30 127 59 107 -124 56 -1 -54 -49 127 -37 27 -39 27 -57 -60 19 68 -32 78 -107 -5 21 1 46 -13 -46 45 83 -75 119 -15 118 127 4 -75 -26 10 -78 37 29 5 84 45 125 -102 38 -46 72 74 19 31 21 88 8 10 52 126 -62 -13 50 -5 127 57 -96 -44 -124 56 -124 -48 31 -73 -32 -31 -12 -13 -16 -36 45 23 106 30 -61 -26 30 81 70 -12 71 -6 -60 67 6 -19 -23 29 94 116 -83 58 105 -107 124 116 -28 -94 -126 127 -58 127 40 43 60 -120 -45 -83 -49 88 114 73 14 -37 -84 57 -19 20 60 112 7 -35 64 -94 75 -53 -109 -24 -47 57 14 -9 39 -66 -119 10 9 -50 -101 -82 82 -62 -17 -35 10 -128 -92 -127 -89 44 23 -82 91 -34 10 -20 48 126 -2 67 -118 23 122 -89 121 58 105 94 21 30 34 5 71 -127 97 99 1 -81 124 -88 -117 93 -14 -9 2 -54 -27 -43 -39 22 4 -128 63 -30 -74 -23 107 -58 -126 59 47 -71 86 -72 47 -50 -17 62 -84 -47 40 69 20 82 70 -34 115 -20 10 -114 -27 -48 -19 -76 103 -78 -40 -100 0 -47 39 -40 -127 27 -70 0 36 -53 -123 -21 -126 4 -10 65 -27 -124 8 -83 -18 -122 -19 60 23 116 35 -21 -15 -86 -7 -3 -88 -67 -89 -3 81 -71 -99 15 -96 72 -38 -55 -38 -9 -5 112 -106 126 -28 -125 127 25 78 -36 127 -17 -124 -124 -69 -109 46 15 -67 33 118 122 0 -40 -107 122 -116 127 103 -100 119 71 77 56 113 127 127 -41 5 -124 -21 -54 -74 -19 69 -2 127 5 -29 92 -127 94 -68 11 -54 86 80 -11 -77 -36 -47 -121 127 37 0 63 44 -3 118 -21 -12 103 72 44 -128 -93 -23 70 71 10 -23 -44 125 -45 -108 6 71 -126 32 -32 -21 44 14 80 21 6 11 126 24 -15 30 94 -19 -18 -58 68 -118 -53 -64 -12 -27 -19 50 10 121 27 29 17 -29 -41 9 -127 88 8 93 -127 64 -74 -60 2 12 87 -14 -119 126 126 -98 49 11 6 -44 -82 -13 -34 -85 41 -80 -96 59 73 -125 -6 28 126 -9 -36 -99 -101 -92 127 19 -2 74 19 126 -52 38 121 47 104 -13 -39 38 -44 -72 -38 -106 -3 -36 -125 -127 -80 95 1 -94 -74 -126 47 45 117 -6 -120 79 -55 -28 -81 -64 -47 -6 -90 3 -33 34 61 92 21 -66 82 57 -54 5 33 6 10 50 -27 -104 -19 -29 12 -115 94 94 12 -39 22 -22 25 -85 79 -18 61 -115 -127 31 63 16 -53 -27 -89 84 -126 -3 23 32 -70 -77 38 -24 49 -32 32 8 -36 70 4 -47 -48 51 -20 -94 -49 -19 16 55 34 -48 40 -27 -34 39 12 55 -113 -94 4 -19 -58 13 -14 -28 2 40 21 65 127 -26 50 -60 26 22 -22 -7 56 -21 -64 8 11 -20 -2 -73 -57 -18 -3 -82 16 -52 -94 -24 -36 35 25 -25 -28 -102 -57 -59 -3 7 -19 45 -17 10 77 29 78 -22 125 -86 -67 -5 -123 -59 -85 -15 -23 39 -12 73 0 -74 4 -22 2 -16 -83 -92 34 36 8 -110 -125 4 13 -56 38 13 -45 -116 9 66 11 23 -2 -68 40 -29 -3 39 108 -62 87 34 -56 32 85 43 -36 -31 58 72 -1 -52 -12 41 7 32 -8 -6 73 36 22 -54 25 -64 36 12 81 77 55 -52 -64 0 5 3 -17 -54 -14 -61 -71 28 45 34 65 59 21 31 -49 87 -117 80 -36 48 -22 -33 -36 89 -13 24 13 -18 11 73 73 62 -98 38 -14 -48 -56 -51 -27 -119 -7 -30 -88 -16 75 58 -26 124 107 23 -38 -91 -9 6 -44 111 -49 -52 -47 9 112 76 -54 -23 -50 -118 -46 -11 20 123 -111 25 29 0 41 -100 -30 36 80 -37 10 -10 31 50 -28 -34 -44 56 -77 13 44 5 119 -18 64 14 44 -64 -16 81 115 87 22 -12 -29 51 -29 45 23 -63 93 57 16 107 -34 -113 -38 -12 47 91 41 11 118 101 2 88 -4 -24 -40 30 81 44 -46 -100 -25 -36 -26 76 -88 -37 40 8 -45 -116 8 -8 -28 49 29 31 70 82 -50 -58 88 78 51 -45 82 44 -4 -34 -66 -67 89 40 16 -43 84 46 -128 -80 -42 -23 -61 35 4 -23 -24 -25 -22 90 57 21 -7 -22 2 -28 20 -6 21 85 -69 -35 47 -44 34 -55 21 94 -21 115 26 10 -12 -18 -105 31 16 73 -27 -31 -61 100 17 92 111 53 51 -6 -86 -85 38 41 -89 12 -74 22 50 -16 -23 20 82 20 4 11 11 2 85 -63 -40 23 49 74 44 -89 3 0 10 88 -40 -80 25 -4 -59 -92 11 61 22 -6 -4 -27 15 3 59 28 27 43 54 -43 9 74 -33 -9 -44 42 -34 -52 -28 6 23 -18 -83 60 58 -88 1 -39 38 -71 8 44 -128 37 126 109 -2 -24 68 127 -127 116 74 62 7 -82 -30 -103 120 10 28 4 42 30 1 -102 26 0 86 24 -126 116 96 -25 87 94 -72 55 -56 97 -42 5 -19 -51 -48 -76 -46 -18 -37 -78 8 -17 50 -26 -50 123 55 -68 53 62 -74 21 71 -34 127 83 -2 36 41 -17 51 123 12 23 53 38 20 12 -11 -64 53 -37 -9 44 65 -78 58 18 -92 -36 53 -39 -43 42 25 -28 107 -52 83 -23 50 -9 4 -24 -20 -36 -13 28 -37 -31 9 -39 4 98 -96 88 73 -52 53 29 -72 17 30 -12 -29 44 47 -40 -61 88 47 -128 -36 -10 19 96 -6 10 -6 72 -58 126 101 16 48 66 64 -10 126 91 54 38 17 -31 -4 53 -16 -35 -41 -120 -56 -107 -104 -35 -22 60 31 -85 33 -21 23 -19 -32 -87 29 64 -127 -126 67 95 -1 -14 27 118 -27 71 52 -61 -61 111 50 16 -117 127 -35 -2 97 -75 -45 53 5 67 35 29 -7 82 -60 10 -41 46 -127 -38 13 -8 31 39 127 21 -104 29 -124 -73 -128 12 -65 48 -49 24 44 -50 68 -28 -30 67 12 49 23 54 35 56 -13 127 -39 31 25 -27 0 92 39 19 16 -39 -25 11 -18 -8 53 -24 6 -52 113 67 70 39 0 88 -116 -69 51 -125 -41 -99 51 10 -72 -9 -14 11 -99 16 -128 4 63 -128 10 -33 -121 -40 16 73 -60 54 121 -80 -69 -14 127 76 10 5 29 37 -67 52 12 -57 -127 -67 5 29 -45 26 -61 -71 -119 -67 -75 51 64 2 -9 -73 3 75 46 -47 3 -16 -30 -58 117 -105 -17 0 -67 -93 -42 124 125 -50 -70 40 4 69 48 117 -16 -127 35 7 -35 27 -9 -104 27 74 15 -50 36 28 -80 -54 124 -12 -20 -3 -34 -34 -40 -70 -51 98 40 69 73 60 -9 33 -66 21 74 5 35 24 -3 -9 70 -78 47 35 -24 -119 -15 -61 -26 38 -42 93 48 26 -23 -37 33 -13 -35 37 61 28 -122 -48 108 -4 -23 32 -25 -62 -49 4 -18 28 5 -97 -24 -127 -26 -63 81 91 69 -128 41 9 -34 -32 1 -72 -118 -124 -45 -126 -109 -123 -47 -50 127 21 -61 123 12 -65 26 84 -106 -57 7 41 -66 -114 126 80 -2 -12 12 -124 60 -4 107 -67 -80 15 13 58 0 124 15 -71 41 -45 -59 -81 -83 -124 -21 -29 117 -23 -90 -67 38 44 -126 -126 24 14 67 82 -19 127 -28 26 -88 -125 93 -125 -87 127 102 16 -14 -11 70 -43 -10 5 98 -40 1 57 10 99 -8 -127 -20 5 10 -35 0 -2 -124 19 73 36 127 90 10 -69 127 15 -60 -127 -124 -26 -78 68 -58 125 8 -58 -123 -88 -59 122 7 49 104 -26 5 -98 125 -126 -120 -24 11 120 -23 51 -26 -28 74 -31 107 44 -86 -128 -65 80 -8 -39 -82 5 -50 -127 -61 -126 -88 -116 -119 -38 115 -81 25 106 -53 64 -28 55 -128 -57 98 58 -27 -63 126 29 -73 -5 -49 -126 27 25 104 -21 16 -112 -125 68 -54 124 48 -125 124 -2 2 53 -72 -53 38 -53 96 13 -124 -67 50 13 -127 -15 48 -46 -100 8 -76 -18 -25 -27 -125 -9 74 -86 -126 -25 18 24 -39 -9 43 -48 74 44 69 19 71 -61 -123 66 20 -90 7 -16 -45 -122 -10 46 -117 -8 62 5 126 -22 -117 -126 127 -37 -126 -84 -57 24 -7 70 17 -80 -100 -84 -125 -75 27 125 3 -41 58 13 -54 36 126 -31 35 101 71 20 63 9 -52 116 92 45 58 0 -77 -108 -53 -68 93 -97 -14 -70 123 121 125 64 -23 51 -28 -14 46 -49 27 -41 -35 114 -67 60 20 97 26 -1 106 105 -30 -17 3 -44 36 -3 28 -34 14 -58 127 -127 -103 2 53 -71 56 -6 93 -111 -62 125 127 26 -6 -102 -87 -20 -108 -78 -127 -75 -68 66 22 -21 -127 2 34 -119 112 36 22 88 -126 -82 15 -126 -123 37 45 52 -2 82 56 86 -97 -59 51 113 -32 9 -8 -38 89 71 -66 -106 -10 -49 -28 -13 31 12 4 -123 13 -17 -78 -68 -44 82 72 49 13 84 -88 -45 -60 119 69 28 32 27 -15 -124 -58 45 16 -72 -13 55 100 88 -40 6 24 104 -40 28 -27 66 -61 69 93 26 123 -121 86 44 41 42 94 56 125 -11 8 -34 -37 16 16 95 -46 -64 -68 -12 7 -26 -76 -25 64 -43 100 25 -125 120 -126 -1 84 -7 -29 -105 -22 -29 -13 50 48 32 123 -94 37 51 -86 -124 -127 127 10 -87 -18 104 127 -73 -117 5 121 60 -94 -18 -14 -30 -2 -51 47 10 65 -2 99 31 -75 -49 46 104 -36 -6 89 -105 24 44 -56 -52 31 -60 11 103 76 -11 8 45 -50 -6 45 -6 27 -52 9 -22 -44 -33 -18 -108 -44 -22 18 -35 -18 -67 43 31 -37 61 -29 53 -124 -6 -43 -122 -112 -33 8 51 82 -110 8 -72 -20 -20 -11 -16 18 47 40 -16 -120 54 8 54 99 118 61 113 69 -50 42 8 50 62 -31 -12 17 52 116 -19 31 -124 -35 96 66 114 -46 21 -53 81 54 -118 54 7 -94 112 -4 25 -126 66 25 1 17 -128 -127 113 -88 42 -91 -11 30 -97 122 125 -96 -108 14 125 -124 25 2 122 119 69 -56 122 95 -47 -26 -120 73 -56 47 33 -49 -106 81 60 -2 64 93 13 -54 -81 -56 -95 -87 -3 -82 -60 -94 34 73 -19 -37 55 -63 -2 32 -64 4 125 -24 6 -24 -24 -1 -14 -128 -48 -24 -117 -69 -114 -34 -29 -6 -61 -10 11 -43 -12 -30 86 10 -21 -22 -128 6 -10 -12 -125 -2 21 -30 102 -90 -40 46 -44 -70 -58 58 -42 -76 -10 57 34 -61 74 96 126 -13 -36 -43 26 -81 26 -28 64 32 -12 54 -57 104 -125 -66 -54 101 -49 -39 94 -5 121 108 44 125 61 37 28 3 94 90 31 46 -27 30 -113 -126 43 -2 -95 -95 78 2 75 127 -84 -24 -95 26 124 126 1 8 41 52 -33 -45 -27 38 -19 51 64 125 126 -126 126 62 -55 45 7 37 85 59 28 26 126 122 26 -52 73 -27 10 3 78 -124 -58 -65 -10 -46 81 -19 -24 96 -15 78 47 -40 76 75 -23 -126 -104 105 -125 111 127 45 -8 46 -90 63 10 -19 -8 -121 -128 32 -15 117 -127 -20 117 -51 88 -99 13 -28 28 -8 2 76 25 -81 17 12 27 -106 -1 -17 -82 8 -19 25 -3 -2 110 5 -8 126 -15 -126 -4 15 26 33 -117 2 -31 -2 0 -39 -62 81 -73 -49 33 -33 19 14 -52 39 2 57 6 -67 -12 -26 -104 -4 -73 12 -122 -20 -68 49 65 127 13 -8 -34 -77 -34 -5 -85 43 -8 23 -17 44 -121 0 -1 -2 -59 -93 17 -41 96 -57 37 37 -78 -32 -50 -10 -69 58 -66 57 55 122 -55 -60 18 119 -47 -83 -30 37 -124 -22 -6 -71 -34 -3 -51 -9 0 -27 19 -2 -13 35 2 40 -27 16 -65 44 83 -33 -71 32 -29 -10 -9 19 -4 -36 -16 5 -2 57 55 -17 18 25 33 0 1 1 -33 -54 -36 42 40 -8 16 46 -3 10 18 -90 5 43 -37 -61 73 -51 -71 29 50 12 6 -55 99 36 -29 -48 3 -4 39 -14 -33 28 38 13 -30 27 -53 -78 21 -14 38 -39 -89 11 -13 -50 -9 23 2 16 -27 -6 -15 -32 5 61 35 -93 -1 -1 -3 6 21 -5 -97 -3 -67 16 -7 16 73 -67 85 -33 -12 -31 81 -57 5 27 63 -20 -93 55 -40 -64 13 15 -8 -27 -13 62 5 8 -46 -10 -43 10 39 -44 -34 -29 7 61 15 11 21 20 -8 2 24 6 10 -17 5 -42 31 12 -20 59 -14 4 -22 0 -8 -27 -5 36 -7 17 -21 -25 7 -59 13 -33 -1 -40 -39 -46 20 -1 10 24 28 -92 -22 54 -85 -9 -67 -31 65 25 -26 3 16 -60 -100 21 23 31 24 33 -22 -17 -57 9 72 30 36 -3 47 52 -17 47 -39 16 13 36 19 13 73 97 -5 66 -33 1 70 -23 52 67 65 -22 -23 3 -32 -64 -73 22 -95 57 5 31 -96 66 -23 16 -64 99 -66 114 -5 73 10 63 67 -46 2 30 -44 -39 -21 -24 6 -7 -21 18 48 20 7 -34 88 35 2 -15 84 -6 31 -52 17 24 7 1 12 7 -85 -11 -31 -19 60 -45 -23 -3 -26 27 -119 -76 -59 49 -3 41 -31 -95 29 34 35 -43 42 -3 47 92 -8 24 -17 -126 26 -4 43 -50 -32 -14 22 -7 -20 124 -85 -2 92 -31 31 37 47 19 4 -77 -24 25 -20 -14 72 31 -94 119 5 66 98 127 26 26 -44 -56 74 -22 41 -18 44 -28 23 -39 -113 -24 4 60 -3 -3 44 90 122 -76 52 -115 37 -125 15 -40 43 -50 -22 -9 3 11 10 -6 -30 53 -65 74 -30 69 -56 -46 14 34 -49 52 23 -29 -48 -35 -3 106 67 -24 15 -19 -48 -14 -7 82 24 -14 120 17 -33 27 44 -36 1 28 67 -19 -35 8 11 5 6 -70 -112 -37 -10 39 -25 17 -20 -56 38 21 -22 -49 -17 -91 -39 20 -28 67 -20 10 55 40 43 -14 -29 -49 16 -82 1 -43 3 -31 83 -8 -9 -69 -38 -47 34 -10 61 -24 -30 -21 11 -50 42 -69 11 -127 -8 -81 107 38 32 -33 13 -45 59 -44 -37 23 121 8 -42 -9 -38 14 -59 -6 -26 28 -32 -6 22 12 84 50 49 -28 -15 43 41 -30 8 -44 -11 -62 0 21 -24 -23 -23 56 6 32 -25 121 61 13 -63 57 2 -37 24 9 119 -4 -41 -14 64 49 28 -9 49 6 -21 -15 67 4 3 20 94 -14 -36 108 27 7 -38 7 19 92 -57 4 21 -17 60 -13 -113 -3 44 -87 -48 18 -31 79 15 53 44 -15 -61 80 21 -3 86 40 87 17 -124 -39 -32 -2 66 16 2 -95 25 -61 28 -79 21 -29 -12 -5 4 20 23 -26 43 22 -63 -27 -38 -38 -38 -7 29 -36 17 -57 51 75 8 15 -43 -57 -15 -82 -69 -25 67 -35 70 -2 -44 -28 -27 22 -57 -1 -28 -21 -25 -50 -49 14 -7 43 35 96 -18 -102 -80 -24 -108 26 87 127 -11 57 74 -18 11 -58 2 32 56 29 42 70 -128 -35 -8 -6 74 30 -8 18 -35 44 78 6 17 31 16 -2 -50 45 15 -64 -33 -24 -10 -27 -11 42 -11 -102 -19 -33 -5 6 38 -7 -32 42 30 -80 -12 -42 0 34 -59 -12 -28 -39 4 -8 -43 10 -66 -105 60 73 -64 48 102 9 -38 -117 -3 -40 -127 29 -126 23 -17 4 -7 37 2 -85 17 -44 64 -82 -60 -59 20 -25 4 -41 -35 7 13 -100 -21 6 -20 -58 -23 51 -107 -38 -6 -54 44 4 -42 13 5 -93 18 7 2 80 43 -22 32 -9 14 -20 -5 -120 -28 -21 87 -57 -38 -12 20 -44 -35 22 -69 -81 -54 15 -52 -13 101 74 37 24 -12 -46 6 10 -28 35 -46 48 -39 41 -59 -32 -40 18 83 103 108 15 -31 -10 1 8 85 5 41 46 0 57 -49 -33 -20 -19 13 -4 -35 -11 37 -25 -32 -82 1 15 29 -98 -34 94 117 46 18 -11 -1 -50 -59 -120 37 34 36 16 -11 -62 35 41 -84 -39 -20 33 26 -5 -83 16 -43 31 -2 -8 0 116 -21 12 -24 65 -127 -123 44 38 25 -10 -102 -50 59 -44 38 -124 23 -18 -4 -24 -17 43 31 -4 -19 -58 126 -62 -23 86 87 -1 27 -38 -49 -13 -21 -19 12 -20 -68 -54 33 -29 -77 -30 -23 -57 -68 55 52 -30 -73 29 69 -27 -23 39 -32 -87 -25 -61 -58 -15 59 -27 -27 13 43 -125 -8 -16 8 -83 -37 -3 -14 36 -94 62 27 -21 -6 -50 32 -16 9 24 -3 -98 -7 -37 -31 -27 34 23 18 68 14 21 3 -51 -67 59 -74 64 -85 -72 -22 -37 3 -96 -25 34 97 -18 23 -110 2 57 59 -5 -8 36 56 31 18 -28 -35 -13 -18 15 7 12 -11 -55 33 31 45 -111 30 6 1 -27 -93 -16 22 -82 26 45 -33 19 22 7 30 -3 -9 26 -35 26 56 65 -117 19 31 31 34 68 26 -43 -14 -3 28 -97 -29 78 47 -26 -10 65 -35 -99 -38 -49 -28 13 -4 69 -38 -14 -6 38 18 -61 10 28 -25 -57 13 28 27 -15 76 45 -44 -26 46 13 -2 -25 -62 57 6 -12 35 -10 82 -32 -11 83 22 17 5 34 -4 -25 -39 -27 -24 -29 -3 -52 124 -68 17 -96 -1 -3 65 56 -31 1 -7 -34 32 0 -45 -46 18 -85 8 106 39 -118 27 -53 53 16 -70 24 -20 -48 -68 -33 -27 77 -79 -48 17 27 -46 -25 -68 13 -80 43 3 0 -19 57 98 51 42 -5 -25 29 12 41 -64 -68 3 -13 -14 -15 -99 -23 13 5 -37 -12 -42 -113 -37 60 -35 1 5 -50 24 20 -21 34 -93 -41 -88 -41 104 7 12 -43 51 -121 83 -126 -25 52 15 -125 -46 126 -1 14 86 10 87 32 -22 39 5 2 -37 -29 -1 38 -27 75 47 -77 124 36 -61 -19 37 44 83 33 71 -14 -59 -21 -26 -109 33 8 -17 26 -1 51 -1 -23 -1 8 -6 15 -76 20 -16 -15 -128 26 -80 18 1 -6 -30 123 -98 40 57 0 -29 85 33 28 -1 39 -46 20 -123 -53 98 29 61 -8 -74 -32 -59 97 62 -14 -102 125 -73 21 30 -1 -86 40 -56 55 78 -1 -88 -3 -65 15 49 -55 -127 20 47 20 -8 -75 -9 3 -69 -21 -1 16 24 -79 -16 -48 -5 -4 -98 -43 -42 -41 6 -12 59 16 0 47 -110 44 -7 -21 -65 62 -85 -33 14 -54 77 -53 -13 -8 -19 -52 84 -30 -79 -28 103 9 -48 -59 -4 -25 -18 -9 88 -42 -30 -77 -83 -23 -18 29 -36 37 -1 -118 -20 65 -69 35 21 -102 -29 -45 -20 -103 2 94 11 -11 -17 75 17 -5 14 45 -9 45 -38 33 60 22 86 79 72 -3 -7 4 -38 -3 8 -85 91 -46 123 19 -6 -13 -37 -68 -67 -33 2 -88 0 31 90 36 28 -22 -39 7 -91 -9 16 -51 -113 0 38 28 -5 32 -10 -122 -33 -37 -5 -63 25 -65 46 -125 22 -46 23 -21 55 -34 19 -46 109 77 12 24 -53 -70 34 5 25 -43 21 30 -10 -101 -66 -5 62 12 -48 -19 70 10 -114 6 -14 97 73 5 -2 -14 1 -81 7 -22 -6 33 -65 -96 -63 11 -47 16 -24 19 77 17 -18 11 41 -6 67 -7 56 -21 45 14 -27 -44 -51 -73 34 -17 17 -59 -6 -29 74 -9 114 -64 76 44 42 79 27 -13 1 -20 -31 22 37 -10 41 102 62 7 12 62 -34 -42 -29 46 16 -26 -50 -39 0 -38 47 25 -46 -109 -41 6 25 -12 24 -83 -3 23 62 -30 5 -69 92 -20 -65 20 -61 32 52 30 31 -43 23 -60 40 14 -67 20 27 -31 -33 62 12 -105 7 -27 -23 51 -111 35 13 -30 -26 2 25 -101 -9 8 -26 -24 -4 -40 26 13 40 -101 -2 35 -25 -30 -46 50 -73 -11 -57 -22 26 48 18 -21 18 -83 82 19 38 -24 31 66 7 -11 39 52 -2 -13 -62 22 21 8 14 -101 -59 31 -17 -70 46 -64 -7 -38 -51 36 -28 -18 -34 2 6 70 1 38 84 -12 -42 -41 17 9 -54 48 15 -14 -35 -25 -36 7 -44 -12 -39 -20 -84 -118 0 -18 -19 -22 -3 46 -66 -9 -20 22 25 -29 14 -34 -126 -20 -22 34 37 1 32 -7 -56 -23 -5 9 29 -22 20 -51 -28 -32 -7 19 -7 70 15 -27 45 -9 -5 7 60 66 49 -49 2 50 31 -14 -16 -7 3 -42 11 12 -84 -7 114 -4 26 -38 -13 -4 -39 -35 9 -2 -96 11 20 6 -17 50 -6 44 48 22 53 -94 15 -27 71 29 42 -70 -9 -52 9 -67 81 -35 -87 -26 -103 41 6 -46 36 -56 -71 -92 -29 -110 12 -15 -8 -17 -34 -22 75 -96 -2 -9 80 -18 23 3 24 -32 -5 -5 -33 -97 11 -124 49 -10 -29 -22 14 -13 4 -20 -8 56 58 -25 2 98 39 5 -9 68 -38 59 29 12 48 -70 -27 -45 -60 -1 8 25 12 28 23 -18 -60 -17 87 37 -24 -27 34 32 -46 -20 27 -42 -27 -49 -75 34 59 -47 -74 8 -14 -70 -24 34 -49 4 -45 -35 22 -38 -9 -51 -24 -76 17 12 -53 76 -1 16 -43 -14 5 30 1 11 -32 26 -68 -70 -29 -5 -22 -29 -13 67 -26 29 40 -72 -5 4 -37 31 26 57 0 -13 113 23 27 -92 9 -65 -25 34 -27 60 -50 -84 -50 -37 -83 36 46 -29 41 -72 -126 -99 -1 26 -71 23 9 64 0 -3 66 -75 -3 -50 34 7 56 11 -19 43 -23 -109 52 -19 18 12 -1 -2 -27 25 11 -66 -30 -7 -34 -10 -34 -111 41 -16 13 99 -9 -105 41 -82 -44 1 12 10 15 44 21 -2 -115 84 -29 -17 25 45 83 -3 -4 107 -2 28 54 62 40 -25 -3 -1 -77 26 101 -13 71 10 59 82 54 14 14 41 5 -116 -43 -48 -7 -108 -10 -23 -95 20 -30 -33 -66 126 19 18 -80 -4 53 -66 -33 -5 -92 15 16 15 64 24 -78 -24 67 -45 51 6 -20 -49 -39 4 37 -87 126 64 -63 -19 -31 30 -3 12 -32 42 -8 -120 -7 23 2 57 -73 -126 -41 -42 17 -18 4 -2 -4 12 27 -28 -73 -5 -42 54 -26 11 52 1 -58 24 52 2 14 57 38 85 16 12 -12 29 123 19 -42 -51 23 -25 65 39 53 -9 33 22 10 70 11 -16 114 46 7 21 -56 -54 32 41 -31 -36 -7 -14 -39 -7 126 -5 2 -41 13 -24 58 26 -5 89 4 -19 17 -21 16 -1 16 -59 -43 42 3 -23 7 23 -32 39 -4 36 -29 34 -21 -128 -20 -8 37 11 11 4 -75 11 10 28 71 10 50 -66 -16 89 10 -43 -74 -38 -19 36 -18 -14 27 -104 123 61 38 68 42 25 49 -39 122 -12 -76 54 19 -41 -35 -8 -29 30 20 -21 15 -71 -47 13 56 -58 42 -58 40 -36 1 20 -42 -26 -4 30 -7 29 105 -47 3 -30 -8 127 -49 93 68 5 -16 13 25 46 -54 -59 47 37 100 -27 -10 -32 -123 -8 37 54 25 55 -60 74 -31 95 23 93 -28 -6 18 -16 -93 33 -27 20 -15 -65 -82 -77 28 -21 12 6 -2 75 -106 30 26 -53 -45 127 -14 -34 -19 -54 -3 -37 -50 -12 44 24 96 -63 14 49 -53 -60 39 -19 -58 32 7 19 -107 -43 -87 7 -124 -1 -13 64 30 -35 80 102 5 -118 -126 12 -39 25 -91 -55 -32 -78 -58 -126 -85 -68 12 29 -34 28 43 32 -33 -53 -80 -112 21 -10 76 127 -27 52 70 55 47 0 102 24 0 -104 -35 28 35 -102 -109 -17 -22 1 -6 -30 -73 -56 62 -2 -107 39 87 -19 -30 -43 25 -9 -99 -11 -28 -127 -8 -27 -28 -21 -11 -32 30 2 23 3 -11 -56 -28 124 -13 -123 -7 -40 -39 -64 -14 -53 55 -34 79 -8 -57 101 39 18 20 10 -44 -121 -2 30 66 -22 -23 -15 -25 -28 85 44 66 1 -127 -39 0 20 -27 93 3 -43 5 -51 -13 -85 29 33 50 69 10 49 99 58 23 22 -10 43 11 33 41 1 12 -125 120 33 -34 2 32 -64 119 -29 -125 22 18 41 47 16 43 -8 -49 -40 1 -17 -89 43 51 -101 30 4 -23 33 -35 69 -47 -19 -9 1 -93 8 -31 -9 24 -17 -55 -9 -90 -92 -5 -53 -33 22 -58 -54 -9 -13 106 -58 76 32 -112 22 -40 -35 52 -74 78 45 -63 -73 -17 -42 35 126 -18 -22 70 54 -128 -42 -66 51 18 126 38 -37 16 23 15 50 -9 -10 34 -92 8 -123 -4 4 -21 -52 51 -29 44 -36 12 -33 -22 -82 29 -35 15 -51 14 78 -62 93 27 54 16 -37 -101 123 0 -54 13 65 -37 -6 -36 -46 -59 -121 -13 -56 -36 -26 -75 17 -36 -34 -13 69 -14 14 1 -101 -79 19 -96 -67 31 -3 -71 12 -10 54 1 -45 14 -32 8 24 -107 -81 -65 12 -15 -68 -115 -4 28 21 -56 30 -70 55 -94 -125 19 33 65 14 -7 53 74 -60 -38 -60 -40 5 -13 -28 -101 36 -34 12 -98 56 -54 -25 61 31 39 -14 -67 8 14 -59 68 -54 -51 17 53 16 3 -115 -63 32 -47 38 -74 106 80 -24 -12 0 -91 10 48 27 29 103 4 -51 -85 -89 -69 -18 -52 84 -26 9 -93 4 13 -115 8 -8 8 -45 3 80 104 -17 41 -72 39 60 51 -4 -8 -65 -83 -56 -14 8 -12 -23 -44 34 -75 62 -66 22 -64 47 -128 7 -60 -98 -85 16 15 -5 10 -127 42 -78 83 46 -67 14 40 -36 -78 33 7 -42 12 93 -33 17 32 -106 -40 -7 4 40 -24 39 -17 -23 39 -59 -69 -10 -30 -2 -24 65 5 11 65 121 20 8 35 -73 -14 -4 -10 26 -55 0 10 37 8 -91 23 35 23 -65 -10 -9 30 10 41 44 -24 -20 -48 -67 -14 27 85 -26 -41 -38 -50 -115 32 -98 -2 44 -13 17 -108 22 -2 2 -68 -123 8 -72 -59 45 49 1 -69 25 -49 26 -11 -31 -67 -34 -16 -32 55 -59 23 -37 -18 -28 -25 -5 -46 -13 -32 -20 12 51 -9 -85 -35 -38 25 11 -79 110 33 40 59 9 28 11 -87 37 -33 -52 -1 -64 -2 -18 95 -12 6 -56 18 78 -5 -5 -36 -93 28 -54 31 24 -35 -124 58 -1 17 -76 -126 -27 -119 24 32 -24 -28 52 35 20 14 57 -17 14 22 10 6 73 -25 -15 -91 -26 -19 -126 -21 47 79 -54 -18 -118 -123 -8 64 -32 23 37 12 -18 -20 -58 -71 -44 -18 -26 79 46 4 -64 31 -14 -9 45 91 36 -24 45 109 72 -41 -82 -20 -21 -30 -40 -14 -8 -50 -23 -8 -69 38 -15 -1 -23 -24 60 -41 -74 -96 35 93 7 -32 9 -70 80 -4 59 6 -62 43 -42 -3 -88 12 -28 -51 -70 -27 17 32 11 12 80 -63 35 -49 -21 -21 -49 -50 27 -12 -64 26 49 -32 17 -20 23 99 -15 -62 -17 -10 127 12 28 52 -44 -3 32 -70 -15 -37 17 -6 92 -101 -52 11 -13 54 31 -39 -21 4 -10 -107 77 38 -112 17 -4 26 -11 -64 -36 47 -28 -115 -33 -63 -25 -78 -45 1 11 45 -36 11 72 -3 -1 14 -37 -7 65 49 37 10 -15 -45 -2 39 -82 64 -47 28 -1 -56 84 -30 7 35 -51 7 61 -25 -25 60 46 76 84 17 60 54 23 21 85 -62 5 -66 -52 -48 -52 110 16 -9 77 -8 -107 1 4 -58 81 -22 10 -28 6 81 22 109 -68 -34 -116 -6 -128 -47 -40 -93 9 51 -13 -18 26 10 31 -18 -13 -19 125 -8 -50 35 42 37 -33 30 -33 -21 -16 -19 45 -24 23 42 -56 91 12 -87 -20 -20 77 11 23 28 -11 28 -21 20 36 -123 -61 -38 -13 -60 -119 -50 -15 -67 -76 31 51 -127 -14 5 -20 3 -44 47 72 -7 -58 5 27 -31 19 23 24 22 -26 -73 63 82 -17 -28 39 2 -34 -4 75 -20 -34 14 -4 -76 -26 39 17 42 36 78 -1 40 -46 -31 19 85 19 28 15 62 -64 -91 55 -49 -118 -34 -116 19 -80 -41 39 -37 63 18 -13 -6 76 37 -46 -49 9 -32 -3 17 28 38 -16 1 -32 -28 27 -34 74 -17 -27 7 -67 -36 79 -29 71 79 13 27 -9 -60 76 -42 -29 -18 52 45 -12 10 2 29 37 -59 12 52 41 -85 -41 -20 -43 -70 -3 41 9 20 31 16 -72 95 -32 7 1 126 43 -8 -21 -90 53 49 -28 15 -44 55 -28 37 93 -20 68 -38 119 -17 -36 -4 -11 3 -16 -4 -26 -26 -36 35 23 29 31 -88 34 -44 -125 26 34 -11 -33 26 10 -11 18 -17 104 41 -93 -8 -36 -10 -2 -23 7 104 -72 79 117 -50 -86 37 -20 -109 32 127 29 72 8 -82 -51 4 -42 -83 -50 -1 -22 13 -2 -127 71 -13 27 36 -1 -3 78 -13 -50 32 -18 -15 43 -32 90 -54 -26 -91 -17 -30 33 72 47 -89 46 -8 25 34 -20 18 -38 -98 49 -4 54 30 -40 26 80 -54 -17 -20 34 -44 -40 72 45 -80 27 -27 -61 62 -28 -13 22 16 29 39 -55 3 28 25 31 30 66 -97 26 19 35 -71 60 28 43 -8 -78 18 21 53 18 -9 23 53 -10 99 -44 -54 36 16 3 -3 -40 19 31 75 -12 14 -74 38 -28 -1 38 22 57 49 37 -34 -68 -90 -32 24 -7 -22 -53 -7 -8 -43 36 66 -6 -55 23 56 17 35 -7 55 86 -30 -67 -32 -8 -13 -84 -34 123 42 -26 42 25 -32 58 -24 64 -19 22 -18 67 -21 -5 19 -19 73 -29 -80 -70 54 7 61 95 -55 69 26 -54 31 -50 -47 69 3 -15 69 9 37 -89 22 -126 -46 31 -8 -16 -19 -6 31 11 -22 119 -1 8 -13 31 11 7 17 9 -40 6 -21 18 20 51 22 105 -19 -107 -19 8 -16 -18 38 25 -14 -51 5 -112 -50 -33 21 10 43 -105 14 94 11 -88 33 -112 -53 17 91 -82 18 124 -44 -36 48 -51 25 -49 -9 -10 17 -51 29 34 104 20 47 21 51 56 -46 22 -127 -11 22 -22 -29 32 -19 -113 -101 49 -15 18 -90 -14 59 34 -29 13 -72 54 -42 -68 -43 48 123 1 -114 8 -63 -43 -3 -62 65 72 -5 17 -39 9 -9 -46 -48 -21 72 -15 67 92 -46 73 20 1 -74 -19 -13 77 32 -74 -59 -25 -86 47 75 35 -37 -106 1 -59 47 34 113 -28 -58 70 32 -6 -53 -74 -18 20 -39 -37 -60 8 -11 -54 -38 -88 -55 10 25 66 -51 31 32 -45 3 -18 73 4 -81 -15 -13 51 -39 -33 -19 -42 46 -6 1 -87 -6 -17 22 -23 -18 -4 -95 3 73 -9 91 8 40 -56 -12 49 -1 -34 -29 35 -28 28 -8 15 -46 -39 70 -63 21 -43 -52 -4 -74 -120 -86 -24 32 22 -49 -41 49 -51 -86 -21 11 -15 -41 -12 2 -3 -1 -36 -35 13 -23 -98 57 31 59 -17 -80 -33 -25 -46 -76 -112 -123 29 -48 -45 -26 12 -95 27 28 -111 23 75 60 2 0 -24 33 2 -47 0 -16 5 -51 -20 3 31 -6 -9 50 -28 -94 -28 42 -79 39 6 -4 -33 7 39 -54 48 -41 -89 103 -40 -67 -3 14 -68 -50 -42 -60 -27 34 118 -34 -11 -23 37 78 39 -45 51 32 58 113 -38 28 -39 -36 42 6 27 -22 -50 106 53 59 -3 64 -23 17 20 14 4 48 64 63 53 31 -119 26 -58 6 102 37 96 -123 -49 12 96 -117 84 59 36 -5 -55 8 27 -118 5 -102 -9 93 2 33 8 -66 -19 89 -102 20 -5 -49 22 42 -16 24 -87 14 17 -58 -59 23 61 13 51 -2 14 10 29 -9 -47 44 81 -41 -8 -22 -70 57 9 48 -5 12 20 -32 111 77 -31 28 -33 63 -22 -35 22 -120 -69 -51 25 -11 25 24 -17 -29 20 38 -5 15 -117 5 -29 -55 13 -20 123 -10 0 -50 89 3 -24 63 -12 -127 -40 19 18 -20 -29 47 73 42 6 20 -117 -124 -23 7 -10 18 52 54 -42 -66 -1 29 -22 -13 39 20 16 -33 35 20 -23 -49 -31 -56 5 -3 20 -88 5 41 -66 67 -11 19 -61 -69 21 122 -25 -40 32 13 4 19 -3 -18 72 68 -46 -94 12 18 -17 -5 -86 -55 61 -55 -44 -33 25 -32 41 4 -8 9 7 -7 -5 -57 127 62 3 43 -45 -25 -60 -69 -2 2 34 -92 6 -88 19 41 13 -67 -11 -35 81 -9 -11 -14 -28 -19 35 54 35 27 46 -1 38 -29 -34 -54 3 78 30 -16 62 -15 -52 -78 -5 21 -45 -37 -39 1 73 -1 -20 -42 62 -79 -48 1 62 69 54 -21 -19 7 30 9 7 98 2 -5 47 -37 -19 8 6 -38 33 14 -16 44 42 70 -24 -14 -65 52 -12 114 48 -30 -7 42 -44 43 -13 -61 -111 -31 21 -4 -34 43 22 -36 100 110 10 1 -5 -63 -128 -14 125 18 -12 11 -119 41 5 -98 -25 23 -46 -112 108 4 49 59 127 -61 2 92 15 127 64 10 8 -2 -18 46 58 36 42 76 -24 -78 -80 123 68 1 -10 19 -89 114 104 65 16 44 -3 1 -47 3 101 4 -101 -1 37 -3 8 -40 81 9 7 -8 97 18 66 -45 -42 -63 6 -116 17 -8 -62 72 7 -5 -11 85 -32 35 -92 53 -53 -52 40 60 -60 -70 23 -58 -27 30 -29 -50 63 -21 -68 39 15 4 51 63 -69 29 23 14 -7 -61 -69 56 -27 3 72 -19 17 -112 11 -11 -1 -26 -23 -4 6 -47 -9 1 24 48 -36 0 11 -55 -6 50 55 80 -33 -18 19 -26 -6 27 46 96 -99 -6 20 18 5 114 25 57 38 42 -12 109 -57 -81 24 -44 66 107 -35 59 42 53 -17 -19 9 23 72 37 20 52 -126 -49 55 22 6 18 31 41 -1 -17 43 -27 -16 -44 2 20 9 -51 66 16 -119 -51 -49 -4 -63 -49 11 -44 -25 -21 -12 35 -44 126 -30 -87 9 61 65 -4 -21 -16 56 35 -10 -77 29 -21 12 -49 -40 -12 -11 -29 79 15 82 -104 4 51 -42 -16 35 54 -100 -128 48 -126 -72 6 47 -62 76 -16 24 -35 -39 44 -56 -119 -64 3 11 88 -26 14 2 52 117 -127 -126 2 50 -64 21 -3 116 68 53 23 -53 -26 59 8 -113 24 39 12 19 46 -45 -62 -85 -36 -78 -38 -28 3 7 51 -54 21 -19 -21 15 -51 -20 0 18 -76 -86 41 37 52 -87 -103 7 -20 -13 -32 14 31 4 -111 -70 37 96 9 63 44 4 -26 67 -36 28 -95 89 41 -19 5 -27 20 24 16 83 -32 5 74 60 -49 115 34 28 -93 33 -58 73 -60 68 85 -20 83 -18 7 55 -2 -24 50 53 -32 -35 7 92 35 42 -13 6 61 71 -55 32 50 -59 -7 -7 -21 -49 -104 11 74 1 12 -55 12 -14 54 122 5 -77 15 14 -99 7 9 -78 -55 -24 -28 75 15 48 -2 -15 -107 -5 10 41 -39 -121 -14 54 57 -66 -8 -21 -55 -23 -54 -93 26 33 55 -11 -97 -20 -7 -72 -71 -62 55 -20 -61 -30 -2 -37 -44 50 -30 3 44 6 35 -16 -120 47 19 -12 -61 -9 66 -2 -11 -4 51 16 34 -40 73 37 -70 -88 -28 -94 59 78 35 -37 72 -45 25 33 -4 84 -7 40 -58 127 -8 9 9 -103 -84 42 -34 -13 32 117 41 9 -8 -4 -10 -54 6 115 29 13 -65 -41 23 -3 -15 -30 -25 21 -79 -3 -51 -35 -20 -86 25 58 73 -66 -15 69 -31 -45 12 76 -3 -72 -79 10 -24 -81 -13 -30 -30 -23 -54 44 -19 38 -13 -67 -75 124 -50 17 -16 46 39 -17 -71 -37 22 -53 5 -31 52 -123 25 -119 -31 -61 26 -8 16 5 -47 2 -67 -40 22 -46 12 126 -126 -51 -57 14 -21 -38 18 -86 2 -127 -33 30 0 -123 -66 -118 -97 -87 102 -39 -39 -45 21 99 -84 36 30 35 -41 -39 -3 -56 -88 -127 18 -32 -110 47 -97 -89 12 -125 93 39 19 -35 49 25 17 7 -52 -5 -49 33 -6 -17 75 -2 76 -23 97 -4 -57 -110 -80 -25 -78 11 -8 -43 127 25 46 65 -32 -8 -79 -40 12 28 -50 -118 36 -53 83 -71 -2 19 35 34 -3 -5 -74 -57 -77 10 -39 19 30 24 2 -51 86 39 7 35 1 -53 6 35 -5 1 -57 -127 -51 -14 29 1 14 -68 44 -43 4 43 48 -63 -29 6 23 -86 50 -90 32 -30 17 -17 -41 109 15 4 43 4 -127 -13 59 -57 -6 -43 127 16 98 11 6 -28 -24 -40 -21 -4 -15 28 71 -14 -36 4 -49 -39 12 4 69 50 21 -39 -1 31 9 -37 16 22 -7 -80 13 26 78 56 104 5 113 33 4 -127 25 16 127 -55 -41 -13 1 -38 -52 -52 -18 20 -83 -33 67 54 35 18 22 27 -32 -34 44 127 6 5 -76 -31 -2 8 115 43 -44 -1 -77 -28 56 3 7 -69 44 -76 40 18 44 47 68 -57 -2 87 39 -35 33 66 0 -1 35 51 -63 -17 25 29 4 -1 65 84 68 55 23 54 36 14 -18 68 -3 -14 -57 -9 66 6 78 42 52 -113 61 28 -108 56 -111 10 4 -57 15 15 10 28 -76 -28 14 23 13 -7 -7 -79 -27 -36 14 -63 13 -1 57 -54 63 1 0 2 18 -42 -44 -106 -5 -63 -9 -6 -97 -15 -18 -52 126 -67 46 58 -37 126 31 8 36 -119 -20 -80 12 -5 4 24 -18 -30 -17 62 -11 74 69 25 -23 -56 35 12 -1 98 -7 -52 -60 -1 36 20 -2 32 -23 30 20 -4 -74 71 -21 4 -34 -43 -14 -13 -64 44 45 -23 -44 -24 -33 -14 -4 78 30 8 0 -55 50 36 30 -2 24 38 -12 66 64 14 -13 -20 -8 -57 -6 -61 -46 -23 32 -100 7 -76 40 -31 -98 50 45 -47 9 2 14 -128 66 11 8 -79 37 -27 -34 36 21 0 -97 -54 -50 10 -81 79 36 25 121 -67 32 -26 26 69 -5 14 -19 12 -57 8 6 -24 -12 50 5 -5 -65 -6 -17 -42 5 -95 -24 -120 49 41 94 16 44 -12 -101 51 -36 33 -81 -1 50 -44 9 51 21 54 91 -108 11 29 24 -3 -72 7 20 -14 -62 40 29 88 -35 -4 -15 13 36 29 87 -25 -55 6 8 -49 86 9 -18 -23 -17 31 42 -54 -62 45 -7 -31 19 -26 -32 -32 -105 25 -39 34 35 -52 -69 14 -32 41 44 -14 23 -7 -45 -52 31 -54 -13 -18 -9 3 10 48 -1 52 -1 70 -41 14 -97 -20 -20 93 -24 9 -47 35 40 56 24 -20 12 5 -29 46 20 -9 68 20 29 97 56 0 -31 -40 -11 -27 -34 -25 38 57 -9 -9 -47 10 74 29 15 28 82 -52 94 -5 -39 -37 -51 111 -125 9 -10 -116 24 -4 -16 13 116 -28 115 21 -16 18 -81 65 -38 30 35 -39 19 6 35 123 -11 -16 -15 -31 -75 68 16 -16 -14 -51 -26 -39 -6 29 -6 124 -29 -128 -37 73 -51 -2 -60 113 -11 -1 86 -62 -57 -68 85 -16 14 4 22 -26 -10 -36 67 -9 -5 71 -79 -29 35 -8 -92 97 31 2 -5 -20 21 -5 51 101 -1 88 26 -44 -16 -14 -69 93 43 33 40 -11 23 23 -52 -40 99 -95 30 31 -16 -42 -7 102 -43 -88 12 -20 -4 21 -43 38 -25 56 37 -60 -61 46 -61 -23 -32 17 88 -47 -23 -98 1 95 10 -10 -29 -3 28 -12 55 25 16 -81 -98 -76 2 -11 20 35 -63 19 -50 -14 -47 -127 -82 -61 -27 -35 -13 -15 108 -72 14 22 -49 -95 79 -61 -8 -27 -7 5 41 -67 30 -14 44 102 61 -13 -1 0 41 58 43 -16 4 21 -56 28 127 52 41 -88 51 46 25 38 27 50 -45 -7 -4 -54 -44 17 18 -19 -24 -39 67 -64 -22 -66 24 -53 -69 -26 -23 111 -69 2 71 44 32 -48 -31 123 36 11 66 -127 -42 15 77 57 18 -89 58 -2 -6 -128 -26 15 -53 -4 -23 -40 -41 -47 -32 -17 -17 -89 17 0 -90 2 -10 -5 -32 -1 -115 -55 -42 -5 18 -24 22 -1 1 -56 2 -40 75 34 38 -31 0 -39 -50 -54 -41 67 24 -36 -73 41 22 56 9 -2 125 74 4 -26 -33 19 -116 -52 -8 13 125 41 44 22 26 -36 48 -81 104 -9 -37 -81 38 -50 79 -36 68 98 1 -72 -47 11 10 -96 54 5 24 -10 11 -34 -27 45 -10 29 34 70 -97 23 -39 -15 17 -20 14 35 58 71 54 21 49 -37 82 -32 110 -92 -1 -18 29 -59 -1 16 -18 -5 2 73 -57 -43 14 74 40 -89 93 -5 -105 23 20 15 107 -58 -20 120 3 -13 -34 37 -23 -8 -37 9 -40 57 -11 -127 11 -98 57 13 -68 -108 54 -24 -3 59 52 -11 -33 12 19 -33 -16 -86 -24 19 46 -38 18 -101 -44 50 50 18 12 51 -40 -35 -11 13 -70 53 22 -33 -33 -7 -42 -5 -20 -42 -33 -19 8 126 -21 20 13 5 126 -6 18 -53 -12 92 -5 -126 30 -43 40 -34 20 39 20 8 -74 -12 0 -35 21 13 39 111 55 -55 13 -23 25 -19 -44 -95 -30 -21 -73 -9 -34 -89 -12 34 -40 -85 -1 -18 27 -41 -44 -12 -48 6 60 75 79 -4 1 -43 -22 21 64 -3 8 -16 -22 -66 -1 -90 11 59 -28 -18 -76 -56 16 -15 -65 -34 2 49 -2 -24 39 7 20 19 22 70 22 -55 -39 -28 44 -75 18 41 15 21 -69 46 -5 49 48 67 -14 13 73 -20 -29 23 16 28 41 29 19 -89 35 -11 -30 61 -78 -94 -18 13 41 99 -13 34 29 -22 -9 -117 50 10 55 40 8 -8 -1 64 89 66 -40 20 -55 49 66 9 -42 69 -9 114 -46 -40 -4 -46 90 9 -4 4 -38 -25 -18 -35 15 -2 -8 4 17 -58 -27 27 54 -26 22 -6 -57 26 -36 -18 -21 26 -54 18 0 1 -21 -38 -30 -62 4 12 -37 60 -11 -9 25 -1 -126 -33 -19 -1 8 -86 -13 41 -8 -59 -87 73 41 42 -47 -22 -55 -73 -122 31 37 57 -83 -18 125 21 -70 -11 24 -78 67 -117 -44 95 -19 -28 5 56 1 2 14 -58 -68 -35 -7 6 53 -42 -25 9 20 -9 -7 -57 -30 -16 27 25 -79 35 22 4 -41 -86 5 0 40 -125 23 25 10 -71 44 -13 26 36 -23 125 -81 -67 -9 -25 33 -19 -36 46 31 -40 -14 -2 21 -41 7 3 -55 21 25 -11 -36 -116 50 54 109 41 79 -30 20 28 29 -121 92 -4 -61 -4 30 20 18 38 -47 -10 21 99 87 -1 -9 -67 85 -5 111 127 -31 13 -25 -33 -97 40 13 -79 -79 -23 -60 -88 -73 14 4 -26 103 74 48 127 31 -29 -13 -8 55 6 13 17 9 9 72 -55 -11 24 -18 48 89 30 24 41 -37 8 6 13 -51 -61 -46 88 52 12 -11 -15 -22 19 33 24 -118 -33 37 -2 -11 26 -37 19 56 7 61 -50 64 -48 76 1 -35 46 -80 31 15 -75 -25 16 46 22 -55 48 -73 40 -18 -47 -8 3 -13 -56 -20 -8 17 27 11 -15 -27 -36 -6 -51 48 1 58 43 13 -29 47 24 25 -9 -59 -15 31 30 -93 39 20 -14 -11 -29 -23 -56 50 2 58 28 -14 41 25 -32 52 35 -9 36 -60 7 40 -54 -69 87 -41 11 21 -93 43 -4 5 35 -6 -37 31 -89 -46 -32 -12 -7 -40 7 71 -58 -18 -22 -31 -10 24 47 -83 67 -15 72 -45 50 41 48 -65 25 14 -100 9 -55 -26 -5 -51 -1 8 -29 29 -17 -23 8 22 50 -14 -47 44 18 31 16 -1 1 42 -69 42 -55 92 -41 50 88 101 -30 36 51 -5 -15 12 -5 -18 -74 -91 -53 67 3 0 26 -35 8 55 -128 -71 -16 44 16 69 -49 37 24 -65 20 27 -88 -10 -4 -15 -18 23 -47 34 26 56 -12 -53 30 -41 -35 -32 -13 4 16 64 83 5 24 -41 -56 -22 -52 59 -67 41 -55 60 20 -50 18 -72 -121 51 80 33 123 -4 64 -12 -22 -39 45 32 -10 -25 32 -53 -67 101 -58 3 37 -18 81 33 11 60 -7 72 -1 -79 -113 -25 -50 42 -4 10 8 -70 -65 19 7 -46 10 37 30 -56 -97 38 -18 -35 -34 53 -65 -35 -43 -35 -40 -37 122 -14 46 -16 -2 -4 -18 -82 12 44 6 12 78 -6 28 -33 6 11 6 65 67 16 6 115 3 -59 20 -4 -67 46 37 -4 127 -46 -36 54 -1 6 12 -3 8 51 -51 -56 -47 -24 -6 -23 -5 -5 -19 -66 3 63 -5 52 -47 18 -40 21 -29 48 -1 -69 -102 3 -33 -3 93 -62 11 11 -19 -98 -41 60 100 47 -14 -39 20 22 -60 19 -20 -69 -20 8 12 -8 -44 7 -29 -98 -16 42 21 35 9 -17 11 48 -22 -91 -17 -72 -92 7 -70 -46 10 41 37 -17 -3 -53 63 -45 -2 -101 38 17 75 -35 -11 97 -51 30 15 8 -67 -21 84 74 51 13 -8 36 -40 21 -63 -33 101 -85 -60 -59 -32 71 38 -37 37 -44 -111 63 -95 31 94 -61 -45 -48 -36 57 -86 -10 46 -47 -13 -56 -11 30 -18 52 -20 53 79 3 57 -12 0 -54 49 54 -18 105 -2 20 9 -9 8 -81 19 -18 -75 -2 29 118 -13 7 -1 45 14 -81 18 30 -95 -63 -19 4 -31 78 78 43 -69 57 66 31 68 8 -75 -18 -35 -12 0 -38 64 -1 -11 -30 -15 -23 -14 57 -62 -17 -43 -79 -128 33 18 4 13 -53 9 -39 55 -57 51 -22 43 29 -12 -53 -8 -9 -47 27 31 -5 13 53 -6 38 -6 -31 -107 17 -17 -56 2 34 -14 59 31 -10 27 -23 -51 8 4 -28 6 13 107 33 -45 71 -1 -18 -19 14 15 125 -46 -21 44 100 -18 -102 -14 -36 1 49 -29 -40 66 -77 -20 -56 -37 -30 -39 -37 81 -14 18 -73 -66 49 -35 23 -38 53 2 -49 -68 33 -116 -61 -79 -39 -39 37 -55 3 -35 20 74 -6 -71 -27 -18 -15 -50 -8 15 -72 12 81 -24 82 -12 -11 -15 -63 -28 71 -44 -57 14 88 5 -6 78 12 -35 -2 74 16 -3 -18 64 -16 4 6 -42 16 -43 -1 -23 36 48 -31 -28 17 -18 41 -45 88 -46 -35 -61 -85 -68 -45 -13 30 -10 -103 -58 41 -13 -19 -10 -11 -23 52 10 -23 19 -25 -72 12 44 51 -124 1 -9 -68 64 40 -41 -19 19 -7 48 48 -83 -80 67 60 -56 -22 -9 -2 2 -68 -18 19 -47 28 -44 57 53 -49 -27 -54 -77 67 39 2 -37 36 -17 6 6 41 -89 51 -19 -36 21 -83 -8 1 11 -19 -31 -15 -29 8 -59 -57 7 -21 -18 50 73 97 -19 -41 2 -20 -9 -23 -90 85 -72 -14 -29 31 67 82 62 -75 -48 85 81 12 -29 56 -11 -58 -85 123 109 123 -77 120 23 38 -30 98 -29 -78 -11 20 -2 -121 -45 -18 15 -16 18 31 3 5 -38 62 -10 5 29 -28 -62 36 37 120 -55 33 -12 4 19 67 60 23 13 14 10 -70 23 15 37 -51 67 -50 -93 -28 -93 105 24 -71 3 -22 23 -70 -29 -69 77 31 7 -21 -37 -114 -52 -109 102 -32 -29 -3 57 -46 67 -24 65 -28 -6 28 -13 -68 47 15 -14 -8 -60 21 12 -21 -78 56 -25 -87 37 44 19 -47 19 4 -71 -2 86 -18 -32 -14 2 93 -53 -75 57 65 7 -1 19 -124 -9 -1 0 19 -25 2 -67 -31 -21 -5 35 34 10 82 -29 -30 -78 7 52 -6 63 92 58 42 32 43 -28 25 -55 71 -27 15 -27 59 43 -6 41 -3 -34 -20 -15 -14 24 -46 -16 12 34 8 11 -26 46 -30 -18 9 -24 -46 0 50 15 -9 -2 14 25 -26 -21 9 -68 19 -22 -16 -9 -10 -1 -14 40 -52 1 5 -8 49 63 15 -37 -26 38 1 -11 -12 78 -1 12 -23 -59 -68 13 -15 -34 -28 64 32 -8 -7 20 -22 19 31 -69 -4 3 19 15 20 21 -17 -27 -8 12 10 -11 2 -2 6 46 -10 48 -37 53 -1 36 114 96 0 61 -72 -112 20 -47 54 30 45 -13 -16 -5 28 4 -32 30 -82 127 16 -15 -7 -2 76 -16 99 22 43 -34 77 40 75 3 42 74 2 51 -45 -16 37 -13 -58 52 7 24 55 87 -56 20 96 26 -59 26 -9 24 18 -32 -6 -21 -29 47 -11 31 35 90 4 -55 21 34 7 -103 37 35 93 -59 48 28 93 -7 27 3 94 -29 86 -5 3 -14 1 61 58 70 55 -20 68 23 -65 40 55 27 7 -14 22 -8 7 -16 5 -39 -42 -71 12 20 -19 -19 -111 -67 -65 4 -11 -34 32 -7 2 -19 29 15 40 75 -12 -49 23 -20 32 50 2 12 66 17 16 -30 1 -96 15 68 13 29 -3 25 42 -4 38 -15 -47 29 -26 34 -12 6 8 60 -79 -51 68 14 -12 33 49 -18 -3 -90 -39 40 -6 56 12 15 34 -8 -49 -14 -36 5 16 -19 2 28 -44 -4 -14 11 -46 10 16 -7 -127 5 30 23 -61 -18 -7 -12 -19 -48 14 55 6 -19 -11 4 4 -18 -17 11 46 25 -22 2 9 37 0 -60 -48 -85 26 -23 -15 33 -52 -20 -13 1 33 -41 -55 -4 -36 20 -54 8 36 -16 -4 11 54 24 -17 -27 -4 1 14 -38 13 -16 12 -5 12 9 -28 34 -23 21 -18 -33 7 9 100 -32 -36 21 -8 -40 3 -2 -6 -12 -27 -24 -15 -49 6 -6 -24 13 45 2 -77 -21 -22 -28 -5 0 1 26 -12 -2 44 0 -13 36 -3 10 -21 61 11 -5 40 3 30 -25 -20 1 -33 55 16 41 -35 9 -12 19 31 -7 -31 47 -12 35 -11 6 -18 -46 2 33 20 14 -28 30 -33 -10 31 -20 35 -15 40 27 31 23 31 44 19 -59 50 30 17 57 -20 46 -66 26 3 -27 -13 69 47 18 -36 -13 -8 -24 -3 -8 28 -24 77 -52 22 23 0 -18 5 -18 0 -21 1 18 9 -7 -29 -26 -7 11 5 20 -58 -47 64 -5 -28 -11 -26 12 -24 28 -1 30 -5 -33 -12 -12 1 -42 -31 -3 9 7 22 -33 36 16 27 -1 1 -28 27 9 36 -77 6 -15 -53 -23 4 -13 -27 -36 28 6 -4 -23 -26 22 24 -20 -34 -18 22 -19 14 12 -1 -44 -52 -12 1 -1 31 61 -7 7 -41 -7 46 -2 15 -15 -3 17 5 9 35 3 19 -25 -51 -37 -6 35 -13 -16 3 -38 3 -20 19 53 -19 -3 30 -31 18 -1 17 -12 -1 -53 -25 16 19 -2 15 -17 6 10 8 -13 5 -16 9 40 -24 -7 -3 -18 15 -13 9 4 12 -13 16 -9 6 9 -4 -30 12 3 32 15 -15 -5 3 -19 1 35 0 -24 -32 17 -25 10 -7 -2 9 -4 -16 -3 7 15 7 -35 -9 19 -6 -10 -28 -16 -19 10 19 14 -6 8 -26 5 21 15 27 7 -16 4 7 -1 -7 9 15 -5 3 -8 8 -3 1 -46 58 28 24 -22 17 -21 23 -13 -81 7 8 -21 -28 32 -15 -91 16 14 11 43 -12 6 -31 -20 9 -42 1 2 6 -17 31 -7 36 20 22 -34 14 -18 16 32 -1 -6 -19 27 19 -59 -10 -26 -35 24 20 19 12 -1 -23 1 -11 -30 -24 0 8 -9 22 17 8 -33 45 -39 -9 -5 49 -36 -20 22 -20 26 -17 -65 -37 -13 67 28 23 18 -18 15 -15 -6 -3 5 32 -33 -6 -17 -27 40 -41 40 -8 1 -8 -17 8 1 0 7 -25 -7 -8 14 16 -8 18 15 8 -36 13 -6 -37 -3 13 -11 -16 4 14 13 -33 9 -7 -1 -52 35 -15 -27 6 -16 17 -52 17 21 2 -10 -43 36 3 8 -33 -17 32 -35 0 -8 17 -31 35 -37 65 2 7 -10 4 6 -32 -15 -6 -19 -8 -39 -47 -48 6 20 -35 -4 -18 -11 39 -4 -24 30 -38 8 -31 -8 31 -20 -36 -16 8 -12 25 31 -59 -6 2 -13 -33 -8 3 36 -21 8 -19 37 4 -25 19 0 -17 0 11 -12 -13 -17 -8 -3 28 2 17 -2 -40 12 -7 15 3 -4 -5 -7 7 10 48 9 7 2 -3 -18 -1 20 -21 14 -15 -14 29 -5 21 -19 1 23 0 19 -41 -20 2 -3 18 10 -21 -24 -7 -14 -8 -22 22 8 37 -3 21 6 17 17 24 -5 14 14 -11 26 35 -37 -1 -3 14 26 -12 10 -10 1 -6 -18 -56 12 0 -24 2 -50 11 30 -100 -6 36 61 24 -21 31 -39 -20 6 -42 17 37 27 2 -32 -34 -1 21 10 20 -39 18 25 2 29 -1 34 -14 38 -4 -37 -69 3 15 20 -4 9 20 13 -14 -5 19 -29 -8 -15 -20 19 -58 1 4 -19 -28 -27 -22 12 11 11 -49 -17 34 -22 -31 -1 25 38 -1 17 -39 -12 22 -29 11 -30 -30 -58 36 -28 -6 17 -32 34 6 -11 -2 -17 -11 10 31 -26 15 -9 -6 -31 -45 12 15 16 -29 54 -14 -13 30 -1 -9 13 -10 25 -4 35 -32 8 -19 20 15 -12 22 19 -17 -6 19 -27 -19 -18 -6 -22 -28 8 -18 33 -3 9 21 12 -6 -17 40 -3 18 31 -17 22 65 46 13 4 -8 -65 4 33 -10 -29 30 34 -29 33 3 -32 -23 32 -23 -7 4 12 6 -27 9 3 22 37 45 -22 -35 7 -68 25 29 -7 -5 -7 6 23 -30 -22 -10 -19 3 21 45 -7 2 -17 -3 18 -10 30 23 -16 27 1 9 -4 20 27 6 35 36 -49 21 -31 -11 -23 27 30 2 -6 3 -17 -17 4 -6 -25 -37 3 -30 22 -26 -19 3 -24 13 23 -49 -49 -22 -2 1 14 22 11 3 0 -1 -16 -46 -31 -6 -13 32 19 -6 -4 -43 5 0 35 -23 23 0 -27 14 2 16 -18 9 2 -1 20 15 -30 -26 13 -15 6 -43 -12 21 43 25 5 -5 29 -42 -12 26 6 10 -16 -14 -48 -44 3 -55 32 -42 29 -15 -24 55 -81 -6 63 -5 -78 -12 2 -10 25 -28 -11 -62 -29 33 44 10 42 10 -31 5 8 -5 -41 -44 -18 11 -41 28 68 -37 33 19 -32 -28 -4 -28 26 -61 -59 90 -19 13 -34 23 17 9 -10 14 -4 -47 -10 37 -4 -27 -25 -8 4 80 -25 6 -4 -18 14 4 -35 -14 18 48 -18 -25 3 66 -76 -17 35 67 20 27 -7 23 29 -37 -64 19 9 12 -42 1 -28 12 17 -74 -16 4 -29 43 -32 -9 -32 36 -13 32 -16 -10 39 20 -54 29 -33 -42 -41 -12 25 12 3 -33 8 4 12 34 34 6 1 -7 44 -27 40 46 -35 -5 29 7 6 27 -31 55 -33 -12 9 40 8 10 -59 -8 6 -30 -10 6 -21 -19 -12 -34 26 -1 -26 -31 -7 -10 5 -29 5 52 31 35 -55 26 9 35 3 6 -4 64 25 17 1 -16 -12 32 23 19 -26 -28 -1 15 17 -1 39 8 -21 12 4 -29 1 12 -27 31 32 14 4 3 41 20 -12 -12 24 -25 21 6 -8 15 53 -1 1 -8 -13 21 -6 -2 18 20 16 13 -2 5 -32 -24 46 5 22 -5 9 -24 28 10 62 5 -12 -29 7 25 11 -1 -7 20 0 2 3 36 -14 -6 -4 9 18 -4 -11 -2 5 0 5 18 -2 14 -21 33 -23 23 45 41 -53 30 20 -6 -6 30 32 -12 18 -14 25 -42 14 -110 28 19 -45 -5 -10 -10 2 -37 -4 -23 -5 17 -47 -4 -23 -18 1 -27 11 -13 -16 -28 -19 -27 17 15 -49 59 -45 -29 -34 59 -23 -21 35 -8 42 -27 -31 22 -40 -6 -49 -37 -47 7 21 -29 13 -16 15 -11 11 20 31 -14 6 2 21 -2 48 -30 32 -37 -54 4 18 25 37 -23 8 24 -38 -11 -64 42 -4 -4 -17 -31 14 -14 -32 30 6 28 3 16 -24 0 -19 -7 -5 -15 38 2 -3 -40 -21 -12 -36 6 40 -46 -7 -7 6 30 1 -53 -32 -4 -33 27 -28 -15 13 4 24 0 -8 14 -24 -15 -9 1 32 33 -43 -49 14 -10 6 16 22 -54 -4 11 -35 -13 3 16 -50 10 19 -2 -32 -1 -18 38 -29 -22 16 1 17 -37 -53 -28 14 -27 -11 -20 2 -23 -15 -17 -5 0 -30 -6 -24 35 12 4 -33 16 -8 0 38 -9 -15 36 10 -51 15 6 -49 -7 -12 -17 47 9 -23 -20 -5 5 -3 -20 25 4 23 10 5 24 -6 33 -18 -2 -19 -6 -17 -15 15 -14 -5 14 1 -18 20 -11 -29 11 -3 -23 -12 1 13 -16 29 -22 -17 -4 -34 -18 24 13 33 18 10 -5 -11 12 -3 -25 -27 19 2 20 -10 22 18 2 20 7 9 10 -11 -30 28 5 -8 5 8 -9 -27 2 11 -12 15 17 23 -12 31 -3 15 1 1 15 -76 8 17 -9 16 32 14 10 -19 -8 -125 -48 -32 56 20 -14 72 5 -10 -9 26 -77 -29 35 59 -25 28 59 -50 56 38 -12 17 7 6 -70 6 -12 -58 -43 -10 -38 -64 0 -30 -28 4 -20 32 29 46 17 -59 11 19 44 17 -11 -54 -31 -24 -29 -19 -28 58 35 0 -67 -50 -36 29 -15 -7 -3 1 34 -58 16 53 15 -72 -9 9 -36 -28 12 -19 7 -1 -9 6 -39 21 17 -68 -63 55 19 92 -1 49 -29 -39 40 -19 9 -6 67 2 -5 48 -62 51 -23 -16 25 55 0 -24 5 -41 -11 11 -4 -23 5 -26 -31 -67 -7 15 3 -11 9 -10 -14 16 -15 -37 1 -12 -24 8 -88 26 -71 5 -11 14 -4 -49 16 -11 -28 -8 11 -8 -15 32 -14 19 -48 9 14 12 -20 -34 -8 14 -27 14 50 7 -66 -57 -6 8 4 2 -49 -29 -26 -22 -5 -4 -8 12 -56 24 6 8 -9 -12 9 14 -13 -56 -26 -12 -30 -37 -4 -5 41 24 -32 21 7 8 -1 -2 -1 30 42 20 -10 -4 -29 -28 45 21 18 -32 -12 47 -8 -46 42 18 37 3 -9 19 51 4 -57 19 5 -27 -21 22 -9 -22 22 42 26 27 -7 -14 -12 -57 36 11 -9 45 12 5 -1 -9 30 5 -9 -12 -1 19 2 7 22 8 -19 8 -34 17 15 -14 -42 -23 7 5 -19 11 -10 13 29 -26 -91 21 -31 2 23 12 -28 -33 -1 13 -10 9 28 -21 -13 -30 -49 44 18 -23 32 -3 9 25 35 -43 -9 20 14 -2 -36 -9 28 20 4 -19 56 -22 2 -32 -19 14 -13 17 17 -31 41 -73 -21 14 -4 -37 -13 32 42 10 -35 -32 -41 50 -25 76 56 14 34 54 -47 37 39 -61 -23 -11 25 -39 -55 -14 -9 14 4 -107 53 -57 45 7 19 -27 0 59 -41 -49 -4 65 -60 -14 23 -46 11 46 37 30 21 -2 16 27 47 15 -42 4 27 -7 -29 -19 -15 -69 -45 14 -73 -9 -76 -11 -23 46 -18 -5 49 8 16 -39 5 23 -28 11 0 97 13 61 12 -14 19 99 70 -1 -71 -41 76 54 -14 -8 8 -8 -26 -43 -21 -10 -69 6 -71 -10 14 25 20 -62 -11 -19 -63 -53 -15 -40 26 29 -8 -12 11 -7 -24 -15 68 -25 -68 -4 39 -32 2 -66 4 4 -7 15 57 -18 41 31 -1 8 -6 12 -6 -7 13 5 -16 -15 -3 36 -14 6 27 5 29 10 -14 -8 38 -51 58 -25 25 -28 -2 -40 -20 -5 -26 1 -6 14 0 34 3 15 -3 -10 -44 -31 0 12 6 23 -5 20 9 -27 2 8 -52 2 -11 8 -5 9 1 -3 -5 -4 8 19 2 -4 -13 11 36 -3 39 -13 12 -38 27 37 -17 -2 50 -15 19 2 -11 -10 -38 24 27 25 -44 63 61 -20 35 3 -14 -44 -19 -2 65 -6 -19 90 25 17 -72 -26 20 -37 13 44 -42 -15 10 -67 -27 -38 70 2 -11 39 -12 0 17 -35 -40 7 15 8 -88 -54 -9 39 49 40 -43 9 4 23 -16 8 19 -52 2 -53 43 -19 8 29 -124 -19 -4 -34 -3 32 -31 16 7 58 -32 -19 19 20 -13 -72 -22 -11 64 10 30 84 -49 44 -47 40 38 -18 19 46 -62 12 -8 80 -40 -76 61 -48 4 -38 -22 -34 78 -8 9 -74 19 -45 1 -40 -28 -11 -6 9 -9 51 10 72 -26 -20 82 4 38 -22 12 -42 -19 -27 -28 17 46 -37 -12 5 8 19 34 -27 24 11 14 -64 -11 10 93 -20 41 9 20 2 -5 29 -47 -15 32 -60 18 5 -4 5 -43 -33 -24 0 25 60 -12 -23 -13 -20 -38 -91 27 -1 13 49 91 -2 -54 40 -19 -27 -66 -30 -12 6 1 27 -12 -32 24 -31 6 42 -31 77 -14 -38 54 43 5 32 23 -7 16 0 13 -7 -27 -10 -22 3 -6 -8 5 7 -19 -19 -44 -51 29 2 -21 -16 -17 57 54 -22 -15 -48 -23 -17 24 1 -4 15 -23 -27 4 19 13 -29 28 -36 2 5 4 58 -7 -48 -6 0 12 5 -41 32 36 -25 -23 -2 39 -8 1 -31 -4 -46 -9 30 58 -18 16 -63 35 -14 11 -27 15 -15 16 -21 9 -16 4 -46 -29 10 43 17 -3 17 -17 -12 -38 -2 40 -56 1 21 -21 13 8 2 39 -14 -88 -6 -19 -37 -30 -28 -53 -2 36 -64 27 -8 -11 42 -3 -82 -39 3 -1 46 -49 15 -36 9 44 7 11 -28 25 -36 8 -48 -41 -24 -52 10 -20 -1 4 16 -10 -5 50 -15 22 -17 -7 -66 -11 -63 -32 -60 60 -19 -19 -5 -20 -7 -34 -11 1 -17 0 29 -42 -21 -31 31 61 13 3 17 32 3 27 -13 28 24 8 -46 -7 21 13 -34 -38 11 -27 -4 26 -35 -17 0 -37 -32 14 -3 -1 36 -4 -20 32 25 21 -5 13 12 22 1 0 -44 -22 13 -47 -31 -6 18 -32 -38 16 -7 11 -32 20 9 -2 -17 -7 0 24 2 21 48 -2 -23 -4 -46 -30 -12 -33 -15 -1 -7 -1 13 13 -23 25 35 8 54 15 2 -22 -25 30 9 3 -28 -5 13 -6 -12 -24 18 -25 -3 2 -22 -11 -23 -29 1 -9 -8 4 -21 4 9 -10 -9 26 -12 18 39 9 -25 -27 -5 -11 -1 8 10 -21 -11 -4 5 0 -20 4 -19 -14 24 11 -20 23 -19 9 0 21 32 -1 13 23 21 6 9 -20 22 9 28 16 17 23 6 24 9 -11 -5 11 11 42 -8 12 53 5 -4 19 -21 -14 6 -1 1 9 -3 -1 -11 8 0 -6 -9 3 -38 49 -5 7 -14 5 -12 -3 22 -32 11 -4 10 13 7 -5 -7 -8 -21 -28 7 -4 -20 27 7 -11 16 -19 -3 35 30 -3 2 -19 -1 16 12 -57 -24 -31 19 -12 36 -10 -4 -9 23 4 3 0 8 21 14 -35 -32 33 -21 6 -21 -34 33 -10 6 29 1 1 -5 -3 -6 4 -27 63 -10 6 26 9 14 -21 0 14 17 -5 -4 16 -23 -15 -21 21 -16 7 -12 13 9 39 -31 7 40 0 -9 -5 9 -29 -1 16 33 21 28 8 15 44 6 -12 -58 7 -9 29 -28 -27 -5 12 34 -1 24 37 -7 -8 -17 -6 1 -3 -12 -14 -19 7 5 27 -3 -1 35 35 -19 1 -11 13 5 23 13 13 -15 -9 0 16 2 -14 -5 12 -1 -46 10 27 43 20 -43 0 8 23 3 49 24 -10 -38 14 6 -11 -6 -32 -49 10 -20 25 -12 14 7 -6 17 33 24 32 -47 -32 -13 -9 9 -11 -15 -7 1 5 30 5 15 -30 -21 9 9 7 5 19 15 -10 -13 3 -2 8 6 -40 -17 -15 -16 -27 2 -18 27 30 17 -13 -7 -30 -28 -11 9 -20 -5 9 36 7 18 -6 10 14 22 0 -9 45 -9 -18 34 -13 -17 18 0 5 2 -28 -1 11 1 6 25 18 24 5 3 -10 -19 -11 -6 8 16 15 9 23 -7 16 -15 12 12 3 -4 9 8 -10 10 1 5 14 -2 -14 -8 47 16 26 -4 -27 -2 -16 -16 10 -15 -42 9 24 -20 -15 3 4 -2 33 1 -9 -34 -11 -5 -38 37 83 25 5 -23 -4 44 -22 33 -23 -24 124 -24 -21 -46 23 11 0 -5 -8 -49 3 20 15 -1 66 77 -19 11 -42 26 10 -24 44 13 10 13 -5 -47 -36 -19 0 14 -2 11 -31 1 -14 2 -31 40 -22 -46 11 -37 16 -7 -32 -28 -22 -14 -17 25 -33 28 81 -50 -35 -24 24 -18 -43 14 46 38 25 -54 8 -31 46 -11 19 65 15 -10 26 37 39 22 -11 -27 42 38 -31 25 -9 -15 13 16 4 33 13 71 24 3 20 39 23 -23 -3 36 5 -43 6 56 16 -27 24 42 2 1 -8 1 -23 -10 30 14 25 -7 34 -31 -21 -10 -39 15 32 86 71 -8 34 11 24 -9 12 31 81 32 -9 12 62 -10 -4 -5 -29 15 -10 -11 -42 52 12 -13 -10 15 -62 12 34 49 -14 40 14 21 -58 20 -17 17 -4 14 -20 33 -16 7 -31 -1 -14 -45 33 7 -16 -3 -27 12 10 30 42 -9 70 5 -14 19 21 -16 7 11 28 12 17 29 15 -26 16 8 -14 -14 45 -14 3 20 -12 34 -4 24 3 -24 -12 25 14 -1 35 -2 -5 -13 -7 -10 10 -28 26 -37 18 16 -18 3 10 -14 -16 14 -5 5 -8 13 -12 15 -1 -4 -7 -1 -12 1 -39 8 12 -3 -11 12 10 17 10 17 -30 -39 -25 15 -7 5 7 -8 -8 7 -6 -10 -3 -21 3 -16 21 -3 24 -23 11 29 34 -67 -39 -46 0 38 24 13 25 21 55 -2 -8 44 -34 -31 -43 -14 -37 19 42 10 -22 37 35 -26 -25 -31 75 21 32 -9 39 -34 -15 -47 -35 -39 -89 -1 -33 -47 2 31 -6 15 46 19 -96 22 -11 14 -20 -4 12 13 35 26 5 -27 28 43 24 -41 5 50 -4 -52 66 26 38 -39 22 -11 70 28 -3 -38 36 -49 -7 17 19 53 56 -10 80 13 -41 2 62 -24 -10 -17 -59 10 -29 -6 -26 10 -36 23 -9 -58 33 -24 -8 -18 -5 -62 -10 -35 8 45 -7 -34 -7 16 7 -17 16 14 35 -7 -26 1 -32 -21 -22 9 18 -1 11 -12 -45 -28 0 -7 4 59 -10 7 23 -40 -20 -41 32 14 -35 47 -13 0 -23 -18 12 23 -76 -24 52 0 29 -10 -24 7 23 -26 -48 -3 7 23 -1 -1 -15 -40 -15 -15 -3 -91 21 11 27 -3 -12 7 -67 -13 44 25 17 -13 -16 45 -1 2 1 -2 13 -2 12 1 -9 4 6 -9 -42 -24 5 -29 14 19 31 9 0 26 8 23 12 7 -13 -19 28 -13 19 -25 -12 -29 -20 -8 -11 -9 -14 11 3 12 12 -26 0 19 2 6 -23 26 27 12 -12 7 -32 11 16 13 12 6 -7 -38 5 21 11 -2 -3 10 22 -6 1 18 -4 4 -6 38 36 -1 -32 -7 16 32 -8 15 17 -13 42 7 -23 -30 15 19 -31 0 23 9 2 64 -67 -25 6 12 7 100 -23 -30 24 -6 -58 12 -5 -48 20 13 74 39 15 33 -87 -92 -35 23 8 -94 -6 -17 29 32 -14 -22 61 54 -21 18 -8 -44 6 8 7 -43 -41 5 4 -22 2 -26 -37 -27 -33 24 5 14 10 48 24 -34 26 -3 -10 3 -60 21 0 -4 -57 -11 16 21 15 -49 9 28 -2 -15 -103 29 -27 31 23 81 34 -51 -102 -50 49 -23 -14 -8 -17 -39 2 36 -68 -36 30 52 31 25 -49 27 25 45 14 42 11 -21 23 43 22 -1 38 43 -48 -42 -26 -12 7 -18 -19 46 -15 -5 18 48 -6 -46 31 3 -9 -56 2 25 -27 60 -24 -23 -23 10 -12 1 -15 -37 31 12 2 37 -43 9 -36 30 -14 18 15 -6 -42 16 52 30 12 51 6 4 15 -22 -17 -7 31 -40 -64 43 24 8 -22 46 -48 -35 -10 19 -38 -39 2 -55 -4 -31 6 13 59 14 -42 31 -22 -3 25 1 -16 17 -1 -16 0 10 11 -2 -36 20 -4 0 -21 22 -5 3 -6 -6 -3 25 2 -26 -24 0 1 -25 30 -4 -34 17 32 -16 -17 -8 -15 26 -29 5 -20 -38 15 38 -8 -5 4 15 5 8 -21 36 6 0 -19 13 -36 18 32 -44 1 -24 -19 12 -19 -16 -79 -15 3 11 -26 18 -4 14 -6 12 6 0 8 8 4 6 -1 1 -44 -6 13 -45 20 5 -47 15 -2 55 25 34 15 27 4 76 12 13 79 -74 -1 -10 51 31 59 -1 44 -8 -9 34 76 64 -12 35 63 48 25 -14 68 14 25 -49 22 29 56 3 51 24 -59 -12 58 0 -2 41 -77 16 -41 25 -7 40 44 -32 49 13 20 -27 48 22 47 31 10 -41 -28 -41 32 31 63 3 63 13 -2 29 4 -66 17 -15 36 59 43 77 19 38 -54 48 -11 74 -27 89 -13 -6 1 -3 -84 46 -48 18 -11 10 19 1 -34 -7 -50 53 -39 50 -15 -70 14 -14 -25 93 43 17 32 -13 -26 -20 46 -12 -18 10 -42 20 10 -33 -26 0 -11 9 18 -1 -25 83 0 16 14 40 -37 -8 13 -4 9 -39 -103 23 -36 26 63 -2 40 -7 -36 16 -34 65 28 -23 23 35 29 14 42 87 41 1 28 -46 46 -4 33 -26 -43 -5 -50 -16 63 -3 24 -3 9 -31 53 -54 -91 25 -5 -19 -12 -11 -30 16 -8 12 11 -24 -32 23 -1 -15 34 -9 8 -10 51 21 -29 30 -33 4 -10 15 38 -57 10 51 2 -40 13 -25 -7 3 -1 -13 -21 8 15 -34 -10 -28 23 -33 26 -20 0 14 10 -13 12 -10 1 3 21 -19 15 -16 6 -40 8 -36 17 15 15 -1 -7 5 -19 -15 32 -3 22 17 -20 32 2 -15 -11 -32 -3 17 -4 5 -7 4 -3 -29 7 26 31 -15 -31 -7 -32 33 29 -4 -15 -69 -45 26 -29 -11 3 -4 4 32 -38 -16 30 -22 5 16 17 10 32 -9 3 0 7 -8 -19 -6 22 16 11 10 -24 -5 -12 9 -26 0 -31 8 20 50 -19 -4 12 5 20 -13 18 7 -2 19 11 18 21 -20 3 -6 3 -13 40 36 -28 -36 10 23 -1 -4 -22 1 47 17 17 -19 12 4 -9 -24 3 2 31 67 22 22 86 6 -1 -17 6 -40 10 4 -18 2 -3 -17 2 -15 -3 -24 -9 -26 -13 -9 -27 -22 -11 -21 1 -9 16 -2 29 14 36 23 -5 6 -3 -32 -15 47 -11 12 -23 -23 2 21 37 -10 12 3 -14 -3 -15 -2 -15 -37 41 7 11 -27 40 -18 18 7 12 -39 6 -6 11 -1 23 -38 -13 -1 -50 16 21 28 -2 53 -6 5 9 19 24 5 22 36 -4 -35 16 36 -11 -7 21 -8 10 -29 -5 -2 -32 -30 19 3 11 24 -3 -22 -11 14 2 -10 17 20 0 -8 -9 9 13 -13 10 8 -2 19 -3 -2 18 8 0 -30 -5 6 -8 -14 -29 11 -8 8 36 10 -5 9 -7 24 -1 -3 -60 26 8 22 13 -24 -11 -10 -8 24 -6 28 -2 1 -10 25 -15 -8 15 -17 -7 -55 -9 -9 -8 13 32 -15 5 -6 -7 -9 18 -22 13 14 20 24 2 -22 5 -1 -27 13 1 1 7 -6 7 -7 22 -35 4 -8 -20 -4 -22 16 21 18 -11 -79 30 -57 -45 -1 -48 15 -5 35 -41 -32 -22 -34 -19 -29 -40 21 -20 -21 19 35 23 37 -19 1 16 -87 -3 -32 25 -13 -3 5 64 50 99 68 60 17 58 -35 25 -31 84 -47 -5 -17 92 -2 29 -21 -27 43 -19 4 -84 -49 67 -8 20 17 33 -19 -11 35 -64 -3 -13 44 95 -6 -7 45 24 -47 -24 69 6 3 -63 46 -73 81 38 62 -24 23 14 26 -18 62 -6 -37 -3 -57 -34 17 -98 8 -39 -12 -5 -44 90 -40 -40 -44 -10 43 -31 -4 -33 -10 -69 -47 31 -31 -29 -7 5 -52 47 -53 -38 18 -16 -18 -19 33 -1 5 5 43 -82 -3 34 81 13 -55 -28 -29 -65 4 -6 -43 -30 -9 -50 -28 29 23 12 -65 -5 -60 -19 13 -50 11 21 -9 8 8 39 -41 -84 -25 -15 5 -14 -59 4 -93 34 20 19 2 11 -1 16 -51 64 -25 58 11 -41 1 4 -68 -25 -14 -31 -43 29 42 -16 -2 10 -6 39 27 -6 68 -23 -19 38 34 -30 -6 -1 -6 42 15 -50 13 -38 0 43 -38 47 -7 42 -1 56 0 -12 13 -13 -31 -22 7 7 -7 -9 6 0 23 -15 -32 -30 -2 -2 -25 -48 -11 3 35 -20 15 32 -4 4 6 19 -4 8 44 29 1 -10 -44 2 -15 40 -8 -28 1 25 -26 -32 10 -24 -17 -25 2 -10 13 -1 -9 -6 6 -7 21 0 -12 25 -1 20 -22 -63 56 -21 6 -60 28 -24 -12 20 -17 -106 -14 -40 9 -21 29 30 26 -32 -28 -4 -37 26 -4 32 -37 -14 -27 -19 -18 5 29 12 -10 -41 -19 -3 40 -10 18 -48 -37 17 3 13 -19 -68 -3 -55 6 -2 16 -28 49 -47 -21 -29 -14 -20 -29 2 -3 50 8 -19 -13 -18 32 -8 -22 -17 0 36 -12 -20 -28 9 -27 2 34 -11 -3 -24 9 18 -13 23 -11 42 31 -48 -33 -28 -39 20 21 -11 9 -28 16 43 23 4 13 10 6 46 0 11 -40 -14 -35 -39 -8 -21 8 -28 -17 28 -11 27 -10 20 -10 40 -7 -24 1 5 8 -23 4 41 -12 25 22 -11 -26 34 3 -15 -1 -13 19 -2 39 31 10 11 -23 29 -8 -26 -11 4 -9 6 7 -14 -17 2 1 -18 0 -9 -5 36 -10 -1 -23 43 41 -4 -47 -15 0 -28 -41 -28 29 27 -23 20 2 2 -56 -23 -6 -26 -18 4 -23 -2 -35 20 20 1 5 3 26 -10 30 -22 -19 -47 20 -3 38 -6 -4 -11 11 -9 -26 0 0 -15 40 7 21 2 -1 3 -1 -14 -17 -11 21 7 -35 38 1 -1 -9 -18 -28 -21 -14 2 1 24 -7 14 -18 9 7 15 1 -16 18 8 17 -32 1 -14 9 0 2 -34 -3 22 -15 -8 -3 21 9 4 8 -21 14 35 18 -17 28 -8 9 -6 -10 -41 -3 37 26 -32 28 31 -9 17 3 5 13 9 32 35 -22 -32 -43 -29 -23 13 -27 7 -29 0 -34 29 1 1 18 12 -34 -24 30 -8 -28 14 -59 -2 14 -26 -7 61 9 46 35 29 -79 -1 -17 -10 3 -46 -27 13 -12 -33 -22 -20 -36 -23 12 -29 -17 25 -55 8 38 31 -28 -17 -5 -51 -31 -27 37 -25 -14 62 31 29 -15 20 33 16 -7 -49 -6 11 2 -28 15 36 30 15 38 11 -25 12 -69 -42 0 1 -13 5 59 18 2 14 9 -2 14 -29 -1 3 -64 -5 25 -22 -13 -27 0 -2 12 -63 -8 10 -16 -13 -20 -27 12 -12 -4 -3 -25 -36 50 -32 5 16 -23 8 10 5 -17 -4 63 0 35 -19 -7 -33 16 31 -30 -23 -11 16 26 2 14 14 14 -17 -20 -19 51 91 -16 -12 5 -13 -56 12 -16 21 -24 -15 42 20 23 44 -16 -18 7 -21 17 3 22 -29 -10 2 -20 -10 -15 -20 18 22 15 -35 20 5 4 -40 -12 -2 -5 -12 -1 -29 16 6 -6 14 16 -24 13 -16 20 -10 2 9 -14 7 1 5 -1 18 5 -25 -24 2 -13 8 -14 11 14 6 -11 -21 -24 8 -11 -13 -8 5 39 -5 5 -8 -11 -5 34 32 -7 -2 4 -9 15 -26 -6 14 -4 -2 31 -19 3 -9 -4 9 -4 14 -25 -11 15 26 -15 -7 33 -27 10 15 -10 -14 17 -17 -17 13 3 -37 -7 6 -25 66 15 -18 7 15 27 25 48 -25 7 16 19 4 7 -1 -16 -16 47 10 30 -13 15 -7 -24 28 -2 44 -2 -17 -23 5 -19 4 -8 -6 21 5 -17 4 18 -1 -14 -5 18 -13 -5 -41 27 -55 28 45 -2 45 2 17 -23 -9 36 17 0 8 -4 -8 -7 -47 -6 30 -20 -26 12 0 45 -43 56 30 -3 -23 40 0 14 3 -26 9 19 -10 -8 64 -24 -20 -13 30 51 10 4 9 -8 -36 -49 11 15 22 -27 -5 17 14 -27 34 -14 30 -24 15 -2 -29 18 23 8 3 -23 44 14 13 -41 -7 -5 33 8 14 6 16 9 25 -30 -1 -16 -31 -12 5 19 0 17 -7 -18 -16 10 -42 -9 11 -3 -5 -26 -7 -13 13 -23 -11 33 20 16 7 26 -21 0 -23 -5 27 6 -11 6 33 -23 -15 10 33 -15 -14 60 18 23 -24 32 -34 16 -21 18 -24 8 -11 10 7 -22 -24 6 4 22 17 17 25 -11 0 -44 2 -6 -42 8 24 -3 8 -35 13 -13 15 10 -13 5 -26 -36 18 22 1 35 24 10 -3 13 -27 -39 33 9 5 -5 -25 -4 -12 7 -19 8 -7 -7 2 -14 14 -8 -4 -7 21 10 -16 -27 -1 -16 0 -18 10 -4 -22 4 11 -13 7 23 -17 -5 -12 -12 -8 16 33 -21 -13 3 27 11 58 26 0 22 -2 -4 26 -17 33 -2 -9 -22 -10 17 0 -2 39 10 -17 -2 9 -45 17 -36 9 9 20 -1 6 30 -25 54 -1 8 -9 22 14 -1 37 -27 28 -44 -17 26 -7 -14 14 -21 -14 6 -19 -23 -8 0 2 -7 11 -16 18 -23 25 -32 3 -11 14 -19 -52 -42 7 -25 -4 -34 7 -42 -5 4 -14 21 7 -29 17 6 -16 -23 -13 -2 3 16 -9 -29 5 20 52 17 -28 -21 -1 58 -16 -39 -35 9 33 15 2 13 2 -19 -11 -76 -2 25 47 23 45 -23 -6 10 -39 -17 7 32 33 -32 28 -26 32 -16 -15 -8 14 23 -17 2 -15 15 -2 -1 17 -23 -27 4 -29 -37 5 -1 4 -9 -27 -19 22 21 21 -26 5 15 -22 -6 -1 -52 40 -26 13 -2 -22 -47 -21 19 -2 -12 4 6 19 25 -4 -16 32 -31 22 -12 -4 -15 -22 -11 -16 -13 -3 7 32 5 -1 -23 -3 8 -12 -25 20 -28 -19 -31 5 -6 5 -35 5 -23 -1 15 -33 6 7 -23 -22 38 -5 8 -36 -2 1 7 -13 6 -9 19 33 48 -13 2 -6 -4 33 7 -22 -8 36 -40 -2 -37 -14 7 -4 20 10 -8 31 -7 4 32 4 27 4 13 0 13 -23 -23 23 -10 -2 -7 15 32 7 -6 -14 21 -14 25 -26 27 -21 26 -13 21 -6 -9 12 20 -14 3 18 -14 -11 -30 22 -31 -33 -11 33 -14 -17 -17 -12 -7 2 1 21 25 -13 7 15 -7 23 -8 -12 9 -10 -12 -14 35 50 -17 15 -8 -39 9 3 29 0 22 -42 -18 15 14 4 9 -35 40 -46 15 -11 31 52 68 -30 -9 -8 9 -8 16 -2 13 9 71 17 -30 21 -4 17 13 -37 21 7 -18 -17 1 7 -19 -22 36 1 11 33 -24 -8 7 -23 -27 2 18 -13 31 -40 28 12 -38 43 0 75 47 -18 -7 -13 -47 5 -40 -43 16 -2 10 -18 57 9 -22 -1 56 18 38 -13 -19 -30 -8 7 21 19 -6 0 12 1 12 -6 24 -17 6 -25 29 18 -36 6 2 7 14 -12 -14 25 -17 -25 25 11 13 9 43 -24 -27 13 20 -13 -9 54 57 4 -12 14 18 17 -31 3 6 -20 -6 5 -13 -11 -23 30 13 -13 19 -4 8 -8 13 -13 4 -60 5 -30 12 2 4 19 -7 37 -4 -31 46 32 22 63 29 12 -34 0 -19 1 8 -4 -40 -16 28 57 30 -20 32 15 1 15 -4 -5 26 -8 -8 -5 24 -24 11 -8 -22 -10 -34 11 5 0 -41 -1 -4 -3 10 23 -7 -21 -14 11 52 -16 3 -22 41 -10 26 18 -1 24 -14 -25 30 2 3 -11 -11 4 16 15 -15 -20 -1 -15 -5 -19 -44 15 8 40 4 -34 -4 -6 20 19 -3 -5 4 -25 42 9 -12 9 -6 -16 12 -10 -13 -4 7 -10 -29 19 16 -9 -13 3 -16 12 -28 14 11 -4 17 18 -14 32 27 11 16 9 2 -21 -8 -36 0 -26 14 -28 12 -66 19 15 -65 -8 -20 -40 48 14 11 5 -20 74 -21 12 3 7 40 7 -41 7 17 3 -20 -22 6 33 -60 -4 -20 -9 55 1 48 -9 2 -9 -1 -59 -21 21 -30 -17 -14 -1 3 -1 24 -39 -16 -29 -20 31 52 39 0 5 -25 7 35 -7 -12 -54 34 32 46 -38 -37 -12 12 30 0 -47 28 8 18 35 6 18 12 -13 60 -6 -58 41 -9 -19 2 34 -7 7 19 71 57 -21 14 40 3 61 -25 -36 -38 14 4 -36 17 3 -31 9 -34 -10 -1 14 -113 -10 6 10 40 -40 -23 15 7 44 50 37 10 22 -5 -26 -55 0 0 -13 13 5 23 -31 35 -31 -22 -2 -14 18 13 -16 -21 49 9 35 -33 -53 -37 13 -9 -12 -8 20 20 14 -27 23 4 14 -33 -32 -11 10 55 -15 18 25 4 -34 -31 -4 -28 28 -29 -17 -39 -14 5 -11 -5 -3 17 -8 4 25 -4 8 -15 8 33 -33 -6 -42 30 4 14 -4 -5 11 -13 21 -30 9 -39 -15 3 54 12 -32 -10 13 5 4 -14 -23 0 29 -2 -4 -27 -49 8 9 1 -2 -14 -27 -8 3 0 3 10 30 23 22 11 7 7 -19 -17 -12 -43 -4 46 2 7 6 -3 46 -35 40 -12 31 19 -39 -16 -2 -29 -12 9 20 19 5 4 -14 -42 -19 6 38 -43 1 -13 16 -15 8 -43 -12 -33 -71 3 11 -21 -42 35 30 -22 -27 -30 2 -17 55 1 -24 -39 -29 -69 -44 63 -73 -35 -76 -3 -49 -5 13 23 -49 34 55 -1 -63 -35 -15 51 22 -33 -3 -30 -119 8 2 -11 -56 -13 2 -35 -6 5 -36 -29 0 -71 -4 -103 -38 -63 30 21 -44 17 -58 13 -17 93 -125 24 -29 -26 62 -28 39 -26 -14 30 -20 -8 18 -18 65 32 -16 -9 -6 -17 -13 -92 -24 -1 13 3 23 -35 20 2 -35 -2 -16 -23 44 -21 -11 -1 38 -18 25 40 0 27 -19 -66 -27 -57 -18 -11 25 1 -49 -3 -5 -27 -9 19 8 -23 71 -74 13 33 -46 -19 -28 28 46 -4 -5 -37 -72 38 32 -23 -20 -33 36 -55 -30 -7 -53 -12 29 -11 29 65 -30 -31 -40 120 -46 27 11 -21 -77 -3 -27 -24 44 63 4 -17 -32 16 18 -7 26 47 -62 -3 -51 9 -21 -51 35 -23 32 44 -8 1 50 16 20 22 1 17 26 24 56 -4 7 -17 -21 7 -63 7 -12 18 1 -21 17 -5 -19 12 4 17 -21 9 5 22 -20 48 10 -28 14 8 -14 -16 -2 8 -6 23 -15 25 17 -16 0 -35 23 6 -6 -29 -34 -20 -64 3 -31 17 -19 29 8 -4 -2 -7 -17 7 -22 18 31 21 1 -35 4 -19 33 26 -3 -4 -37 7 17 -28 23 -8 -11 -14 -17 37 -32 10 -11 -24 11 -23 36 35 3 14 -51 -23 12 8 22 88 -24 66 -34 46 -39 -38 -23 39 -37 -25 -32 -28 97 -11 18 8 62 -17 49 -13 21 -14 60 28 21 -76 26 46 -32 -26 38 57 20 35 31 23 -8 9 3 -11 -18 0 6 -40 -19 91 56 14 38 82 -16 -14 -3 12 -73 50 11 -8 25 2 13 39 20 -9 26 10 56 64 -5 -17 82 -27 84 -18 26 12 -46 -22 -19 6 0 56 34 9 45 -33 116 28 127 12 -3 44 31 0 -16 -40 4 -60 -11 21 44 37 -24 19 -9 44 1 -9 -13 -8 -12 50 14 24 -19 52 -32 -76 56 -35 -29 -33 -55 19 -29 14 32 -1 8 -10 30 -6 0 123 3 -14 -40 30 37 5 38 0 -2 27 -36 -14 25 -44 -8 112 63 -2 33 -41 -39 7 -53 -9 32 -17 4 17 24 -22 -15 25 62 -16 26 -49 62 21 16 26 67 -6 8 68 -21 30 -9 -26 -18 50 -18 12 -10 -31 36 -11 -7 -2 -7 -29 6 31 -2 -14 12 -69 -7 -8 -15 0 -34 7 2 -31 13 17 21 -5 -19 -59 25 -32 6 -11 -34 -11 -11 -4 -8 9 32 19 18 -13 3 15 -2 13 -23 -13 -31 -7 18 2 -10 -27 20 -114 -1 -8 15 -24 56 4 -19 -14 -32 -24 -28 -3 -7 16 12 -18 0 13 46 3 -15 -12 19 19 31 -7 6 1 -42 -17 -43 11 26 8 -40 -60 -88 1 12 21 2 61 26 5 22 -44 5 39 16 34 4 18 33 43 -32 54 -26 8 51 40 48 -103 42 25 14 -54 -3 58 -1 -66 74 11 10 39 -43 -70 -1 -23 76 -6 -43 16 57 20 20 59 12 5 -6 43 -25 63 -19 -1 -24 88 -56 53 32 22 2 -9 12 -2 52 3 65 -55 32 30 31 -58 -13 5 1 -19 -8 35 12 29 0 9 -27 -32 -2 -21 78 31 6 -9 66 -11 6 -9 -16 73 -1 30 -51 32 -35 -41 8 -48 13 59 -5 49 40 47 -23 3 27 -9 8 -3 -11 24 -23 -45 0 -35 -34 -12 -39 -19 57 -44 21 31 -69 1 28 -30 -70 -18 -8 -13 -28 35 6 27 -21 5 -14 -6 -88 -10 -63 78 22 51 -73 -35 7 42 -17 1 127 -29 -11 55 49 -49 -65 -74 -43 -39 43 -20 11 46 43 21 5 -26 18 14 5 -26 -18 25 29 -12 -31 14 -68 35 69 -38 40 -50 14 47 26 18 -6 -32 -11 31 -27 20 18 27 32 -51 2 22 11 53 14 11 63 -4 31 4 -17 -29 -51 15 15 -3 25 25 12 28 24 -17 21 -26 -18 44 -15 22 0 -15 -4 -32 25 -18 -56 30 -6 30 65 -18 5 -55 -7 -20 12 21 46 -8 -5 -10 -12 -32 -2 12 -22 36 -47 6 -38 40 18 -10 51 -11 -24 -17 9 -21 -13 16 -48 -33 26 51 22 8 -28 7 1 10 1 -19 8 -64 -30 -40 -8 35 40 1 28 -17 -3 39 -76 10 81 -7 2 19 56 16 74 33 45 19 37 -43 14 72 12 19 25 44 42 16 31 85 113 124 34 21 94 25 -11 22 13 28 13 19 34 26 41 45 22 11 28 93 0 -27 -43 -16 22 47 22 -12 51 -11 -9 25 -15 -63 3 42 1 -67 -40 16 27 16 122 30 -67 -56 40 11 125 22 -45 -17 71 -13 4 26 -45 45 -8 41 -3 29 -71 -78 43 -12 74 -36 20 6 -42 -70 15 63 3 -34 127 1 45 31 -30 -10 36 23 -28 -59 18 -24 8 53 53 9 -13 30 119 -55 -36 -17 92 48 21 34 29 20 28 -9 -23 27 2 72 16 -19 -22 23 -30 31 -91 14 -40 12 -41 30 12 7 33 -3 -42 3 37 25 -48 21 29 59 -12 22 109 -13 -51 57 -56 16 54 -40 17 -34 12 47 -21 4 -53 100 0 26 27 42 18 -59 17 -10 14 41 19 -10 -3 -69 10 -4 35 32 60 -21 -20 41 -26 8 -27 8 17 6 -17 13 -26 -32 3 -9 -31 -27 -17 -43 -15 -5 28 29 -11 -67 -26 -42 1 7 -26 43 -16 -29 -26 31 35 -26 103 -14 22 -26 25 -51 28 26 -10 17 -15 -60 15 -13 -5 -3 -7 40 -35 27 0 -21 -13 15 -13 42 -121 -16 -16 15 23 -27 8 21 -3 -51 34 -12 18 -47 -30 29 14 58 39 -32 24 -21 40 61 -2 74 -23 5 -20 13 -80 35 5 -12 -28 -8 -67 1 21 9 110 -92 46 -7 -29 35 103 -16 -11 54 -14 1 -16 -21 12 -35 -80 24 47 -56 -13 23 -14 95 -3 -40 37 -42 52 46 44 -11 25 -12 -3 -79 -75 -5 18 -40 37 39 28 -30 98 41 -18 31 23 -41 52 23 85 -15 40 21 -6 -48 -26 -26 81 10 30 -20 6 66 -19 14 72 42 33 -24 11 8 20 69 55 0 23 -13 10 -5 10 -12 45 -1 42 -10 11 -24 7 7 57 -37 23 35 -16 -43 50 2 61 12 7 -25 32 -13 -7 69 8 -16 41 20 -46 -20 -49 -12 56 15 41 33 25 25 38 -15 71 -17 30 4 -43 -21 -26 -24 -44 -35 -50 32 -3 2 11 5 -1 36 6 12 2 11 -43 -1 30 17 39 41 -26 -23 6 68 -17 22 13 14 -51 26 -24 36 28 0 56 16 0 -15 -16 14 -26 2 -25 -18 -4 -31 -12 -16 5 -42 -27 -40 9 -30 32 40 45 -16 32 40 -22 20 25 -23 16 47 22 -8 30 66 -19 13 13 -34 -32 -6 -4 44 -24 2 20 32 -3 -29 -11 7 -33 77 22 -20 8 6 16 15 -3 -18 17 10 70 -20 -9 -33 -22 -1 13 6 -35 29 -15 8 -19 -36 -30 52 13 39 16 -35 -39 -28 -17 24 55 -8 19 32 5 -5 -1 21 -42 -11 7 24 -94 51 6 23 -13 44 50 -45 38 62 -75 34 -18 -5 10 -15 15 -27 34 -62 45 -79 127 -24 22 -69 6 4 7 -7 2 -25 -21 11 13 -62 40 -15 -6 127 75 -60 10 15 -41 1 5 -14 -25 26 35 121 11 7 19 -2 -1 -17 -56 25 2 86 9 8 -9 -3 61 22 -48 3 -64 -35 19 9 85 55 -11 28 77 -41 14 -80 4 0 70 -29 69 -45 -45 -53 40 -31 26 31 11 41 11 -21 65 -37 -14 44 60 48 20 32 77 65 -79 -56 18 -8 8 -3 25 6 -42 45 24 -13 -21 -54 -17 32 67 -28 12 1 -33 50 -35 -12 -56 -11 -33 -54 21 -2 37 19 9 -5 21 10 -35 -27 8 62 50 -39 11 51 -9 21 28 24 -9 -62 -75 -79 -51 -48 68 59 20 -58 -20 32 15 31 -38 57 25 -17 17 35 20 -33 -25 47 22 -7 21 -38 -22 24 -49 -6 -38 -14 20 61 -14 21 -15 -21 8 59 -35 50 -16 -35 3 -6 -14 -35 -40 -19 23 14 19 -4 15 8 -54 82 -46 -20 -38 21 -63 9 3 -24 -2 11 -18 -8 24 -28 -17 30 36 -27 3 45 3 -20 -22 -45 16 -6 14 -6 16 10 8 8 -26 -5 -4 38 -20 0 -1 -25 -37 7 -20 23 8 2 14 -11 5 23 -2 36 26 11 -1 -11 -8 30 -38 -92 12 25 47 29 -25 20 -31 69 26 -26 24 40 44 18 15 54 -40 -14 -39 -47 31 -93 -17 -27 -45 46 16 -27 57 -50 55 -84 -37 -10 -69 -104 7 30 -16 44 41 -12 -15 3 -87 0 -21 -92 18 -5 -37 -6 81 -36 -12 44 1 -5 -61 50 38 91 29 -38 -67 -32 -23 52 -11 -40 44 -18 -30 -62 -34 -21 16 9 12 22 68 -10 -36 -28 16 -1 -19 -16 -31 45 24 4 21 38 27 -20 -68 22 22 -31 -84 -78 27 -77 -5 1 -90 -29 37 28 71 -27 29 113 -14 33 10 36 -78 24 89 -48 13 -47 -51 0 -44 -6 -67 -17 -34 83 -69 -100 0 25 -64 6 7 63 22 -28 -40 -57 -26 -43 -13 42 -10 70 -41 1 3 -8 -21 -113 47 -52 -44 -42 40 -38 -81 34 56 19 -20 -72 -43 0 -75 68 49 16 -74 -23 48 17 -80 35 83 -38 -30 29 40 56 -58 32 5 -7 -48 -55 77 3 17 -9 -27 3 -5 -42 -58 -58 -2 -18 -47 25 -25 49 10 48 14 30 64 21 17 -15 3 -21 -17 8 -12 -23 -68 22 46 26 2 -29 -14 7 4 58 -32 -94 -5 -111 -11 21 14 29 6 -15 -4 -25 -46 -13 14 -47 -8 -42 10 -26 -6 17 32 34 35 26 -8 -14 1 -3 7 -19 17 16 -11 5 -17 14 21 7 6 -60 35 -3 -18 -51 -18 -6 -73 6 -42 14 39 18 -10 16 -49 -13 -14 -32 -19 4 36 36 -56 -13 -29 7 2 3 81 26 73 -8 18 -87 -42 -1 -17 -38 -3 29 45 -21 -46 20 13 41 42 -3 -4 -36 35 -6 -33 3 -31 -14 44 -20 -63 -53 -45 45 13 33 -26 -41 32 -10 -77 -16 -23 27 -40 -4 18 -19 -26 29 45 19 -11 1 -7 -5 14 15 6 -30 -22 -1 -33 40 -23 82 -11 31 -6 -17 38 -28 33 15 -51 27 26 26 63 7 8 -19 18 -55 55 -6 71 -60 2 33 38 10 -9 -40 20 4 -41 9 -15 -5 -27 75 -15 9 6 -90 14 16 -7 19 4 25 -38 -56 -9 60 -2 -22 -61 -60 -58 -33 -12 -7 42 25 5 -2 -6 -25 -47 -7 -30 64 6 69 41 53 -32 -20 27 92 13 -22 50 31 -77 45 -20 -31 -70 15 58 94 -11 16 34 3 59 -26 113 -39 8 127 -56 12 -42 37 -4 38 -9 25 23 24 15 -18 -37 45 4 12 71 38 -15 -29 -8 43 79 -1 17 38 36 -13 8 16 -25 43 0 19 -2 -10 10 -13 -44 9 -9 -10 28 21 -27 14 -15 -4 -32 3 9 33 -43 30 8 -7 -14 -5 25 22 33 7 30 6 28 44 7 -25 20 -14 14 -51 -8 -14 -53 -4 -58 -1 62 -14 -56 1 -10 3 -8 -16 -46 -10 14 31 50 3 33 47 22 2 78 34 -35 6 38 -8 26 42 -15 25 -16 19 16 33 -2 31 42 54 -31 11 11 10 -30 47 14 -14 7 5 31 5 -21 72 -38 -89 32 -20 35 56 127 39 -27 65 16 80 5 -30 41 -14 -89 -43 46 -50 -66 -11 62 10 -14 23 -22 20 -72 -49 -25 3 82 44 -36 -21 35 -34 4 22 81 18 -46 37 55 -75 45 -21 3 -4 11 32 103 8 30 -35 114 52 111 63 69 -7 -20 -18 -21 -111 38 30 124 76 5 57 127 0 -100 29 33 22 52 38 -32 14 54 -32 -7 17 2 13 31 -71 36 -49 21 57 -111 28 -29 -24 -2 -74 24 -27 -47 70 44 48 -40 98 -58 -122 -100 90 2 109 15 -19 -57 31 20 -20 -70 26 126 105 9 -74 14 108 3 47 82 -4 79 71 -26 7 -28 -2 -59 -16 2 70 83 36 51 -30 31 -70 -79 53 15 -67 -16 -2 -70 127 53 73 -114 -34 -20 91 38 30 42 122 -2 34 3 3 -48 39 5 -6 -41 -112 -57 -22 51 36 -13 -31 21 -14 54 101 11 -13 35 -16 42 36 8 3 -16 31 -15 63 -120 -1 -23 27 -46 -25 -24 9 -51 -14 22 -27 119 14 -4 37 -56 7 -17 -53 5 11 -16 37 42 39 12 66 24 70 20 44 33 -16 -34 17 51 -20 -42 -17 -26 -30 2 -62 -24 48 -47 11 9 -72 81 17 -49 0 47 -38 27 -18 2 -29 -84 -43 46 -7 3 10 49 -10 -4 44 25 -35 21 -15 -15 4 -41 21 15 3 -48 -5 35 47 6 37 -49 -2 37 98 -16 10 71 27 61 -18 38 -6 95 -42 -12 108 -21 -68 -34 69 -70 -73 91 46 29 37 -24 24 -1 16 -5 -31 -5 -64 25 51 11 127 -15 -73 -37 91 -32 15 -37 7 -38 59 99 -28 94 -1 70 -56 -34 -54 7 -3 -3 -13 -24 16 7 30 39 -91 34 -79 -23 9 12 118 -8 82 -5 -14 -28 17 13 1 -38 85 54 30 -35 15 81 -18 11 55 -46 8 -24 -28 50 23 -4 -15 -44 14 -54 -33 -33 -50 29 12 -15 25 -19 11 75 -41 -2 -96 -56 52 -20 35 36 83 -20 -25 77 -17 -71 26 -54 32 99 51 24 -18 -20 32 22 6 -42 -8 -40 -54 0 6 25 -39 19 -25 -99 -50 41 16 45 -32 -74 88 13 -1 17 -32 33 88 71 5 31 2 -94 8 51 -25 12 77 -33 -40 42 -57 -42 -23 37 -127 -48 -9 52 -2 10 80 -1 -52 -7 -1 -16 22 -19 23 -20 -28 59 -28 30 -19 20 -9 74 -26 -22 11 21 61 16 59 -21 23 -3 -33 36 52 -43 -10 -57 -75 -29 -95 -27 -43 31 26 9 -26 19 -23 -14 45 13 -37 -20 -4 -22 -24 -51 -34 53 -10 -57 45 -19 -52 39 -11 3 -8 -13 -41 9 58 -15 0 -61 16 30 4 3 51 36 11 12 34 3 50 -18 -27 -35 19 -21 -19 -27 -52 4 6 34 -11 -35 -2 23 -7 39 28 -14 71 -31 26 50 -5 56 -7 31 -36 72 -26 13 54 58 34 28 79 -17 -8 93 -30 117 83 14 -18 58 24 5 33 63 -31 -3 65 66 103 -67 -23 12 19 51 59 -8 -29 51 60 -58 26 55 -44 -31 61 -57 120 58 90 -39 -15 -12 -25 -6 60 -8 27 16 0 -12 -28 60 11 27 -30 66 28 -35 66 122 49 1 -27 7 45 31 -34 -66 -2 11 47 34 -48 52 -61 68 41 36 19 21 -61 -19 5 -58 11 -18 -46 -12 -2 35 0 45 21 -49 48 -9 40 37 -38 -11 -71 36 -5 -21 45 5 -3 -19 -33 -11 -36 -6 63 -16 36 74 -18 -8 -27 52 -23 22 -31 -33 -10 25 -21 -9 24 12 -9 1 16 -5 -74 41 27 21 18 -6 -16 -28 -78 4 0 -77 36 29 14 -7 -91 -26 -44 -7 29 -14 -13 36 88 2 32 16 -1 15 17 33 6 -3 43 -30 -26 62 -16 4 50 18 -11 -14 -15 7 -3 12 4 -53 -1 31 19 8 -17 -12 46 -21 -21 -9 78 17 0 56 3 22 -1 37 -32 -34 5 -15 3 -13 -97 -59 -22 -15 8 4 -69 4 -44 -11 1 5 13 -1 29 -15 -29 19 40 -4 -89 6 12 31 -26 -26 -21 -19 -16 -10 26 12 5 -25 -4 -17 19 -16 23 12 -15 -21 -50 24 47 -52 -8 -30 -34 0 5 -5 21 23 -30 -41 45 18 67 -24 -1 19 17 -33 -22 -10 44 62 31 -16 37 -12 36 26 6 -27 -3 19 27 5 52 3 7 12 -34 3 58 28 66 51 23 -12 12 14 82 -23 -11 -19 1 43 59 -22 82 1 2 48 35 20 -1 2 -36 21 -32 23 -49 11 43 57 -28 -19 21 4 -53 51 -10 -30 16 -25 55 17 21 31 70 -23 88 -55 21 64 3 -28 17 19 29 28 3 -18 -3 26 28 54 -7 42 -25 40 -1 45 32 73 -17 28 18 54 -36 11 13 -35 10 -26 16 83 1 -3 96 18 9 -11 63 32 -7 26 -37 -4 11 15 43 41 -8 -48 10 24 -4 -14 -37 29 -66 -14 49 19 -27 27 17 1 89 12 26 -2 -25 77 7 -42 -25 10 35 -70 27 -34 42 -22 -12 -22 25 -6 -5 -31 16 17 25 19 -102 45 47 14 -1 5 16 -8 54 17 21 3 9 46 -11 17 0 48 -31 41 -38 62 -31 68 37 -19 33 45 21 5 42 22 -4 -8 -16 30 26 15 19 -2 17 32 -32 -12 36 -26 -33 -27 -29 7 3 -65 -30 45 6 49 -16 -39 -13 -9 15 26 51 12 26 -7 41 1 4 1 35 -16 -56 16 8 0 42 -48 21 -5 -13 -21 7 25 7 16 20 -9 55 -1 -11 24 -10 31 13 -1 -3 21 5 -46 -13 15 31 -8 -27 7 -26 16 -16 -7 8 5 17 25 13 31 -7 -21 -34 -21 27 10 -4 21 57 -29 28 -37 -8 -14 49 -23 0 67 22 -39 25 12 26 102 54 -11 -18 58 -33 45 17 47 2 78 31 3 -91 107 3 34 31 -5 30 -51 -75 -15 63 107 34 10 -68 -42 -3 -56 47 29 27 -3 102 92 59 40 55 -79 15 -43 32 -18 21 12 -48 98 -7 40 -34 -10 -24 -46 -61 76 -2 4 26 45 19 -66 -56 -6 7 37 52 -37 5 40 -27 -35 31 -5 71 62 -19 19 -30 36 -99 -10 46 43 62 -43 -99 36 -20 27 68 -5 34 23 2 -33 39 -18 8 21 -43 17 -16 37 -57 -11 56 -3 -9 26 -6 -54 -46 10 -31 -15 6 50 -41 -30 42 18 54 0 34 24 8 -10 -18 -38 -28 -55 18 -4 -53 -6 57 99 -12 65 78 -6 -77 4 -72 -91 11 43 -32 103 -25 11 -1 21 9 14 55 70 17 -90 -19 27 41 12 -5 -82 -32 10 -27 -4 -1 25 -9 24 -22 30 57 -24 19 98 51 13 -59 -40 -1 4 1 12 7 -10 -23 20 -8 1 -22 0 5 -33 -26 0 -2 0 4 -23 -57 10 41 15 -15 49 5 -21 26 25 -31 23 -25 12 -11 17 1 3 -19 3 5 20 -30 8 -16 6 -26 -18 12 -30 -8 13 -39 15 4 -40 -21 -35 -46 -16 -25 -22 -1 29 -5 -48 44 -2 -17 -8 30 16 -25 23 -4 14 -8 -4 29 14 -6 -3 -8 -35 1 50 -27 35 127 -14 -54 22 -24 -10 -21 -49 -64 12 33 -36 56 -1 -31 36 -11 14 -82 -21 -5 98 8 2 72 7 20 61 57 49 9 13 65 -68 38 -12 43 124 -16 30 12 39 -78 7 101 13 44 63 -23 -17 71 89 -48 -7 53 -4 44 2 19 -78 123 0 52 -4 25 -8 32 12 -81 -46 18 75 16 -7 44 -17 59 -35 34 -1 40 127 44 -27 38 -80 7 12 29 -32 -39 -52 28 2 35 4 -29 -22 -12 -20 4 -62 124 19 28 -34 48 -46 37 34 46 -14 -19 11 -18 -67 24 -66 15 -21 42 -41 66 23 8 48 -40 27 -28 24 32 29 21 55 -21 -61 26 105 21 -35 33 2 -23 10 7 -17 28 82 23 36 36 3 -19 30 -28 -11 59 -42 -82 69 -112 -21 26 36 -26 75 -1 -22 43 74 -20 22 -9 38 -34 -39 9 27 60 -5 -61 -41 -49 62 37 -1 10 -23 -37 -25 -15 26 -13 -17 -42 -45 -32 -12 10 20 -11 15 17 47 -15 -7 -8 13 -19 -35 49 41 17 13 -19 3 -22 -4 0 -65 42 -58 -44 -12 -51 -20 0 45 4 15 -4 -8 -35 -33 -26 43 28 3 -4 -3 -36 -11 -41 -28 -26 -13 -20 20 -26 5 -12 13 -15 56 58 -45 -12 28 -33 26 -44 -25 -8 43 5 -9 -4 -69 20 -32 27 4 -27 -16 -31 0 55 21 36 -18 16 17 16 41 26 -11 26 -21 48 26 -15 10 24 -15 18 18 40 -13 -54 36 -4 102 24 -15 88 -45 71 80 28 32 21 57 22 -33 33 -21 57 -3 20 -37 -31 -14 28 -27 29 52 1 58 25 -12 42 76 85 -8 24 -49 33 -66 39 29 127 46 22 127 32 -35 62 -94 2 23 103 73 -46 21 35 26 -39 -4 -88 -72 90 21 76 -26 32 -38 -16 83 45 9 -4 -123 -61 -50 19 -28 -54 -19 51 48 93 -31 38 -18 -63 117 -25 -38 44 122 107 42 -110 3 -71 -8 -68 -10 14 -14 -64 7 84 -8 -14 -37 16 18 37 -60 -41 -79 -53 29 33 -29 74 105 37 89 -17 26 60 -21 30 25 -35 75 31 -52 -32 34 -17 66 66 -33 57 -34 -43 77 44 -10 107 -113 18 5 26 -90 -16 -2 34 -37 -8 85 126 -24 -24 -39 105 -4 -19 -22 102 -26 31 14 35 3 42 19 -2 -10 -35 -16 95 18 94 30 24 18 102 40 -7 58 -31 -1 16 -75 -12 -16 -52 17 7 -9 27 35 -26 17 27 -9 4 -64 23 45 13 -29 24 -3 -22 -24 6 31 -59 6 9 15 -20 5 -46 21 -4 -9 27 1 60 12 55 -29 -77 53 60 63 6 19 -13 25 -36 9 4 -14 54 7 48 -57 -7 -26 -5 -11 38 12 17 26 18 -12 39 -9 19 -62 -22 -42 -6 -13 -11 3 -62 -8 -47 -11 23 17 -24 27 -25 7 -38 -12 72 48 -44 -44 -36 39 10 -52 4 49 38 -39 68 63 57 38 29 -27 65 -49 -36 -29 -30 71 -108 34 63 -25 40 18 -14 19 -29 -2 59 25 -12 21 -8 -6 33 -90 3 33 -22 16 50 -122 84 -28 96 36 111 81 37 -23 -4 9 35 -50 47 62 -31 23 -115 31 -43 -51 -46 76 -62 120 3 101 21 55 69 0 74 10 87 -41 60 -29 4 68 -83 81 38 36 6 5 65 30 -12 53 21 -124 49 18 -55 -75 -43 74 -23 2 20 30 27 -19 2 -9 10 22 1 20 -76 -8 22 48 27 -12 47 -37 -60 10 9 10 42 29 42 19 25 19 18 60 -22 42 -66 22 103 22 47 -3 18 66 -9 -7 75 -84 83 18 127 -16 20 -57 -17 -69 38 -73 -24 -27 -34 35 70 68 -3 23 21 9 -15 11 -83 70 66 14 -20 26 53 42 -55 -63 8 -41 11 -24 -6 112 44 10 0 -30 -89 -24 -42 -49 53 5 -46 -20 -14 -38 -31 8 -31 5 45 20 -22 -14 23 -1 19 -68 40 -8 -37 48 20 -24 14 -7 -40 -16 -18 16 -8 21 -20 28 3 -31 -47 13 -6 26 24 -11 -35 -4 -86 -4 48 5 -34 43 22 32 -63 17 -22 -2 -25 7 6 -38 -8 25 -19 -39 -40 -33 -4 38 27 54 2 22 -8 -4 -12 -49 -5 3 -21 -15 17 0 -33 42 3 66 1 -1 13 -34 35 -29 -29 -4 102 17 -56 -52 28 -88 7 89 21 -34 39 -14 95 81 3 -9 3 -70 -83 39 4 -69 23 9 49 3 -28 15 23 30 1 19 -49 -72 -109 13 53 -104 -5 -31 -33 -32 -33 -27 25 29 8 -52 -44 67 17 -24 79 -6 -48 -2 -108 46 -17 -11 -4 -73 18 -90 -64 0 67 -63 46 -72 -122 19 -31 -6 -19 7 11 -35 -53 65 0 -9 11 45 -14 -3 -69 15 -95 60 68 20 25 -19 -97 11 41 67 -34 -112 -45 86 -39 23 -4 -13 31 60 16 113 39 90 47 7 -5 24 81 107 4 120 68 -24 20 18 18 -46 18 97 -55 -32 -70 60 -41 72 -79 53 -13 24 -28 0 15 -44 -97 -24 -71 -47 3 -36 -2 -115 -40 -13 -10 -50 25 23 -38 93 -32 -34 65 29 81 -33 -13 -79 -15 19 34 10 -6 16 87 46 -20 -33 -22 5 -58 -49 -12 -49 8 -63 -34 1 5 -8 -10 -39 -36 13 25 9 -14 -26 14 -23 23 14 -29 -13 20 42 -98 -6 28 -4 -105 -16 3 -15 -33 8 66 70 64 -7 -12 73 68 23 17 99 65 -19 -20 38 121 29 3 0 24 1 26 12 58 15 35 68 43 -9 28 -61 14 -26 32 -7 13 1 27 -50 -16 71 -63 -56 -28 0 22 -17 -52 -53 -20 -26 -48 13 -78 7 -28 51 31 -82 2 -27 59 18 22 -19 45 -1 -12 -22 -10 -3 35 13 -24 29 -17 2 -51 80 -13 4 39 81 81 18 7 30 10 23 18 -47 42 90 -48 55 -40 69 -21 24 51 97 -78 -16 40 22 -4 -63 -10 -7 -104 23 -35 -78 35 45 16 -17 126 16 28 -70 6 1 32 4 123 11 14 46 21 5 2 -81 -26 -63 22 3 26 -86 -18 28 32 -39 -19 60 21 92 28 42 -8 30 -55 -18 4 -11 -14 37 -20 23 3 -4 -6 51 -53 31 26 -31 -11 64 66 49 41 -22 15 17 4 0 35 -21 13 79 -32 -28 26 -44 -46 55 53 17 -16 4 29 23 -46 -68 17 65 -11 28 45 29 71 -30 106 7 -10 -68 27 4 5 -39 1 -62 -2 -57 -7 33 39 117 11 47 9 20 -28 -18 55 -45 -17 78 4 -33 -43 77 50 39 -37 40 69 23 -87 8 24 4 -29 31 -10 13 35 1 3 10 76 -57 24 -24 -27 35 1 17 32 22 -73 -52 42 34 20 -15 -14 35 2 25 64 -3 14 1 22 -17 13 2 -8 -11 -38 -9 -33 21 8 10 18 21 68 -22 -68 5 -15 20 -128 -9 4 -5 19 16 -4 88 -9 -27 22 55 -23 -17 -21 5 -24 6 4 -16 -16 -12 -26 -51 28 12 -11 9 -24 9 13 1 47 -1 -11 19 35 -21 33 -19 22 -4 -9 -3 0 -49 17 33 -17 9 18 -4 -4 23 -15 -31 -31 26 2 22 -11 25 -52 50 18 11 75 34 -12 42 32 24 47 37 -2 9 18 34 14 10 35 27 17 43 50 0 63 64 67 2 9 2 53 32 67 12 33 1 93 22 -12 50 34 -40 6 -2 6 69 12 32 -15 -24 65 71 4 22 54 32 45 35 31 -1 27 4 48 6 77 72 -65 37 81 65 5 48 84 39 -10 51 11 29 37 -33 47 54 21 14 -7 76 -22 48 53 33 -6 -27 -28 -7 -18 10 44 89 23 -74 -44 -81 -91 6 14 -36 23 -49 -72 94 -56 -5 124 36 54 -48 13 34 -48 -22 104 3 34 36 -52 18 -49 -11 -56 36 -56 19 -29 -23 3 83 6 0 18 8 49 45 -53 -34 18 24 25 5 34 19 -1 15 -8 -12 27 -19 15 9 -6 -12 69 15 29 14 -6 13 -11 -38 -13 8 31 -27 -73 -36 -32 -63 -29 -5 -52 6 -23 11 -25 -48 -24 39 3 79 28 -26 -3 37 -35 -29 45 -42 6 -20 13 12 17 -9 -4 14 26 26 -37 -20 52 8 -57 -24 4 49 22 -8 -5 28 28 -22 -18 11 28 71 11 -29 -113 -21 -56 39 -18 -44 -7 2 16 5 6 40 23 41 -35 -25 4 59 41 -15 -36 -47 55 13 18 -13 74 35 -2 -21 -2 -23 -3 -19 -24 29 19 -2 -1 1 -41 11 25 4 -24 -28 9 33 58 -16 -7 -58 26 14 17 0 34 -10 -30 -26 -42 2 37 -2 8 4 121 42 37 39 1 -18 -22 -12 24 52 -28 -46 -4 26 -65 62 74 -26 0 86 14 12 -30 -67 -37 -27 0 -10 -19 47 48 -25 16 11 -39 -50 11 -31 24 -25 43 51 -21 -46 38 29 -23 27 -48 -28 7 5 52 -47 14 -11 10 -22 -16 -9 -53 -39 -28 86 -33 49 -25 -38 -24 47 -17 -40 21 2 11 48 37 -13 9 -45 77 1 35 41 57 -35 -11 73 6 -57 70 47 51 78 -24 61 -36 20 -54 19 12 2 -3 53 -46 -19 67 12 -40 27 -14 -26 -17 17 8 2 38 -51 4 89 -18 -71 -15 -41 13 29 -23 33 47 9 24 -3 -51 -7 9 27 -3 29 0 -20 -71 -18 -30 -34 -24 -12 -53 14 33 68 -23 -7 32 -39 -6 -19 5 -27 -40 125 -16 28 37 -36 -51 -27 -19 -76 6 80 -10 -9 26 13 127 -60 18 -18 23 3 -52 -46 9 16 0 -57 0 38 -116 -31 40 5 -38 48 -47 -16 -28 -11 22 -3 -36 23 52 -5 -5 -29 34 -23 -7 -7 37 2 35 16 51 -36 -22 11 -9 -30 -8 -9 -27 -24 26 -14 -11 9 3 -42 -47 -32 51 -10 -18 26 -8 -5 -17 -10 -22 27 -48 -9 -6 49 -11 -17 -31 36 -5 -12 12 -3 -5 -54 18 -24 -30 38 -41 4 22 -16 -6 -14 11 44 12 -44 62 -5 33 25 32 3 1 -11 -62 46 7 -67 -3 -27 18 36 -11 -55 -20 1 25 -25 20 6 18 9 123 4 24 -39 16 -45 -5 -64 22 -26 4 15 -66 5 -83 16 120 -12 0 -15 25 37 118 16 -28 7 49 31 -34 -94 2 54 -62 -41 -20 -52 -44 -38 -8 37 -30 -42 -20 -9 68 87 21 -21 14 -40 45 -32 15 1 -67 -55 1 -51 35 39 -20 5 -14 -38 -67 14 -53 56 16 -14 4 21 -52 -19 -45 -33 6 -17 -38 -22 56 25 -47 -30 34 -10 -19 -13 8 -7 -54 57 15 71 -4 -14 1 -16 28 68 48 81 -54 -74 -35 -13 -17 2 -43 -17 -7 8 -9 3 -11 -92 32 27 -28 1 -60 67 60 -15 13 -42 48 -37 0 86 2 53 56 -22 43 10 54 -31 -8 -13 2 37 -19 0 66 33 -23 21 49 -16 -11 36 38 4 57 125 -66 -9 -10 92 55 -51 -84 43 28 -20 -5 63 -56 0 -32 79 8 -5 -31 39 37 3 43 -46 -41 -27 -4 -26 6 -5 28 39 13 23 -1 -25 15 -3 -18 -39 19 19 -15 -19 36 -15 -29 4 -5 -22 39 8 -30 44 -13 49 -52 -51 20 -1 35 -9 15 -7 -40 -23 25 3 55 -10 42 14 -34 10 -68 9 13 -15 -34 13 47 20 41 -15 64 -10 44 -29 31 -8 -20 26 7 -65 -9 29 -27 -3 2 25 5 -49 -111 27 -9 2 22 -7 -22 -33 -1 -2 20 -6 5 17 28 -12 -23 33 -50 -50 -5 -5 -30 1 14 111 -24 -52 31 47 4 30 -10 39 -16 76 -122 -6 34 -23 -23 -59 22 59 -26 -127 32 45 -34 -63 34 -43 -1 -44 108 37 29 2 13 -80 23 -5 -90 -28 -24 -12 78 -2 32 13 19 121 41 46 -86 48 -12 -16 -72 -20 -21 12 31 59 48 4 101 31 -14 -28 17 -33 -11 32 112 22 -53 -3 -13 33 28 124 -50 -60 -54 -57 -46 -8 55 35 -2 -60 36 0 -49 18 -27 -18 3 26 29 -36 -11 -57 116 127 -13 28 -43 -101 -35 -39 -98 -1 2 -40 -28 26 105 -7 0 43 88 -53 16 85 -29 -89 -18 48 -34 64 26 10 -65 0 -14 13 32 41 -22 -15 22 7 40 -36 -15 -61 4 38 -73 13 -11 30 16 45 -55 -32 -3 -52 16 -40 -33 -59 -20 5 -40 -110 -78 -68 -16 17 54 41 30 -48 125 -18 53 9 -8 17 -12 -30 57 69 -8 -32 -95 64 21 49 37 2 -12 20 21 -64 36 -16 27 0 19 -26 55 3 17 13 -15 33 21 -26 18 32 -4 27 -3 -15 1 22 11 2 41 4 -44 13 76 -12 -33 -12 -4 -8 26 -6 -10 -26 -18 -21 -30 -5 20 -12 25 -13 -35 -37 -64 23 -20 23 23 0 12 -6 -30 1 69 11 -49 -4 -44 -58 -33 4 10 21 -15 -26 -39 34 41 -24 -7 50 -25 6 18 18 15 -5 19 -42 72 -28 -34 14 3 -56 -24 -37 27 26 5 46 19 101 62 95 32 78 -4 -29 22 42 -20 -14 14 85 93 66 44 -10 -49 29 7 8 27 -44 11 54 53 16 20 -77 -7 17 12 35 -16 -9 77 57 -6 15 38 -6 23 41 -54 11 -41 74 -5 117 25 32 63 -21 -34 -53 -63 -11 73 54 11 15 2 23 -17 -5 21 24 -69 11 -7 -14 0 -47 41 -43 5 2 -15 -11 2 101 -39 65 5 -9 7 52 43 -31 -14 -1 50 67 -52 -1 -75 22 33 -13 -16 8 15 -50 28 71 1 31 35 27 -25 101 -27 -5 31 -78 -37 -77 31 24 -34 69 29 49 -52 11 -95 15 82 -35 -31 2 7 54 81 -86 41 -12 1 16 65 91 4 -24 44 43 70 -12 -1 -45 -39 9 -22 -46 13 10 2 11 20 70 30 -80 12 -39 67 123 -24 -15 88 -12 107 17 57 -32 -3 -33 -93 -27 -1 -5 39 53 39 -57 -16 82 -2 -66 18 -12 -12 103 -14 33 10 12 -1 -13 -35 30 27 -3 -3 -4 -28 1 -13 -26 -18 76 5 -71 -31 10 -25 -39 -78 60 35 -28 -25 28 -18 -2 2 55 3 -18 -17 -18 7 34 64 8 -18 32 20 41 15 -12 14 -114 3 -28 23 6 3 -4 15 -37 -41 -33 -26 -26 -14 -22 14 -28 34 43 8 41 24 1 -44 46 13 -30 -25 -12 -25 14 -43 22 -13 28 -19 6 9 33 52 -8 7 -15 101 -3 17 0 -45 54 -15 14 40 -82 69 59 2 25 88 87 48 -42 -2 4 0 13 -13 46 -75 61 69 110 125 69 20 65 -9 1 -20 -41 29 70 26 65 47 -15 -6 38 48 -21 63 -4 -6 9 67 47 31 64 -24 30 25 -12 30 9 41 107 -7 43 13 -71 -32 19 -24 67 -36 -97 89 -21 35 21 21 -10 35 45 79 -21 14 -17 0 -19 42 63 110 33 -16 112 2 24 87 24 -24 61 49 -3 -66 -33 14 -28 -31 -7 9 -39 19 56 16 -68 -26 5 36 -31 34 -42 22 -17 -68 25 1 41 -1 7 22 -66 85 31 31 -17 14 39 -4 -48 8 -69 -2 -46 67 -35 -10 -31 18 38 23 33 2 -49 -37 -17 22 -23 -9 -5 6 11 126 8 20 -17 38 0 6 13 40 76 35 20 37 62 -12 -12 53 -10 -57 -21 -46 28 -17 -43 56 -46 -12 18 41 -32 27 49 12 22 -25 0 0 35 -1 11 22 -5 13 1 7 38 11 -3 20 2 7 13 -18 6 5 -3 26 25 15 31 31 -39 -22 22 -18 -27 7 5 16 30 -24 33 -5 -6 -29 37 6 -14 -13 -6 44 -16 -16 12 16 24 24 -26 -2 41 -46 5 -1 13 -69 18 -18 -3 34 -28 6 -7 -13 9 -22 2 11 -25 19 8 -12 23 -9 24 -12 -1 -14 1 -2 11 51 31 10 25 -4 -6 13 -5 21 14 68 -11 -12 7 20 -59 34 -38 16 -22 30 -24 -9 -72 25 -34 -12 22 -43 36 -45 60 23 4 -27 2 -77 -60 5 81 44 -30 40 -7 50 5 -87 -51 9 -23 -91 38 -2 -19 23 -44 -4 57 -77 -29 49 -61 -1 36 -7 39 -43 -2 -71 -20 -63 -38 8 77 25 83 -57 33 44 -31 43 22 -59 8 -67 -10 -7 10 7 64 4 -65 -9 36 47 65 -28 -16 5 -5 -20 28 14 70 -124 -45 69 18 15 38 -36 9 27 -12 -6 16 39 37 16 38 23 -51 8 -91 -40 62 -100 2 10 31 1 -21 7 4 -6 48 10 12 -47 1 24 -75 -49 -26 17 -25 -30 -25 30 41 -11 13 82 -40 71 -27 -32 10 51 54 -68 -46 -58 -37 -70 13 7 -21 1 25 41 -2 45 -14 -16 -2 23 -10 22 -17 -44 -51 2 1 13 45 -35 -32 -5 -45 -34 -17 -70 -37 26 62 50 -17 -77 19 -11 -102 23 -5 39 59 -3 13 -1 -32 16 -55 -27 -41 -10 -8 15 1 -42 -44 34 -21 17 0 47 -6 69 -14 3 31 44 32 30 -4 -10 22 -31 39 -16 -5 -15 4 -33 33 -4 -32 -21 14 -38 13 4 22 9 -5 -59 12 8 13 14 -17 3 -15 -33 16 -12 -5 22 10 -16 -18 -21 -8 31 26 -22 30 -36 36 20 24 29 29 29 -7 19 34 1 6 -15 7 -11 8 -18 -13 -16 -45 -31 13 -12 54 -1 21 -22 62 3 -28 58 13 -47 -76 -8 25 -89 41 -16 25 -14 7 63 52 20 -74 -35 -48 -16 46 -62 26 11 23 48 -11 -2 -8 12 -42 49 -25 -46 -20 -99 -54 25 -9 -11 -44 6 24 74 86 -5 37 54 11 97 -10 10 -16 14 15 -28 1 69 -112 -2 0 -14 -21 -19 45 8 -19 -43 -17 -3 26 28 -57 -8 70 3 23 35 66 -79 52 -5 91 22 7 -63 68 -32 -15 40 -81 11 -26 -9 19 32 2 10 -3 -44 -49 76 -26 24 7 -13 -24 -12 -64 56 -1 7 3 -4 47 46 35 -50 -52 -24 -16 -42 20 13 39 -64 24 -1 -13 -44 38 36 -22 114 -41 44 -38 -16 67 -75 -77 -10 -26 -23 -41 -14 27 35 -63 -32 -48 88 50 5 55 7 -69 1 -49 -8 13 -87 80 -6 -39 -56 32 84 -24 16 30 -54 -52 50 -52 53 87 8 -31 62 20 -67 52 -13 6 11 -16 -33 -61 29 -36 30 9 29 40 39 -3 24 33 -47 -14 -27 1 24 -5 12 32 62 13 15 -8 -4 40 -49 13 21 -3 -6 25 -45 60 -54 -3 35 -16 4 3 1 -42 -26 8 -15 -8 -46 -76 24 29 6 -1 -21 97 -22 10 17 59 -51 -34 -38 26 -9 11 -32 43 -9 -29 51 25 10 -14 13 27 -17 0 44 6 1 -20 -1 -2 -37 32 21 13 -64 8 -16 -3 37 -59 16 -20 45 78 -22 47 -55 -9 -18 66 -26 -31 -7 -63 89 8 50 -41 35 20 29 50 -8 -49 -31 -49 36 24 58 35 6 20 14 28 -42 -114 -2 17 6 2 127 -39 -8 83 14 -62 11 -21 4 -14 -6 55 7 28 105 -2 -4 38 58 0 -1 -108 31 -31 -56 47 -23 -16 2 0 -54 8 -32 74 -85 69 -41 -91 102 -10 -52 2 -13 0 34 -50 -8 -59 1 5 -81 45 75 73 12 -1 -49 36 -82 0 31 -4 48 47 -127 -30 37 -41 -15 -31 58 -127 -1 -23 61 -5 -52 -41 0 -37 -28 -57 3 101 -73 32 -126 -8 15 -29 35 -59 49 -3 62 39 -61 -41 -3 -35 -19 24 13 -70 -39 79 -27 -6 29 -1 29 -127 18 -47 3 75 17 53 10 -37 61 19 -105 -3 53 -41 -9 29 -15 -57 36 55 79 35 -6 -26 127 -46 -101 -36 83 -7 -42 10 106 -9 -10 -57 -36 12 18 0 55 -21 13 7 -60 -9 45 12 -37 7 1 5 20 15 13 -46 -43 53 11 -13 -41 18 31 5 -18 37 2 -30 -32 -20 -45 -7 -10 -30 -1 7 -1 10 1 -23 -53 -36 9 3 -30 8 26 -11 3 0 -62 -10 28 -28 -3 90 23 -17 21 15 -49 41 -21 30 24 -47 43 8 2 -10 -8 -50 31 -46 14 -1 21 -11 -26 -66 3 -11 0 1 -21 -22 8 5 -13 55 -43 39 -19 72 50 -28 -1 16 23 84 50 -51 36 -94 41 -27 -14 -19 6 -22 36 -79 46 38 -11 -19 -57 -35 28 30 0 -60 13 83 3 -30 7 -3 35 23 17 -10 -38 39 -54 -8 -29 -14 68 -5 31 8 23 16 26 61 -6 -7 47 22 54 43 23 26 82 3 -55 -47 -32 30 41 18 -12 -86 63 -10 -12 -23 56 122 -15 3 -21 -36 0 -20 -2 -17 -41 7 85 -54 -12 -47 39 -37 -29 40 -40 -4 47 -31 66 67 51 45 28 21 -70 -34 7 -1 24 2 -13 -56 -42 42 -10 6 -38 38 3 54 21 -54 33 -73 -17 -30 -42 8 -60 0 -13 6 -42 63 49 -12 -24 14 27 -44 15 20 -18 -53 69 79 46 -18 15 -9 -5 76 92 -21 13 -24 39 23 -21 -35 -6 -22 -20 0 -24 25 31 69 14 14 26 -4 20 99 -58 29 119 94 46 7 -5 57 26 59 0 -5 33 5 13 -60 21 44 40 26 -40 -10 29 8 -24 24 -15 3 -19 13 2 12 -45 19 11 -27 3 7 27 -26 -14 -16 -1 65 -7 54 -14 35 -36 25 18 29 -42 -61 -58 -7 27 -27 -38 18 -5 -18 -18 17 9 -10 33 -1 -4 -12 23 -7 -20 20 -43 59 -20 53 -64 -14 8 -5 31 28 -8 45 15 -53 12 -18 23 -34 7 -71 -2 15 -6 82 21 44 -3 35 -27 43 -12 -14 24 14 33 32 -7 -11 35 -42 79 -6 41 -11 -3 -33 13 -36 98 31 102 26 62 48 71 -128 -35 -29 -24 -21 70 34 -66 15 -73 -39 -30 -42 -44 9 -69 21 -50 -1 -54 -40 -1 -29 -37 -69 -76 41 -19 -25 -33 50 6 -7 -46 -66 -12 -9 -128 4 30 2 -1 26 -7 124 -82 9 -128 -38 58 -42 -43 2 2 68 -10 -18 7 -31 -11 -38 -104 31 -11 3 -8 15 -15 25 -15 6 -107 -2 36 -14 -41 -18 36 39 -83 -7 77 -2 -99 -20 -84 9 49 -2 33 29 11 -63 -54 18 -27 12 -23 -34 -5 2 -22 41 -44 0 -8 36 -52 -36 -4 21 14 28 -33 31 -27 10 14 -67 -117 -14 15 -73 -44 -9 57 -48 -73 53 37 -22 38 -41 15 -48 49 51 -39 -43 9 -110 29 -21 -55 -26 -19 1 38 3 -37 59 -38 81 -82 8 23 9 -75 -35 65 -40 33 79 19 23 -73 49 46 -23 -51 39 14 1 55 65 -53 -23 53 49 -28 30 33 -29 22 8 -10 -6 19 26 -16 -56 18 -30 -34 -29 22 12 61 -3 5 4 9 13 78 -22 94 -12 -39 45 36 -44 -22 38 -25 4 63 11 12 -30 6 3 55 -44 31 17 -22 -5 -23 -24 27 -60 -56 -31 -11 8 0 -40 13 -19 9 10 56 26 33 26 6 -50 4 19 5 38 -19 -14 -23 41 -27 -40 -13 -32 33 -8 -7 38 20 13 2 -23 23 -1 8 -27 17 33 34 -76 27 5 68 -22 -6 64 37 27 62 8 19 14 78 31 27 54 10 26 82 5 -29 60 14 76 81 13 99 26 -67 45 61 4 80 37 55 15 -11 -62 -31 -15 66 97 59 0 -30 -34 92 2 -2 -8 -48 -21 27 10 106 39 39 47 76 7 6 -27 60 35 33 -5 -2 2 43 50 45 -19 -49 62 23 74 72 33 55 32 63 22 22 69 -6 -27 -1 7 91 124 79 -10 -38 125 28 43 19 68 -23 39 -41 -16 -24 -1 -10 -12 7 42 8 29 63 -87 1 7 -57 -42 21 -19 -10 -13 -3 63 -13 -69 46 24 65 -40 -55 -10 20 5 4 -15 -44 42 -34 -3 5 8 7 22 -52 -5 -34 9 51 20 -51 57 -10 53 -31 -15 56 27 -95 -1 -12 1 -29 -27 -20 -27 -47 -9 35 51 19 18 -84 -48 42 17 24 6 -30 -51 12 -32 27 23 -28 -12 -38 -4 1 27 34 17 -50 -11 6 -8 15 13 -22 -5 -13 -8 -2 0 -8 -10 12 42 -30 9 22 9 -1 -11 45 -4 -6 -8 -6 13 14 23 -8 -66 -30 58 -3 2 -12 21 2 -1 20 -7 1 -4 -24 -15 3 -2 11 15 -1 -32 -37 13 5 9 -49 27 4 13 17 8 -13 -4 -19 34 -8 1 0 -14 -24 0 0 -4 27 22 0 -45 8 29 14 36 5 36 -6 -64 -9 -6 10 -8 -22 -16 10 -11 0 -1 -24 -30 -12 19 21 19 21 -19 -7 52 43 -60 65 28 3 2 6 21 24 23 17 -14 -9 -19 15 28 -91 10 -5 -7 22 14 8 11 -35 27 -31 -8 8 84 -28 -8 63 34 42 -1 66 22 19 -10 42 -72 -36 -46 -30 43 38 38 -51 25 -105 44 -46 15 55 44 -33 -7 -41 -94 41 -31 4 5 1 -5 -5 5 -13 -29 -13 24 34 -127 -16 32 -109 -34 -49 12 52 -1 -13 11 -41 25 63 56 23 -78 56 43 24 41 39 15 -32 -53 7 34 -17 -12 75 -6 54 -34 -19 86 -11 -61 66 25 -11 56 -41 -18 23 39 -96 11 16 -42 8 1 15 4 27 27 -52 -22 -37 -35 -2 41 48 57 27 8 6 -49 1 -22 15 -24 -58 -10 -16 31 3 -26 -9 -35 -9 59 -45 -5 -16 14 15 8 -23 32 26 34 21 -15 -31 23 31 -18 -17 52 16 34 3 59 25 -3 10 10 -4 59 6 17 10 -24 1 -16 -41 -23 -2 -25 7 -19 -5 21 -75 7 26 9 -9 23 1 23 20 17 0 -19 86 -51 27 17 -17 18 -2 -11 -50 19 -2 6 3 -9 -5 -15 -20 -27 -45 9 11 20 -7 -9 -21 25 -15 -5 0 0 2 48 -15 17 -1 15 -13 9 -27 28 -24 22 -26 31 26 4 -21 -14 -14 -14 12 -3 2 -22 35 -10 -14 13 -13 -44 -5 7 32 -12 34 22 17 -56 -4 -17 43 34 15 32 12 -15 -38 -28 -21 -9 -13 14 -29 -14 5 55 38 18 38 29 -30 64 -7 -17 -5 12 -48 -3 27 -26 -30 -49 -4 21 44 -60 40 93 25 -9 53 -26 72 30 10 -20 -10 10 48 -17 -50 -37 -31 -20 39 -21 14 5 6 -13 66 37 1 -64 81 61 0 -38 -4 -26 -26 35 53 29 -74 49 72 56 42 -8 34 21 -6 57 77 46 -28 -65 -12 4 84 -92 71 42 65 59 41 78 28 65 -25 10 14 53 0 33 42 125 29 -11 17 29 -8 -48 6 5 25 -78 0 -5 10 -31 0 8 -45 11 38 -45 -34 22 -36 9 0 -18 41 48 -123 -4 -45 -3 -33 37 -9 35 -49 -71 10 -5 26 37 89 40 -7 23 3 11 -50 -25 32 15 16 37 -14 -21 -52 -38 25 0 -49 -97 -21 39 -111 13 42 3 42 22 40 -29 -8 18 -15 9 -36 5 45 -63 -20 6 49 -12 25 44 121 27 -11 -24 6 31 -39 37 -16 23 -34 5 25 9 -2 0 -4 7 -28 -12 74 0 -5 -23 3 -53 14 -39 17 13 11 -57 3 10 -17 -30 24 26 -74 -8 3 -1 -6 -39 -5 -24 -12 0 -49 9 19 16 0 3 43 26 8 16 -6 16 -27 -26 -21 12 -9 -22 -38 -16 33 18 21 -1 -13 -43 26 -8 -10 -1 5 -64 58 -31 12 -23 2 20 -8 7 -65 0 17 -43 -44 -6 -12 36 -30 -26 91 -45 2 26 96 29 79 40 17 57 56 1 39 -41 91 38 82 -3 7 -42 46 57 -124 54 -6 0 11 -1 -40 97 50 19 -45 46 18 -9 52 5 21 -61 -36 76 27 55 11 8 -3 -20 35 -36 38 12 67 110 -75 57 -7 -47 -40 -40 47 89 -45 -20 -20 9 35 94 59 1 18 68 4 18 59 -26 -13 2 26 61 -47 -128 -122 -15 5 46 -43 -25 36 31 42 1 86 -2 42 66 -119 38 24 53 12 17 5 13 11 15 1 2 -32 36 33 -8 -39 59 65 44 9 31 -11 0 12 10 10 9 -37 0 117 25 41 49 -13 15 -24 -19 26 33 -18 23 -75 75 -77 30 13 -13 25 28 1 31 72 2 26 -9 21 3 9 -28 12 -41 38 14 11 -25 -36 -10 -53 2 -38 40 -8 -10 -14 29 26 -4 114 -22 46 -58 63 17 14 -56 1 -22 -24 -8 -6 51 64 69 -5 -53 -35 -9 10 65 -16 -17 -13 -50 6 -22 2 -15 -19 11 5 23 -1 -33 5 -30 -17 64 -27 -26 25 -16 3 14 33 40 39 31 33 -29 9 -6 -9 -6 4 26 38 -10 -4 -22 -23 3 2 6 -4 -59 28 -8 -6 21 -18 62 21 -21 -11 48 20 -10 -1 -33 -49 15 28 18 -10 4 2 5 22 5 -3 51 -4 26 37 -60 20 15 11 77 0 12 -28 35 -29 15 15 -25 3 -65 -17 -14 -111 54 23 -40 7 26 70 126 5 19 -58 12 -13 13 -33 -23 16 -123 -5 24 -15 46 63 -81 -123 57 -58 33 122 -41 70 35 121 49 -14 -40 -67 68 29 31 76 39 -28 -17 57 -76 -13 -62 34 -120 67 23 -9 80 -58 84 -66 10 -60 -54 -9 71 -67 92 -7 -124 -20 11 -88 -19 -19 -28 -17 46 -13 -9 10 104 86 -51 99 -58 46 -42 25 49 15 49 -30 55 5 31 -6 -36 -72 -7 17 -31 10 54 -28 1 21 57 -12 15 46 21 66 -40 -26 6 -57 -69 42 106 -128 19 72 -12 -48 24 -126 -20 -44 44 49 66 22 -81 -49 -24 -49 -67 39 -53 79 127 46 -3 51 -127 -36 28 0 -33 5 -24 15 31 -73 -30 31 12 40 -22 52 59 2 28 90 -27 -39 67 -32 -1 -33 11 124 7 -18 37 -32 -91 105 36 -71 94 -77 75 10 -34 -5 -2 -71 96 2 -4 -23 109 -82 -1 19 -3 21 49 -111 19 -27 -9 32 -16 -6 -12 11 24 -12 -36 35 24 -82 -39 8 58 -9 30 17 -13 8 1 -124 -46 -19 -22 -44 -47 -25 -55 -2 -8 -33 -27 57 11 29 -3 -16 0 -87 -4 9 13 -17 -43 13 2 -21 -51 -50 4 -16 -55 -6 -46 -25 68 49 -74 37 -16 -11 9 -23 36 -30 -23 0 37 -8 -63 28 24 37 -35 3 23 29 17 -53 -33 73 22 9 -67 52 -45 -30 -13 0 31 84 -36 -16 13 85 72 10 73 12 26 -107 -6 -43 71 4 30 0 -31 22 25 -61 24 -12 5 -22 -12 -34 52 -12 1 -120 -30 -14 36 12 50 -7 -24 -34 1 -10 -2 31 6 42 26 -46 -23 -2 36 17 48 44 90 -24 -1 -18 38 45 9 -47 13 39 26 -39 54 -63 -38 -25 -63 -16 14 36 50 -32 -7 23 44 -26 -23 0 1 66 45 51 19 15 21 42 64 24 -21 3 21 -102 3 15 10 18 28 -26 3 -90 82 -1 45 15 8 6 11 26 -118 -27 19 16 -9 61 30 55 -49 -9 4 57 4 10 30 3 44 9 57 -27 60 16 6 18 -8 38 -6 10 39 -26 -10 33 71 31 37 22 -8 -30 32 73 -17 11 -63 -31 -47 -56 -5 -35 -4 30 21 -92 38 19 4 -123 27 10 -22 70 69 6 -42 10 -8 93 111 -19 14 36 -16 21 -34 27 12 26 -44 82 60 7 0 28 27 15 -16 -37 -27 -10 33 80 23 -9 -17 90 38 -13 -22 44 -2 -1 55 52 5 0 10 51 -26 -2 32 28 -13 -31 -19 3 0 -4 -19 -18 25 -20 -14 -13 -49 28 5 -36 1 3 -2 49 -31 -2 3 -12 65 -34 6 -22 15 -21 -43 22 -57 -34 -21 21 11 -29 -24 10 10 12 -5 -23 15 9 -40 -28 16 15 6 -8 4 3 29 18 -9 11 -48 -5 -20 8 69 15 34 63 24 14 5 25 -29 52 -11 5 31 57 22 -17 -17 61 31 18 19 -67 -56 -10 2 65 60 77 5 56 -2 0 60 -13 0 -60 -17 29 25 -22 16 5 -20 75 126 -4 -44 -12 -52 -45 27 -45 21 59 -9 -46 2 30 -29 48 7 -55 -80 0 -54 -28 4 61 69 -1 -6 24 7 57 -45 -32 59 8 -64 37 -24 -51 -21 22 42 -67 -16 -3 14 56 -8 -9 19 64 -57 58 -12 -26 -4 -69 36 59 13 -26 -17 -53 -50 16 -33 -3 -5 -57 -47 82 -21 -32 -39 0 36 -6 33 41 13 -60 20 -4 32 65 -34 36 13 101 3 -90 -45 96 37 19 80 -19 -48 -12 -9 21 37 -94 47 -28 10 12 -60 -23 -41 82 -30 -2 7 26 34 -43 -36 13 41 -19 73 -30 21 -22 26 -45 4 61 116 -17 -6 82 -11 43 11 -45 -44 -19 -50 17 21 13 5 -18 88 -71 -103 -26 -50 1 -47 4 -6 -20 26 16 -13 -3 6 -4 -23 47 -5 30 13 48 -7 38 4 -44 -25 -6 22 -16 11 43 13 13 -10 -16 34 12 -31 -6 -4 -28 -38 -8 33 37 4 14 -42 49 4 -14 3 13 12 -7 -3 9 14 18 2 -15 -12 -19 13 36 -57 12 -9 19 -43 7 12 25 17 -7 37 -5 -34 18 -20 -5 -10 3 -27 3 57 -5 19 9 11 29 -5 -13 -6 -49 -25 20 -55 -1 2 5 -37 48 28 -8 24 -20 87 -32 0 38 28 35 63 -1 0 112 34 -12 -17 -3 -1 30 23 8 122 21 -3 47 26 48 81 33 47 104 -23 -26 -10 51 32 23 42 15 58 45 31 97 -33 74 -110 47 58 107 65 -22 21 -34 92 41 20 26 -23 46 7 34 -35 65 32 72 41 4 18 -6 57 43 45 38 24 43 64 19 51 23 45 -15 -63 -17 31 14 21 55 67 -5 99 55 -17 57 -11 7 51 1 -10 30 5 45 -28 20 38 -21 20 -51 89 65 16 -57 52 58 -22 -14 -26 18 -28 -21 22 -40 3 15 15 4 -45 -20 -30 0 52 8 26 -9 1 29 -59 -7 7 7 -29 15 18 12 57 39 47 -9 -53 23 -15 17 13 48 6 1 -18 -50 -7 -36 17 -5 -65 -12 -15 19 25 -27 76 27 15 52 -11 7 -10 47 -1 -37 -6 52 -10 -12 -42 34 60 13 25 12 -3 -27 -13 -6 4 -61 -39 -31 -16 19 -32 -43 29 -30 47 12 -9 -13 6 -24 12 -1 49 -8 -15 10 -17 -5 -2 -13 -10 -18 41 -28 4 -40 8 4 48 -29 31 5 -44 -76 -45 -34 -16 36 -3 62 11 -8 -24 14 -17 -22 -57 -13 7 -5 -14 -14 25 -66 -50 -19 -32 0 10 48 35 13 2 -3 -36 -20 38 49 -2 4 25 -23 57 31 52 2 16 -27 4 51 10 -31 -7 -5 10 6 17 32 -37 75 22 9 121 14 -27 -25 22 38 78 66 33 -19 52 81 49 24 66 26 80 32 47 -101 75 -58 54 44 33 52 6 -15 11 36 -30 28 52 12 7 35 -28 60 -73 -42 5 91 -17 29 -8 7 27 4 22 43 51 17 92 -48 45 -41 -42 -46 37 -60 19 51 8 42 18 -35 73 -33 26 -10 74 59 58 101 64 36 -43 48 123 62 58 46 31 -6 15 64 33 8 -79 83 -15 -3 6 20 -84 24 -1 33 6 12 -62 55 14 9 -19 -27 45 76 6 -18 2 -42 84 16 16 17 -13 -57 56 -65 -38 -16 -43 -33 -40 -33 -45 -2 -25 32 16 -28 90 -6 -46 3 -86 15 -11 60 15 17 -61 -12 10 20 -47 91 66 20 -47 2 37 -29 16 -3 43 -21 16 16 49 18 -34 35 2 13 -92 9 -40 -15 -75 127 6 -7 -3 -34 27 -5 -6 39 -8 -68 -15 -55 25 -19 -40 21 -89 58 20 5 -24 8 -24 -6 -20 10 -9 -35 5 7 10 -34 -30 -27 -28 -3 4 7 19 35 -16 2 -1 4 32 -83 58 -9 14 -5 -15 -9 -29 8 -57 8 21 -27 -8 -16 -7 6 13 26 21 -2 -9 51 40 24 -26 30 -3 27 -3 10 -21 -25 1 -17 21 13 8 13 -5 -4 24 -22 -34 11 -24 9 -36 -6 18 -22 -22 12 3 26 7 26 -19 21 43 -41 -16 -17 0 -21 -6 8 -2 40 -7 -16 10 40 -34 28 7 14 63 90 0 -35 -43 56 -16 79 29 -71 22 -45 44 6 43 -18 19 -29 -25 118 3 34 38 20 19 -25 -75 -22 -2 -25 -29 28 66 12 93 24 -18 -9 10 14 -15 13 10 96 59 -45 93 51 10 21 11 26 -27 17 -15 11 16 -9 5 70 -27 64 40 29 31 -2 32 18 -10 -11 -21 16 52 -13 50 107 93 -22 -44 40 -2 -65 46 13 -20 56 -12 12 52 -46 -17 57 48 -6 -14 -50 49 40 25 37 -23 -19 30 40 3 10 10 -24 -1 -19 -29 -11 6 -70 -30 6 28 9 36 26 21 -72 39 25 -12 -11 -15 2 67 32 0 -27 -7 -2 3 41 72 11 -23 3 38 -38 33 -9 84 -20 4 7 -7 -128 -1 61 -30 -16 26 -1 63 -80 4 -13 40 -3 12 -4 -26 -6 -25 2 -43 15 26 -23 43 -69 1 21 52 6 -19 -44 -55 12 16 -3 16 -22 15 30 34 14 26 -23 -43 19 -30 1 -14 -16 -21 24 7 48 -62 4 -28 -46 3 -15 -1 -1 49 -30 -60 -6 35 -35 3 1 -1 3 -2 32 -28 6 19 27 -9 -43 13 -43 -11 17 14 -32 -22 31 15 28 -95 -8 -13 52 -24 23 14 -2 -33 10 -8 -7 -3 -28 8 -10 8 -5 -9 -23 3 -29 -31 53 -27 11 -9 35 15 19 -22 0 -16 -32 -19 -10 26 -8 44 -39 -13 -61 49 -5 -87 10 -44 27 7 10 26 -18 -44 37 13 15 16 -9 -6 38 2 -23 19 -24 43 15 3 -1 -1 -61 28 -17 -28 -15 34 78 108 -17 -9 -9 -86 4 5 -62 36 -39 10 17 -9 -16 -47 6 24 -42 8 71 -36 34 6 33 -59 -7 -1 -38 -38 -1 -25 -6 -34 -11 23 -61 15 33 127 -54 13 36 52 -38 -110 35 -6 32 -28 11 45 -44 102 -9 75 -61 -22 39 93 11 66 28 -40 -25 32 7 -59 0 46 -28 -71 44 74 69 79 -35 16 13 -1 -43 -13 28 -21 5 -10 -4 12 82 1 -38 51 -6 -55 -15 -6 -55 49 -15 -1 -12 50 5 48 9 42 -11 -64 -26 -41 20 13 -2 70 -10 -11 61 2 9 71 -19 -14 62 66 29 26 -61 27 13 81 20 48 37 -10 -75 -7 -15 -32 46 57 5 -8 10 54 -42 74 2 -36 -11 63 28 39 6 -56 71 -31 -30 9 -25 -17 14 17 25 -7 -25 30 -5 8 -14 -9 18 -12 -33 -30 72 3 38 -23 18 41 24 36 1 42 -8 -18 45 -16 -45 -44 66 3 21 15 -10 -27 -9 -9 26 22 -2 -5 -37 -11 -12 -28 15 -12 -57 -27 65 72 -18 -2 -14 -2 3 24 16 -42 -7 4 -41 -5 22 17 -10 -27 -13 -13 10 -13 -22 -12 -23 -24 29 -3 -5 -2 -4 -21 18 3 20 51 28 -10 24 -9 20 33 -8 -25 -34 -14 75 -71 24 35 -49 27 -61 60 7 -10 38 17 103 13 39 -81 22 5 54 -35 80 -23 124 -30 11 -37 35 -21 71 63 26 -21 29 27 19 43 49 7 41 -23 -69 -19 -86 -12 6 -11 22 17 18 -63 21 32 83 38 53 59 48 -56 32 75 -12 68 -18 -77 -8 11 -34 69 20 47 28 -67 -6 6 1 -8 0 -128 -5 8 11 -21 -55 46 -34 59 -9 -9 -56 45 47 24 32 39 42 -14 -3 -17 -103 49 -18 -40 12 89 -8 16 32 12 -8 18 -24 -5 -45 33 -10 -7 29 55 13 -25 50 -12 -11 -12 -7 -35 -20 -42 -6 -24 11 37 -1 -71 18 -37 80 -3 22 -8 -13 -12 -17 7 -12 19 -97 7 20 -10 6 44 16 -67 6 -9 69 -32 -8 24 -11 -46 24 -33 -75 -51 -8 -14 22 17 1 31 -20 -4 -59 68 -43 -14 -24 15 -69 2 17 -12 17 77 5 61 6 -16 9 -17 9 -23 1 23 -22 -22 -18 -11 -3 -17 -18 -25 17 21 11 24 27 -33 17 7 21 -5 -16 -4 26 22 9 34 42 -8 2 -30 -13 -3 -17 4 0 -23 -34 20 19 16 52 -19 -22 46 10 -43 31 16 -18 11 50 -28 6 28 -4 1 -14 12 -22 -27 -42 31 -6 -33 11 -52 1 3 5 -17 8 -13 -6 62 12 -60 8 19 -6 -1 9 -44 5 53 -17 43 -8 -41 -22 -18 -29 -43 -13 63 15 48 -20 15 73 27 47 11 76 14 50 10 39 18 -17 -16 49 15 -4 29 -4 0 -33 62 4 13 30 -66 -20 -3 -6 31 42 -22 16 -2 19 19 13 -15 72 0 51 10 7 -3 34 -41 -51 41 101 37 23 23 80 -6 -24 -22 16 7 11 10 82 21 40 16 82 -36 -6 89 88 83 -9 14 37 20 -25 16 8 72 69 -30 49 66 -22 61 -22 -8 -51 -54 39 110 26 -37 40 -50 12 36 27 -4 43 -81 -35 10 30 -50 42 46 4 15 -6 -27 -36 -26 51 -28 -23 18 -31 -19 56 -30 -31 2 5 3 2 -55 4 15 23 -4 -50 4 26 -7 57 -21 11 -38 -6 18 -61 28 -39 -9 -41 -34 -6 -26 -4 27 -62 -48 25 6 43 -18 -61 48 10 4 -32 24 43 -17 11 -42 -29 -34 6 10 1 -6 -15 3 13 26 -36 -19 8 75 31 -9 24 48 38 -43 -18 -4 -8 -17 22 69 -18 18 -5 -12 11 -14 -40 44 -5 2 18 -15 2 10 -10 -24 13 -1 -12 -2 -31 7 22 11 -43 5 -60 8 28 10 41 -5 22 -12 38 12 13 3 4 10 -56 12 -8 27 15 -32 0 -6 -60 -30 -23 4 1 4 2 -21 54 -38 12 1 -20 -20 -40 10 1 -11 -16 16 4 -4 -17 -7 -42 11 -3 33 21 -33 11 -10 35 -3 -6 15 -18 -25 19 -3 -2 -23 52 -25 51 16 -10 39 49 93 71 1 54 -29 53 0 30 -3 -59 -122 16 14 118 68 -17 -31 -11 -107 -21 35 12 -26 38 59 -25 23 30 5 -107 64 30 41 -12 9 -49 52 -27 69 67 -22 -25 -10 50 -97 19 25 109 37 57 78 21 -53 28 -65 16 65 -94 52 27 -44 -3 8 -98 -25 -35 51 63 33 72 54 19 25 10 66 35 22 -12 -22 67 19 -46 39 -31 5 80 29 -11 17 -22 46 42 11 17 3 46 -5 60 125 -24 -24 -57 -8 -31 -39 19 -58 -24 -80 -8 -7 -43 -44 118 3 -1 -76 -61 -15 39 3 -19 -9 33 8 25 84 -28 -3 -46 -11 50 45 22 -5 22 -13 -74 -31 0 -84 -14 6 -30 1 23 19 -36 33 -71 3 -15 3 -61 -24 -67 20 36 10 -50 -49 -21 -56 21 -14 -60 29 -17 41 62 39 -81 -34 14 5 -8 51 -25 26 112 -70 56 15 -74 7 110 6 -30 -62 -71 38 19 -4 38 40 72 -53 106 7 -27 -32 23 23 11 -14 57 60 8 -12 34 -8 -13 17 -27 -6 51 38 -6 1 -63 2 -6 43 21 -14 -25 -22 50 39 -7 -5 24 -3 -3 22 5 50 3 -54 -14 20 11 7 -21 16 -52 18 9 -22 18 66 95 -50 -8 65 -20 -22 -10 -13 15 -64 -45 -33 40 6 12 -14 -29 5 -23 -8 5 51 0 47 0 -31 -22 -4 17 14 9 -34 70 10 -17 73 -24 56 56 33 16 30 -70 -41 10 -7 7 -23 -20 35 -40 32 -10 -24 -4 47 -25 54 18 -30 49 34 -3 49 -56 -20 48 -21 -105 -40 62 3 -11 40 -21 -18 15 -10 -13 -108 3 -1 -84 -37 109 12 -12 -14 16 0 -12 -95 -31 43 -49 -42 42 0 0 -16 -59 -65 30 -13 -66 29 -25 80 12 -23 -21 74 -25 37 41 12 30 12 -38 17 -20 62 -66 24 54 -50 -52 3 -11 -22 89 -37 -16 -5 -15 33 45 -79 21 22 17 -52 20 9 -12 -127 0 83 -29 24 1 25 -70 -27 -53 67 127 -39 -68 30 15 56 23 23 31 -22 21 55 -10 9 -86 56 -36 47 24 -2 52 63 -31 -100 7 71 -7 23 32 -20 -60 -21 -33 -76 -83 -40 -6 -11 36 49 -94 24 16 -70 -42 38 11 -33 -17 14 1 -16 -14 -4 -46 -2 19 -31 26 0 -69 51 -4 4 -19 71 24 77 -64 8 33 54 19 -19 4 3 26 -11 -75 -17 -7 -10 25 -9 4 -24 22 -13 -17 32 -18 16 10 25 -66 -6 -7 14 -43 49 -18 -19 0 25 0 1 24 -28 19 -13 9 16 -22 4 -22 37 -29 32 4 -12 -38 66 -4 -9 39 -2 2 4 50 -2 -19 -2 57 13 -24 -14 37 -12 23 24 -13 -29 -24 -10 -8 -42 1 8 -17 10 23 14 -19 76 -8 41 14 17 3 -63 3 8 -23 -67 15 77 -17 75 -43 15 17 20 -61 -41 -19 -36 -48 18 -4 -3 18 -2 29 -10 32 68 28 18 39 13 53 -17 12 27 -14 -24 78 79 51 42 -2 75 3 73 38 -30 7 19 41 9 48 3 7 3 70 49 89 57 11 -10 22 59 92 76 89 83 2 30 7 -62 46 61 -20 31 38 -98 -12 9 19 17 56 -47 41 -38 66 72 -7 -40 -3 -86 70 63 4 5 4 10 -8 -12 54 10 0 93 37 -51 -11 -34 -102 -37 -53 -52 27 -33 80 -104 54 -30 -60 12 -54 19 -19 -51 3 -75 -4 6 -28 52 35 -29 -20 -22 -73 -64 2 -60 27 16 -13 -29 -53 -22 121 18 126 35 -16 1 39 88 11 -7 -51 -31 19 -55 78 24 28 -66 -11 -128 39 49 -67 -85 69 58 26 -16 -71 99 18 76 -3 44 29 -79 84 -9 -25 -12 -7 125 55 -126 83 -52 -33 28 58 -40 55 -13 26 32 -5 35 -20 29 44 -39 -26 -73 -5 -7 -18 21 46 26 1 5 -23 -20 8 10 4 69 -14 74 45 14 -39 -21 -36 68 -51 7 -31 -24 -63 8 9 -24 21 -106 -59 -23 -10 21 31 -13 10 -3 -40 -7 6 27 13 21 42 52 13 45 -28 -8 20 -24 -14 -28 33 -44 10 17 -12 -30 -62 38 10 5 13 -9 14 3 19 -27 -33 6 -43 -16 -14 108 -26 41 7 -11 11 0 13 -25 1 -67 -75 5 -29 -36 25 -18 76 -15 -16 12 77 -30 -1 -69 -87 -23 -40 -6 -61 -65 18 -10 57 30 91 18 -8 3 -58 -42 -48 69 -42 -6 -18 18 -6 28 0 17 3 4 -56 9 0 -11 11 18 -29 -8 64 22 -30 40 6 52 -27 -38 -9 45 -11 -13 1 13 29 -7 27 122 15 4 -15 -39 -7 -4 16 1 -55 -37 -21 10 -4 -19 13 -116 -7 10 -45 26 -7 12 68 -72 49 52 21 76 -70 42 35 14 -41 -31 6 55 6 16 -46 31 27 -2 -77 14 42 -80 -12 -56 78 4 21 26 -7 -22 46 15 53 -16 50 4 -74 -16 -41 -1 -15 25 -10 -1 14 -4 125 2 36 52 -53 17 -45 93 -16 -56 -24 -8 4 -42 21 -52 -55 -38 -50 13 18 -38 63 -55 -31 2 -54 -55 25 -39 -26 31 17 -12 63 63 61 -27 -75 27 -27 3 -27 10 54 1 -34 59 4 12 11 -47 -45 -34 -41 -7 0 22 48 -28 -31 -64 17 -18 93 -9 -9 32 -31 73 -12 9 6 12 -4 40 13 -27 33 -38 -41 -13 -11 31 22 16 -34 22 24 -12 4 -15 -13 8 -40 -23 3 19 32 4 1 13 -8 48 11 -42 -17 64 15 18 -16 -10 -14 -7 -22 70 -10 -32 -27 10 38 7 9 -13 -3 5 -17 4 -3 3 7 -22 23 16 -42 15 -3 -12 -5 -9 -25 35 -12 11 28 -43 37 2 -2 -19 -62 -25 -5 -29 -4 30 72 53 -4 48 9 -32 25 11 15 26 27 37 -29 3 -18 4 -69 -60 28 4 -31 -33 -9 15 46 -6 37 35 -1 -44 -15 -76 35 -45 33 37 3 55 -29 -14 36 15 -64 4 23 -21 -14 -1 -6 10 44 -19 12 -121 -25 36 -28 -36 -33 22 -30 -33 -87 56 22 -127 -76 73 -32 2 39 7 33 -56 -24 -20 -13 -13 54 -65 -12 10 -23 52 33 -93 -42 -51 -46 -82 14 -70 -78 43 -65 -14 -9 19 15 63 -30 -12 1 19 67 -21 -32 13 -19 0 24 -6 14 -23 -1 -74 23 2 42 -18 -31 17 -27 -15 -8 -53 -16 19 69 -15 -52 10 2 17 12 -44 -58 -30 58 -27 -26 -63 7 3 31 -9 65 -10 78 -10 25 -12 21 -6 -15 11 21 9 -33 -43 56 38 22 -52 -10 10 -19 4 6 12 -28 -6 -50 -33 -73 9 -39 37 60 -1 7 -55 -2 20 39 -9 11 -60 -8 68 4 24 -28 40 25 11 -42 -24 36 8 1 -32 -16 -4 34 28 4 -45 -12 -31 34 27 6 0 65 4 17 30 -28 -39 29 -36 21 -50 42 15 -34 -14 26 44 -14 -17 -3 47 -5 -30 -39 19 32 -3 -6 -42 -20 16 -24 16 48 20 33 6 3 -6 6 32 5 24 18 -15 36 -51 -37 -19 22 -65 20 29 -25 -19 13 -6 40 12 -4 19 -17 5 -9 -29 0 13 0 -1 -44 -17 -38 -13 -36 45 -22 36 9 -7 8 70 41 -36 60 27 -12 39 19 64 11 36 2 47 -55 27 50 24 -46 -5 97 1 19 -16 9 -28 44 -1 -39 28 39 49 55 19 46 16 -37 -44 58 -17 -9 -1 8 26 -2 82 22 32 46 37 29 31 -15 41 -3 15 -2 4 9 61 41 0 -18 2 23 -27 16 82 61 -37 22 35 16 -45 -41 -25 69 10 17 10 6 -6 1 -7 62 42 -2 -46 15 30 0 21 15 -23 59 -4 9 -21 -25 -24 -25 -2 -15 -7 42 12 -5 -90 -2 37 -6 -44 -54 -71 -17 -20 -5 35 -29 26 -24 13 -2 27 -21 9 -2 -38 39 29 42 89 -33 10 47 68 -2 22 34 -7 -17 16 38 -27 1 -70 4 44 67 41 -7 6 52 -15 -29 -9 17 16 -22 53 60 1 4 41 55 19 39 9 7 -14 1 -31 -40 33 31 23 -57 -17 92 44 56 76 -18 16 -10 40 0 -31 33 -25 21 2 -20 9 -46 5 -73 25 -44 -4 -3 -5 11 -51 -27 40 -32 -34 -3 -42 14 44 -39 -24 -45 12 38 21 -3 -31 -10 19 -39 -15 17 10 -52 2 88 4 3 10 48 7 0 40 -34 9 -27 8 -38 39 22 -2 18 -16 -5 -32 -17 -81 3 -5 10 -94 10 -42 11 -13 -18 -3 17 -4 7 18 -4 17 1 -14 41 37 -19 -26 -15 -68 -49 -1 6 -4 53 -4 -33 20 31 23 26 69 57 35 -2 -51 22 -10 10 -58 35 -64 47 4 14 82 127 61 127 17 -64 -7 -81 68 -75 -23 -46 31 28 14 6 61 43 -18 -18 59 -21 55 84 11 26 -37 -71 -29 37 16 -16 65 26 -12 -4 27 -78 -89 64 -53 33 -48 38 5 28 -2 30 15 67 -18 24 44 -19 54 -43 -10 -1 25 3 -38 -128 16 51 3 30 89 26 20 53 32 21 33 -4 7 24 -17 24 37 48 -16 0 7 4 8 41 8 -18 8 -15 -11 -30 5 -53 5 -1 -3 3 -28 18 12 -29 29 4 -61 7 20 22 -39 17 34 -22 -36 3 28 28 -34 -14 9 -14 23 59 12 -13 -36 5 -47 -19 13 -18 57 65 50 8 50 -6 -12 20 31 -34 25 75 46 -77 14 42 41 -72 -81 -82 -7 70 88 -14 1 -18 -14 -25 -32 -20 4 25 49 30 15 -46 3 -18 -17 -18 -11 -6 18 -24 45 5 -51 -24 46 -24 -5 28 2 -7 -3 63 -19 20 32 56 29 13 24 10 43 47 -11 13 19 48 70 6 55 11 -12 27 -7 -24 3 -3 -37 -59 -8 9 2 -32 -13 -8 15 20 22 102 2 -5 13 28 -14 -13 4 6 13 -3 16 -13 -21 -3 -2 -21 14 51 7 30 10 1 48 25 -58 0 -27 22 -13 -13 -12 12 -4 38 -20 -30 -37 46 38 35 -33 5 -47 -17 -53 -8 2 15 -21 -1 -10 -7 5 12 -7 8 6 -7 -6 13 9 -23 4 11 7 -1 -17 20 -15 11 -13 6 -10 -3 -20 2 -6 -9 1 -15 21 1 -5 2 -4 -11 -3 6 -3 -22 -7 -6 -2 -1 11 -11 -7 -23 -12 1 -2 1 5 -6 2 -11 -1 -5 -11 1 -11 -3 -11 11 6 3 0 -3 -4 -22 -24 3 20 -10 -19 3 1 12 11 1 4 -12 -18 -17 10 -7 -14 -6 -13 -1 -21 16 -26 6 -10 3 0 28 -1 7 2 10 -10 -17 11 -11 11 11 18 -6 9 16 -13 10 0 11 0 -9 -6 -30 12 40 -1 -18 -10 -18 9 5 -7 -28 8 22 -1 14 3 24 -19 0 11 -3 -3 -1 -14 3 -29 12 -12 30 -8 5 1 5 0 4 -2 -3 30 -1 -5 -5 3 32 -5 2 -13 -2 -23 -15 2 28 17 -8 23 -4 -6 -22 2 -5 19 -14 6 4 -7 7 7 -4 24 11 -5 8 3 4 5 5 6 16 -2 -19 -3 14 -3 -18 -12 4 7 -8 -12 2 -1 5 -7 -13 3 10 9 9 -8 22 -2 -21 14 11 -2 1 -3 16 2 -3 7 0 8 -19 -10 0 5 7 -9 -11 -7 18 -5 8 -15 6 6 5 -2 9 -12 0 7 -12 14 7 2 17 6 -13 -21 2 5 3 -11 -4 1 6 1 6 9 7 -1 14 -11 11 8 -18 -23 -8 11 -1 -28 4 14 24 9 5 6 -5 -14 5 12 17 0 15 -1 6 17 -25 2 -24 -4 2 -33 8 21 12 -9 15 -19 29 -16 -11 -12 -19 -35 -15 12 1 -10 8 -11 -4 -3 -22 -13 -22 16 -31 1 4 23 -3 15 -9 -3 19 13 -2 5 -5 11 -18 -13 8 -1 -1 4 18 -19 -20 -13 -6 7 17 -15 15 -1 -17 2 -21 3 -25 11 -1 7 -35 11 14 -24 -17 -17 -6 -6 6 -10 13 -4 9 -23 14 -5 -19 -31 31 -42 -42 -6 35 -21 26 -3 -3 -15 1 -5 -2 56 -28 43 21 26 10 -7 16 20 -29 36 5 -11 -13 -10 8 34 -15 28 27 0 -18 -44 27 -3 -26 -9 19 13 15 27 -15 -23 15 7 45 -2 -25 6 -2 45 -22 23 -7 -25 -2 -1 -52 6 29 -7 -4 -25 -13 34 11 1 -4 -6 -20 48 29 -51 -36 -5 3 -8 5 4 32 -42 -26 -29 12 -8 3 36 19 42 1 -21 14 8 27 2 -29 -1 10 19 -6 -10 17 19 -6 -6 11 13 -1 -6 -4 29 -17 3 -12 19 20 26 -3 -14 -14 8 0 14 4 -23 -16 2 26 3 7 16 27 -1 -13 -2 -12 5 21 -6 -10 -14 7 -5 30 -25 28 1 17 -4 16 25 3 -15 -21 -20 -18 22 -2 -4 5 7 4 6 -15 -18 -4 13 18 17 -15 -4 7 -21 13 24 -7 -28 -24 0 -2 5 38 -16 -17 26 20 5 -4 -7 -12 -6 -20 -14 4 9 -19 13 -8 25 -26 2 -42 -35 -56 -9 -13 18 -12 -13 -24 -15 6 10 -9 22 -37 5 -25 -20 -2 -28 19 -12 -16 2 -18 -25 -9 34 -42 18 25 37 -15 -14 -3 -31 0 7 15 10 -2 14 -19 29 20 -31 1 14 33 -26 -17 -36 5 32 -5 -21 50 -39 -5 -42 -19 -28 -16 -10 -8 -9 -2 23 5 -36 -16 52 10 -10 -8 9 -30 -29 12 -5 11 -34 -49 -39 -47 -77 -49 -5 64 -47 8 -2 -4 12 17 -36 36 -36 -29 8 28 54 -19 -6 13 15 -2 40 -9 -26 -76 -12 -23 23 -8 3 -18 11 7 19 6 -13 -17 18 12 64 12 30 -17 -67 48 -24 -15 43 -46 7 32 2 -39 8 -5 22 15 18 -38 -7 -51 -4 4 -34 -36 -2 -19 6 -33 -33 -6 -21 -26 60 -35 28 -68 37 6 17 -32 47 9 -26 1 1 35 -24 -8 -28 6 -5 -7 -34 -1 3 -40 4 0 24 -2 -5 -11 50 -7 -13 -4 -19 4 5 6 36 -36 24 13 20 14 -3 -9 18 0 0 -7 14 -9 -22 -33 11 0 -25 -14 27 15 -19 -10 17 -4 15 27 -20 5 14 1 11 12 -25 18 -1 5 3 -9 27 8 -10 -8 -24 -1 -68 -22 -13 24 1 2 -7 2 0 -3 22 16 -9 -7 17 11 -6 -5 -25 14 4 -23 7 8 -26 40 12 -21 -5 10 32 -4 -34 -46 23 24 -9 -5 4 8 -14 13 8 17 -1 -35 16 -90 -8 15 53 -10 52 10 16 -13 6 7 31 4 78 -3 -60 -15 -12 -3 24 -7 21 -13 35 21 -26 -3 -14 14 2 -44 26 -2 -35 23 19 30 4 6 18 -25 16 12 9 35 -7 -8 26 2 -6 -7 12 11 4 9 -12 17 -36 0 20 39 -9 -23 -36 -5 7 -12 22 28 61 11 26 -36 -21 10 8 -14 10 47 7 -23 6 13 4 31 45 12 -9 27 7 -28 27 57 -17 31 26 7 -45 -6 -29 -15 -2 -43 -27 34 24 -20 6 29 40 -35 -38 2 -2 -20 -71 12 -22 47 -30 41 19 23 1 -5 55 -15 -38 22 1 42 8 -2 -11 -17 -1 -6 37 15 -39 48 78 -20 -11 -38 -11 50 34 15 -39 -45 26 5 -8 4 75 15 -30 36 46 76 -68 -25 21 3 24 -33 20 -31 88 42 19 -5 29 -26 8 -16 17 -37 -10 35 29 5 -8 -26 -4 -14 61 16 -41 -11 -12 21 5 -14 23 2 17 56 -15 4 -14 12 45 0 0 10 -28 -22 -12 8 3 -8 34 -8 -10 -18 21 -7 17 16 31 -5 -41 10 31 11 8 -10 -10 -23 2 -10 -8 14 -22 10 28 -4 -5 33 -12 -4 1 26 -4 0 8 5 36 23 25 15 19 -14 18 3 25 2 -21 24 -28 -2 -9 39 48 21 19 30 19 -9 17 23 -31 -26 15 7 -23 8 -39 5 -13 16 -34 0 -15 -11 41 -55 52 -12 68 24 29 8 11 -40 17 58 18 -40 39 -37 -24 9 -33 -82 -4 -9 4 16 7 -28 1 15 0 -2 -7 -41 -23 -1 -40 41 4 28 1 -23 11 26 23 -12 3 -18 -28 17 -5 -33 -19 -32 -11 -17 5 -22 13 11 -19 -5 30 -19 10 4 -11 -32 -11 -10 2 11 -27 0 6 -13 -28 22 1 -79 -13 90 5 -23 21 3 26 46 22 -50 6 41 37 -4 -7 -21 15 29 3 -4 -46 -8 -20 8 -18 -64 -25 57 11 67 -15 -10 15 57 -74 15 -23 -35 -72 29 28 -9 30 -8 15 -25 -55 7 -6 7 -51 3 -19 52 14 -14 26 58 23 0 -5 25 -57 28 25 -20 -7 118 -17 5 30 -7 0 -46 17 -33 -10 -10 1 -74 -50 -18 26 15 42 -10 -91 -18 -80 -34 33 -1 -11 -39 -36 -55 6 -32 -7 23 0 -34 16 21 12 36 -72 -2 3 -5 24 8 -27 0 -3 -5 -10 -4 1 20 -3 36 -28 6 -12 47 4 -2 0 20 0 -17 8 69 0 -12 -44 14 -14 28 -28 -14 -8 -3 0 1 -8 6 19 -3 13 10 19 -20 1 12 2 4 10 -1 23 -6 -10 -30 17 7 17 -5 10 -8 50 12 -6 13 4 19 16 -17 -7 -5 11 -2 41 -25 -58 13 -10 22 22 26 16 37 14 16 -14 37 47 -34 -1 39 -13 -22 -27 34 5 17 -31 -31 15 12 14 36 17 3 15 -22 22 1 10 -15 5 22 70 42 -47 70 28 17 -13 -28 -20 -3 -9 15 -46 0 -10 -8 -8 -1 0 -19 -15 39 -4 -7 -7 36 -2 11 -4 59 -40 -47 26 10 -2 10 -28 23 -1 -21 3 -32 -20 -51 39 15 -25 18 22 -42 15 23 9 -53 21 -5 8 17 -14 -4 28 11 13 -3 23 -41 -25 80 11 -13 -49 -5 7 -21 16 -83 -16 25 21 78 -38 -7 45 -24 -42 -3 41 -4 2 -33 17 49 32 -13 39 -49 -38 -21 -30 -73 -9 16 1 -27 -11 9 -76 5 18 -79 15 15 -22 22 -77 59 -24 18 26 -90 -20 0 -10 -15 28 27 4 -6 24 52 21 -2 -16 -3 10 -9 44 -6 -25 23 34 29 -29 1 73 -22 57 -9 23 -37 -42 45 115 -18 97 -3 -14 -28 -15 23 -45 -59 56 -29 -18 17 -1 10 -6 -5 -7 56 -47 15 6 35 8 -34 35 26 8 -23 -20 2 15 -26 -12 -27 3 -2 8 12 -17 -28 -4 -25 27 -12 13 56 -2 34 28 -7 29 19 26 11 -34 3 -37 -10 6 20 -6 27 19 12 6 12 11 16 43 14 28 2 -34 -2 -12 -3 -36 -57 -12 0 -4 -12 33 0 -31 -15 37 -10 -34 9 23 -6 12 -4 -3 -27 50 -8 14 -15 -56 2 42 42 55 80 -84 96 74 -73 -17 -3 48 -99 -59 8 -4 -2 126 -40 125 62 4 64 -18 -6 118 3 43 -127 -12 47 44 29 84 42 -32 -34 45 33 -29 123 -17 -23 75 28 -58 5 -98 17 -14 52 -55 -51 -122 64 5 -3 -127 127 29 -67 50 63 -125 45 -45 -40 -11 -53 -99 22 -80 -45 127 -102 33 127 -16 24 3 98 -104 -29 61 20 40 124 -70 -22 -50 -68 -35 -117 -36 -2 -2 -119 27 18 -18 112 -22 -43 7 125 -11 -20 -80 42 -120 6 58 127 -77 55 82 -113 54 -23 39 8 -14 -83 19 73 90 -16 84 1 32 -36 -77 -45 111 61 -87 -127 27 -73 124 -35 -111 -53 -67 58 73 51 -8 -53 49 12 94 125 39 36 -11 -6 -46 98 -19 119 -128 39 -25 -62 -87 -127 -84 24 -39 -43 -40 6 -21 114 57 -71 -46 -10 -128 43 33 -49 -127 127 -128 127 -124 -128 -5 -59 127 -99 -74 36 -86 -19 20 7 -61 40 -15 29 -59 46 86 33 38 -3 -65 28 97 21 -62 3 -25 -3 29 60 -1 -127 58 -50 -32 34 -23 -40 40 -1 58 -25 90 -31 -9 41 -99 -32 -2 -126 73 -26 -66 13 -112 -108 -28 63 53 -6 43 -26 30 -20 127 -54 127 50 -16 -11 -23 27 17 95 -28 10 -10 -47 -6 -28 127 23 -56 -3 -3 -33 19 65 6 66 -20 -33 83 87 -71 68 25 0 75 18 -11 26 63 52 -7 50 -61 -79 33 -125 -16 90 122 -57 -70 -101 114 111 17 124 -10 4 -49 -25 -26 111 3 -2 -30 33 2 -100 66 32 20 -72 -56 -60 64 127 26 -89 -92 34 -62 8 -11 -28 9 -40 -63 -91 50 55 -70 -126 -14 -1 -44 64 -41 0 -127 116 -31 42 -74 -56 -37 -1 36 77 120 49 15 22 0 28 80 28 2 -123 -22 -21 9 -45 63 -127 123 -90 38 -4 -99 -40 -76 -59 66 93 -25 40 -126 99 -125 -101 70 -60 28 30 77 -44 42 -128 124 -15 -42 -81 -80 86 -85 -71 -26 -125 123 -26 57 -1 113 57 -95 44 31 58 78 17 -128 -116 -20 8 -76 3 -45 6 -52 14 -2 124 37 -54 -122 52 67 -99 -35 104 -92 125 -51 60 127 -16 -75 125 -57 121 123 21 21 -73 -13 -77 43 -54 77 127 -114 10 27 40 127 -94 92 -21 -108 58 127 -123 101 -20 41 -127 -100 -68 108 115 48 40 3 35 -24 9 -41 -21 18 -78 -66 -2 11 -56 -123 11 -50 -24 -81 -11 -32 -66 3 96 6 -35 -55 34 -40 61 61 -27 53 117 -127 -23 127 -127 29 -6 44 -19 45 -75 -58 27 -86 81 -32 -122 -85 35 76 -63 78 -107 -26 127 -57 -61 -20 34 13 -51 11 118 34 13 -83 -37 90 125 -42 85 72 1 45 -41 0 64 52 -63 106 -32 61 -59 -61 71 35 -8 7 87 -114 -51 -11 -42 80 -110 82 101 -3 -95 52 -14 -13 -13 -124 -28 41 -43 -62 61 -82 22 -3 123 14 -44 -6 -36 12 -38 44 -37 69 -5 35 -27 -123 14 107 58 7 55 -122 -53 -29 55 -14 2 -25 28 81 -49 -54 -91 -31 -21 -21 98 -55 89 125 -118 28 -103 48 -88 -57 71 -48 -46 -51 -96 -105 -98 27 -63 -59 -68 18 104 74 58 -50 -62 -9 32 -40 58 -90 -128 -13 -23 -33 -118 -16 109 -117 19 -77 125 -24 -54 -7 126 37 3 22 105 -112 -45 -41 75 75 65 124 -44 -68 -77 -123 -55 -128 -76 38 0 -29 119 -103 -125 97 43 -111 -8 -30 -57 -13 53 -82 -78 -43 -101 -49 -46 -29 27 35 85 -67 127 75 47 68 -126 -6 -49 -27 -68 60 -128 -82 87 -39 77 -30 4 55 15 32 -95 -6 16 -2 -102 -57 -66 -48 -34 -4 61 -80 -11 -122 -66 -73 -105 -37 124 -38 47 62 -40 -84 -34 -40 -66 26 116 58 -15 25 -48 -104 -32 46 31 -68 -103 4 36 24 -30 -127 80 -74 -25 62 -6 21 89 25 14 66 -34 -81 -6 -34 -52 -19 -14 -11 39 -47 -38 95 -1 43 -36 3 -20 -63 -38 85 40 -88 -17 -25 -77 22 46 70 -7 89 42 20 -118 -21 -97 28 -22 57 71 5 69 -69 119 -21 46 11 -14 -24 45 69 18 -27 -32 -28 -25 6 -36 20 3 33 -81 44 -65 91 89 37 8 33 55 42 -65 53 -123 -104 109 -51 36 12 61 -3 -109 7 -125 35 60 -91 -23 -8 92 -26 124 105 -65 21 -126 -122 -54 96 -48 1 -121 72 45 -29 109 57 15 -92 -127 -106 -73 28 86 -125 73 -1 127 50 -16 31 -80 -127 16 -43 20 -125 8 -65 122 -23 -73 -50 -9 -40 127 -18 -32 -58 -52 -8 -45 -117 -92 -18 -101 -35 116 125 10 80 28 -10 47 66 61 -28 -128 -105 43 -31 -125 98 -63 -98 20 -125 60 -85 32 -50 -127 29 97 127 16 -128 -83 77 -128 -3 112 9 -126 11 24 -7 -71 74 -51 102 -20 18 75 -128 11 52 -126 7 36 27 -127 58 11 123 126 -127 43 127 7 -28 -27 -61 4 -56 122 -58 -72 60 8 127 124 -36 117 122 127 -72 5 42 58 54 -122 -92 -71 82 27 -57 12 -21 -46 -41 17 -99 -36 57 22 49 -11 36 -103 61 86 -4 126 12 125 -54 -120 -87 -67 65 101 35 33 1 -125 62 37 30 -89 55 16 -17 -49 -111 -43 64 77 -126 -80 -1 -34 65 21 44 39 32 -71 67 -10 -121 -65 34 -59 75 -44 -119 -66 27 -46 -56 81 4 56 -126 5 43 -20 51 -33 -10 -49 -37 -118 67 126 101 -5 6 33 57 87 -56 -45 -121 -41 -36 105 22 -19 -59 125 55 -20 -9 56 81 58 55 20 -115 -38 45 -121 -63 23 4 -28 71 -46 86 -104 71 85 18 31 -25 18 58 -53 64 -53 10 75 77 -31 125 46 -127 -118 -5 -27 74 16 8 -122 103 115 22 -71 95 -32 -86 10 -25 42 -105 -6 55 -6 123 74 22 123 91 -7 -26 -127 8 -31 -33 -58 37 107 -22 127 74 77 -119 37 -8 -15 -115 61 92 -111 118 -72 28 49 30 -64 -25 127 78 -98 102 -89 118 -28 -75 43 -27 -79 -34 19 -13 -59 60 -92 -82 17 109 -57 82 -128 120 -50 121 -114 -30 -93 48 -67 116 25 30 -28 -104 32 28 30 76 118 -128 -88 -120 -76 39 -24 -127 -126 79 28 127 -63 22 -117 -85 39 99 96 -128 113 -21 93 -52 106 116 -128 127 -20 -47 99 -120 14 -128 -29 -1 -91 -61 -118 127 106 -9 32 127 10 57 -105 -28 127 44 57 -7 -68 123 -10 -92 -123 -109 51 91 -25 116 -114 120 -39 -127 125 0 20 -56 -24 -13 -22 -74 -128 68 -25 -128 102 11 -127 76 -25 126 49 -51 -82 40 -115 -125 -80 -16 -21 31 24 36 -24 53 -69 -9 82 -2 27 -103 -70 73 -64 40 -54 39 -26 83 -103 22 13 -109 16 36 13 59 45 -28 -116 51 -5 80 97 60 58 96 10 96 -55 -65 64 0 79 -20 -69 -26 25 110 124 6 -77 48 -96 -60 -26 -127 -23 67 127 61 76 -66 115 -22 -23 105 -15 40 -68 117 14 116 8 105 -43 45 12 -12 -53 17 -127 -109 105 127 -8 -24 81 19 -17 65 -54 5 -14 69 122 -30 1 -121 -126 -81 -121 -110 -90 -35 -50 -1 19 62 -7 80 -30 -12 21 82 -103 56 121 -37 76 -87 -125 -121 -87 -128 -91 127 -37 -79 114 -21 -96 -122 73 -52 -125 82 36 -45 50 -126 109 -91 -126 -42 101 -69 -3 103 89 68 55 123 53 120 -5 -63 -99 -15 -28 101 -72 -69 127 -32 35 95 -127 -123 -126 105 3 -124 44 -79 -127 -33 -127 -101 -6 42 -87 34 75 -36 -111 -47 22 -26 -123 127 127 20 -122 76 45 68 120 46 -114 -114 -27 -99 27 115 -52 -102 -38 -115 10 -29 127 -92 99 18 -60 -29 82 50 62 -65 76 -46 53 74 14 127 -100 124 -127 -115 71 -21 -28 -23 31 101 73 81 126 -110 -53 121 80 -45 125 -1 27 -128 -56 -124 -48 -40 45 44 67 -43 -12 1 -11 66 127 -48 -62 35 116 -85 -21 117 -118 11 -15 20 17 -47 41 -12 -128 -96 -83 127 -14 21 127 83 46 66 -69 -84 69 45 103 52 -128 -5 -55 49 44 92 -19 40 42 -30 8 87 52 -88 -36 14 98 32 -2 -2 125 -43 41 28 -15 70 -10 20 26 -89 -23 -125 24 -27 65 127 60 30 -1 -101 -2 64 -29 52 -37 39 58 12 127 43 79 -100 104 -20 65 54 -22 -72 -53 -11 32 20 -9 5 5 102 3 127 48 4 28 59 -19 -18 -8 19 -128 123 17 -15 60 29 -20 26 126 -97 -119 -69 -98 -8 124 41 23 -69 -36 -99 -98 -15 -45 -32 -120 104 9 22 55 -24 45 127 -15 -2 10 127 94 -55 -54 31 -40 -107 52 113 126 -79 6 -5 127 127 8 -128 -38 -92 -53 -7 -28 -60 -127 -88 115 -44 -44 33 5 -60 -116 -2 78 -52 88 111 95 -66 93 127 -55 25 -128 36 -58 68 -127 -67 122 -101 11 -63 -125 38 -22 103 9 6 -39 -71 -127 -27 13 17 -117 15 -79 -49 -126 26 29 69 -39 -28 8 -53 -2 127 -8 -27 60 -92 -125 -116 48 70 -64 -8 113 11 -103 -62 71 112 88 44 -71 127 127 -111 -5 -30 -103 -80 -75 18 -65 127 -127 29 36 -37 -70 4 59 -74 91 -53 127 -22 66 -27 35 127 13 41 127 5 33 57 -43 -127 -73 73 36 81 126 0 -94 -4 -73 -128 -121 7 -128 8 54 27 11 -49 -32 -108 126 -72 -123 -19 -87 125 125 77 5 -123 -119 40 105 -87 -74 -52 -122 109 -8 -78 -127 69 102 -41 23 -61 67 38 -30 29 -111 29 -95 -17 39 53 -15 17 -89 31 7 65 -33 71 116 51 44 114 -75 22 36 110 -88 19 -43 122 47 91 2 -61 -54 38 8 0 11 -11 26 -37 43 -89 -95 91 -15 -96 4 -17 79 30 31 73 122 19 34 -6 40 0 127 21 7 0 -25 12 77 72 -125 -71 91 -100 40 54 -128 -83 -13 32 -1 87 121 -93 82 125 -11 -69 -100 -119 68 120 -100 4 50 41 127 39 107 -126 -111 18 39 -54 69 -100 116 15 67 11 -46 25 38 -128 -61 -102 -126 -8 54 53 8 -90 24 6 125 127 16 127 -38 -108 -50 -124 73 -96 -86 -120 124 -114 18 68 76 -19 61 127 -92 41 127 -3 45 -11 127 126 -123 -73 -127 -43 -30 123 -125 8 98 43 70 95 -28 -85 20 -124 -16 92 0 -5 -128 -55 99 123 -40 -23 -80 39 -68 -4 -59 -12 27 -12 19 -36 -47 2 127 -123 121 -124 -113 -120 -125 117 -127 -123 -54 86 33 117 11 -1 127 119 -99 4 41 -114 -63 -2 58 -30 -127 -125 -127 8 -125 -128 54 20 -55 20 11 -128 -122 0 127 125 127 127 94 118 -50 -128 127 -17 119 -52 -97 -111 13 -128 125 127 127 98 -70 111 101 -127 112 -47 -69 -64 47 65 -84 4 -66 78 14 19 -91 20 -44 -82 16 -26 -59 121 116 -66 -14 55 -127 -47 -34 24 8 2 -18 -127 -18 48 -124 -49 -15 37 43 9 -46 63 -30 -16 -18 46 42 9 31 -65 51 92 -52 81 -104 107 -101 -46 117 100 -4 -6 -126 -6 -56 -127 42 -14 -42 99 -16 8 -64 21 47 126 46 -89 -27 -107 113 120 -1 35 34 -96 -72 40 -33 4 51 38 -45 92 43 -92 13 35 9 5 25 -14 -5 127 -65 47 -98 4 55 -25 -128 -89 -63 36 -64 44 87 -6 124 -83 -23 -45 -69 -37 -25 23 73 114 -82 -128 -32 98 -89 -93 0 127 -126 -103 -85 -23 13 114 -63 -115 -106 -41 23 -12 106 -46 127 -30 46 -121 -118 46 82 31 -128 22 -120 -121 78 106 39 35 29 -33 -125 -126 123 123 -128 -34 -119 -94 -127 127 -2 -128 70 28 41 -88 124 -13 -67 122 -98 -71 -21 35 -127 70 -65 2 124 -38 -40 -85 -40 20 -23 -12 61 56 -128 11 49 127 -127 118 -125 -82 67 127 -26 96 -72 52 -63 -11 -111 -126 -15 105 20 26 16 -87 -29 108 84 47 -99 121 127 47 -13 54 126 -25 -6 73 41 56 -31 -46 33 125 -122 -89 82 127 23 -63 127 126 -105 -46 -91 -117 39 123 126 82 125 65 24 127 127 -89 127 -54 70 -122 125 5 16 127 -13 20 127 -127 121 -2 4 10 6 -97 99 48 -127 31 109 -31 53 -125 101 -125 -16 -98 -65 -65 -125 -126 74 92 -100 -25 59 0 -128 19 38 -39 -122 -127 -75 -123 -17 111 -124 -121 -9 64 34 49 -123 40 -3 16 23 66 -16 -123 -26 -36 125 102 89 -34 -123 52 -2 -116 -1 100 57 -128 126 -87 -74 124 57 -116 6 16 15 20 -44 28 81 99 6 9 62 55 -92 82 77 -2 -36 -122 -72 -127 75 12 96 59 6 -55 77 58 64 -49 -122 -42 126 121 -54 64 -52 126 79 -46 28 -33 -128 -50 127 -127 -128 -38 100 -75 23 53 96 -107 21 -6 -13 -107 -50 -67 -67 -128 111 127 -127 -107 60 65 -106 81 95 127 12 -52 -81 50 127 45 117 18 -10 70 -104 36 30 57 -32 51 16 80 -128 -21 21 124 70 85 12 100 -41 -28 -126 -128 111 70 89 -32 -69 -90 100 125 -101 41 8 -3 68 -125 33 94 11 -44 49 -5 52 -121 56 118 -125 -98 127 -79 -4 -17 3 109 -70 119 -57 122 -125 10 -93 -93 15 38 -108 127 -3 91 -104 -105 -23 51 -23 -42 -92 63 -67 -66 20 -108 -35 73 -122 -125 41 93 -71 88 122 101 -13 -98 66 55 -120 -128 40 0 58 -81 56 124 96 13 90 22 127 -61 125 -117 -105 68 -91 -112 5 96 119 121 108 -67 -89 -5 -40 -7 8 -113 66 -92 4 -66 17 -58 -90 -127 127 76 -72 -61 83 -21 -128 -57 118 66 -127 46 -54 36 103 127 30 92 -128 54 -97 80 112 62 -51 38 -13 47 -127 -107 -125 -79 -106 -66 -118 20 -11 -18 63 92 62 -17 -117 -29 -4 29 -74 20 66 -41 -42 -107 -40 -37 40 60 7 -62 -96 100 124 15 -30 -39 -103 112 -40 -95 126 -33 -110 -86 4 -91 68 67 9 -27 -127 -121 50 -77 40 22 -26 -31 -58 105 125 -7 61 -124 14 84 -45 112 44 31 41 71 -113 52 -44 14 -124 -18 -27 3 -1 85 -72 -29 -26 -11 -32 9 -128 -32 36 -4 37 -30 33 39 -20 71 -49 -101 -64 75 -21 -38 41 -128 20 11 -20 123 -89 -86 -115 41 54 -62 127 -20 -42 -16 122 -116 -123 1 -29 -81 65 -82 122 127 -125 -112 -93 -128 -88 -112 117 -127 -27 -42 125 73 -121 -126 57 37 -105 -127 69 -77 122 122 124 -94 -105 83 -34 0 126 81 52 99 -14 127 -128 -127 -81 86 -26 -47 -87 -128 127 -116 127 10 38 -25 -6 125 127 -90 126 -3 -128 121 -59 -124 -126 -4 -23 -20 15 -12 -84 127 -15 98 23 -82 -44 18 -28 48 -52 67 -126 -114 -127 120 53 -39 -33 62 120 108 127 127 -128 127 -94 127 54 61 -94 -14 -54 -103 -121 119 -126 127 -127 26 120 -69 127 73 86 -67 117 95 123 38 36 126 11 112 55 35 82 -16 62 51 -3 -126 -58 -124 58 127 127 86 -71 10 37 11 126 -115 6 -49 -114 15 31 -98 13 -32 -9 -124 37 -126 15 43 -60 -61 -3 -43 -9 97 -113 97 -126 -47 -70 -6 -28 -22 -123 24 -46 -38 47 -19 104 -17 59 -4 -85 19 -13 64 -116 90 56 -122 76 43 -126 124 -98 -97 -19 13 -110 -81 106 29 101 -128 -89 -97 -101 52 -11 -34 15 1 12 7 -96 -22 111 -80 27 -34 1 -127 96 69 127 32 61 -57 -42 0 -121 -10 20 -5 54 -7 77 2 73 -51 30 -128 -23 67 -71 -31 69 -106 -26 -119 30 -30 -127 -52 -39 -36 69 86 7 33 -48 65 -6 73 82 -15 23 90 -123 -21 40 80 9 -45 -24 -18 -128 -72 73 -114 92 26 -37 126 10 50 14 35 -13 127 -14 127 127 92 -127 -52 67 -127 122 24 125 15 -68 20 47 -110 -60 115 -22 -128 41 -126 -111 13 113 86 -97 -79 -110 127 -70 -60 127 6 125 -30 98 -17 -107 93 -126 -46 -63 89 -127 -127 -1 -7 116 -91 8 -54 -114 54 -31 -10 -1 -36 -128 80 110 125 -110 -62 -127 -67 126 -74 57 -92 47 103 -12 -104 88 -15 -35 29 -128 125 30 -9 74 127 74 120 -97 -28 113 14 19 10 32 -91 -124 127 -60 20 44 -57 -42 127 -127 -59 -127 127 -128 -128 124 127 69 92 21 -25 36 -126 127 127 68 33 122 92 28 22 126 -52 -20 9 23 -123 119 -111 92 127 115 -24 19 53 -15 -125 107 -126 -125 76 52 -23 -70 -8 43 -121 112 124 -120 -59 -23 -128 -128 51 -124 116 127 127 115 68 -125 -93 6 119 31 -73 -124 -109 -1 -127 101 -126 35 -6 -100 44 70 -40 -20 -91 -17 -20 40 113 64 -28 -115 126 -76 19 -14 45 124 -36 118 -24 98 -127 -128 42 -122 26 102 -8 5 -21 106 81 47 -124 -14 -73 -62 -72 -33 -64 -117 -24 122 -123 -30 -32 -64 -123 -103 119 119 10 97 100 -59 -114 2 124 -24 -109 55 83 -30 123 -38 -79 28 83 45 28 -127 -59 8 35 -91 -119 100 112 68 -62 68 -85 7 6 -65 -41 -127 79 6 -46 74 -128 111 4 -10 -38 64 -55 59 12 -9 -115 14 -122 39 127 -105 71 127 113 34 98 115 123 -61 -42 55 -7 36 -97 56 -111 -41 -103 -76 14 -125 90 62 -44 37 25 -119 -102 -41 68 -62 127 123 3 36 47 18 40 127 -89 16 102 -96 -37 16 82 -7 125 -52 -98 52 25 126 -64 40 -123 -71 -101 7 -18 -127 -119 20 48 -124 -83 -55 127 90 -34 -51 -18 127 0 -8 29 -101 35 48 66 -27 90 74 -128 65 123 -1 -44 -17 -101 -111 126 48 35 -96 -103 -23 -5 -53 -50 -31 99 25 33 25 -38 -48 117 -55 -29 34 -69 59 -47 -95 10 -112 76 109 127 -128 -92 -86 -128 75 -66 42 -78 51 24 -35 107 9 -126 43 104 127 7 -33 127 -37 -29 -34 21 82 -27 118 -125 -123 100 -107 -4 -44 -125 88 -66 -51 125 -74 -39 -105 -61 108 30 29 -33 -21 22 127 32 -69 4 -87 -30 -100 -126 -7 35 -128 17 -105 -103 46 -11 -10 -20 73 4 43 15 127 -5 85 -124 -27 -69 12 72 72 76 13 -57 64 -15 -68 47 -128 27 38 57 -55 -21 -17 -74 111 64 -4 -7 -75 -127 5 -21 40 -12 20 -75 26 9 -21 45 -50 -55 -17 78 -41 -49 60 -36 33 -8 -11 29 42 33 -94 4 44 42 -14 104 -65 -19 -128 72 -28 121 -51 -98 -79 -38 -38 -8 -13 -104 -23 24 112 118 89 -117 22 -73 -1 116 127 -2 103 125 -68 -89 127 -26 -101 69 -112 101 34 -114 -35 126 -80 -124 125 88 -4 126 41 -47 43 -127 -126 -74 -96 110 -1 -44 -32 -10 37 96 -127 -127 121 -101 88 65 103 -123 70 22 -26 27 -44 120 -62 80 40 125 -34 16 -41 -88 -108 38 -93 121 -58 -78 40 76 41 -18 -125 126 52 2 0 -63 -99 64 -43 70 -126 -127 -47 121 -104 -121 -41 119 8 -10 62 -91 -126 -99 70 82 120 -1 -46 -128 -11 -127 -2 80 81 49 -76 15 -66 111 4 19 -102 -126 -128 127 -78 -108 58 -16 127 -55 -57 -105 127 112 -25 -32 106 2 -86 -126 39 105 -127 126 -110 -126 -128 -127 -39 -40 -79 -35 110 -110 95 -122 -70 35 37 -125 117 101 -40 -127 3 81 -121 84 127 127 33 102 -13 -17 23 -32 49 62 -44 -108 -124 -124 121 -41 -99 58 49 -66 37 108 -51 127 127 -43 -113 -25 126 127 -36 15 -114 -12 -126 -63 -110 -118 43 -43 -59 7 -63 18 -35 127 55 24 125 -126 -32 -128 -124 77 -115 66 -110 56 -56 -127 127 48 -72 -118 -122 -88 5 49 -88 -76 54 0 31 -128 127 -127 -48 8 30 46 -16 11 -76 25 -26 41 6 -123 127 17 61 -20 56 20 -20 53 -115 -127 -9 -55 -46 98 22 23 -109 115 -35 -111 -127 -83 0 -22 39 -57 -125 -87 124 -103 35 -69 127 -96 -85 127 -110 -115 -72 -128 92 54 10 24 56 -17 37 88 116 106 -44 36 -13 60 62 -128 126 110 -6 -17 24 30 19 -108 70 10 118 -73 82 -71 -31 66 -112 -114 127 48 127 16 -31 -108 120 106 114 -24 105 11 -17 -89 -19 -25 112 116 19 -121 -17 1 -22 -75 -24 46 127 -71 -69 86 5 19 44 -94 -107 -70 -128 -112 -106 112 -105 -86 -102 67 -31 6 50 -33 -7 -125 -119 4 -21 -80 113 -43 -68 -12 -54 6 -128 -80 -72 -20 126 39 127 -102 126 126 -114 -122 -126 52 -73 12 15 -94 -87 82 120 -127 -9 106 104 56 124 -74 -97 88 -119 -34 -66 -43 90 -42 -45 -121 -84 4 82 107 -7 -118 127 -4 -58 70 -65 -124 -85 -68 -30 18 -31 -110 -126 -126 127 15 45 -126 -40 48 20 70 -125 8 103 -126 10 -18 16 27 55 127 110 -85 -125 21 -113 72 127 37 124 -127 101 -10 127 96 126 106 -77 116 -62 -21 -52 50 -121 -2 -46 -44 -70 3 -17 48 -102 -32 -36 36 12 -49 103 -20 126 -89 45 -115 -58 -99 76 -9 8 -45 59 -29 -52 10 -118 -121 -54 -57 -30 -28 -127 72 81 -125 -41 -110 -128 -121 -16 118 31 -128 -61 -18 79 -62 -118 14 66 -126 -23 -101 -112 -68 -62 -53 14 -127 107 -115 121 127 84 -47 79 -26 81 22 58 -63 -120 -61 107 32 -127 94 -128 -128 126 -93 7 -125 126 7 42 -21 -125 52 -128 -87 10 89 11 11 74 119 -14 -14 70 76 126 39 120 12 -74 -127 102 127 6 -8 -125 67 45 -11 117 38 81 -36 27 34 121 -128 -120 -25 -127 -58 -64 -111 53 -15 -128 67 -16 -19 127 -11 -108 68 108 -10 114 87 94 57 -81 -92 28 -128 99 79 -74 65 109 -18 -37 63 51 88 -93 -54 -122 -42 123 -126 -64 -126 -64 -69 -47 -83 -40 -127 10 -123 -120 62 125 -13 115 -128 -128 -21 -118 -125 127 77 -4 118 -38 -34 109 127 -127 65 -12 29 -11 123 -2 90 -118 73 23 125 1 -127 109 -128 -128 -96 -126 -14 -41 37 -127 127 -19 127 -22 -12 -62 2 -123 -127 127 -128 -125 120 -128 -126 127 -3 108 99 78 -80 39 -99 113 -111 127 124 11 1 -11 -24 110 -110 127 -66 -80 66 17 -119 127 -53 -3 -5 -26 126 -127 -28 25 -98 34 118 -17 -127 127 127 38 -19 83 -128 -25 5 39 -35 -121 -127 -2 -70 -52 28 127 48 15 127 -94 -82 39 65 58 92 19 121 126 127 50 86 14 -51 27 56 47 127 126 32 33 124 -103 21 50 110 -118 -97 67 29 -84 8 127 18 -28 -19 -37 -8 119 1 58 -103 -59 -34 -27 43 -43 107 -77 127 119 -96 108 33 -5 12 -62 40 46 124 125 -39 22 -19 -4 126 -53 -38 -59 5 -118 102 60 -21 124 67 -19 121 123 127 0 33 -19 0 -32 -7 -1 -72 -58 -44 -5 23 3 35 -5 31 77 11 -23 -37 -3 -22 -10 10 -41 -22 33 19 22 16 -16 -60 -24 14 8 -25 41 3 -91 20 54 -51 -40 33 -71 -94 -10 -25 -26 5 -77 39 13 38 18 22 31 -75 4 -24 -61 -7 11 39 -33 -21 20 3 0 -8 13 48 -33 60 -8 60 1 -65 -65 -60 26 18 27 16 7 -8 -17 50 24 -3 31 -32 -55 -2 -52 63 4 36 -52 -127 -35 -63 -76 32 73 31 -37 33 12 -89 -94 -57 -69 -12 50 -10 -85 11 -52 108 -44 77 -81 -2 -66 -13 -123 31 -2 -17 -9 16 -128 39 -42 -3 -117 35 127 9 123 -71 81 -26 16 79 -108 67 41 -80 2 -128 -14 -41 72 -8 -128 -41 -43 17 11 -65 -41 127 -27 -73 -64 -5 114 -126 -25 22 76 -84 49 127 101 59 -67 61 55 -51 -127 4 -17 60 -39 63 7 -19 51 109 13 90 -30 125 -28 36 13 15 -77 -13 -24 127 37 0 35 121 6 -20 39 -128 -19 -50 6 -56 -18 52 -16 -12 -13 4 51 28 -48 -18 -67 123 43 -11 -47 39 127 -23 8 30 -16 -108 12 -25 40 10 58 -6 19 52 -17 -19 37 -8 57 36 1 -3 21 -4 67 7 -119 2 40 -39 36 44 -35 -55 40 25 -12 -20 -128 18 -126 9 127 6 -14 -36 -50 -63 -16 29 -34 57 -12 62 -29 -47 -18 -42 26 25 -70 16 -8 -22 -3 -17 2 27 -78 -2 -12 -23 -11 -43 38 -126 37 65 22 37 3 -4 -17 -34 -41 25 27 -11 39 65 -72 0 -57 -34 -49 62 55 37 -1 -39 -43 101 -27 41 -69 15 -113 -19 16 -39 11 26 70 -118 48 -4 -62 17 -10 42 4 -35 -8 -99 -14 38 36 9 27 32 -66 23 -9 21 -51 5 -10 -2 -16 127 -18 -28 -89 6 -12 39 -41 -49 3 -14 38 -62 65 -7 -30 88 -47 -121 83 -47 -99 -60 -84 -38 55 -125 101 32 -48 -33 -16 45 -123 52 98 13 116 -24 46 78 -96 32 64 -27 -43 -92 10 112 -79 -26 23 4 22 -127 126 89 -92 52 42 -23 95 39 -42 9 -78 42 102 21 12 -18 1 -9 -126 -30 -54 -90 -82 -83 -62 -121 126 -77 -83 -34 -36 127 127 -8 -25 -28 -125 29 52 -128 -128 11 41 -54 117 -52 125 -77 -119 125 84 102 -63 102 61 71 -29 -89 41 40 29 79 67 46 -89 54 11 -11 -2 12 -3 12 18 65 -39 -1 -17 -70 -67 -34 -90 -48 36 52 14 12 124 -58 49 55 -7 -17 -30 20 126 23 -97 51 126 127 4 -5 55 40 127 10 75 127 56 9 0 -20 3 8 54 -50 -22 -7 47 -116 71 -22 37 -73 -11 30 30 11 16 90 127 -78 -128 13 -60 20 -128 104 26 -101 17 124 50 -21 77 -55 2 -93 -83 30 -54 -128 -23 52 -126 -46 14 -35 -34 -58 43 125 -29 1 -71 -41 126 -18 -11 103 -125 68 -12 26 -120 76 13 -77 -25 -13 -5 87 29 42 19 -39 35 -30 127 18 -6 127 54 55 3 60 6 72 -34 25 -106 78 78 -2 -42 123 -51 -98 -45 8 -15 -25 85 -34 -29 -26 -29 52 -4 14 16 127 46 101 21 -96 30 -37 63 -13 64 -50 37 -105 46 24 -102 -8 -64 61 35 57 45 108 12 -44 84 2 -2 124 -95 39 -96 -125 -91 99 14 127 82 -126 73 25 117 -127 58 3 -97 -98 79 14 -20 44 23 51 61 105 98 -125 -125 82 0 -71 110 -8 -76 26 -63 126 107 49 -70 -63 20 127 59 17 -66 -124 127 -49 13 127 -50 -57 84 -120 -14 2 -69 1 47 -12 -84 -128 -77 55 125 -97 -20 -64 99 25 -127 -122 -118 -18 -86 127 -3 74 -112 124 64 45 -91 118 -19 -96 86 86 126 -25 47 -6 30 -127 -88 16 10 -70 -18 -22 -69 -3 5 -20 108 109 0 8 -1 124 -34 43 -9 26 -86 19 95 25 15 -13 16 50 -90 14 17 -22 -20 -80 0 9 -93 -82 40 -33 16 -119 14 44 25 69 126 -62 -39 125 37 50 29 -64 -31 -3 0 41 -6 82 75 -71 -22 11 -5 78 -114 -127 21 -81 91 -20 76 -30 67 -47 70 -26 -89 52 9 -12 4 9 21 -14 -45 -43 91 -28 -41 33 -50 54 -80 -55 -121 9 -30 17 125 -57 101 -14 -43 44 18 -6 18 -80 114 15 -108 25 39 -78 -18 50 5 21 -22 47 9 -21 -64 127 -108 40 43 36 75 73 -81 -126 12 127 -8 42 -14 26 -5 0 58 27 -40 -53 -116 61 -58 -38 -42 -47 123 -59 127 24 80 -93 -28 -10 5 35 -65 58 3 116 -27 -9 -127 -127 15 -43 -68 -60 -63 -67 -82 77 -127 33 26 25 -117 -28 108 -23 61 104 45 -28 52 54 -68 -27 -58 57 125 7 1 -81 72 -66 38 126 -14 -68 39 40 99 -54 -13 -30 55 -35 -128 -111 73 20 -41 -109 -66 127 -62 -56 -36 -18 -104 -127 57 -93 126 -45 127 -70 24 10 88 81 -104 -118 -50 127 71 67 15 -125 -45 127 -38 127 -36 17 127 127 -118 64 -125 12 -66 -20 -18 -126 -125 -72 -125 -66 -52 125 18 -123 104 62 127 -121 -23 99 -65 -17 -55 -53 -120 114 50 18 -123 69 -128 127 1 -7 -109 9 -101 29 -60 9 117 -1 47 85 89 50 29 -10 -44 -15 -35 127 18 -19 125 -55 11 7 27 11 66 -71 35 -113 90 24 4 -73 13 127 15 -73 -118 -12 -5 38 93 54 41 -33 38 117 -8 -77 2 52 96 51 -60 8 97 23 109 92 20 -43 46 -57 96 5 8 0 -27 124 45 48 127 19 -45 67 127 21 -8 36 43 56 91 -65 27 16 52 10 127 -37 46 -54 -127 42 -41 -96 -4 43 127 13 -90 -106 -116 92 -13 -46 42 -49 -32 -27 6 -22 -31 -22 125 -30 30 8 -78 65 -13 -63 43 -15 -36 127 -55 -79 -99 127 -55 127 -82 56 20 38 -46 -24 -106 43 -16 -128 -54 -54 -2 104 86 -83 92 -83 30 -28 127 127 -96 -66 -33 -64 -87 -51 -65 -52 42 28 -75 -33 6 -45 10 -106 -14 100 34 126 31 -2 -67 38 106 -13 60 2 -56 -37 45 -50 -8 -55 -89 46 -23 -126 -81 31 81 117 -121 51 73 -82 88 19 -116 30 20 18 -9 2 -7 -32 -42 -113 126 -101 127 -10 87 -52 -109 -49 -50 -128 53 -20 53 -125 45 96 -14 3 -104 114 -35 -71 126 -118 -122 -9 -83 -115 53 -23 42 32 120 44 -122 -45 37 -120 -27 59 -12 -71 127 49 -45 28 -40 95 -75 8 54 28 -128 91 21 14 -98 46 -47 127 5 -127 50 -124 -43 12 26 -14 57 -100 -128 -29 -22 58 45 32 -57 107 -55 9 17 -85 48 16 29 127 94 -94 5 -103 16 7 -30 43 -7 -29 -18 -71 -33 -13 11 12 87 -45 127 8 -19 41 127 -122 20 -125 -76 -85 126 124 127 -43 89 -28 28 63 -55 -6 -3 13 -51 30 -118 43 14 -34 56 -70 3 57 -64 71 -32 -43 114 86 -27 81 1 -26 -29 59 90 -101 48 -25 -108 28 23 19 -40 -25 31 26 -94 -52 14 -47 -113 -125 29 61 -125 -36 -4 51 -59 60 107 127 -128 94 28 86 35 -44 -26 24 23 119 33 64 -47 67 -6 -120 -79 64 6 120 100 0 -127 65 127 76 57 -127 -37 127 -2 51 -122 43 51 -45 4 44 15 84 -17 -39 -115 -15 -126 43 -23 -117 12 -33 88 4 74 -112 -35 -13 -84 -68 -122 71 -19 25 -85 91 -126 -67 81 18 -9 -19 90 73 70 -89 119 -29 -86 126 27 50 53 -110 103 -28 117 -88 19 -10 124 116 -128 -121 127 -6 46 -36 -121 62 113 110 -58 -104 -12 -17 19 -104 127 98 -56 17 -91 87 -122 73 -79 84 -102 -116 30 -23 -59 -51 -7 -30 123 -1 -15 -128 39 117 -22 -34 123 -1 126 -75 -85 -80 78 85 -51 14 -50 2 16 48 -118 -2 -68 27 124 0 -73 4 -50 -56 29 46 22 -13 70 -45 -110 -50 -26 -56 -77 107 101 53 -123 -66 97 127 -53 94 18 -121 16 3 110 17 -126 108 -33 -127 -61 -18 -15 48 -6 -22 127 2 68 12 21 -71 29 -6 -4 -127 50 66 -5 -67 48 -15 -2 -48 122 0 -13 11 1 -6 -55 -41 -19 107 74 -118 49 93 -30 -41 41 -125 51 -55 24 -126 -58 -78 -41 56 -37 22 -22 127 -58 -11 -14 127 -3 127 1 -26 -43 84 -111 64 -123 13 27 -74 -70 75 -127 -17 26 -78 7 9 32 -35 58 85 -9 65 -56 -127 53 -128 -26 -16 99 118 36 -62 97 15 -31 22 14 7 -29 -25 -43 -40 -48 -47 20 -34 -4 -50 22 -53 -11 8 -36 -42 -37 -32 -56 11 7 20 -7 -9 -5 -68 13 66 25 -15 -23 34 -8 13 -13 -56 -43 -30 -29 3 2 -18 -64 -27 89 112 -40 10 -26 -34 -45 -37 -26 -2 44 -65 -67 19 -53 -16 -33 -1 -17 70 -74 -27 -33 -72 -12 -60 -34 -11 -33 -123 25 -15 11 -42 -34 -33 28 23 -32 -35 -70 -13 -7 0 64 47 58 -81 -49 50 -49 -4 72 30 -3 51 -12 -57 -49 11 -38 14 30 -21 -128 42 6 77 -79 -57 -61 13 -34 3 -21 35 14 -37 -5 19 -87 58 -29 -13 -59 -23 88 44 13 -56 20 23 24 -10 -10 78 -3 -17 -2 -112 -6 6 36 40 -31 6 6 -28 17 -35 -72 127 -28 -121 -62 -46 80 -50 -60 97 49 -78 55 -14 120 38 -60 38 3 -25 -44 -45 37 11 -8 -8 -35 54 10 61 7 64 -18 65 4 35 -49 -25 -32 22 59 4 -17 25 8 -10 17 11 -13 9 75 -27 13 7 -29 112 -13 0 -15 -21 -12 11 -29 -20 33 -3 -47 -6 -18 74 -5 -4 -17 -67 -22 1 53 -4 1 5 40 14 39 -41 -120 56 3 -8 1 15 -2 23 3 -33 62 42 -33 -42 71 9 37 50 -5 18 11 107 -25 -64 -61 3 29 -49 76 -19 -15 -18 -22 -39 -1 19 -14 56 5 91 -43 43 15 -23 125 -47 -64 -2 -6 -26 -105 81 93 -56 82 -69 -47 -40 46 -35 72 73 -8 -1 4 120 -51 101 -34 12 54 5 19 -123 53 87 29 58 15 24 -126 72 3 52 -50 -7 12 28 -42 1 34 35 -99 -7 105 6 27 -109 -19 -74 -34 -10 -57 -34 -10 89 -6 -31 34 -91 59 -17 -33 60 -28 8 -16 7 -22 -39 -49 -56 -3 67 -8 -94 -22 -18 -10 -2 -20 -27 -103 3 -76 11 22 71 47 51 -95 30 -3 -128 126 3 -79 -13 28 -65 24 -117 49 86 9 8 52 119 -126 -10 77 -33 34 -70 11 16 71 39 -107 24 45 -107 -49 -2 -21 -3 17 8 23 -10 95 58 -30 14 21 12 -18 -43 -30 -8 -2 20 30 53 50 -117 -13 -36 -112 -96 2 25 -35 -78 -8 -58 64 -50 34 22 71 103 99 93 -48 -49 59 34 -31 -34 -48 14 56 -117 -38 -3 -10 -39 -25 -16 26 92 -10 82 8 8 -99 -30 25 -7 -31 2 28 63 12 -126 -18 23 20 2 -15 7 -69 -37 19 -44 -18 -125 10 -116 -73 -37 2 -11 -61 -95 -44 -65 -42 -32 -24 30 -53 68 19 13 -28 23 49 -42 -91 1 -30 46 86 -2 127 1 93 123 -5 -117 -4 -14 14 -26 -104 2 34 -15 70 48 17 -26 11 13 -22 -33 37 80 95 43 -48 13 101 37 -77 -13 -4 -18 23 -7 14 83 116 -19 -22 -27 97 -30 34 33 -20 52 -56 52 -6 31 -11 -123 -65 61 10 -47 10 43 71 -22 14 24 70 17 72 -41 19 -23 46 67 22 85 23 -62 69 -65 -19 80 14 2 121 -75 52 84 -30 -42 12 -71 88 58 -6 54 11 14 -58 1 -47 39 10 48 6 -8 89 -8 -67 -36 -67 -5 -62 -43 -16 22 -37 0 22 1 63 -55 -125 -38 51 -69 -23 -68 -47 68 -2 -20 -31 -36 47 -9 -39 26 -96 -22 -89 -68 -23 33 -1 97 -24 113 -50 -62 -22 58 -2 -20 52 -41 -2 -70 1 -81 18 22 15 36 -96 -34 16 -55 51 20 50 43 10 -78 80 41 3 27 -6 127 -2 -19 2 96 51 100 -25 -34 1 3 48 9 -64 -73 35 14 -4 26 58 -44 49 -20 121 58 -80 -7 51 25 -63 -95 44 5 -60 -23 -31 44 29 -20 -47 -42 -2 60 -112 73 -1 32 -17 124 40 -1 46 46 -42 -37 61 30 68 -117 -43 6 -28 -96 7 -34 81 2 -6 -73 41 67 27 13 70 41 44 27 89 20 -6 81 4 58 -20 -26 75 48 32 34 34 -19 -66 31 -38 -25 29 -31 30 32 14 -59 -5 -115 1 40 -3 7 20 0 38 -42 -60 89 -34 63 -36 7 -5 -1 0 32 49 51 48 3 -4 56 58 89 13 -111 34 13 19 -101 84 -78 17 62 112 -36 -28 66 9 -3 -19 37 -56 -61 -28 -33 17 31 -1 127 6 -44 -92 -40 -19 -90 44 -41 22 99 13 41 -125 -58 58 -4 -84 -35 70 -1 -82 -28 -25 38 71 40 108 -39 -88 34 67 -69 69 -60 127 118 -1 61 8 60 -98 -106 -55 -5 7 25 45 15 -34 29 80 -103 -16 56 -37 -123 -77 114 -20 14 -19 46 -52 31 -13 0 16 -81 -57 43 -28 32 -114 -84 -16 -3 -79 -24 109 -15 50 1 -32 -17 -116 -87 -42 -9 -102 121 -6 25 55 20 44 126 31 7 62 31 45 -96 -71 -9 87 -45 107 -32 -9 -54 -62 -5 113 -1 -2 -9 21 -58 -49 43 38 -33 -128 13 -43 56 -96 -89 -65 -4 -40 4 -67 23 -12 -85 -33 -79 73 -109 -50 35 10 52 14 -1 63 -79 68 38 62 55 4 -85 -42 42 -68 40 24 23 16 122 20 29 -64 111 -26 10 46 -123 75 -24 10 -104 19 -41 -15 -27 -67 39 85 -7 25 22 -3 -31 17 9 -32 50 52 -101 1 43 -9 102 -12 35 0 -59 -61 15 -15 65 -33 58 82 -11 125 32 -10 -57 -7 -104 3 39 -69 -32 -27 18 57 10 16 47 -41 67 127 2 0 44 23 -5 40 107 -103 23 -14 -77 35 26 7 -14 38 -19 -13 22 -92 -13 -1 75 125 20 -6 18 -6 96 37 16 6 -70 63 83 -8 46 20 32 -44 -126 47 -54 -3 64 33 93 101 -127 20 31 -43 1 85 -57 -8 37 -28 -123 64 18 -46 -125 123 7 -16 103 70 -65 51 -5 10 50 -27 -66 -51 -48 121 -13 125 -30 93 -54 49 -72 -3 10 -76 101 5 -78 43 105 124 2 -17 114 -2 -44 -33 88 -38 126 -112 -4 -62 -25 -128 -10 -89 63 63 -51 125 -40 126 -33 56 -48 -77 -70 -43 -105 44 12 -60 16 -45 -13 60 -16 3 -84 33 -24 -25 -8 -17 -95 14 13 -12 -116 30 18 23 -107 -128 67 -21 -102 97 34 -49 26 -107 -106 121 94 -66 54 -101 33 -4 6 14 27 -92 -43 68 -35 -6 39 -113 15 31 109 -5 24 15 -20 13 20 121 -57 77 -53 -26 -48 -66 -86 -14 -13 -46 -77 51 -4 40 126 -31 72 14 82 4 -61 81 -2 -63 -19 -77 -101 39 52 -97 11 7 -119 -126 -37 -13 -79 -39 74 -7 -68 119 53 91 14 0 87 -33 37 -11 -4 -41 25 -68 -2 -7 11 21 122 14 -84 20 59 -62 -58 -10 86 14 -119 -78 -4 -33 74 29 123 -51 -29 86 -24 -6 127 94 -1 -17 52 17 30 -81 20 -68 -37 -6 -33 -28 -65 18 -4 13 -3 -39 -64 -12 27 105 65 56 9 53 -70 40 -49 -121 43 54 74 -78 -11 -43 -10 38 -52 0 -30 -57 -40 -18 -12 -60 3 -17 -35 -82 -4 -9 6 -4 41 24 -33 -4 29 -30 49 -16 116 117 -7 -5 -32 -122 -8 -46 -15 9 2 -38 -4 75 -8 -37 0 -2 57 82 -11 -69 79 -75 40 -32 -31 -22 70 44 16 -82 31 -46 -98 69 127 -111 -42 -16 -46 -80 22 -47 70 62 -50 -56 56 45 109 52 -94 -47 90 75 25 9 -40 -9 42 14 -82 8 21 -27 -50 -110 -3 -28 -72 -56 -81 85 -86 -66 27 2 9 40 -28 -60 -7 30 -34 -5 71 51 -2 -121 117 -8 19 42 -20 -64 31 -3 -68 34 -68 31 121 13 -83 -32 -92 -40 -31 -12 71 -26 -90 37 -121 -28 80 3 -19 -21 44 -59 7 -19 25 13 -7 -6 102 22 8 25 -16 -48 30 -52 -16 63 -10 6 66 -26 -69 -76 53 -40 4 111 -44 -64 -17 22 -34 69 -26 59 9 1 -118 29 40 -57 -105 7 -25 69 -19 -43 -67 -29 28 -57 3 -25 -31 -64 8 113 -13 -44 40 83 -107 -36 -21 -41 1 -43 124 -67 -10 127 -82 -55 -62 -99 -69 24 80 6 16 10 104 -46 47 33 -47 -16 -13 11 -78 -4 -102 5 51 -54 17 -23 -67 -5 49 95 -13 -60 24 -3 71 -11 -1 54 -30 20 2 6 126 -20 -10 1 65 -14 -64 9 -5 59 -13 11 67 -70 -78 -47 29 22 -59 -53 29 57 -18 12 -55 47 -4 -57 -16 -19 -7 -95 -51 -124 38 -45 26 28 9 4 81 124 -17 35 7 26 39 71 14 -42 51 51 -30 -27 -124 -82 -47 -7 -109 7 6 -9 23 29 27 -25 14 28 16 -97 -128 13 53 62 74 -9 -16 4 65 -117 23 68 -128 -36 4 42 43 -10 -128 -78 7 -125 -124 -31 -34 126 -67 53 13 -59 -100 122 -104 -125 -85 23 -49 30 -119 -1 -11 93 23 39 -85 -27 101 -128 -42 -127 -29 -44 -30 -34 57 43 -22 -69 -102 2 -47 18 -104 -42 48 -79 -127 -126 18 -77 30 -16 16 124 25 -38 -61 -86 -119 -25 60 -105 51 122 15 -25 -61 57 -62 15 76 33 -1 -124 5 -65 52 -45 -127 -124 126 -128 -17 79 -124 -125 79 -73 -11 19 48 -83 -69 34 123 81 45 19 -90 -73 -93 -127 -125 -64 36 4 11 -102 -79 38 -120 67 -32 77 34 4 23 107 -126 -118 31 58 24 -89 50 -18 0 -71 5 127 -119 89 -42 -36 86 50 127 -5 -87 90 -56 -63 112 83 34 68 -83 22 -3 -32 21 -40 -81 -84 -12 -65 -127 -127 58 -44 21 36 53 -71 -15 61 84 -109 24 23 60 -114 -124 127 37 88 -67 126 -68 -23 -110 45 -5 37 117 -51 127 31 -21 30 -127 -50 14 49 -128 -12 11 57 -41 25 -27 -16 -90 15 -8 -127 100 19 -58 15 52 -20 -44 44 -18 32 -100 -41 -47 79 10 33 -13 -11 -40 -106 82 39 3 -12 -2 -23 7 25 -56 -23 6 50 -71 67 -12 -33 -42 -36 -16 -16 76 -79 38 49 77 -20 -23 28 88 50 18 106 -4 -36 25 -76 -87 -116 27 -100 17 -21 18 -26 -7 17 35 -126 -49 106 58 -45 -31 -12 -33 85 5 90 25 93 -128 40 -11 -64 -93 36 5 73 -22 7 -22 -14 -126 37 -99 -123 -73 -3 -9 67 -89 -13 107 45 46 -4 -55 48 -99 -97 -18 126 104 -109 -8 61 122 74 -119 -126 -32 -44 32 -101 -128 20 2 22 -126 -31 -27 -66 107 11 80 124 74 -11 -24 -94 37 -73 81 -74 58 126 12 -8 -13 -55 -117 78 69 51 115 -63 18 14 4 70 -12 127 97 -127 114 64 -72 -112 43 105 73 -41 65 -33 -90 15 127 56 -25 25 -47 -33 17 -92 -41 -113 5 32 62 93 -58 22 -15 127 14 -2 108 -18 106 52 -40 48 -39 30 125 -59 96 -85 101 -42 24 -33 -126 127 -48 -26 23 1 116 -11 -5 8 -128 39 8 78 21 -43 -20 14 -5 -27 45 -16 -128 61 -9 -44 -96 -127 72 16 -63 -21 11 -12 -8 -66 114 52 -57 64 -45 61 -38 -20 -2 -7 10 127 -60 -75 5 66 34 -27 -24 24 75 28 -55 72 -127 88 11 118 -46 62 4 84 -20 21 45 33 -49 -40 125 -127 40 -8 -56 -2 127 33 24 -7 64 32 -124 53 -19 79 -7 -82 15 -102 10 -50 56 90 -30 -19 -40 102 12 32 -125 -24 9 -19 -10 76 28 -15 70 21 5 -23 1 16 13 35 -104 12 15 -51 26 28 -14 34 -62 0 -108 80 19 -4 -52 -52 42 75 -25 -6 28 -125 -22 -127 -24 79 3 -108 -104 17 127 6 59 59 126 -31 119 -58 41 69 -48 66 -35 -76 113 28 -106 80 -87 -118 -46 126 108 55 127 -67 53 39 -21 63 63 -48 14 -19 -120 117 103 120 21 -121 -82 127 3 70 3 12 18 127 9 -117 -25 69 -33 85 89 127 61 -119 -26 122 116 59 26 126 -41 33 117 -126 113 125 -6 68 -126 95 -45 -44 -3 84 8 -112 39 126 -58 70 -127 28 127 127 -23 95 127 110 -42 -7 -34 64 -21 -36 -39 -27 -56 -52 127 -91 -94 33 126 73 110 68 -51 -127 -71 44 -51 64 37 59 85 70 -23 -2 36 -38 -6 -57 127 127 -29 -58 117 -13 -16 -16 127 15 29 -84 -55 117 -34 -124 -101 32 -113 -102 -125 -12 -128 112 -46 -127 -114 -41 38 -114 67 -17 40 127 -128 126 -89 118 57 63 -65 102 -57 -118 26 68 -69 -126 -121 84 -61 105 -66 87 124 -127 -13 108 -11 -60 -127 -41 126 126 1 -107 -126 20 -127 -121 127 48 -128 -53 124 -74 -45 51 89 46 121 -2 126 -41 -40 17 127 30 -23 -18 126 -14 3 31 -45 37 -13 -49 -22 -106 76 33 -4 -74 -60 -98 20 121 -17 56 -47 -1 -73 35 17 -10 -128 -92 11 -126 33 8 -88 -85 11 126 -44 79 -42 31 -42 -20 -94 -46 -54 -66 4 -25 9 85 38 58 -44 29 -53 85 49 77 74 63 7 45 -65 -125 -124 -58 125 -126 37 -128 24 109 20 -80 2 13 67 -124 71 -41 117 46 -120 -15 -62 41 -67 -9 1 127 104 15 35 27 17 -54 -30 -88 93 -62 -116 -26 84 74 123 91 34 -2 119 -128 -22 75 60 127 64 78 39 -23 -128 122 -59 -21 80 -56 17 -8 -4 52 89 -103 -95 94 -93 19 -8 6 50 99 49 -34 124 76 -96 -84 -122 8 50 125 -1 65 59 81 -123 -128 -14 39 52 12 10 -3 32 91 66 29 -119 -93 52 -123 -15 -98 30 74 -126 -12 127 107 -45 -15 49 -31 47 -21 29 -116 7 -40 18 -105 54 56 -127 79 23 28 -93 -41 44 -48 -3 57 -15 66 -35 47 -81 127 -35 -61 -30 127 -21 -128 -3 32 13 1 43 75 -85 49 82 -56 125 -84 34 126 4 -27 -28 8 -16 127 76 -32 10 92 -66 126 27 33 40 -10 -19 -63 10 126 -117 19 27 -14 20 -90 -58 36 -42 -2 56 -18 -33 -28 -124 127 42 -61 -62 22 -16 45 8 -108 -128 -123 89 -127 27 104 49 -46 48 -26 -61 -1 65 37 -59 -58 -18 95 11 8 -126 1 16 -47 -35 -16 18 -2 -2 18 -126 35 -3 45 -22 124 66 -9 -3 -113 -28 22 -109 35 -127 0 -10 -3 29 87 -67 23 -23 33 -35 -22 -1 112 29 30 59 10 -61 24 85 -43 -68 56 -3 0 42 -44 44 55 -30 -127 77 -29 -29 38 123 6 -6 127 18 -128 -1 -17 78 64 -57 118 -63 -82 -53 49 58 -14 33 85 -106 126 112 -16 -8 51 -111 126 24 76 -2 -112 -75 107 -128 -70 11 -127 -92 50 -56 -34 118 5 -66 6 108 -4 97 111 -17 120 -41 124 0 -62 21 112 -24 -125 126 -69 -29 -29 75 95 -38 -18 42 27 -78 -38 81 -39 54 -96 69 -44 -6 -105 15 -24 -47 -115 -4 -120 -40 30 -21 -104 37 -128 -122 116 125 -3 96 8 -33 27 -46 54 27 -61 -10 -32 -78 -103 0 -80 -101 30 127 65 -9 17 37 8 -127 65 -128 -89 -37 29 -31 -23 47 -8 -107 -38 -41 74 74 8 12 -13 53 -124 -101 71 -5 -14 -58 27 -94 -72 -16 57 -8 -123 5 -44 -7 -41 -8 127 -53 -27 109 23 34 -4 -44 3 22 28 -59 21 -58 -4 119 -96 31 1 -73 115 86 17 63 14 -9 70 -74 79 126 17 -39 -127 -25 -50 -88 -16 -2 -58 80 -75 108 -44 -2 2 -61 16 111 -128 -5 81 -28 -41 -71 29 60 -126 -31 -4 -67 -3 14 49 11 -42 21 -42 -120 -56 -14 -89 -86 -90 -91 -33 -106 48 41 47 10 -26 -30 16 -124 25 -13 9 12 -37 30 -14 99 78 -16 52 101 39 -27 -88 -48 9 63 124 47 -2 7 21 35 -101 39 -7 -17 -15 -66 -16 -83 -74 -35 20 80 -86 35 9 -105 9 19 1 -4 -124 -96 103 120 18 -71 9 -81 125 0 -64 -128 -66 92 -119 51 112 74 -71 42 124 123 -1 -52 -3 91 95 47 -107 122 45 -121 43 127 62 14 27 -24 37 100 57 59 -9 2 -58 -27 53 83 39 86 59 117 32 -69 -24 -13 26 125 -11 -4 -99 57 126 -4 -80 81 64 -22 20 -4 92 -3 5 -121 -68 -43 -15 3 126 -5 -22 -19 80 22 12 12 -67 55 -87 -54 43 -102 49 -8 -43 -84 111 -41 76 67 -34 -6 -19 28 -36 -60 106 59 -125 54 -4 49 -27 -52 -119 -24 24 127 -15 9 -82 -63 83 -67 44 -45 -25 -35 -74 37 15 115 42 -97 -1 31 -19 -91 -55 46 -66 -12 -73 -49 -57 21 51 -43 -27 58 16 54 72 -7 -85 8 43 117 49 -25 -27 -128 -10 41 -79 127 -31 20 -57 -30 -99 -31 82 77 84 119 43 -14 -43 -128 -9 -54 -21 -53 -31 -54 35 53 125 58 90 40 126 26 -2 50 -2 33 45 -12 29 68 -112 37 102 24 67 -127 21 -41 16 71 -37 49 16 -21 -112 83 126 -127 34 -93 -27 -1 24 32 46 88 -50 -76 -10 -64 -16 75 -1 -34 -59 -6 31 121 -15 88 -63 -86 -11 -37 107 33 116 -48 -57 21 -126 87 23 18 -16 -82 11 -4 37 59 -73 -22 60 -34 62 -49 24 -43 17 -18 -84 -21 -19 -11 -98 -126 -2 30 -43 76 -6 49 25 67 103 -20 126 58 113 88 11 95 -95 57 101 36 5 -5 -3 5 64 39 19 -27 47 33 124 2 -25 -1 -49 -2 -28 5 -56 17 -27 -50 7 -21 13 34 29 26 24 19 14 -18 -7 -29 13 -16 23 13 5 38 5 21 1 -3 74 -17 125 39 41 1 -14 -11 21 26 26 9 37 -17 -15 -71 73 8 -22 -30 50 30 -48 4 11 -4 17 -10 -14 68 5 72 -16 45 -83 21 -8 -11 -16 10 21 15 31 13 44 -2 25 17 89 -5 22 27 -32 5 48 -7 98 -11 -13 -42 40 -70 -6 121 32 25 -53 -53 4 41 15 -12 -9 -17 16 -3 28 22 46 -11 52 -32 -4 1 -47 -16 -22 9 48 -23 -43 -18 17 -95 0 -29 17 -44 60 -54 104 -32 48 22 10 -16 55 -74 33 -1 -37 123 3 -41 12 -34 -35 11 -18 18 -9 5 13 -14 6 37 15 0 69 35 -9 2 -12 7 17 50 -6 -8 -16 -22 7 -26 -30 1 -7 48 -58 3 14 2 -18 8 53 -18 21 -12 -16 16 9 16 -22 -30 13 -18 -30 4 -26 -17 15 26 6 25 15 -8 -33 6 -59 79 -17 47 -4 1 3 1 -7 15 0 6 -8 -95 -9 -10 60 2 -19 -1 8 -17 -17 -77 -5 1 26 -62 -10 -5 -10 9 4 18 -1 -9 3 -14 30 -4 2 -20 -9 -37 1 80 27 40 -6 -9 -38 -32 4 24 11 3 3 -15 17 54 -81 0 6 22 -44 -12 16 16 48 -22 -22 -25 -24 59 50 55 -27 1 -14 -73 1 10 -12 -26 13 -21 -12 26 -81 31 60 -13 -59 -3 -80 5 -11 3 28 -9 39 -73 -26 -23 40 2 -2 5 6 15 -26 5 1 16 -5 9 12 -13 22 53 -6 1 -13 68 -45 2 -41 13 -18 54 27 -64 -16 14 -26 -6 -22 -45 2 -44 -6 -12 20 9 -3 -23 43 4 1 -8 31 -9 46 -6 -13 -23 20 4 -90 -30 54 -36 11 -21 31 7 -10 8 -16 -19 19 -11 -16 88 124 -11 22 -9 -23 -3 55 -24 22 -127 28 9 31 -44 -15 -4 61 7 -13 79 -41 31 -12 -22 45 7 -9 -16 -35 -34 -34 101 11 47 -29 24 -7 -67 97 52 12 18 3 -16 -1 -54 1 -46 -74 -35 -48 20 12 25 32 -46 -19 43 12 -26 -3 -19 11 126 42 -13 50 -7 -62 13 -127 15 -3 -128 -69 -8 -4 25 -19 -22 17 56 -98 -42 -7 -19 18 -3 -16 2 -1 -5 23 -24 2 -47 -2 1 -43 11 41 7 9 -26 8 -126 0 15 -13 43 -10 38 -22 14 27 -17 -40 16 25 78 -10 7 -2 -13 -15 2 25 35 -6 -9 -47 -1 29 -32 12 -3 -6 -24 16 7 3 -96 -78 -9 3 4 -9 -18 6 15 -1 -77 2 -3 0 -2 -20 21 -1 19 -30 -8 -2 -7 -57 21 0 -21 19 -23 -5 27 39 -15 -28 -10 -4 2 21 -1 4 6 -10 83 36 6 48 -72 76 19 -45 82 52 -64 32 1 -34 109 55 -33 -54 -104 -30 -45 -127 50 126 -50 41 62 69 125 -75 22 41 -19 126 15 5 105 65 -39 77 127 11 -7 33 74 -59 -24 -18 47 70 30 17 118 20 16 126 35 39 -3 127 122 -15 37 15 -26 76 6 -97 32 -44 -59 125 42 -22 124 35 32 -2 67 45 -125 19 46 4 108 47 -47 -128 65 121 48 52 120 37 41 -28 -28 123 30 6 31 -11 -95 -82 35 -1 79 23 -33 40 65 24 -42 -58 25 -74 13 -31 -74 119 -94 44 23 -123 50 102 38 65 -5 36 -40 -17 -56 14 -126 -67 83 59 -23 21 15 -2 46 8 -22 39 2 -1 29 -112 74 44 111 5 20 77 111 3 46 -47 28 -8 11 -62 2 -53 -61 -92 -42 -107 48 32 -75 101 32 20 58 62 -18 5 57 38 116 42 19 -74 -43 23 58 11 11 35 34 -105 8 -64 -123 -12 43 63 63 -110 20 22 -5 127 -124 -28 47 -19 125 -25 -91 -15 -9 -21 27 23 50 -70 21 -14 70 -90 10 88 -4 7 -107 -115 -33 25 -19 -16 -22 62 -31 1 -77 -42 35 -29 -2 6 125 -70 -52 20 18 -45 5 -2 -74 59 8 -2 4 40 -54 -35 -19 34 79 -126 -12 -105 -40 15 120 32 20 -9 -120 7 30 -78 72 -42 91 -59 28 11 1 38 36 109 -40 -81 -26 -98 -77 -68 64 30 -67 -57 17 -84 -127 -10 -62 11 10 54 -43 24 -27 -87 -43 18 -99 30 -43 -73 15 -31 40 4 -47 -90 -81 -98 -45 -83 14 120 -35 -79 32 47 5 6 -124 45 -17 -99 -84 -126 -96 31 43 -53 -25 81 -112 -124 -46 -90 -127 18 -105 74 -45 -50 116 -34 -127 -41 12 -127 24 27 -40 -51 -60 114 47 -17 -98 -58 -63 -73 6 -55 -96 4 -19 -127 -123 62 -103 28 25 13 -11 -7 -80 99 32 17 -42 -42 20 10 1 43 47 90 -38 29 74 86 4 -118 43 -52 -41 -17 13 24 -126 13 15 -45 11 21 95 -26 1 -100 -26 37 -67 23 -23 -25 26 16 -69 3 87 -16 -25 -21 14 64 -72 -74 -84 -14 -78 -100 31 -10 -68 21 61 125 -16 0 -17 -33 -24 -76 -59 -10 51 2 -25 -59 28 8 -28 11 0 125 -57 -19 30 -71 -52 -31 17 -29 -22 -44 -15 46 24 13 126 5 11 -72 67 91 8 -49 -5 11 -12 23 -31 103 -52 92 -56 14 26 6 17 -42 -2 -39 48 -31 -84 -13 -36 30 -42 -26 13 28 -7 -42 58 -51 -16 17 12 -38 15 20 4 -18 -50 41 -16 -118 -92 -53 -127 58 -47 19 -24 73 -19 61 37 82 73 91 21 36 24 -28 9 98 -10 37 -33 -63 21 -77 7 18 41 53 -22 56 108 30 12 -72 84 78 75 73 101 47 26 -21 -101 91 -20 -99 -78 8 -110 52 -42 102 120 30 98 66 -30 -7 -91 63 18 -15 13 -30 42 -59 20 87 5 79 -42 106 -24 86 91 15 92 48 71 76 -14 69 -72 -6 13 32 -90 75 -52 61 6 -35 -1 113 10 7 -17 -72 -20 -58 -20 -30 -26 -26 47 -30 69 79 53 8 98 13 42 -26 22 35 42 -13 66 -35 -1 78 100 -59 31 -53 -18 97 -15 60 -83 59 30 -33 24 45 41 24 82 96 -21 -34 -21 21 85 52 121 -35 20 -52 40 105 -62 47 73 38 21 0 88 -50 17 -72 -81 -9 -49 -22 -83 -10 -4 17 0 -55 32 47 25 21 -29 126 -2 -13 96 49 -43 -46 -92 22 57 -36 -2 -32 25 -16 2 -83 -94 78 -31 11 -85 34 -53 14 -30 35 10 -54 -39 -20 59 57 -35 13 -122 68 -52 -46 -79 -14 -22 37 21 93 -15 70 44 54 -46 32 29 92 32 -84 51 -7 77 67 41 -110 -122 28 33 -7 22 42 5 60 20 4 -8 7 30 17 20 112 86 17 64 -127 -60 -49 -37 18 37 9 -109 53 41 29 -127 -14 16 -44 -49 -20 -26 106 7 -55 -11 -28 6 -36 118 -30 74 -9 -30 -69 -44 -79 -25 90 51 -90 111 17 -34 42 -31 54 -26 -125 22 -38 -31 40 89 93 -19 -55 -4 51 -45 77 -33 35 0 -7 -9 6 67 -46 76 5 10 -127 -13 -19 59 -38 34 31 41 57 -46 69 23 35 60 23 -39 16 13 18 68 93 3 40 23 11 41 -55 118 -9 87 -27 -17 59 39 49 125 19 9 -7 31 42 -27 21 3 -8 -94 109 -8 19 46 113 14 -3 17 45 -19 118 67 19 9 -35 86 -26 -27 -11 10 46 38 -28 20 2 -56 82 18 38 -21 21 -33 7 -3 75 17 -21 78 18 56 -75 96 10 -47 41 -23 2 -3 127 -17 23 9 84 44 -1 21 127 -70 -18 4 -40 -17 85 -32 -7 7 86 23 61 -2 -44 72 6 -38 -10 63 42 -12 -52 -31 46 24 44 38 26 -25 19 26 -73 33 24 -26 -26 20 14 6 -17 -24 9 -12 -26 -18 -18 -5 12 -33 -2 -40 -16 53 -65 0 4 25 24 -15 -13 -26 -61 17 46 71 6 -18 9 -53 -64 25 -56 -67 -46 -13 -12 -19 118 50 -27 -16 -86 48 -49 -31 -36 31 28 -33 -90 -20 -10 9 38 66 -4 -16 6 19 30 30 -55 19 -3 19 25 -11 12 -64 46 -22 -31 -14 -16 -84 21 -27 -15 -16 67 -35 48 60 50 -2 -12 -38 -33 15 68 -43 43 -32 -34 -24 25 -30 0 -51 3 30 -2 43 6 54 22 -44 -56 42 -36 -63 11 -30 14 -39 -33 -28 -44 35 21 -39 5 -28 -65 25 26 50 -76 -1 -19 -1 1 57 24 -30 -15 -3 61 51 -17 50 33 37 -33 -44 2 47 -22 33 -23 -10 -22 -70 -24 114 -20 59 -39 1 -53 20 39 55 66 -108 -56 69 -96 -95 -116 53 55 15 -13 54 -42 0 56 29 -47 -52 -72 46 103 -126 115 84 -12 19 -123 2 -98 -84 28 36 -97 -17 -22 95 -60 37 -45 -14 -35 -42 -11 -59 -96 16 42 -3 78 -17 24 -124 -124 25 -113 -127 -61 85 -32 -66 -79 -54 -38 -68 10 20 -32 -4 -59 -101 53 97 -127 -15 -34 -112 -67 -79 -32 -41 -93 -117 -52 -64 61 -102 -19 -7 1 13 113 -15 -30 -12 29 68 -28 101 71 -47 24 -60 -76 -70 62 -45 21 -12 -2 -34 101 30 -120 -65 -4 32 123 -118 40 -47 42 -75 -43 -19 19 5 3 36 -76 25 0 -80 56 11 -47 -3 -54 117 103 1 -11 -57 -58 8 -21 -15 0 53 36 12 -61 -128 27 11 4 -42 -101 -62 -37 4 70 26 2 82 2 70 18 -36 21 18 -97 28 -69 -13 64 20 -19 -24 -9 -8 -7 -5 2 -8 12 17 -64 -73 -45 -32 -40 48 -59 31 -115 -78 -40 -39 -59 -3 -56 25 31 -42 -51 42 -81 -31 115 78 35 -126 -5 -72 -125 51 -104 52 -78 42 30 38 -70 48 -47 -50 -71 127 -60 -61 -45 -82 11 75 -23 -22 -47 19 -124 -1 -81 47 20 5 15 8 -59 -128 -23 -100 -23 -6 21 -34 -24 11 62 12 36 55 -23 127 -9 37 -26 -42 1 69 -86 58 -52 69 123 -54 11 64 -86 -92 -104 25 -47 -63 102 69 -56 109 39 -19 -119 38 -5 -38 -40 60 -127 -119 -22 51 -25 -59 71 57 24 -48 76 127 -51 -27 19 -10 -2 -121 -110 -92 -77 -71 50 115 37 12 44 9 23 80 45 25 -3 -80 -52 42 -63 -89 35 -58 -54 -39 -65 -126 56 -118 60 98 -70 15 119 -107 68 68 -77 15 96 -9 -89 28 7 111 -14 31 -10 73 -3 95 -77 37 24 19 -126 -24 -18 -35 -22 32 -11 26 85 -1 -58 11 40 -71 11 16 43 -11 55 18 41 -54 -37 8 -39 -99 -13 23 -114 23 -28 55 -31 -24 -8 64 -41 5 63 -5 6 -50 -64 13 25 -74 23 6 -75 56 110 -29 8 -12 27 -39 20 117 32 127 3 68 -83 25 44 45 -28 2 -13 14 0 -38 0 51 12 85 -38 6 5 -8 24 32 68 -48 -21 -27 7 8 87 38 10 30 2 -20 -37 9 -52 51 33 59 27 -19 -99 98 -99 -92 -3 4 40 75 19 30 55 7 -44 -27 -46 15 -93 -114 31 -24 -98 1 -49 -82 86 -49 72 -8 8 69 49 -27 4 -35 89 -49 89 62 -12 3 27 -45 126 -33 19 122 -92 -2 106 15 31 -34 64 -21 -56 -51 -5 -25 127 -36 66 -68 -58 -9 125 -50 -73 6 -7 116 53 127 21 14 49 30 16 33 -111 6 -16 -14 89 115 18 73 -64 -78 29 72 126 -75 94 44 -57 105 66 26 -33 -36 -27 -110 42 -69 -74 -23 93 -6 54 -67 -36 43 14 -76 26 -39 88 103 65 -6 -36 -25 -2 37 15 124 40 -38 1 109 125 -60 79 -23 90 123 -32 -117 -128 4 -111 21 0 34 42 -118 -118 -12 -47 22 33 -19 15 65 64 -22 -90 85 -109 77 -127 -10 124 -76 -123 126 -19 -21 117 -128 -116 -14 51 75 -88 108 127 -63 91 -86 39 -87 -118 0 -45 34 119 -83 -52 117 22 46 16 -49 41 37 -66 -52 -128 1 -58 4 -87 55 27 -27 -35 -99 42 -2 65 51 20 104 69 53 114 44 51 97 -9 -39 14 -4 125 -32 126 -36 43 127 -6 9 -71 93 -36 36 6 109 13 34 -16 -21 65 110 -22 25 -7 115 -71 40 6 121 -15 60 108 78 -105 -59 -35 76 13 -33 -3 86 -80 -12 -27 23 78 -65 -48 43 -128 -67 -123 89 -35 -15 97 18 52 -122 26 -127 -8 -21 49 -127 -27 -127 -17 -11 41 -123 -54 -36 -38 -1 -55 12 -21 7 24 -4 -18 16 12 -54 127 40 -13 50 -14 41 73 -82 -107 58 9 -54 44 81 -66 9 -63 -30 -40 -98 -9 -8 -29 39 -36 -84 -7 25 22 7 60 -22 25 -7 51 2 21 118 -49 26 -88 127 -81 -15 -16 3 -97 -98 23 -73 -72 -78 65 -102 62 10 10 -18 -7 14 -128 -54 -123 -125 104 31 114 75 -45 -25 -3 -22 32 -5 -11 96 -68 -38 7 -70 -72 74 -116 -13 -32 -14 -14 94 67 -34 -124 76 -13 -73 5 5 64 -61 100 1 -67 -22 42 40 50 -83 -4 32 35 127 -25 -40 -85 -53 11 -72 5 -80 10 -50 83 31 30 -2 21 -15 -47 95 17 -122 20 -31 -39 -55 15 111 21 23 -65 29 -80 -127 -94 -2 -6 60 -24 -89 -50 -76 54 19 -9 5 -45 47 -32 64 58 -121 -59 -103 13 18 -47 -59 -75 83 8 -120 127 -9 -40 -74 70 -2 3 -123 13 42 -1 -9 -11 13 7 -34 -75 10 -13 -14 -122 35 48 -10 62 90 69 2 5 -31 14 30 -53 -59 -5 50 -47 -19 -18 109 -86 52 94 18 -40 69 -9 -31 -107 -34 18 2 -23 -52 -111 -121 9 45 7 -61 -50 -72 -52 8 -91 -37 -95 11 58 -25 3 -20 64 -1 65 47 114 56 -29 -40 -2 -38 -71 22 51 63 -125 3 -61 0 29 -63 105 -85 13 -3 41 -35 34 -35 -37 108 -36 26 28 47 -39 62 -46 47 81 18 37 10 -89 41 108 -54 11 27 44 9 -78 -3 -21 -124 35 48 -57 -83 -36 3 6 23 -73 47 26 -8 -59 60 -21 64 -47 -102 -8 9 -71 52 27 -110 -127 -46 75 -32 -44 55 -61 -48 -105 -42 41 -126 -60 40 41 35 -68 -90 -21 -99 54 -38 -4 51 4 41 20 20 -38 -105 -52 -44 11 -9 -11 77 -94 29 -121 -12 -6 4 47 -71 82 22 89 -4 21 38 -15 54 -127 24 -47 20 89 113 -34 93 91 -14 59 -1 7 35 37 40 86 50 45 -87 0 76 -73 29 -4 21 59 -63 54 38 -55 28 -24 -75 -17 43 36 49 -37 -27 63 55 71 114 -65 -49 9 50 25 -24 116 -4 2 -49 -93 83 -127 66 -92 -64 -71 -11 79 0 90 -24 96 25 -80 56 35 -64 14 -58 106 -123 -55 -34 127 -101 23 -56 81 -45 -9 -70 26 -73 -13 41 -70 -32 -116 32 -42 -57 -3 -38 -38 35 -55 -127 -26 -87 -15 22 59 -47 -1 11 -63 -8 -26 -78 10 -22 24 57 54 -66 -18 17 66 57 -67 39 102 15 -124 -8 -35 -46 43 -10 13 -44 103 -51 77 57 17 125 59 123 86 6 55 64 117 92 -108 18 15 -107 -78 -73 -9 17 -121 72 -124 -31 -56 105 122 -11 -109 -18 84 54 78 -49 127 -3 54 13 10 -63 -82 -17 29 23 126 -36 2 12 -51 19 -66 9 31 57 -82 -49 111 -4 11 -23 57 77 -109 49 9 76 -72 -49 25 -50 27 45 -60 53 -75 -10 10 -50 32 34 -12 85 -11 -40 -61 51 57 82 -26 15 52 92 18 -3 90 -28 47 -19 -66 100 27 0 9 -49 17 1 -4 7 42 26 90 -82 3 44 -3 60 126 83 -31 -77 12 9 -55 79 -47 -11 -21 -40 115 59 1 -36 20 -103 -21 32 125 47 40 1 -91 15 -125 -92 13 -19 -15 51 65 -5 126 89 -9 -38 54 -109 -38 -79 -5 60 -17 38 -71 -87 -4 -97 114 -20 -50 -83 34 68 -59 -42 -54 -66 45 41 -115 -68 -117 -90 -36 14 -126 -54 2 44 -23 -82 11 -5 -7 -51 116 51 -68 -41 -114 -117 87 -59 20 -47 -60 -127 122 10 119 -29 -11 -106 -10 -127 -119 119 -32 17 -91 11 -97 -52 -68 -66 4 79 -60 83 -114 -8 -41 -21 -59 -12 -19 -24 -63 -17 -90 23 19 -26 -4 -124 9 -29 73 -9 -41 -52 1 -69 3 -50 -31 -71 -73 -38 34 -126 32 54 26 -127 41 -10 -128 -83 -51 -45 44 58 -1 20 60 26 75 62 -25 -88 -74 5 13 105 75 -85 -59 101 -72 -27 67 -19 20 -128 -3 -56 -64 -17 -61 102 81 -91 29 14 -20 14 -128 0 11 -41 47 -127 -92 -24 -4 -65 -4 114 -39 -55 -128 33 81 -108 -97 -102 78 54 61 -34 96 -6 -118 29 11 21 18 53 23 -53 -52 -14 -22 -1 -29 -21 -28 67 58 66 24 22 -42 18 -31 44 -25 -98 -54 -1 -30 47 0 -29 -19 -9 29 -12 -39 18 88 -35 -22 39 76 -47 -15 0 -25 19 84 18 7 64 -99 -9 -40 90 35 16 25 -43 88 82 68 -78 -3 7 98 -49 49 -60 -7 123 12 105 23 62 -59 26 -17 -29 36 113 52 68 -62 47 -29 -4 47 -113 -29 48 -18 -15 -29 12 -37 -3 -51 20 -69 60 -81 -39 15 37 -70 44 86 3 -12 20 45 -86 -66 -34 -12 -1 28 4 -12 33 35 -121 -5 -45 -35 -19 -1 -36 -5 62 -44 75 16 -29 0 -76 -119 -76 -16 -70 17 -40 31 127 28 -18 -33 58 124 -2 40 -40 50 51 -25 0 -98 -110 42 -24 106 -48 -48 -21 -28 49 -80 -40 15 -47 -89 -52 18 95 -20 4 -11 20 21 123 -71 -70 -47 31 13 -109 -8 -47 -128 -68 -6 -38 -4 -39 -63 -6 -37 25 23 -31 -16 -30 -7 -18 48 -5 -118 -38 -39 -44 3 -72 -21 -27 -2 64 74 2 67 -68 -19 -5 0 8 6 -19 36 96 4 -14 -56 59 94 -55 -6 -41 41 -122 -88 -7 -80 89 -75 93 -11 -88 41 -77 -84 -104 -1 -89 52 7 13 49 -11 -5 17 9 -81 -72 89 26 -29 -47 117 -21 -38 60 -52 -3 -16 -36 9 -38 -4 3 95 23 93 -80 -8 -47 -6 -101 -54 29 -32 9 -16 56 38 -17 3 -56 -31 -3 39 -35 -9 -30 -2 46 21 33 57 23 34 -6 5 23 -10 -25 8 -16 -93 11 -70 -85 40 -20 -5 6 -16 -21 48 -8 -27 0 -53 42 -64 -126 28 53 34 -27 -32 42 70 -3 39 -4 -16 2 -77 72 -43 -7 103 8 -35 38 -29 20 2 17 -31 -2 62 87 43 41 27 -6 -31 -29 -12 36 -26 -65 55 -63 77 23 95 17 -36 -31 -3 -9 -61 89 -55 -12 61 51 -88 35 2 -31 -125 -50 43 -125 -26 76 69 126 -79 -78 20 123 -31 -65 57 78 -22 -4 118 -38 2 -55 55 8 39 -18 23 58 -4 127 -112 -47 72 -30 -49 8 50 43 7 -23 127 61 -21 91 83 23 -62 125 32 52 -56 40 85 59 87 15 -105 44 -38 -78 3 -45 -42 29 94 -101 70 15 -55 -36 -38 14 26 79 25 55 -55 3 88 85 30 -8 41 89 21 -9 -112 -28 -6 -25 -56 -20 -58 -67 -18 -45 86 67 -11 -1 -28 41 -49 -16 -70 87 21 2 -13 9 56 -23 18 65 -23 -20 -48 -29 -40 -44 -1 15 12 -7 2 -10 -43 7 -65 -80 -23 -8 -10 -65 -42 -18 74 112 -13 29 -9 -28 -13 25 4 30 -45 -4 38 25 65 16 -34 -26 41 1 11 41 -41 59 45 2 27 101 85 -30 51 1 6 -26 75 46 -25 -22 -12 -55 51 1 74 27 44 27 21 29 68 -18 -128 73 13 -16 -44 -79 19 60 -98 79 87 -68 -34 127 -84 -84 16 -74 -44 37 -66 10 -16 -2 127 -64 41 68 14 -122 23 32 -26 34 -45 11 60 19 -116 111 48 -16 -32 80 4 52 -68 -12 20 77 26 21 -110 -19 -88 127 -38 37 -108 -33 118 -91 -93 -21 -66 18 -1 28 59 11 118 -3 50 -47 10 63 -73 0 -38 -19 2 -62 54 21 -34 127 23 -29 -44 16 5 38 21 38 -80 38 -26 -125 80 -11 -40 8 28 -45 57 66 -58 38 -13 -29 10 62 88 53 -7 33 -64 -11 127 -96 -15 41 -57 -12 -1 -54 80 50 6 -55 16 72 63 -45 83 79 -61 -45 26 -6 59 10 86 118 -8 25 -120 -55 62 -34 6 22 -11 62 19 -81 20 -11 93 -9 14 86 49 41 41 1 21 -38 34 60 85 -76 -16 -24 75 -33 -45 -27 62 35 -20 59 -13 12 85 97 58 -14 -35 -6 -59 49 -121 -37 37 -47 -12 -47 -52 26 0 -85 -44 24 5 26 39 -84 105 1 -11 111 -70 -113 -16 21 -35 13 2 23 0 52 -35 -4 -31 -27 -14 -40 -31 -22 -46 26 88 83 -77 -1 26 -38 49 -21 -29 33 -7 63 116 44 54 53 86 -19 3 -7 -26 76 -90 18 33 -6 -103 -91 5 7 53 -31 -10 75 48 -61 25 37 36 20 42 58 -5 15 -37 -14 17 -88 -41 -11 126 4 18 -26 -69 37 -33 9 55 31 53 -13 27 6 27 -28 -92 -24 42 69 39 -17 2 -27 -30 24 30 4 -44 -51 -63 -9 59 -30 80 34 50 7 -56 9 95 -28 -17 -59 -4 -61 21 -124 -76 110 -4 -36 56 26 -23 19 -10 -75 -28 5 -37 51 51 28 11 17 -43 41 14 -60 35 4 -20 72 25 -98 -12 -20 49 61 63 -40 -11 -88 28 -50 98 -29 12 23 -44 36 69 21 -8 16 -6 16 -23 -47 -64 9 69 36 -26 -89 -10 14 49 -23 -61 54 -53 -37 -37 -64 -18 -11 -114 -125 -4 -3 -15 -127 57 -58 41 -86 -24 -60 -33 -88 60 -65 -63 48 57 -51 -10 36 -124 32 8 -16 -71 25 26 -13 104 -50 7 -121 14 122 44 -97 50 -13 -7 -56 -110 -127 -66 -66 -73 -9 33 63 69 -119 58 -32 -72 13 -93 30 75 -29 85 -123 12 -103 -33 43 2 69 8 -7 -63 32 -14 -125 25 -97 27 25 50 -39 -39 -55 6 70 70 11 42 -71 34 5 124 20 -51 25 40 17 12 38 -68 22 -21 107 -110 -56 58 -109 78 -75 23 123 34 7 11 -54 43 -50 89 57 18 -5 119 3 -66 47 101 69 -85 -124 43 -124 81 37 -13 72 -16 49 -49 -56 -60 16 54 123 15 -23 7 21 1 21 103 -42 64 57 -48 41 -41 27 -65 40 -37 -76 30 47 -103 -30 -38 -2 -35 60 1 24 125 -59 4 -58 -127 20 -61 123 -43 97 3 67 101 12 -95 -116 -13 42 -81 -3 -8 -113 -127 -128 66 -33 72 -63 -42 53 68 81 90 -116 43 -13 93 125 37 -12 82 -39 -68 16 85 -113 41 11 -112 51 -103 -64 99 59 -14 -24 -11 91 -43 127 21 -32 49 -28 127 -5 -30 30 12 -85 -18 60 24 37 -86 74 -67 -123 -127 57 7 -33 61 58 39 -111 26 -15 -65 -13 -38 -127 38 -21 38 58 62 -65 -56 33 -33 -88 65 -77 -35 19 -50 -4 -47 -62 -5 -21 -108 -120 41 39 -128 -1 48 -60 -90 -52 38 -53 -110 -32 84 -30 -15 -65 -85 -5 4 -89 -86 13 32 -49 -29 -71 -57 -121 17 35 -12 -14 5 -36 -13 122 -127 -41 51 -14 -68 -5 -121 37 -21 -78 -79 -120 -48 6 -70 -36 -15 -54 -53 -76 66 -27 11 -127 -96 -116 -12 64 -45 121 -51 -30 18 117 20 -44 26 -15 -128 20 17 -38 -60 -54 -90 -116 -26 -70 15 -41 30 37 51 -15 112 56 -32 1 -124 31 -50 75 69 11 79 28 125 -33 -29 -15 73 -55 -76 48 -43 -29 21 21 32 -83 -29 70 29 -100 -83 32 -48 45 11 -33 -64 2 7 18 62 53 2 -13 94 -126 -42 -9 -4 -72 -4 51 -56 -18 10 84 17 97 -87 -125 -66 -55 117 -40 -52 -38 -51 -61 -121 23 65 34 15 13 -48 -34 -35 -51 -66 -72 43 -5 28 -26 74 -81 22 63 -46 -45 68 -29 -20 -26 84 -14 42 -31 -44 -59 43 -21 37 -124 -1 2 -52 63 -72 35 67 -51 -67 16 -96 31 46 123 84 10 -72 64 37 23 1 18 64 -6 -62 35 -19 8 18 -73 -14 -53 45 -68 13 -65 14 -15 24 -60 121 -34 59 -22 10 9 -73 53 -56 61 122 3 -36 28 73 39 -33 62 1 -51 -78 20 8 -49 -8 59 127 23 14 -65 86 -61 -44 -73 26 -81 37 -98 31 19 29 -44 1 124 28 -126 -18 -17 13 -20 -76 -7 -5 67 -106 -10 40 -14 -26 -1 -30 56 -17 -35 -47 110 -18 40 -27 9 -107 -102 -51 -48 7 125 18 -70 -31 53 -79 44 -109 -57 32 -29 -88 -77 33 -100 -71 -92 27 39 101 -16 -102 -4 -37 -14 -126 33 127 -60 29 -81 -47 -39 17 -61 105 43 -7 -30 -77 -116 -48 -74 -74 -83 -7 -103 29 -68 -92 -56 77 50 16 -105 24 -25 65 10 -1 20 -68 110 -42 -42 -80 42 36 16 48 67 -116 -26 -15 6 98 -28 17 15 37 -122 -16 -100 17 96 -121 -11 -66 39 -112 115 -39 -88 -68 -68 -119 -45 84 98 9 -53 -102 30 98 4 5 24 7 91 -114 69 85 -70 46 108 53 -30 -62 15 -73 -18 33 -29 2 -125 -19 -97 64 120 -107 106 30 17 16 -41 59 39 -61 111 -30 15 -53 19 4 -33 119 -3 -77 -22 -122 110 21 58 109 -58 38 -5 46 -19 56 27 -19 66 -90 -125 -114 21 -66 33 53 85 -3 50 27 -13 -48 -47 -114 -34 114 -125 36 93 -89 86 19 -91 -74 119 -64 -22 85 -5 31 -126 -22 -35 86 3 84 -9 -53 86 1 -23 -7 -70 -14 -125 53 64 -40 -10 -21 -62 127 -38 110 -52 -15 -35 -32 9 23 11 -18 9 91 69 -66 -37 -21 -26 -4 37 28 3 38 -81 -1 5 28 47 -20 -84 53 2 73 115 -34 -24 -63 -15 13 -82 -28 -15 -82 -12 -4 14 38 -57 -24 108 82 -6 -51 -5 -115 21 35 55 22 -66 38 -73 0 111 53 8 -111 -36 -56 -44 -105 13 -16 -15 -28 -2 -46 -73 -38 -57 -71 -5 -103 -122 14 17 -26 46 -34 35 32 -14 66 -66 -44 5 -17 -87 36 0 -6 -14 89 14 -82 -128 42 47 64 124 -63 -25 13 -58 -71 -24 -22 -71 -46 32 -17 -25 1 4 10 -33 -98 -100 -39 -60 93 -49 48 -27 -15 70 -23 28 -50 10 13 -41 -23 -8 -9 -5 16 9 -24 31 15 -75 89 83 -124 -14 -37 -2 -53 58 98 -21 2 61 -38 13 -54 39 -28 31 55 7 -9 -5 46 65 3 -1 14 -50 -24 28 -38 -15 15 -77 126 -23 -62 9 -29 19 17 -31 49 74 4 4 42 -23 -80 22 -31 76 -121 9 0 23 7 29 108 40 -9 23 95 55 27 11 -1 -12 -24 -78 4 24 12 -3 8 30 -2 -10 37 115 119 39 31 -44 -45 -35 -6 118 -85 -65 24 57 34 -4 127 99 -42 -33 -82 -95 100 -93 -44 88 12 42 34 -54 5 -52 19 55 -84 18 4 75 50 4 -28 -101 -14 74 10 76 7 -79 52 -23 -88 125 125 70 -61 -14 -8 -54 115 -78 39 -78 -28 14 71 48 43 -44 -116 76 39 63 -77 122 -27 -12 -122 85 -118 50 -31 -51 -40 77 -33 -33 -125 -16 -49 126 -62 -11 -100 31 -84 -109 -41 38 -108 -105 7 33 -58 -51 -40 -48 -93 -105 -33 -45 30 -9 12 -126 -112 -24 5 76 11 74 57 8 36 51 4 -43 -47 -15 -68 -122 52 -87 76 80 -112 -17 73 -59 -7 -109 -48 38 -4 -26 8 -41 54 -8 -33 -11 -30 15 -51 18 5 40 21 54 -69 70 -39 -77 -9 -47 -56 40 -128 8 79 -23 64 -4 -62 -124 17 13 -23 -54 68 33 -11 -110 57 110 -28 -33 68 51 -52 -126 -75 12 -41 0 27 -10 -16 -16 -10 -22 -42 -56 -63 22 -52 -15 -19 15 -37 -49 46 29 23 -15 0 -49 31 54 3 63 -68 -44 -15 23 -72 -3 12 1 -18 -25 127 -98 23 -70 -61 3 57 96 3 -91 106 27 -41 -116 -59 127 -9 -3 21 3 12 -12 -25 -35 -72 -70 53 -38 38 -33 -38 -24 -79 -3 1 -28 -70 2 60 -100 -34 -10 39 -32 -103 -18 123 -13 -36 -40 3 -25 -45 46 -93 2 36 -107 5 10 61 -15 26 -49 -31 -48 -36 45 18 -41 -98 44 31 1 -7 -58 -16 103 -15 13 -71 41 -56 -28 96 54 0 17 -69 7 47 14 -79 -3 -18 -37 -128 -61 17 12 29 -37 48 -34 42 18 84 26 -73 13 -27 86 -30 40 61 52 29 27 -44 28 -62 -8 82 35 -48 -57 22 -67 8 -53 16 -73 -50 -71 20 48 -14 44 -90 67 41 -49 -21 19 13 -46 -69 59 34 -54 -6 -7 -68 0 28 -48 122 1 22 31 -11 69 -23 27 127 -19 -38 -125 -30 61 -19 -21 -39 5 -47 -73 -82 69 67 31 103 -2 59 -70 62 -11 64 21 -4 52 -127 53 -14 -19 124 -19 89 -127 44 -34 23 -20 -47 -41 75 77 -27 8 79 35 82 98 -14 -43 36 86 17 121 -124 -51 16 -76 69 2 -6 127 -3 -3 45 98 -127 20 15 -51 -68 45 -17 4 21 66 56 40 103 -8 -4 20 10 -24 68 73 79 -88 59 28 -18 119 27 -11 -48 22 4 44 -87 -29 -32 -37 -51 4 -1 28 -21 -62 32 -34 -9 -57 -20 55 8 -63 72 -49 68 -10 72 71 -35 19 -30 -49 35 -84 3 2 -22 -33 -110 -99 11 37 11 -16 -82 -73 -22 92 -10 88 30 -24 -2 8 -71 -56 31 49 -125 0 99 -60 9 0 -56 4 -8 -15 52 27 16 13 -20 54 15 3 -54 29 -2 28 -50 -18 22 6 -38 26 48 30 25 -33 -19 35 106 -3 21 60 -18 7 -25 38 -20 -43 24 5 -2 -15 33 -28 36 -12 53 -11 -65 -26 -122 -20 32 -21 -40 -73 20 -20 -64 -54 -69 43 23 -62 -69 58 -69 38 34 -59 -16 56 8 -36 42 -38 16 -38 40 25 -19 -25 -107 98 -53 -4 -6 -128 -63 103 21 44 17 -101 -50 27 63 -18 58 -43 104 -1 18 -1 37 -85 0 -16 26 13 28 30 -74 -62 -126 -35 19 -38 41 8 24 37 -21 59 -39 -112 -13 68 75 30 -22 -61 -81 -21 36 21 26 -115 59 95 -11 -49 65 6 -2 -123 63 -19 -87 -44 -126 32 -82 -99 -92 -73 127 -2 -117 31 -115 -73 75 -68 -50 -6 -110 63 -24 -21 -53 -71 -10 -11 -33 -57 -24 58 -30 94 -21 67 -74 89 -46 -40 -29 -42 -18 -32 -44 -51 -62 4 -76 44 -10 -60 13 18 -125 -58 46 4 13 -16 -38 -47 -28 -27 -39 -81 -51 -43 -41 -68 -82 33 82 -83 20 1 23 -8 -66 -72 73 -19 11 53 -101 -105 -24 74 26 7 96 -48 -24 39 -44 -47 9 -1 -121 -89 49 -84 41 -1 -11 55 3 -57 8 -92 46 -12 -64 -25 -123 -5 -70 -126 26 -49 -91 -30 4 -43 -24 -32 36 57 -84 -42 -24 -36 71 3 23 -6 -99 9 -17 77 76 -87 7 87 -7 -35 -31 -59 -59 -66 51 32 63 29 19 -4 -95 -128 97 -5 109 -24 -33 38 -61 0 -92 21 4 -123 87 -63 -64 99 27 -2 48 4 33 55 10 -122 -100 7 12 -50 -32 109 43 -33 -39 -55 91 44 17 -61 75 -33 9 -15 -76 -35 -15 34 58 8 -18 -10 -40 54 -73 -75 -54 61 99 -45 -107 38 73 40 31 -57 82 75 11 14 -78 60 -3 -72 -80 51 76 30 32 -13 -37 -71 14 115 -38 -31 -32 42 0 61 -38 -30 -29 -6 81 -38 49 26 -68 -50 -28 20 -31 60 -10 -61 39 -122 -62 -23 -66 41 -63 -72 11 -41 31 7 81 -38 24 -84 21 -56 121 25 -61 34 -26 -62 106 121 -37 -78 -26 -18 88 -70 -58 -47 124 16 51 -2 17 118 23 -19 -113 -128 -68 -44 98 -63 -117 -109 15 -63 -59 -116 -16 -44 -21 95 52 3 -123 60 -99 78 -67 -125 98 34 107 -7 -38 -25 125 113 56 93 25 -35 60 -37 15 19 26 20 -19 20 88 -13 31 1 17 64 65 85 80 121 99 26 -47 34 -101 29 -5 -89 -126 26 -83 101 34 53 60 -89 -125 -92 -11 -57 -15 -100 65 127 -112 -7 13 -18 49 -15 28 -108 -96 -75 123 -43 -32 4 -43 -87 -31 14 -121 -112 -56 47 -17 -70 -39 -5 -3 83 -80 113 88 85 -32 8 -123 -67 -3 -9 35 103 -55 -128 -32 59 86 -115 -90 38 -125 84 123 65 -55 -58 -59 49 -82 -87 -64 54 80 -60 59 -63 -76 -52 -28 30 100 -10 37 -116 -80 68 -14 58 -4 51 -128 -45 -43 115 -23 -70 34 44 41 -82 8 -85 5 -94 -75 -38 40 38 115 40 7 -34 -71 21 -126 -124 55 66 -123 -16 -8 32 18 -27 50 -70 102 -22 18 104 -20 -46 11 25 39 57 44 126 -21 67 -24 79 97 -44 -86 7 -86 -71 13 -122 -21 -117 -107 -16 82 124 63 -38 -1 16 0 100 95 -12 -65 3 8 -29 -3 122 -85 30 -69 125 17 78 35 -2 -10 -104 40 67 127 17 -14 7 103 7 19 113 -1 -62 -4 88 -9 -30 30 103 92 -29 82 -15 -92 25 70 -107 -33 57 -8 2 77 -16 -12 -32 -27 19 -56 13 14 -46 -15 127 52 -37 86 68 126 55 -6 1 -71 -38 -16 59 -61 -5 63 11 -20 -11 -15 1 -56 6 6 4 120 120 36 -4 -43 -111 68 107 -82 14 98 17 83 45 19 -125 -5 -22 2 91 -21 20 18 -48 53 27 30 66 -36 92 -45 52 -6 -42 -86 -108 -1 -5 -19 61 -53 -26 77 49 -25 -67 -39 -52 -16 -52 13 18 -17 -2 3 -23 65 15 -6 -23 6 -68 5 34 20 20 34 25 -4 -4 -80 -92 67 -7 -46 67 -29 -7 -88 3 -65 103 -27 -80 104 43 -54 -25 -18 -2 -33 40 18 26 25 17 33 -125 -29 -42 38 7 -54 -17 36 32 -19 -11 31 -32 38 -24 49 7 -14 -29 13 10 -6 37 14 82 -106 -8 67 7 -30 -79 65 -28 25 -27 -37 65 -56 -52 -18 -18 -22 -100 -16 -60 -55 48 50 79 33 124 60 44 65 -58 -65 -81 -51 70 66 22 10 37 24 -68 -85 -3 17 58 -1 8 -41 -50 6 -99 66 69 -36 -39 45 12 3 -127 72 -27 -3 -2 -87 22 72 108 -84 77 -1 9 10 17 46 -26 18 -68 -11 -28 -6 -14 -38 -61 32 -17 -19 15 -88 28 -49 -14 23 18 83 -59 2 47 42 -97 -57 -58 76 -50 7 32 126 -28 -3 -14 122 91 -1 -23 39 1 101 -61 42 123 39 -2 -24 -4 -2 4 29 -11 -8 -1 -22 54 51 -19 34 127 24 51 37 -56 73 13 68 94 29 37 50 20 86 43 5 96 -20 -49 -15 18 -24 10 74 -24 -23 0 -46 -31 -85 55 50 36 53 92 126 -55 20 64 -17 75 16 45 -28 -15 60 -29 -13 16 -84 -61 69 -31 31 -2 55 22 -28 43 67 69 -55 76 -38 14 -21 18 -49 -28 30 10 5 37 8 -19 -11 -29 -32 24 -25 -5 33 25 -4 9 -23 -24 -11 -45 10 0 -23 -22 16 -12 -74 64 -6 -26 87 5 42 46 -53 18 15 -2 -2 92 26 6 14 4 13 -5 27 68 -59 -27 22 -34 -21 43 -54 50 -10 2 68 -5 -4 -1 -7 -31 73 20 -21 -15 -27 -7 -47 12 55 42 -33 -14 46 -8 23 13 58 -39 -33 42 -95 -4 -8 56 9 21 29 21 40 21 12 33 12 -15 -15 -39 1 -43 21 34 13 -47 59 -29 -15 36 -22 -26 14 -76 3 19 -24 125 15 -13 -17 33 -10 64 33 16 25 -37 15 40 48 -9 61 14 -46 64 2 -18 74 -21 30 17 5 43 25 -3 8 -30 127 -44 -10 -24 -29 30 -16 -9 28 -4 6 74 3 11 -72 -30 -18 -6 -46 38 -18 60 6 -38 94 37 31 -31 -59 -10 16 -20 63 -18 9 27 -30 -33 -49 41 -21 76 -45 15 -24 -70 -53 -107 -42 -33 12 -40 19 -18 -78 41 25 -90 45 -38 105 -74 -89 64 -75 -29 -67 -115 -40 81 -60 41 68 -18 -5 -79 -8 16 -74 50 38 -56 -125 6 -78 -16 -50 11 -126 -50 -60 -27 49 -68 -63 48 -1 60 15 33 42 26 -61 -18 -52 3 -61 -33 -18 -103 86 -47 -81 -55 64 18 -29 -22 -7 -113 69 -6 47 11 -19 -102 33 -8 54 27 -84 27 -4 -86 -46 -92 109 26 -123 32 -97 -76 48 -32 13 -20 -126 -2 -21 -126 -107 -11 10 47 -113 9 46 42 -65 -57 54 126 -11 -111 -33 31 -48 -51 -11 18 -12 41 -25 71 43 -81 60 28 -101 -25 -93 16 96 97 -57 -13 2 -105 66 10 27 66 30 53 105 65 -47 31 -53 44 -41 12 6 102 -51 -25 -89 -41 10 -118 6 126 -40 -56 -49 -39 -4 -32 -16 -75 38 80 -28 23 57 -128 -3 -9 -99 -40 -75 -27 -12 25 -21 36 71 15 -4 -63 26 -102 -25 -36 -97 96 75 -32 45 -6 60 -8 8 102 -3 8 -19 -1 -90 -17 86 -56 116 89 -74 -42 37 -4 -24 -36 32 72 -2 60 127 83 -24 46 15 88 4 48 -101 -20 96 -9 114 42 -64 18 -87 -24 -6 -32 48 38 -124 -15 42 6 -51 -66 27 -127 92 34 47 -68 40 -54 -22 -117 33 -86 36 3 -41 42 -11 -6 -35 72 48 -128 18 96 27 -15 92 43 65 -27 123 24 43 58 -11 -57 -30 48 17 10 61 46 40 -1 -7 37 -23 2 18 -29 13 -13 59 72 98 -19 33 91 39 22 38 -66 22 26 32 36 -3 43 99 -11 44 23 55 76 45 58 24 29 31 1 -28 -9 -10 -40 -27 20 -28 29 7 -11 96 127 54 -60 28 14 -49 36 14 25 -26 52 65 6 33 31 -117 39 -9 62 92 -23 63 40 64 42 0 76 -38 64 -29 -2 19 42 0 -43 32 -3 47 17 22 -29 9 -21 -6 13 -12 52 31 38 -23 47 8 -6 87 -24 -24 39 18 0 43 -10 -88 38 -25 -11 44 89 -2 10 -17 -23 59 -9 4 -28 -12 -13 21 26 -6 -17 20 30 -49 -36 -37 -6 23 18 -66 -6 -14 -21 -14 16 16 -15 18 -3 -22 -32 75 -2 -37 22 -60 -16 65 -27 -68 -21 -62 5 -41 8 11 -63 -2 8 27 61 41 20 -2 76 -13 -116 2 25 37 -120 7 -22 69 -31 -26 -4 102 -46 -1 49 20 46 38 -14 -51 33 46 -38 15 -46 -3 37 -25 -17 -50 78 -86 127 109 -21 82 -105 76 19 21 32 127 1 67 54 -96 63 7 -1 40 -20 -8 -17 -9 9 -45 -35 39 18 -8 -61 -1 -35 -19 -20 4 50 -13 43 23 -77 -2 6 15 -60 8 -10 -15 -17 16 88 -24 35 61 -13 27 73 -5 -42 81 21 59 -92 -48 -4 -23 60 -16 -6 62 38 -25 12 -82 -50 43 -56 -44 -61 -13 20 36 0 -55 -45 -38 -13 122 80 -7 16 96 65 27 24 -3 -27 21 21 -84 -2 25 -36 -37 -33 79 91 37 -10 93 34 1 11 23 26 -24 -4 71 33 5 -54 121 -25 -9 -9 -9 16 2 -15 7 66 92 42 -34 -38 4 6 28 108 0 -30 -45 68 -19 47 8 111 -16 2 31 117 36 60 -52 -49 63 51 -59 16 -7 73 -60 16 -32 1 -71 -15 0 67 54 -15 97 34 -35 58 15 13 -7 -15 76 16 -29 15 -113 -36 85 -61 127 58 91 -15 -27 33 46 -46 120 -50 -101 -45 87 18 -29 29 40 -29 20 26 -54 -16 23 5 31 26 31 48 -45 -4 -91 85 -23 82 68 -11 42 110 33 -50 -14 51 -18 33 -9 -82 -63 -41 24 75 82 57 51 -22 23 122 73 -52 21 60 49 -14 39 85 -46 2 8 -60 53 -120 -47 61 56 -11 -56 -41 58 -111 -67 4 95 -45 102 114 -30 45 101 -95 -103 -32 -48 -44 -27 -127 -80 123 86 35 -65 -3 34 19 19 -44 51 -6 38 -106 -18 -10 41 -48 64 -84 11 44 11 -118 43 88 -116 -13 -92 2 -124 -14 32 -94 51 6 16 -94 -30 87 -6 -47 53 -36 -109 37 86 25 70 -15 -5 127 -28 -100 -40 86 43 18 51 -75 23 -9 -56 26 -23 -43 21 -58 26 -69 29 22 124 -92 100 -29 -25 56 60 14 11 105 61 -1 61 120 -7 87 16 19 -7 -32 22 68 9 1 61 126 -123 1 72 53 85 36 64 50 33 53 14 124 31 -40 -11 75 -54 -6 62 -7 -38 -7 79 -53 116 97 -31 17 -2 55 105 50 61 4 82 -32 -22 -54 -23 74 39 108 126 -46 -41 127 91 10 109 29 48 2 35 -35 8 119 -97 -34 -14 116 48 80 117 -21 91 16 50 43 39 110 -41 50 -6 -30 -25 -80 23 -29 -95 53 11 -111 -31 -51 17 -10 -75 -13 58 -37 -85 -66 54 -19 27 82 10 123 13 51 54 -11 31 -18 89 -34 16 96 42 16 -10 -43 -15 46 43 52 -12 -35 -1 39 88 75 -15 -25 -27 30 -67 75 60 -98 40 19 127 14 -124 -52 28 -14 -44 113 -84 31 47 -11 70 36 42 -51 35 59 16 13 -14 0 3 -17 -4 51 10 53 -33 36 61 97 47 -51 7 19 -59 33 -38 -52 -24 -64 -42 31 -10 85 -70 20 18 69 21 44 -61 33 -5 -18 -12 -34 119 19 -39 -50 -26 -30 -9 21 -15 -5 -37 -54 -5 -98 -34 -7 9 3 -89 -12 89 -48 126 -33 -92 -20 19 109 67 63 -95 42 -118 -46 -60 12 -48 71 16 -33 5 0 -13 -85 -23 6 -43 -107 -29 7 44 101 -7 109 -107 11 3 -64 -80 21 -44 -63 -64 38 44 25 32 -86 39 -1 30 -89 -88 -50 -29 -60 72 -4 45 31 75 71 -38 10 -48 -40 -88 -127 -52 116 -99 -122 -26 27 -34 -126 -42 -39 -8 -5 -7 -62 27 17 27 -32 -124 109 -74 -125 15 -33 -126 67 -75 97 -46 -54 9 116 21 60 7 -44 57 -31 37 -122 49 61 28 -36 -127 -28 -17 -82 122 98 -5 35 86 -85 49 -11 -78 117 -126 -24 12 -15 21 15 36 27 -78 -82 54 80 -54 -91 -42 -1 24 -67 -69 34 -14 34 -73 -22 -24 51 -9 0 43 -28 -15 -20 27 -72 9 -110 -17 124 2 -124 -124 -19 -43 -41 -16 0 3 -53 -54 7 28 -19 22 94 -30 6 1 40 -79 -87 -10 -73 119 -40 -13 24 -35 -59 36 -70 -70 42 -72 0 -72 -51 -52 -28 3 -126 47 -115 -80 50 -8 -127 7 93 25 -56 -127 -97 59 9 -80 4 58 -4 -128 44 14 44 -55 37 14 26 6 76 4 60 -30 -52 -26 62 -33 29 -89 94 -46 -62 -16 6 71 -11 42 112 19 -31 65 -14 -57 -59 27 -66 28 -1 49 -10 85 -53 -112 -125 -72 -25 27 -28 8 13 53 9 34 32 -11 -58 -64 -47 1 -13 127 -5 -6 44 -19 -82 -127 64 1 80 41 -46 -8 -17 -20 55 49 70 -86 2 48 17 -56 -12 35 110 -44 43 -11 -43 -47 -43 75 -31 -127 54 60 -74 124 -42 25 8 -20 -71 -8 10 38 -66 23 -15 -127 19 1 -58 -20 24 -33 44 100 -22 23 -59 -101 -26 -122 -63 -4 52 45 10 -126 22 -95 -12 6 14 50 -22 -122 -27 -12 -23 26 13 56 -87 -15 57 5 20 76 43 122 28 -80 79 -107 -124 -28 58 -11 50 -78 -37 -28 -51 -48 -31 28 -79 -67 -32 -53 84 65 -5 -60 -120 83 -41 -40 -9 -89 -35 -81 19 64 -98 67 -11 -9 1 16 -73 -54 -81 -3 -90 10 -10 -26 -124 46 -52 -64 -118 -7 -7 -44 -10 -7 -21 -34 28 9 -87 -72 83 18 -41 53 17 59 23 76 15 16 -39 4 0 -6 4 -41 8 2 17 -82 -8 73 -16 36 -15 -47 -38 11 -34 -34 -7 7 -15 15 -5 -36 0 -125 4 40 12 24 -16 46 9 12 39 4 99 -62 53 -10 1 20 32 27 -65 -50 -26 32 -64 4 -45 -24 -11 -123 73 2 10 11 78 -25 65 -47 -25 76 -23 -126 42 20 3 28 8 -124 -8 69 104 -32 -35 43 -27 -91 34 -12 0 -43 -18 -26 -50 -55 31 39 91 -60 20 -43 48 31 57 -11 -11 -21 41 -93 114 -23 -64 -26 -37 92 -42 -67 65 -6 -60 -50 -15 -17 5 -47 25 -102 -5 15 -44 -79 -28 21 -26 -12 84 53 35 14 23 -13 -19 -15 -28 -69 -32 -25 -20 -11 23 112 12 35 37 -64 23 -5 24 -15 -11 53 -13 -12 63 -63 28 3 63 -39 -66 -81 66 -51 -17 13 45 26 -52 -19 40 13 7 -9 29 65 24 -116 79 16 -6 -82 62 -9 -56 72 -99 -75 23 -29 -107 -40 6 -28 14 46 37 -55 -64 16 14 21 -71 -29 -119 94 -102 -63 10 -34 41 -21 -39 -40 87 -84 -37 -19 36 124 90 49 -123 32 79 -18 114 37 -23 -39 -32 -5 -54 -22 38 -106 -102 7 -24 27 48 -91 88 -117 -35 -7 86 -75 79 124 13 31 54 42 52 62 -94 4 99 38 32 -13 -42 -93 24 -88 -54 -41 -48 59 -29 22 68 -84 20 -72 21 78 -2 22 -37 9 44 -32 -125 -56 41 17 23 55 35 40 -39 -58 23 75 18 9 18 -25 -28 -5 -36 -35 -25 7 77 -103 16 -48 -85 0 -25 20 67 8 -14 -88 23 -23 -78 -38 -74 111 -19 63 -54 -18 9 8 -33 37 46 -49 -11 -79 -89 9 11 39 47 -35 -32 30 -17 11 15 -66 -11 -27 -15 -43 6 -51 13 -10 -30 26 -43 -5 83 -124 -108 19 -64 -101 -63 -17 52 10 -120 -32 6 -125 31 -5 27 -38 -7 -96 -30 -55 1 7 25 -53 32 3 74 -95 -90 -66 -89 3 98 37 0 -2 84 30 115 5 -17 -67 -19 -86 127 -126 4 12 -117 71 31 -44 66 81 -31 -126 -43 124 -22 -33 9 -111 -1 -121 -23 -25 28 -39 47 22 -27 -46 31 -66 46 -7 42 -12 93 -8 -69 -53 -42 -25 45 -101 -53 41 -64 125 84 36 24 -63 -19 13 6 127 33 -33 9 -31 -34 -74 -3 1 -49 -50 -37 -26 23 16 -31 -123 -63 -19 -39 -68 -54 48 -55 21 -10 37 17 -28 25 -56 -27 -17 -28 6 -4 36 -113 -45 -7 -57 -41 -4 -42 -5 -110 25 21 -71 51 27 -25 -38 -86 -45 38 -25 -24 -68 3 -10 -7 8 -111 34 -1 -7 97 -116 -48 -69 24 -36 -41 37 -83 -2 -22 3 -18 -1 -113 16 -126 19 -16 -49 -107 -25 19 -15 -71 35 -69 -41 -46 0 -52 -69 26 -36 -73 3 9 -97 -8 -8 -58 3 5 110 -36 1 -69 -38 -60 53 -49 34 -9 12 41 -58 -10 22 10 -30 -7 -31 -37 -7 -29 0 11 -35 -20 127 -51 -82 9 -62 -77 -1 65 -66 -24 -32 -38 -56 53 -20 63 4 95 -19 71 -20 4 -1 10 38 80 38 -90 -62 -19 32 22 -80 89 -10 2 4 31 41 -59 -41 -102 16 -84 48 -11 126 68 28 -36 -54 -64 -47 2 -70 -49 5 -59 18 -42 -3 -44 -34 -11 -21 -14 -10 7 -1 -10 -26 36 31 60 51 30 62 43 106 13 -5 -52 66 -2 -15 0 27 -5 53 -13 90 -60 -120 13 -75 21 29 -40 -6 1 -15 20 -49 16 66 1 -26 101 -9 60 11 -28 -17 31 81 -6 -71 11 38 77 -11 54 47 -40 -25 -13 -16 -44 -16 8 21 1 22 -38 14 -35 -2 -89 -40 -16 -39 48 11 -13 -28 -30 -15 98 29 35 25 26 37 -15 34 -3 -3 -127 -22 28 -81 33 -69 -92 58 11 -128 26 12 -23 -46 -15 -72 -125 120 -99 -17 -75 -40 -113 -28 50 -3 88 -47 -89 23 74 -102 -14 15 -126 -9 -66 -72 -89 11 113 -76 -6 71 48 -64 53 47 -45 60 -37 -69 -38 -39 44 12 22 -127 6 -62 90 97 -110 58 -16 -124 3 -10 123 -63 10 -10 -26 33 39 35 -21 5 -108 -47 -93 -5 -36 54 37 56 -126 -29 38 29 -17 23 -33 -85 12 -21 -29 -26 13 -34 32 -5 -2 -31 17 42 -79 -34 15 49 -79 47 -32 -89 -19 -12 -68 36 -32 -26 -46 51 -29 -93 -97 78 -45 27 100 -24 60 -13 34 19 65 18 -38 -11 83 102 41 24 -36 -19 -67 68 -26 -38 -48 -2 -86 24 -35 -29 -66 5 -41 16 42 -28 49 -27 -1 -36 -8 -35 59 -68 -11 40 -41 6 -14 -21 -12 -15 -7 -72 80 74 -33 -49 -42 -19 -39 50 -12 -29 -8 -59 21 19 -1 -98 -23 -6 7 38 79 63 4 -60 -48 17 69 52 65 101 67 -8 -6 -9 44 97 -8 -56 -73 25 -29 30 66 41 27 -127 -51 -91 9 34 16 -4 -113 -120 21 -17 -43 -19 45 10 0 -39 91 -34 3 2 -59 32 76 65 107 -67 -2 2 -23 101 66 52 54 -10 -5 30 -28 21 85 123 -96 5 124 -31 -82 -25 87 -60 47 -17 -49 11 -22 20 4 46 31 -67 109 -28 -58 18 -27 73 -34 -32 14 -17 -7 -16 36 -10 10 -96 21 -3 76 -106 -7 67 33 8 -61 69 -96 -3 -12 25 -24 -81 -123 -106 17 -61 82 41 -33 5 30 -47 -35 -92 -57 55 -41 -107 -29 -93 80 -50 22 -126 36 26 -57 -8 -39 48 55 -33 22 -29 20 25 -3 38 28 -47 22 18 66 -41 4 52 50 -69 -115 2 84 -112 27 39 -115 35 -42 -20 60 -19 -67 -84 -72 29 -57 -1 -64 89 -47 -28 -92 117 -17 22 -43 73 76 76 -27 -103 25 -11 45 -34 92 23 28 -15 48 16 -9 60 125 110 10 38 -6 -26 105 29 -123 -17 -1 8 48 -28 99 -126 66 124 56 32 33 24 -25 -127 80 -56 23 58 -40 -84 -127 -2 2 -27 -30 -35 -108 16 -48 -3 -11 -127 125 6 -49 -18 -83 94 -59 41 48 70 -42 1 72 -5 73 -55 84 33 113 -116 -45 -25 -69 -56 58 127 53 42 23 1 55 49 46 2 -116 23 40 4 5 -29 51 -128 60 52 -47 -126 27 84 -4 -25 -11 80 24 23 46 -65 14 12 -53 -65 -19 -18 -24 30 125 -13 6 22 -7 -6 -23 -66 4 -44 101 -111 -53 -32 8 22 86 -44 -23 -27 -3 88 -33 72 53 -30 90 10 -56 43 20 -106 24 -25 -7 -10 -25 -93 -18 25 -69 -39 10 -20 -30 7 58 70 -56 -66 -60 -79 -30 48 46 30 51 -95 4 -42 -30 -11 -22 -54 32 -3 -8 23 -110 83 -28 109 76 49 -71 -11 72 2 -73 10 38 -9 -95 -64 -94 114 -119 -31 -125 48 -62 -24 -22 62 21 45 6 -42 10 124 -127 127 53 -126 43 26 -10 -31 3 -72 22 -15 7 -5 115 85 26 24 -112 66 9 -29 13 -80 112 -30 17 54 -97 0 127 34 -16 -14 122 -8 127 -128 42 -2 67 89 15 56 -94 -82 -68 60 26 11 -41 -20 -21 59 16 -25 29 -56 55 -127 -16 -98 5 2 -21 -32 -94 43 -38 -5 -75 -57 1 -39 40 55 1 14 127 -91 125 -91 73 -33 19 -62 19 51 64 64 83 -9 75 2 -35 92 41 -67 -13 36 -52 75 11 -51 -54 70 126 4 -80 62 -68 47 -16 51 -14 13 69 27 -33 -59 24 -12 -11 59 -60 -11 17 -16 -33 -6 11 56 -11 97 54 -25 22 53 32 -125 45 -39 126 -33 -15 124 -13 42 80 -19 -33 127 64 66 18 -18 69 18 54 -49 -36 51 106 74 -58 -31 -33 26 22 25 -46 29 35 -58 -10 -83 -123 -18 -92 -32 84 4 109 49 14 55 -24 -36 20 45 1 97 -117 -47 47 64 -97 27 -36 -46 66 -64 40 56 1 28 47 -37 -42 8 25 -64 -22 30 -2 28 2 -46 45 -32 -8 -34 48 -41 39 6 9 -94 -47 -119 127 -9 -128 60 53 -20 29 35 -9 -57 43 -42 34 50 30 49 58 84 30 -77 -38 116 124 63 -93 -5 69 50 95 20 -19 -85 -43 -71 31 11 66 22 -9 126 19 42 88 71 -2 21 5 40 36 9 -40 -10 7 88 105 29 105 98 73 127 -70 -82 49 -2 127 62 82 0 -62 106 113 58 -29 104 94 48 38 20 62 22 22 66 53 -105 116 36 -28 123 93 -42 111 31 5 126 118 49 43 96 25 3 -50 118 38 59 69 87 111 -17 -47 -6 66 124 -85 62 -25 55 66 -66 -59 -53 -29 -108 98 -58 44 40 90 69 105 21 -55 11 124 127 -60 98 19 -2 98 -126 -104 -1 24 58 -68 -17 53 80 112 -75 -30 33 45 -127 -21 -52 -58 40 64 -8 47 52 7 27 101 28 -58 19 13 78 -13 -122 81 -44 -109 34 -32 -27 42 -55 31 -46 -19 41 -51 -12 -29 75 -42 -89 -81 -128 53 -7 3 59 -101 -52 44 -65 51 -67 -51 34 41 27 -58 -95 33 47 87 86 -49 34 -3 53 -15 -53 26 39 -37 36 -1 47 -25 4 -14 120 -46 -77 77 34 73 -31 -2 -18 7 18 2 62 87 39 -6 15 75 -124 29 55 -41 72 -22 -128 40 21 -70 39 -15 18 69 -39 -49 94 12 45 -62 -88 -104 -7 93 -118 2 75 6 106 -23 -85 17 58 -18 82 -60 -54 14 -5 -4 -9 -128 -56 5 8 78 63 -35 16 -53 75 116 -105 88 25 -83 14 12 90 -87 31 -68 8 16 -30 -101 -32 123 126 -3 -21 11 -11 -84 9 -4 -1 81 -74 -43 -59 -52 -3 18 -12 -43 -20 -34 62 10 19 -7 -114 -96 -35 -77 -14 95 49 -91 120 45 -125 38 52 -5 93 20 -4 24 -55 93 -124 -58 -16 -48 -79 -89 -76 -47 -18 -22 -60 3 16 -124 65 -32 -29 100 45 -47 57 -23 50 -27 -16 -31 -82 8 37 -24 2 114 -49 -100 -51 -19 24 -88 47 -27 20 -125 -68 40 7 -2 32 28 -63 -15 -61 -19 63 -37 41 53 26 32 -7 -51 12 20 -28 11 -9 44 20 -17 34 115 -55 25 -27 52 -22 -70 14 -68 -42 -118 -105 -8 4 30 7 20 81 38 -97 -62 -12 60 -5 32 47 -72 -99 30 17 -1 65 127 70 21 -16 -8 6 22 -14 -9 64 -11 63 -68 -12 17 1 66 -73 1 -88 -1 -40 78 21 -29 -27 5 83 -31 -41 -87 87 17 40 -17 5 117 -43 -22 -4 31 15 -30 14 29 -11 -31 9 1 26 35 -55 12 -41 42 11 24 -39 20 -20 3 -76 8 -32 -69 0 8 -22 4 -17 30 8 -36 15 -11 -26 15 -11 -11 65 -71 -25 30 11 30 -20 -14 -15 70 -55 -30 73 -22 -37 77 -7 66 -29 -49 19 -20 68 -61 21 0 -53 103 92 -71 16 -18 -19 122 -9 0 -66 52 -15 -62 -28 40 -29 62 54 -7 86 41 -47 7 51 -6 26 127 43 62 -68 20 -46 52 1 111 -44 -43 65 24 74 126 47 8 -54 94 -116 53 12 -122 55 23 4 -55 -8 53 -76 -124 5 -125 -48 -80 3 53 4 49 -32 -32 -113 -37 -100 -123 78 -16 -124 47 -54 38 -23 23 -66 56 38 -4 69 -18 -10 106 16 16 122 -55 49 -23 -50 -116 -63 8 61 97 35 98 11 -10 -10 -90 -31 124 -38 127 -42 -25 -52 42 -49 -78 87 -71 -19 126 -89 -35 -51 60 -111 1 84 9 9 81 34 82 -17 -11 121 86 13 -32 38 52 -61 -97 48 -87 3 89 90 18 127 5 -108 54 -17 -62 23 -65 111 -122 39 110 -113 75 -20 124 42 -113 76 -23 62 -39 -7 116 52 73 51 -4 27 31 -96 -59 -20 -89 109 62 -23 88 -80 -27 -29 20 15 21 -123 -16 -28 -5 83 91 -14 -1 -19 -23 90 -95 -81 37 -10 51 17 -3 -1 12 9 17 22 -75 9 -34 -106 98 109 -105 -5 -39 -20 67 -104 -13 5 29 40 80 127 57 122 -127 -50 -5 109 -73 75 -25 127 90 -5 -122 -7 -127 -16 19 -55 118 32 78 77 -127 39 104 -79 63 82 -57 97 -127 10 121 114 -114 64 -28 48 -2 47 -31 35 17 -38 -122 -59 32 -39 91 -53 -59 33 -62 104 -65 -48 127 64 -32 -68 83 -57 127 -44 19 -97 -17 -38 116 57 -82 76 66 31 70 60 76 6 33 -80 -45 23 -61 60 57 34 -37 72 49 77 -42 -66 13 9 -69 7 107 -11 -41 34 -123 11 127 6 86 -20 30 31 41 -45 -127 125 -45 127 34 -11 -38 -128 -3 3 124 -125 -49 105 -26 -59 51 69 60 51 -38 0 -48 -74 69 -92 -24 30 70 -94 127 15 43 -99 50 -85 60 -61 63 -15 -22 102 67 29 96 -78 -108 51 57 -55 -55 21 -25 83 -8 -12 1 -23 120 16 -64 -20 80 -95 63 63 -26 -72 -35 58 122 32 -27 5 -28 112 81 47 -39 17 -105 27 7 -25 62 -81 7 -39 26 -84 -82 -17 6 27 -124 -60 -9 117 -50 111 -10 -77 49 33 -19 12 -70 50 -9 7 82 -54 67 30 -35 32 -97 51 62 4 1 22 36 55 -49 -40 -29 34 17 30 -128 15 -8 -62 83 59 23 -29 -34 64 57 0 2 -46 120 25 -34 15 -55 79 -66 30 -66 -67 54 19 17 -11 63 -70 -11 -95 13 -33 72 57 -63 -6 64 -65 116 -29 -37 -57 -31 -4 -47 24 50 -31 15 -80 103 -11 -17 -101 104 46 -5 -7 -80 59 114 -2 14 -19 49 123 -114 -54 -2 2 -116 -9 87 -3 52 6 108 4 -7 -5 59 -78 32 -7 -114 127 41 -122 17 49 -20 70 -27 64 -20 -25 96 -128 38 -125 86 65 -83 -31 24 78 -41 23 -77 -99 -88 96 -38 80 21 1 27 -120 -59 -7 -7 -118 -8 42 -15 -20 71 87 36 -73 72 51 -53 61 -29 53 -27 -102 16 126 -11 18 -53 126 33 -15 -17 -60 -104 -99 -58 -54 99 -67 -28 -20 125 -107 -25 71 41 -19 66 29 -27 119 44 124 -100 -96 56 -30 29 -94 39 73 81 -48 95 -63 99 -94 125 16 39 57 -32 -3 -40 -96 -28 71 -19 50 120 -96 -122 -7 107 123 75 59 127 126 -53 127 122 30 54 13 26 -127 -86 99 50 -40 41 -64 -26 118 62 -30 25 -37 41 126 -44 -1 39 -14 17 -27 -85 -77 -2 -32 20 125 55 -23 -17 -7 -66 -33 -71 -57 -21 -127 -70 -116 -35 52 -62 69 67 -19 -15 -125 69 63 -48 33 -96 92 79 -15 69 -69 39 -20 -18 100 -56 -6 -9 -101 28 35 -127 -123 89 -88 26 -84 -83 22 64 90 7 -66 -102 -46 15 -87 -52 -127 78 99 -67 -97 -79 -4 20 21 55 10 7 -83 3 -52 -72 -34 -66 50 52 -13 -29 -34 -1 -10 4 127 -47 3 38 9 118 -40 -69 -83 -127 -16 71 -31 20 24 -41 41 0 -88 -25 24 60 -86 54 123 121 127 55 4 29 42 -63 81 -44 -106 -58 -54 -81 72 -84 -104 29 13 60 13 -67 110 35 -38 87 61 -92 -16 100 23 85 65 7 32 123 37 51 -11 69 -128 127 11 87 41 -56 -35 -123 -17 -39 6 -58 60 -12 125 121 29 -70 28 -60 -59 -40 26 -28 65 16 -17 -9 105 -21 -13 0 93 -42 -54 -51 -1 -49 45 83 35 -124 54 1 -30 49 -38 -29 -1 51 -64 19 81 6 34 24 -3 80 -66 -26 -7 -66 33 -63 45 48 21 25 -63 48 -50 -16 -113 43 4 -125 2 -38 -38 -26 17 103 45 -13 -47 -108 3 -24 37 32 -22 104 -22 -22 -52 -54 29 91 11 -72 -128 -105 54 21 -21 116 85 15 -17 79 -104 -55 -16 -36 61 5 -19 112 105 80 -44 -23 -6 -62 -33 69 43 -23 -8 -58 71 26 -43 17 -21 -106 -54 -50 10 14 17 21 8 95 -9 -49 -3 72 -29 94 70 8 126 -34 12 89 -2 -1 61 72 56 -25 19 124 -49 30 -27 51 4 -45 -52 35 46 36 -22 -55 -15 125 41 -42 82 -13 23 -98 -60 -83 18 41 25 -18 -33 -126 34 -22 -19 32 -36 24 -51 108 -29 38 44 -93 -38 3 17 -25 -93 -15 8 0 29 3 -68 -24 -36 -34 -14 -19 46 -42 -15 71 -40 -42 -37 81 -32 -22 59 34 -12 -90 -53 -23 127 -26 0 -47 -109 50 -55 -72 -48 -43 125 55 -12 33 -62 -53 -40 -28 -16 5 33 10 -12 47 43 23 -46 -92 30 70 56 -60 -49 47 -27 14 -29 -102 -69 61 17 -72 -54 21 28 54 -96 -17 -97 3 -71 -61 48 -49 -23 -126 27 126 32 -97 9 -4 -57 95 64 68 -5 -27 39 9 7 -10 -46 122 61 71 60 45 -81 -128 42 -21 71 -9 82 3 79 35 48 -19 -126 -4 -33 -41 23 48 67 63 28 28 30 -21 -65 -80 117 -28 -42 21 79 45 10 51 49 58 76 20 58 53 120 64 127 33 -40 15 -7 -7 -66 -63 70 -50 69 38 54 85 122 -39 2 -25 -73 54 42 0 39 86 -108 72 53 -57 -45 57 -93 28 -24 -17 28 -8 -94 107 63 -43 -84 48 -82 124 51 58 -35 10 112 42 -28 123 17 121 18 81 -52 125 -40 -16 25 16 110 5 -3 79 35 41 -119 15 87 29 -16 73 32 -56 91 35 49 -35 -73 127 45 -118 1 -99 115 89 -127 -55 -125 50 55 -30 -10 -20 17 22 82 -24 0 31 -2 -120 91 -7 -74 7 -62 -123 -79 87 32 -24 -21 32 48 9 45 91 65 -59 36 -64 -70 26 -119 64 -127 124 127 25 -74 22 94 -102 25 -49 24 51 -41 -54 -12 -100 68 28 -76 -79 -128 -8 62 -37 47 -42 -1 -26 -88 65 7 -103 30 19 -15 29 127 -39 21 78 -52 57 -35 56 -11 -44 -28 47 75 -53 -70 42 39 -9 -64 22 127 -68 66 57 -56 124 -65 -46 87 20 -54 1 122 -23 21 -69 127 -71 81 -64 -23 -26 -109 39 -17 11 124 -69 -24 -83 105 15 15 -42 -27 -30 19 -7 105 -22 -63 15 -127 47 89 84 -37 15 51 22 -36 11 -40 -76 -70 42 -24 -53 40 89 110 127 15 38 -102 19 -9 -17 93 13 50 92 -62 -62 13 71 25 20 -122 -27 39 -62 -112 14 -60 -41 102 -24 1 18 11 32 -17 48 19 39 -76 -18 -40 40 -42 -1 36 68 30 -10 13 -55 -22 21 63 -16 61 114 59 126 2 -22 -11 -8 85 -13 22 -117 10 -12 -66 -23 1 29 -34 63 106 56 9 69 27 81 -23 24 -51 9 42 41 -28 -42 120 90 -37 113 34 -87 17 72 32 -34 62 -77 50 47 71 -16 60 -48 21 -14 -22 84 -2 105 20 -43 -17 -6 99 2 -16 91 -29 72 -45 34 69 24 24 7 -102 -11 -69 43 117 -39 14 -12 -102 -63 53 54 76 7 -2 12 61 -71 51 3 -30 -26 -31 27 -94 15 15 -4 15 -6 22 -113 -50 68 -73 31 -45 -1 52 121 -12 7 96 -61 28 24 6 102 -99 2 119 94 48 -45 -20 -67 -88 54 -104 78 -56 18 -14 97 -59 -84 10 78 -54 -17 50 55 27 -13 46 47 -76 18 -35 -123 31 -50 -127 -65 65 38 29 90 12 -61 -2 109 -83 -22 -24 41 -118 -99 116 60 45 0 -56 123 -45 71 42 -81 95 37 -32 -89 2 -72 -77 -33 -34 70 2 10 -3 119 -21 44 -10 -76 -126 9 -79 -47 -6 -5 -62 -62 -72 -15 -50 -4 -124 -76 -65 -11 -8 -81 -32 16 -49 84 6 -128 1 111 54 -63 61 104 58 -6 46 -11 -59 -65 -54 -77 18 -20 -77 57 53 -51 -20 39 71 17 103 18 10 -34 9 43 62 -55 75 74 40 70 -21 46 -13 32 19 84 30 93 -20 11 -2 -7 -4 -34 -6 56 -18 26 -10 89 -17 109 -21 83 -19 -4 52 -108 -9 -56 4 9 3 56 -83 -15 32 126 59 41 31 55 22 57 92 50 109 16 63 -18 34 -46 75 -57 -23 92 1 126 126 -35 127 -42 19 -62 46 -35 59 122 -1 50 -42 32 -44 -95 -47 58 -38 16 61 70 60 8 55 28 39 52 -7 0 -20 -23 -52 -1 13 72 -58 -48 38 -90 27 -23 6 78 122 -29 45 35 -51 71 -36 -12 -36 73 63 5 52 16 -44 5 -95 63 49 -83 40 24 42 95 3 19 27 75 19 -56 105 92 -104 -66 -13 -19 -23 24 -124 16 -13 -37 38 -15 47 24 -16 54 -27 -11 -82 35 -17 52 -12 -36 44 -37 -58 -2 -33 -89 43 -11 66 -24 45 60 -15 -31 -53 14 -121 31 -25 -14 62 35 -10 5 -19 70 16 -38 -19 -7 16 -3 5 -112 29 42 27 -57 -32 -30 63 -25 12 1 -26 -63 -19 -14 22 -31 72 -20 48 -33 81 -13 -74 -14 115 -83 48 -30 51 60 34 -24 35 -14 67 17 23 2 -92 12 31 -89 32 -86 -95 -14 47 -64 -24 64 71 -40 16 127 29 6 -41 81 65 81 27 -102 10 -89 -31 55 80 -11 -1 -10 58 39 63 12 -5 -56 -91 -38 88 -60 2 -10 95 -89 15 -1 -31 88 37 50 45 44 -85 -62 6 -70 10 -55 -50 -68 -27 -52 -64 -102 2 -16 -29 52 -4 -8 -5 -3 -13 19 -21 18 -109 -15 -127 72 51 -50 -61 40 2 126 93 -114 -47 -61 -33 50 87 14 -48 -71 27 -3 34 -63 -21 23 -101 86 -31 55 33 18 57 125 -121 -19 -15 -63 -108 3 102 21 20 -3 40 86 6 -97 61 12 6 19 72 7 76 -127 21 57 9 -57 -38 51 -1 -117 44 -76 2 91 9 -8 -33 15 -24 -53 -13 -65 39 66 4 30 25 -123 -46 39 -84 -62 57 -114 51 -73 -62 -58 -13 -67 -61 -40 -72 -71 19 -27 11 -33 -18 -16 98 -82 -21 10 79 -25 0 -14 28 -11 108 -42 -24 53 5 115 99 16 -36 126 -40 -4 48 -81 47 -19 42 -17 105 14 -23 101 -44 120 -10 -7 -29 126 100 -32 -63 -66 -5 9 14 69 15 -54 76 19 -30 -43 -29 2 87 -49 39 -16 52 12 -25 8 44 -22 -17 62 13 -40 19 -2 52 37 -12 8 -41 -55 40 59 6 82 75 30 90 46 -59 -51 -49 103 -118 -51 34 53 -55 -75 59 71 -120 -85 28 4 -22 61 5 5 -5 -18 24 -81 46 -1 122 39 40 35 -120 -41 54 -49 16 126 -10 -26 -27 38 -66 -14 -73 -39 -27 21 17 -66 -51 -128 -26 27 59 -95 -79 -127 38 -67 -49 -57 -69 -111 39 44 8 39 -41 25 67 -19 20 90 120 21 -31 -47 16 100 -29 65 85 50 62 -39 54 117 -128 57 60 31 27 -85 -8 -61 -50 95 5 -61 -59 -55 65 23 55 -10 -20 88 -67 -11 -64 47 4 -36 86 -20 -118 -38 -27 27 39 -66 69 33 -94 -47 5 78 -4 39 -29 -71 -29 79 60 43 -5 -45 1 -85 122 23 -94 23 39 -51 25 -28 64 29 -106 5 49 14 122 -66 -57 2 48 -120 0 -120 -36 -13 -11 -100 30 -61 18 -124 4 52 -58 96 0 -33 69 -54 109 -6 -116 81 -86 -78 -8 8 -94 55 -50 -89 40 -80 24 -34 -97 2 -52 2 54 -6 29 -29 -64 126 60 -82 -67 28 126 -56 123 95 59 -115 -4 26 17 60 -29 14 -61 -127 45 -43 34 -13 45 -18 66 -6 -35 -96 -94 82 51 -45 -52 -32 88 -102 -42 -24 -50 -68 55 15 -64 113 17 127 61 41 -108 -47 20 -29 92 -67 126 8 -60 -82 78 49 33 -24 22 22 45 43 -22 48 121 -33 0 37 73 -30 38 48 49 37 41 -9 51 10 -35 34 -102 -16 25 -23 5 2 -31 -48 57 30 36 6 -48 5 84 -12 -36 -45 -57 83 17 -123 -18 63 -42 12 37 -73 27 21 126 -45 16 87 -67 3 6 -63 85 25 -60 52 -15 -56 127 -1 -103 -100 93 44 -7 -55 -30 -46 49 -59 6 -46 -16 44 51 -76 67 -29 -42 -128 -77 23 -118 -32 -26 -1 85 99 37 -52 127 -75 126 -17 106 120 -19 126 -128 36 2 -51 49 106 -45 29 -65 69 -47 -39 121 -78 -35 66 62 109 123 -2 -108 15 -121 -16 -119 -62 -120 -54 -56 31 72 120 26 24 -67 6 102 86 39 -31 2 117 -68 -8 80 -87 46 37 -91 -67 -76 81 65 127 51 127 126 -128 87 -67 -75 29 -52 -114 -34 -4 44 72 -45 -105 -89 -9 -30 124 -124 17 64 17 63 -50 16 65 -127 97 -86 33 -65 104 119 -60 -53 48 0 6 35 -122 16 -100 -76 126 52 -9 74 -1 -102 106 52 -55 48 58 3 28 44 -12 -2 112 40 120 26 80 -62 -16 127 122 -125 -8 69 23 -25 2 81 51 16 6 -26 -30 62 73 1 63 -10 -30 98 26 -51 70 32 -90 69 69 49 125 -7 -53 126 71 93 -44 -59 4 -62 -114 17 5 -116 -45 27 51 -32 66 -124 97 -37 -100 102 -46 4 -40 -99 41 -13 -82 45 -35 49 -127 79 91 -41 -19 58 40 -123 -88 48 9 35 23 55 102 121 17 -30 39 44 2 87 -17 87 -68 64 -20 9 25 -24 29 -68 -118 -43 -88 41 -78 -117 -14 127 -128 95 48 -38 124 85 102 -31 6 -9 -3 52 60 -124 60 -38 23 94 -27 91 -42 -10 -30 -64 -9 -61 -26 -63 -66 -5 125 3 -55 29 -60 -75 -21 -93 20 -16 -13 35 -58 -63 -13 -100 -120 -28 -52 -10 -3 -65 -22 46 81 -14 -38 0 -119 -43 13 -24 -123 49 -67 -68 -89 -18 -121 38 120 -85 88 27 -44 15 12 -116 -71 14 -105 58 51 55 11 20 56 126 -1 42 9 -30 -27 28 -13 -31 44 114 124 -126 -56 -14 -29 49 91 -63 1 12 -58 -51 -58 11 33 33 -18 56 -82 -39 -100 -119 31 -126 -80 -23 64 -66 95 -8 -120 -43 -11 -16 23 -48 3 -3 -64 67 -1 17 -59 -83 -10 88 77 -125 -7 37 32 -50 -82 -30 21 -30 -25 -47 -87 1 56 4 119 -58 -128 17 -124 -12 90 -30 -10 21 29 -91 -75 23 -7 6 14 -74 -47 -123 -48 -75 -126 -39 -27 -33 2 27 -9 -103 -127 10 74 45 38 32 -65 86 -116 26 -18 -30 -38 53 56 -126 90 -89 34 87 71 40 4 4 -109 -53 -37 30 -93 -38 -29 -7 -70 -21 44 8 -23 -35 -17 -128 -3 42 -17 51 -72 -12 22 44 4 -123 -92 -12 -107 7 44 124 127 21 -103 31 -73 -43 -28 -4 -127 -34 33 30 -127 -3 -7 4 58 -48 36 121 -57 -128 7 -128 -12 18 54 124 36 -86 29 50 -26 31 51 -61 -34 96 -117 -4 -94 62 -66 101 -95 121 9 -101 -32 26 -22 127 32 49 -94 68 -85 8 72 -106 74 53 -28 -34 -23 14 -50 -64 -10 -92 19 1 -23 -38 -70 7 -19 -27 87 -11 20 -71 -64 -33 -3 54 -42 46 20 85 50 -52 44 -36 1 5 99 -45 -51 -73 56 -48 -26 118 30 18 -64 4 14 -114 -7 45 -4 -2 -55 -17 17 11 -12 -7 -24 -98 -14 -51 -70 83 20 56 53 53 -94 33 34 -32 -58 -2 -61 -87 6 -13 127 -90 48 -29 58 -26 -66 39 59 -11 -69 -16 54 61 124 41 127 -84 -84 36 -126 67 -11 -59 -58 46 -11 -12 12 3 61 -25 45 60 78 -4 -30 -52 -72 -76 24 49 -48 -27 45 -104 32 41 -54 9 -96 -37 55 41 38 64 -65 23 -38 -25 105 -65 36 -13 -23 -15 -52 -128 -29 92 -18 73 -6 -63 -3 -32 9 -39 -3 -81 -126 29 -48 -54 49 89 14 -120 18 3 -14 -8 -8 -67 12 -21 41 3 22 -79 20 -115 -6 127 51 53 -11 -35 17 -32 27 -93 -17 -77 -8 33 4 4 -110 29 -28 -89 88 56 -56 42 -87 -34 -8 77 -51 51 -58 13 13 64 12 -6 -86 -28 -46 32 -17 41 55 48 -28 -59 3 127 -46 -70 68 123 6 -43 54 33 89 -117 98 -80 -104 0 -30 -41 -44 -60 12 -88 -31 14 -67 -30 -41 -3 -90 49 48 -1 12 -33 70 69 -13 5 127 14 -16 -128 -126 -66 43 9 0 8 -28 105 -52 45 24 50 33 -108 11 -127 -122 68 -46 -127 115 -45 20 20 -110 -87 -5 90 54 11 6 -17 4 39 18 9 -22 -57 -71 75 127 23 65 0 -91 -126 19 -28 -36 25 108 -48 124 19 -47 78 -23 108 -40 -3 86 -56 -67 -126 2 -81 -114 40 -54 -128 -95 12 51 103 -127 122 -104 -59 -12 78 -34 -30 -67 -8 -126 -119 -40 -82 -113 122 64 -124 115 -5 -15 -49 -18 1 105 -32 39 -68 -96 8 23 6 -48 26 -38 29 -61 -125 -24 -88 -100 15 -13 80 124 -22 -19 -91 -56 -58 73 -61 -19 80 30 56 -22 -109 3 -15 40 61 41 -26 -63 -25 37 50 18 60 34 -111 76 -65 108 4 2 -6 6 1 2 30 -123 71 -73 -6 -53 39 -3 124 32 7 -9 40 -12 -68 -42 -86 -19 5 -15 -44 21 33 103 27 28 -73 58 -79 -59 43 -71 76 39 33 -19 -46 56 6 14 0 -61 23 21 44 -6 3 -96 1 -55 23 60 -50 -5 -92 -4 33 -1 75 36 -74 -69 -21 -45 -36 -1 -93 -21 -125 -19 -22 -15 2 92 14 -27 -20 29 -54 -8 33 -55 -21 74 32 -29 4 29 20 78 37 -33 4 86 16 78 67 -9 46 -45 -9 29 -55 -28 67 16 -24 80 41 17 43 -11 2 -22 -15 127 127 -75 23 102 -19 40 37 -80 -2 -79 -58 -38 24 -116 -52 -19 -19 -23 -63 78 82 68 -64 -8 -1 -48 89 43 57 11 23 36 61 28 29 1 79 72 22 -34 14 37 -36 8 -80 -58 -60 -24 -33 -49 117 -8 -56 -98 12 -23 27 -4 6 -106 -16 35 92 -57 44 28 -120 -19 27 19 15 -46 -127 -25 -37 -60 -109 -89 -73 -14 65 25 -124 -19 -37 -50 54 9 2 -8 87 -15 -32 33 -71 41 -19 -90 -83 -19 4 -6 95 39 -55 -45 -88 -69 -54 -121 -49 -16 -98 -33 25 -68 -47 -19 -13 -8 35 -38 -8 -18 -118 10 41 11 29 65 1 32 -90 -91 -38 -123 -125 11 -79 -107 0 -93 -8 40 29 -57 -67 -26 -29 -118 93 -41 -127 -127 -45 -36 0 -63 -27 -65 -8 -126 -41 -1 -31 -28 50 -6 -18 -50 33 -10 -107 -48 -34 58 -56 61 10 -16 2 -111 26 -57 25 -64 2 17 29 83 49 -11 1 -16 -8 -18 25 -40 -10 27 -45 66 -53 -6 38 18 -41 -57 -57 -22 3 -9 -5 -22 -36 -95 0 -29 36 -52 17 -17 13 -70 -34 -3 21 13 -17 -23 -66 -22 -18 -101 15 19 27 -23 77 19 -23 39 -17 -57 -26 -10 -26 5 -20 12 12 -42 7 -67 -52 -33 -22 -33 14 57 -32 -4 -31 105 31 12 -4 -7 -13 32 34 -13 -9 -12 39 -3 -34 39 12 8 22 -82 22 7 18 -35 -98 -70 35 10 -14 -4 1 -79 -32 52 -78 -4 -62 -20 -60 74 -77 -6 6 -80 11 49 -70 -67 -77 -30 34 126 -21 69 -9 63 -86 1 25 -36 72 -11 20 20 -17 -19 -98 -91 38 44 93 -4 41 -91 49 -20 -37 -54 -28 -8 -58 -7 -2 3 57 -36 36 62 20 -33 1 19 -11 -22 -20 -17 3 82 13 -93 39 -8 50 83 -20 123 53 -69 53 -22 -25 20 122 101 -1 -72 55 32 57 -49 -54 -127 -20 -83 58 -25 92 36 16 85 37 -24 -8 -64 -3 58 5 -125 -106 -30 104 74 113 23 53 32 64 -95 85 -30 39 -22 27 -14 2 -41 -3 -17 38 9 20 104 -95 35 -38 8 28 52 -115 51 54 -7 48 48 114 -38 6 -78 41 66 -38 -40 17 25 79 77 -39 85 52 55 12 -45 -54 65 -52 12 -8 11 -86 20 -2 -127 -63 -74 -37 -32 -44 127 -34 2 95 -14 47 -30 33 -53 -127 -8 -5 -5 -9 -44 -16 16 -45 -55 41 84 -49 99 10 -104 40 -24 -42 -57 -11 -26 -127 -5 -36 -80 -43 -38 110 -18 -23 -7 -16 -33 -51 -36 -29 56 -55 -6 29 -71 -63 -72 50 -61 39 -34 91 -7 -39 -11 41 -122 -4 -13 27 37 45 -47 22 -17 47 -70 34 -7 -18 -58 100 29 -102 -55 9 -18 31 -27 -16 85 -3 -1 47 46 56 -47 -29 124 -66 19 -34 44 45 40 -21 35 4 -13 -37 -12 -42 64 -71 -41 33 42 -40 -20 -60 12 63 -46 32 1 -55 -36 4 -41 -73 127 14 3 118 29 -12 27 -26 82 34 75 -95 33 -1 -18 71 -47 -74 -18 -44 24 40 -28 10 -45 44 12 40 -27 37 -30 26 -103 22 -6 -62 -68 22 -93 111 99 12 -77 -53 -4 50 5 18 24 -35 -11 122 46 -11 -52 9 -20 -116 -30 -21 18 67 36 -18 -60 -106 36 123 -84 -7 -110 -94 -90 -61 16 -34 -125 -81 -57 -83 -35 1 25 118 19 47 109 110 41 -70 -83 -127 102 -50 -54 -16 -115 117 -40 -29 -28 -25 -6 119 -6 -43 -16 21 -37 -9 81 -123 -95 80 -27 -17 35 -57 7 99 49 15 1 38 -79 2 8 -110 10 68 -33 67 -49 -108 5 -12 -121 5 9 107 -16 -33 -41 117 -36 71 -30 72 104 -99 -4 29 -19 55 -104 21 -21 24 -55 90 36 -30 19 5 107 -68 -87 57 126 44 43 -69 36 -73 74 61 8 -89 34 103 -24 -32 118 -69 -47 -39 -8 126 34 -58 -70 -76 60 -56 22 28 14 -36 -89 80 105 -28 18 31 -107 34 73 125 -93 -125 -35 26 52 -90 2 -42 -45 114 -18 81 127 39 27 -53 49 6 65 -48 12 -74 9 17 60 116 42 46 58 26 96 -33 81 64 -71 -59 71 -59 49 26 -14 -3 -44 -34 115 -5 -28 -21 64 118 -16 -48 -37 46 5 -75 36 -53 47 95 9 -29 -52 -12 -78 16 76 12 -47 -8 -24 0 -56 -53 -19 22 -42 29 -70 -55 9 -53 39 30 98 58 -14 -90 77 -41 -7 -125 42 -13 -53 -1 -53 3 29 -36 87 27 -45 -51 -13 72 18 -23 35 9 -34 -88 -19 18 -12 -125 -124 -19 -30 -17 -8 -59 11 -75 5 64 -48 36 19 -96 -127 7 -67 25 30 -25 21 -46 76 -24 31 45 98 -8 -2 26 32 26 -22 -65 74 -109 -16 34 42 -16 31 -2 -40 75 50 -24 39 27 -119 7 -27 -25 -13 46 -27 57 18 -20 20 -26 -55 19 69 -66 15 12 -9 33 9 -34 -53 -38 18 -56 107 55 22 -19 51 34 -33 -16 -55 9 -84 26 3 58 2 -7 -87 56 46 -125 15 -37 19 36 -1 -11 16 -55 -121 9 -32 58 -59 -30 -27 59 11 -33 -4 78 -24 -81 -51 48 -14 13 29 97 -14 -121 10 36 -25 41 7 -40 38 -17 -35 -71 -41 -122 33 -38 74 44 5 17 11 -46 -47 -40 -21 89 -7 -44 -1 -23 125 21 51 -30 -1 16 35 -38 -50 34 33 -117 119 -25 -126 48 -11 44 34 4 17 4 6 87 11 -7 43 53 -14 32 -29 -31 41 72 -9 41 -23 71 -4 56 -89 123 -62 20 -100 4 -21 29 -43 73 40 -23 -18 34 68 -47 -58 -78 42 -30 -22 -60 17 0 15 -48 -18 7 20 23 -4 -11 18 -85 -9 70 10 101 -5 -17 28 70 -19 1 72 95 -35 1 66 -10 44 -14 -4 44 -50 28 -35 -101 97 46 -108 -33 -84 -3 -45 34 -54 -69 49 -62 -69 102 -20 -3 33 -21 10 66 -40 79 -35 -75 22 46 -16 10 52 2 -44 1 57 -71 35 12 -37 57 55 -40 14 -50 30 -17 50 39 -34 13 33 -57 -40 14 32 -37 61 37 -97 124 8 75 125 -14 64 -16 -33 -14 9 63 4 9 2 -41 40 126 126 51 26 -32 -81 67 86 41 35 29 3 -19 15 0 13 56 -33 75 45 -23 0 36 19 57 80 -16 83 82 55 15 38 -74 46 66 -24 -18 55 -9 53 -30 8 64 -10 22 127 112 43 -39 33 -79 126 28 109 17 3 58 52 -2 78 -10 64 -14 72 62 40 111 123 -16 47 127 81 -30 -29 46 -11 -45 11 -26 -29 42 44 -56 3 25 -24 1 -43 22 -79 -49 15 -24 -65 -8 -45 1 26 -12 -43 -52 126 -19 -64 42 7 -15 59 9 -25 -25 -10 58 -27 8 22 11 -58 -81 17 64 63 -26 51 -40 31 -62 74 12 -63 3 71 -45 38 -25 -95 25 2 -23 13 0 -22 -2 -25 -20 11 1 -18 21 -49 -55 -34 7 -95 -55 -19 -55 6 42 20 -11 -3 -72 3 75 15 -74 11 -5 9 90 -125 122 62 -108 -93 -17 18 49 -2 19 -6 -128 -39 28 -93 -32 73 46 58 127 -23 92 -127 -50 -63 93 -60 -87 -128 -56 -70 -19 -21 -37 -49 -7 -21 -44 -63 125 -59 26 -12 86 -119 38 -46 -29 -11 -27 37 -2 124 -38 -25 20 122 -128 18 2 68 -66 -74 32 -127 -6 -28 -69 -128 8 -65 8 -92 -15 26 123 39 64 19 -85 -127 -126 38 -30 10 94 51 27 -21 54 40 108 53 -34 -59 -29 -12 -44 36 6 -107 -97 6 46 -10 -41 -28 -36 0 32 -86 22 -41 -33 -60 2 -31 -20 -17 -120 -42 -5 3 -22 -65 -45 -64 54 -70 -15 -48 -21 -127 -117 26 -101 -60 -31 -124 -11 -23 25 -99 -102 -98 -40 -58 29 -68 21 -59 14 -47 5 -63 -40 50 -83 -49 -125 -78 32 4 -12 -64 29 -101 -22 -73 -29 -31 -31 -88 27 -80 -59 67 -99 -29 22 -67 -70 3 -60 -82 -58 -27 -5 -114 -72 15 59 -57 -69 -19 -38 10 99 -66 127 -10 32 54 31 -29 -87 -18 -44 41 -8 21 -19 12 -66 52 -8 20 -85 -21 20 -67 3 42 10 -50 -47 -21 74 61 -100 -65 65 -14 127 -59 -26 -30 -24 31 26 31 -27 -21 14 -73 49 -52 31 52 -72 7 -24 -14 -1 -79 -30 39 5 -2 -93 -10 37 -17 -53 -106 36 -8 -46 22 -26 -1 -28 12 81 -2 -105 34 16 -19 -54 -111 -12 19 72 -30 64 7 11 -33 113 47 109 75 -94 -84 106 34 -22 -103 13 127 50 -125 -23 -74 -13 75 49 108 -85 103 5 6 53 57 28 43 -38 -8 -29 76 6 -6 11 59 29 -25 15 -76 79 -73 -1 25 -101 77 27 84 14 0 -23 2 22 107 35 30 71 24 -36 90 -75 -28 -47 -106 -127 56 44 -64 -16 31 13 -23 -81 -4 -7 7 121 -55 -58 78 45 -44 61 31 -6 -23 -38 8 -94 24 85 -39 -69 19 -82 -69 -47 97 24 -128 -26 72 62 44 -78 -108 3 12 -28 37 -127 -126 124 -57 3 -85 -58 -43 109 -76 -59 -36 -83 -6 -39 -123 -36 -41 -46 5 -42 -32 -67 10 -127 -71 16 -47 -98 -25 -87 -51 -15 92 -36 32 53 55 -18 -60 123 -35 -4 -27 -64 14 10 37 -31 52 127 -40 -17 109 21 1 -1 -2 -78 56 2 40 79 -66 -54 -121 -8 40 39 -82 -46 18 -60 -18 -11 -57 -42 -76 -58 49 -6 -62 19 21 25 49 46 103 46 16 66 -127 -100 -3 -85 12 4 61 2 25 126 17 1 8 18 -27 56 60 -115 28 -100 18 35 77 -39 22 47 8 56 15 40 11 -96 10 24 18 46 -43 -94 12 -83 9 16 -20 27 -13 -61 -71 122 45 -58 -80 27 3 -44 48 66 -29 -2 0 126 111 27 -8 -36 40 -52 61 -68 -73 54 49 36 -9 -16 20 -1 49 -55 0 -116 65 85 -76 123 20 -13 27 60 -13 62 84 -3 0 71 11 -29 -100 -124 -111 -11 30 17 -8 77 -31 -17 95 58 -19 63 66 -21 0 25 -37 -82 -39 109 26 79 -2 21 -31 26 11 63 -38 4 -30 51 64 -50 127 127 4 -111 -33 -11 26 115 -40 12 45 60 52 48 -66 85 -73 36 -28 -108 15 -57 40 -24 47 100 87 -83 10 61 2 -50 -5 4 -36 38 38 77 52 10 -20 -128 4 97 -35 -5 -29 -63 -11 11 70 -88 -9 -106 -3 -30 54 -34 -28 -51 -35 -22 38 -40 35 -13 -66 4 -24 24 -51 -52 -59 36 29 -9 -26 -77 -115 17 -5 5 -50 -44 -59 -30 22 -112 -64 -29 -31 97 49 22 -28 -20 -3 -45 4 -26 25 -6 -21 62 -35 -22 116 58 -18 -55 -4 22 -6 -125 -10 -120 -36 -73 31 31 -38 -24 -123 24 -66 39 -33 -50 -31 11 -106 -8 -5 85 -9 30 -99 -34 -26 -46 7 -38 -67 18 26 -73 15 -76 -113 -9 28 39 -15 33 -15 -33 36 3 17 24 -20 -20 -21 8 -20 15 -22 -22 127 -40 -16 9 -10 58 30 -48 10 -19 -45 -7 78 -23 13 -18 14 86 77 21 -34 15 -108 -8 -2 52 10 -1 39 47 11 16 8 24 -15 -23 20 40 -20 27 6 -12 -62 54 14 71 28 -53 -29 39 33 16 17 90 14 -40 -121 83 0 127 98 5 -10 -26 -121 -14 -18 106 92 53 -53 -31 18 5 9 22 11 -69 -8 3 -36 73 -38 8 -5 49 46 46 32 28 -60 -25 23 120 10 41 40 28 9 -66 -96 -39 -51 -34 -54 24 70 -29 -16 -43 18 -8 -107 -119 -42 -19 50 7 -32 -36 5 -37 42 17 27 -19 -47 24 -62 48 106 -37 44 -40 -8 43 -84 -43 2 -35 -19 93 11 -64 -62 27 17 66 -17 36 -56 5 -66 42 -17 -41 5 46 -29 80 33 31 12 -40 79 -8 -25 30 -17 114 -121 67 124 17 56 -44 58 -104 -54 83 70 -14 5 57 123 -102 -37 -93 2 -39 75 -73 122 77 79 102 23 -116 26 -49 25 43 49 116 -17 20 73 23 82 124 47 -70 -127 19 -39 -74 59 -38 -84 -10 68 0 -125 75 -57 -2 -8 24 -52 102 124 127 -55 -95 -42 -19 -23 11 -123 -98 53 124 -41 31 32 -123 8 8 38 13 50 -80 9 83 64 124 25 -69 -52 61 48 -84 50 -86 -104 -63 -123 5 40 50 -37 -21 -15 23 -71 -94 -46 6 -67 78 -85 -99 88 -121 -4 94 -2 6 126 -51 18 -40 61 21 -7 -35 -113 110 -63 124 -44 29 88 -102 20 102 -13 -36 -45 3 94 -61 -93 -26 12 -26 76 7 81 79 -2 10 -12 -30 6 -34 -119 35 13 -125 -36 -126 18 9 -16 7 65 -76 66 15 -2 -18 -33 1 -102 11 -30 -47 14 -67 -117 126 -39 -12 21 -40 67 23 20 81 -45 79 58 -50 41 29 52 -103 91 -29 126 -16 20 -75 58 -47 72 -126 -35 30 -34 -47 34 -66 20 -77 12 88 -92 -97 -25 -104 -125 82 -7 -125 32 97 127 52 21 -89 66 23 -125 58 24 125 -18 30 9 8 31 29 119 8 -34 -55 -46 90 -74 -88 -53 54 -124 -49 -128 30 -18 11 -9 65 -7 78 9 12 -7 -46 53 -49 127 34 -70 38 -96 -24 126 23 91 -99 46 -25 68 -14 -1 63 13 -16 25 -37 -34 21 -19 26 -27 2 55 -3 -87 -111 -125 -51 -108 14 73 -128 50 -91 58 -28 -56 30 -29 -69 -68 -18 7 -75 39 -10 -101 -127 26 -57 -60 8 -40 -50 44 -113 -41 -53 -3 9 15 -70 3 -27 1 -37 23 -114 -4 -66 -23 33 108 -127 -32 8 -62 18 19 122 44 62 -115 3 -58 -64 5 5 10 30 -33 -45 -72 -126 35 -125 -31 80 -89 -59 40 55 -34 -55 -47 -22 -20 -122 -19 -59 68 -4 36 -43 51 1 53 -37 -23 21 -78 -65 -15 -18 0 30 -41 -33 9 2 -10 17 -122 -5 -4 -65 6 47 -30 -101 65 7 40 -30 95 -127 -34 119 4 -26 43 24 -3 -39 99 36 -36 -63 4 8 -17 -76 65 -12 -82 53 40 -39 32 -57 13 6 -45 58 -7 106 -13 -56 -94 -57 1 -68 -54 -73 -44 -29 -86 -57 4 -24 -16 32 31 53 37 -60 -49 -41 -6 -47 54 -18 -25 -36 59 -70 13 -128 -27 0 35 -73 1 17 29 115 99 -47 58 34 -71 -71 -74 -60 -52 30 34 -91 98 75 -45 83 42 68 -1 30 119 3 -20 -88 -90 -12 -27 -51 -116 66 18 11 77 -28 13 -26 75 -24 72 64 48 -8 7 -26 -12 68 56 37 43 -24 127 59 -58 -1 34 -63 -64 -6 1 -29 15 39 43 -49 -15 -25 -30 41 86 -15 -54 3 -76 -32 56 -75 -77 42 89 -80 -12 127 -11 96 -31 60 -97 -119 33 -59 9 24 33 22 -61 98 -96 28 -42 127 63 -44 -4 91 63 24 -63 -18 124 -1 18 -4 -42 22 27 31 -23 53 -35 68 -80 -21 26 -100 86 44 86 51 -50 -30 -54 13 -36 -125 1 -7 56 3 -57 -33 47 -42 11 -74 -10 56 126 -112 -31 36 -36 107 -46 23 74 -52 69 12 46 49 -22 -25 88 34 38 47 53 -96 73 -36 -81 -5 -83 28 78 -90 76 127 64 -104 13 17 -57 -52 111 78 34 31 25 -19 -3 10 33 -48 19 -41 -47 -84 -24 -47 -4 37 -40 -35 76 23 73 -27 87 -2 -84 48 -54 2 -88 -9 31 62 34 -82 -36 46 -81 -9 6 -38 -33 -49 -68 -46 56 -11 0 -52 -115 35 -66 45 31 63 -38 -95 53 121 20 -65 48 -76 -8 -5 -50 3 -6 -24 -23 109 -14 1 15 -39 11 -12 34 -63 -28 -7 -24 71 -2 3 -90 14 20 0 64 -5 16 -37 14 -65 76 57 122 -24 -34 6 -8 -6 9 -74 32 -18 55 -99 -105 127 46 -19 74 -45 85 26 -111 54 -109 -25 25 -72 -12 -13 -25 -34 1 -63 23 5 -83 5 -26 -4 -50 -2 -59 23 14 -97 -118 0 42 41 119 -68 -57 32 10 -108 36 -76 7 49 -100 -71 55 -16 -2 15 6 12 -62 110 43 39 -68 78 13 -38 -8 -34 -65 -23 -31 38 -24 15 63 -37 62 -49 5 19 20 23 -17 -62 -19 14 -68 -31 -32 2 -66 18 -46 -74 -48 -39 -52 117 -117 55 -57 68 -89 -19 58 -64 -43 19 -22 -121 -12 7 122 38 -40 -110 -57 -123 -30 40 -106 116 -68 9 30 4 49 31 69 24 -47 -102 -19 -3 -1 83 5 -15 65 -52 -4 -37 -10 -76 -125 -83 58 -2 -1 45 65 44 -42 -47 -7 -32 93 -55 39 -70 -112 6 116 -39 -21 -27 -79 17 127 -84 -1 -54 17 3 41 15 -5 -44 48 11 -19 -76 -66 87 25 34 -3 -8 -10 -32 -9 -61 -19 72 119 6 -58 52 -29 22 -4 -90 9 62 14 127 -127 58 -38 58 11 -104 20 -39 54 25 18 -28 -47 -117 62 -108 27 -12 58 45 -76 -59 -47 -83 -39 12 -32 -8 25 -50 4 116 -90 -40 6 16 -11 82 27 5 72 115 4 -69 53 95 -35 -59 19 -8 9 77 24 -4 53 -39 -6 89 -32 54 36 -35 27 -101 39 45 48 2 -30 -4 63 33 -9 -22 10 -94 -3 -15 18 77 -78 -15 35 72 41 -22 -1 -26 110 -11 10 21 29 90 -116 -42 99 24 -123 -79 114 -61 -33 -54 -15 -30 0 -68 3 27 -128 -9 -55 -123 62 -24 45 74 12 -61 -34 14 37 -43 90 -25 -70 80 12 16 13 -25 23 -20 57 -1 -5 -40 28 19 -33 -14 40 33 -123 -31 23 -54 -119 79 80 59 67 -62 -14 -21 -26 44 114 41 -52 -24 99 -91 -115 -83 25 -53 48 -88 -26 -66 -84 30 -36 12 -44 31 -14 -23 -7 -2 -22 20 -28 18 -65 -24 39 -123 -106 -17 31 -45 46 92 38 -11 38 39 -89 -1 -2 26 127 62 -29 121 -23 2 11 -24 27 -98 -25 -87 -35 74 -103 74 -41 -25 67 -85 38 9 86 92 -95 -6 -94 49 -21 20 9 70 50 -3 43 -84 -16 -30 53 49 -92 -2 1 -12 -11 -18 -111 9 -30 -120 41 -96 72 -50 -127 4 -2 -16 47 0 -34 -30 16 -30 -30 91 -82 -19 56 -50 75 -53 -98 -28 73 -74 -65 63 -34 -44 77 17 -61 4 -90 -20 -79 0 9 24 -78 12 -66 9 16 -17 22 -10 -72 125 -12 -39 48 -64 -36 42 -64 -53 -5 31 -30 56 -128 85 96 -94 3 110 53 31 92 -17 8 -31 100 -24 119 -16 22 -97 39 124 -6 -21 -7 10 15 14 -99 6 -70 -115 -81 -28 59 -67 75 123 -1 16 91 -34 12 74 -35 -15 -85 0 -51 -29 7 -47 -9 -49 53 49 44 -59 -48 71 35 65 5 60 106 113 48 -76 -62 40 -62 13 -27 35 -63 -128 -13 -9 -35 -3 70 -20 93 -3 -8 -22 93 -62 -89 43 37 -86 27 4 40 81 71 -37 -33 -66 90 -97 69 -26 115 -14 -35 -55 126 -60 24 -84 -87 -107 -75 16 -68 97 73 38 -52 -25 -127 -89 -72 -128 -126 -3 -86 14 64 -79 71 -113 10 -56 17 92 15 -120 41 -15 120 44 49 -84 -65 -116 -61 -53 -73 85 -90 26 103 -119 38 -2 125 -21 17 -6 32 45 -60 -20 -37 -35 -64 -40 24 2 -1 109 79 -84 93 -48 -64 -2 -28 118 32 -12 5 -28 -95 -24 -16 -21 51 17 -33 6 115 -17 -30 -45 -31 125 17 89 54 -43 -126 43 -6 -9 55 -73 -39 93 -29 91 1 -36 -111 0 -60 40 20 30 -27 -48 123 47 -89 80 35 7 -9 -43 -54 -24 -127 -98 -100 65 89 8 -95 -26 -19 66 -47 -10 -57 10 -78 -31 -50 -7 25 -95 87 4 -69 108 94 90 -50 55 89 -90 36 28 -66 -48 -119 -60 33 85 -51 -62 -101 16 -81 -9 -4 -103 -59 11 -16 44 120 -26 8 -95 33 2 -14 -38 19 -21 74 -52 81 -50 -106 -125 7 -62 49 22 114 8 -20 -3 -6 63 69 60 58 32 33 94 65 -27 20 -18 61 -17 60 69 -8 29 58 63 8 58 46 56 4 -128 59 -12 65 45 127 -29 46 40 59 -12 32 -5 127 -114 92 31 117 -14 122 59 126 123 -87 -6 30 -122 55 -114 -110 26 69 -93 44 -27 72 61 -19 -127 -27 -107 83 78 -32 98 127 -38 -101 13 126 -50 93 -38 82 -120 16 -36 41 -95 -46 95 -127 -40 108 19 5 -55 -76 -37 33 60 25 5 -39 -119 -8 -96 -52 43 -71 -57 -28 38 -84 62 78 -36 58 -78 -83 -64 13 49 -17 65 -10 -120 -81 -105 117 35 -43 -10 -18 -37 30 -1 -11 59 -123 14 33 125 126 12 126 -19 -20 -127 58 112 102 -47 68 3 -14 -22 15 -119 16 1 -46 71 -122 31 56 -40 127 -2 -27 72 -50 72 -118 6 -27 -46 37 53 -8 80 -29 -44 57 -94 -124 -55 16 20 -5 18 47 84 -30 -74 51 -66 39 -37 -10 -20 -44 20 -59 -3 -4 -57 27 5 65 62 17 4 9 -119 -3 60 -29 113 25 27 76 -52 -30 52 -86 -3 55 -10 68 0 -29 91 0 -99 80 8 80 126 -18 -81 57 -41 -80 44 52 12 -61 -41 83 -74 8 -35 126 -12 -10 10 -14 42 98 -28 67 79 67 22 4 -14 -5 -14 15 -22 -26 100 10 -35 6 -51 112 -31 -41 -78 -17 -1 -20 89 -36 53 -17 69 92 -17 32 13 -10 -38 15 -54 -25 -32 0 -21 -60 -20 -66 9 -57 -38 -39 12 -26 -58 47 48 -24 63 -41 -86 0 -12 -60 22 -33 -9 -31 22 11 84 -29 8 20 -46 107 76 -13 29 -29 3 -60 -30 25 -40 70 127 -86 22 45 118 123 -5 -9 -21 22 80 -28 -4 49 -64 3 -4 15 24 67 -1 -41 -32 -12 11 -25 -27 -50 -27 -37 -34 18 42 6 36 48 -60 41 14 41 38 31 -7 81 42 -36 -8 -21 28 74 15 5 -37 -5 -11 101 35 6 -34 6 -29 -76 87 -21 53 16 11 14 -8 -52 4 37 -7 -1 -128 11 80 8 -120 -6 -6 42 125 -63 38 -45 -31 -104 -41 14 2 -83 103 20 -79 -30 28 9 -49 -59 -44 -48 -80 53 60 -4 -62 -42 -56 11 -68 -62 -63 -120 43 -106 -104 -23 10 -20 -44 -11 75 47 92 -31 -33 -83 -36 -80 -25 106 59 -89 -119 -124 -31 -66 -126 -38 -23 -81 -127 17 -63 43 9 -51 -43 -46 44 9 94 -30 -125 -123 53 51 21 23 -25 68 -30 -76 -16 -75 12 47 -2 22 -124 85 -60 -30 -40 -29 -28 3 23 18 14 -9 61 -64 11 29 -73 -9 0 -4 -22 35 -18 -99 14 39 -69 -17 -50 -16 -39 -51 122 119 37 19 -46 23 30 -41 -5 -124 -12 28 0 -42 -14 -22 80 13 -5 -94 -32 -39 -70 39 19 9 99 -34 -28 -41 -63 11 1 -7 -12 80 62 27 1 -30 -16 -41 -31 -3 36 10 55 30 -61 44 42 -32 -17 -42 16 47 35 -71 -6 -17 -28 60 127 39 -3 6 58 -94 -83 67 -20 -124 36 47 -33 -121 127 39 -128 8 -55 -69 20 -17 -70 34 -121 72 127 49 94 63 -90 98 53 1 -18 35 -127 51 -77 -126 62 22 -17 -62 91 10 123 15 -21 48 70 -64 127 -50 8 -50 92 -87 48 -13 -123 127 127 35 25 -16 -51 11 42 25 -106 -44 77 -72 -121 63 69 97 -69 -40 22 2 64 81 -35 12 -47 127 -47 23 114 125 8 27 -69 -22 5 11 -127 76 -115 8 -46 -124 -15 -86 91 -83 -91 -73 -34 -25 14 44 116 -10 -49 -5 -33 -35 -60 -26 -62 -26 -126 -1 -16 -68 34 116 25 -79 -29 43 -3 -77 -61 -3 -47 25 -41 -49 -67 20 -59 -36 -73 -15 68 -11 -98 98 41 13 16 21 61 -3 33 -72 -124 -84 -125 75 127 -71 50 -73 -17 -22 -52 -22 -48 -126 31 1 -12 -11 -84 -125 -29 26 -44 -92 58 28 -78 -78 -97 -81 19 -18 9 -15 -25 -33 1 52 -25 -44 -16 -6 -72 -12 12 -7 -35 -31 -25 79 34 -46 40 1 -53 31 -37 50 -79 -13 -22 20 -18 5 -14 -1 25 -22 -62 -19 -7 -34 68 -7 -11 -62 35 40 -30 13 -16 57 -51 -88 11 45 22 118 -8 22 -8 4 -3 1 -38 -27 64 25 -53 -41 -5 -89 18 -16 22 6 18 28 -64 -64 9 30 47 57 11 -38 5 37 35 -109 -29 42 15 -12 2 -10 15 -110 -5 25 29 -1 -51 -67 36 71 26 -34 -89 125 -17 28 3 -19 -29 29 54 18 -34 -24 -17 -72 -74 24 126 -35 -15 56 80 -48 -128 -4 -110 8 -66 -59 -50 69 24 38 -17 -52 -7 -25 2 -8 -32 45 77 -112 64 -28 -52 79 -50 14 2 53 34 -14 109 19 -78 -127 -64 -127 -9 39 83 25 32 -10 21 19 -48 -72 -127 -86 -127 -96 40 98 18 24 -34 107 -128 -5 24 -24 2 73 -46 -89 -61 -53 127 8 30 -93 126 63 -58 -33 -85 1 -36 -124 28 34 -84 -87 18 57 -6 -41 13 -77 96 -2 18 -72 -84 -72 -91 -55 2 -63 5 -50 3 57 -41 108 -109 103 9 -2 -17 16 -36 -8 -18 -50 -38 118 -112 44 -5 -77 40 15 -124 -105 -97 -34 123 35 -14 -7 6 -110 104 38 -37 66 -10 -44 -56 -29 59 126 -114 33 -77 -14 41 -55 -93 38 4 -47 21 9 14 119 -118 7 -14 39 -52 67 107 23 1 -58 23 33 8 79 53 5 -55 74 24 -49 74 114 -30 87 -36 -67 -82 -19 -60 52 96 -2 -13 22 1 127 -122 16 76 -76 30 53 -40 -37 -94 19 -18 110 37 67 68 -43 1 -50 9 34 -76 -7 -15 -80 0 5 -37 10 8 13 -7 -32 126 -23 4 12 -97 8 47 -41 -40 -57 -93 -17 105 3 -103 -2 -28 0 42 -37 93 -61 14 -22 -6 -113 -10 -33 -14 8 -35 -13 72 -29 29 39 64 18 39 -68 58 -55 0 -59 8 -72 -4 -8 -55 31 -62 -46 -4 49 15 -10 14 107 34 -14 29 3 -16 29 8 -24 79 45 -4 -80 25 63 127 -47 -19 84 -73 51 66 18 -5 -40 78 -35 -53 -8 26 -57 127 -9 -66 34 -110 104 68 -8 -49 123 -32 127 19 97 -75 79 -66 -3 -90 -18 28 75 -56 -54 107 -37 22 122 3 28 -75 -39 98 -67 78 65 4 -6 5 -77 73 -52 35 -31 -6 -65 38 72 -127 -34 -99 -37 1 95 -34 -93 69 -80 -110 0 12 -33 77 20 -25 -11 -46 126 88 -5 42 0 42 59 55 -48 -72 23 86 62 29 119 41 21 98 -80 -30 -71 -30 -23 -32 -80 47 17 17 -19 -29 99 16 -13 72 100 -118 13 56 -2 -4 80 -9 -17 36 37 18 -28 29 -3 38 118 79 -119 31 96 -22 8 -8 64 -40 -77 31 5 -4 6 -33 22 4 -79 -56 -54 -72 0 38 8 21 73 41 69 27 -43 -8 4 -13 -126 -16 -6 121 -73 -32 19 20 -67 83 48 -21 -127 19 62 124 69 44 2 -120 6 19 80 -122 1 -113 56 -68 125 -12 -31 80 1 63 37 -1 122 95 -16 11 -111 -77 -5 19 33 49 -103 103 -53 -128 -47 47 28 -121 -21 -101 -12 -88 -31 -10 70 -59 126 47 96 -5 12 -12 -16 -124 54 38 13 21 45 -15 -37 9 -120 12 -24 84 -127 20 -66 -34 -14 -20 38 -62 77 -98 -45 -14 3 -96 -23 -56 57 75 -34 10 -55 -7 23 10 -123 54 74 -50 21 -15 -10 -82 112 -87 20 -25 -122 -10 88 -91 -59 -84 -29 25 20 -48 85 -40 17 -77 37 -64 -30 -6 9 -105 -18 -56 -92 -65 -30 62 -39 -50 -124 -29 -126 -8 44 -14 0 79 32 3 -8 64 127 -39 127 -6 31 -21 45 72 75 -39 -22 -22 20 -23 97 5 -30 -51 -29 -79 86 67 -3 -32 -43 -45 10 -58 -23 -60 0 -53 -51 67 -123 -9 -15 1 26 -35 -40 26 74 -28 -39 12 22 75 21 68 -21 76 47 -32 -39 -127 5 73 -21 36 68 5 39 15 -47 -86 -71 6 17 -65 48 56 -25 -8 9 49 61 -14 -73 56 64 -44 56 126 -28 -18 79 110 -72 -5 -3 22 74 12 33 41 125 -26 -72 6 -20 23 -60 80 21 55 -3 -21 5 18 -2 78 69 -6 25 -124 -15 -87 -56 -108 -32 -71 15 -42 0 -36 -48 5 -15 -49 -45 -64 -59 -7 -32 -88 -50 -50 -45 43 63 120 -94 37 10 60 87 22 -11 8 -61 103 0 -61 57 -85 7 -9 127 -14 -100 -13 -95 -23 71 -8 127 48 47 -22 127 -23 15 5 77 -57 3 35 -128 -16 0 -35 -30 -128 111 12 24 -27 37 -44 -61 -79 -29 115 -32 -78 16 127 54 -1 -53 -13 -55 -122 6 -12 1 -5 -45 25 -2 -24 5 -118 71 -39 -18 -6 24 74 -51 -32 57 71 68 -15 -3 21 36 71 30 -59 115 125 32 -67 -47 7 -17 -30 -4 17 -74 -41 17 -55 80 -39 -7 -68 -10 -16 -25 -12 30 -5 14 -3 44 -112 -23 -9 125 -98 20 3 -22 -26 4 31 78 28 -2 11 -47 -56 -101 -100 -97 24 122 18 -28 -15 35 32 121 65 -79 -46 -12 -69 20 -35 36 -28 65 -4 56 49 -41 -9 -8 -22 10 -56 79 21 -121 110 12 70 -54 -56 126 -13 17 -48 60 -71 51 31 19 4 -104 2 -16 44 -75 21 -30 -52 23 -61 -55 12 -24 43 38 -108 -35 -119 -38 -26 -73 -65 15 -66 126 45 -119 -21 25 79 -82 -22 -50 -5 22 -115 -103 -2 -50 66 -7 -108 -17 -50 30 50 -51 100 124 99 -54 -68 -6 -28 83 -82 23 116 -25 -43 11 89 -47 37 -35 21 4 -49 -79 -28 52 -116 -122 -40 53 113 -32 -31 -17 -74 9 -10 -16 44 22 67 16 13 -68 43 -89 2 89 40 -19 81 18 -126 68 4 -11 59 -31 7 -50 22 83 -28 76 50 118 40 -32 -86 -13 79 -79 -72 18 -23 23 -21 99 42 20 -55 48 -28 -107 17 36 -26 -15 -32 -57 127 -40 27 19 33 -108 61 94 86 -10 -45 18 35 19 72 -72 31 -61 -34 -22 50 17 -128 0 -32 94 -32 -54 -112 74 -17 98 48 -42 -63 7 -64 20 -71 10 -48 22 -3 -58 99 93 16 -70 54 53 92 -76 8 -56 90 -8 61 -99 14 -112 -70 -100 -75 59 20 88 86 -19 51 68 -47 10 48 -86 -15 -67 21 -20 84 10 21 64 -46 34 -21 5 57 61 -32 -13 -31 -99 -31 -36 -45 -19 22 -41 45 -13 42 37 39 -42 10 12 4 51 -44 -3 13 -1 -71 13 -42 -49 89 -56 17 -33 -26 14 16 26 -86 -127 -8 6 -32 26 11 36 -128 -35 77 -98 5 -35 31 11 35 52 31 59 10 19 -12 -58 106 -19 75 -2 -124 14 -81 -31 57 43 8 -1 -71 24 38 -4 2 23 -17 17 -66 -38 51 5 -6 3 46 47 -1 21 -6 -39 62 -49 9 -18 2 48 -26 38 -10 42 -20 -64 5 95 -58 -20 47 -36 36 123 -16 92 79 -59 -49 38 -62 68 -20 -33 -11 26 -22 47 -107 107 43 32 113 -17 49 34 31 20 -82 -90 8 55 44 -19 5 -15 23 -62 -44 57 43 29 47 20 6 -101 -68 -25 23 53 52 25 71 -20 32 120 -20 -47 -6 -51 -36 -94 73 39 -78 5 -126 -1 -25 60 -44 -27 62 9 -126 29 -66 63 -76 59 45 2 -59 -13 5 -42 48 126 -55 28 -97 -67 -5 -28 -36 -1 -5 8 53 -6 -49 121 60 -41 32 74 -40 23 -126 16 -21 11 58 1 21 -2 -23 -63 -41 -39 -55 -5 -53 101 -33 42 11 29 -38 -17 -51 77 9 -18 -11 -17 102 -10 57 22 55 3 4 -37 -35 -6 33 15 -45 6 -45 -19 49 14 35 35 23 -25 -9 10 38 61 43 23 69 -32 16 -2 64 113 10 28 61 -7 47 57 4 3 60 -87 100 28 -59 -46 -27 -68 47 -6 102 -12 6 -5 -16 67 63 -18 75 78 42 127 -124 -66 -83 -50 3 -48 -34 -34 56 43 71 63 61 58 39 -99 76 -124 23 -14 45 -49 20 -8 -22 -37 -124 14 68 -57 0 -50 6 -12 43 20 23 27 -28 87 75 6 -36 113 -12 -1 -26 -92 91 91 -25 -98 42 -39 -14 -78 -32 46 -109 39 28 60 -7 -12 48 60 10 -47 -25 27 26 47 -7 -49 -12 125 -59 -23 -2 22 12 -4 21 47 -54 -65 -20 124 63 -61 6 -71 -94 -20 -124 -14 -61 -71 79 2 -44 -72 16 62 -22 15 55 -104 21 31 -39 -57 -24 -26 17 55 86 -72 0 -57 -64 -123 -59 -9 28 14 48 47 67 6 49 10 35 -66 -45 -9 48 120 41 -48 -6 55 26 35 3 -10 55 -25 -32 -15 -42 -15 52 -56 -44 -21 -87 68 -46 -23 -37 79 104 -2 31 30 -40 -64 54 73 -3 0 -104 -25 58 -66 33 41 19 -125 68 57 -55 -86 -77 -22 -10 127 -52 56 5 -11 127 -77 -14 -59 0 -90 -40 -18 -46 -4 -53 24 -58 35 18 118 54 121 -55 20 -20 10 23 38 -51 117 -14 79 4 -48 9 -56 31 50 -15 43 -16 8 -6 24 6 -52 24 -20 -67 -60 -100 -17 -81 -66 -15 -29 -47 -3 -48 15 23 -21 6 -4 119 -70 14 -8 51 54 -42 -10 -8 -91 46 -125 13 78 -29 93 -91 12 -20 43 -54 -10 8 -4 -114 5 75 -37 67 13 -51 122 38 -13 -19 26 -8 74 56 -6 -64 11 10 1 -11 51 68 18 9 -83 25 -61 97 -3 -68 13 21 -105 -51 23 17 71 21 38 72 38 -67 127 -7 26 -91 -22 -1 64 15 -8 -19 5 -125 -48 -42 16 -28 -15 40 21 -88 69 -31 22 -126 -17 -24 -67 -18 16 21 5 34 123 -114 -54 105 -76 -74 -40 12 -51 -43 39 0 -40 -53 98 11 -3 92 31 -46 20 31 51 126 91 -6 -44 15 -71 -114 -47 -80 50 -79 61 -61 -103 80 -124 -93 34 81 -114 42 67 18 89 -124 -55 80 -46 58 14 -22 14 -90 -81 -7 -100 -32 -97 -3 42 -27 23 -57 67 33 -67 -15 -76 -37 -68 78 -35 -104 28 -121 33 30 -85 122 126 -2 -74 5 60 -120 -8 -67 -120 -6 -33 -45 50 66 116 -124 -49 124 7 18 127 -36 -80 -66 -32 -12 38 -92 -70 45 -65 89 44 16 -103 -48 -27 -13 9 70 33 -120 77 3 98 36 43 29 4 54 -45 126 -99 39 3 -30 56 54 101 37 125 53 20 25 -40 -61 -81 -15 -20 -48 127 1 -59 -18 -8 46 85 57 17 -98 16 -24 -14 -64 20 -99 -56 -22 68 -128 40 46 104 22 58 74 75 -10 18 -50 -56 1 13 20 -88 127 10 -10 21 -122 19 84 0 -67 127 1 80 -52 -41 121 68 82 -78 -99 -23 97 -4 125 -17 33 24 -47 65 64 -4 -34 -5 -99 100 -91 52 95 -128 -94 -88 65 0 -33 -89 82 -69 -4 -75 18 -80 -26 6 97 20 39 72 -79 -67 -89 -12 -43 -29 -49 -16 -60 -93 -63 -117 123 -51 19 73 -57 -55 -103 5 -89 -13 -119 13 -72 -31 12 -57 22 -117 54 5 58 -77 16 13 -105 -63 44 -2 0 9 -6 91 34 34 -127 -123 -86 -112 122 27 -121 11 -51 41 31 102 -94 27 -74 -48 -123 -104 -18 -21 -66 -78 -91 13 -122 -31 -93 127 127 -109 94 3 -57 5 6 -127 -7 -72 -41 -33 47 -94 -41 -70 -80 76 123 7 -54 -32 9 -23 74 -40 -18 -36 -10 -126 -29 -55 -125 29 -5 -40 16 -5 7 -26 -3 -125 38 11 -106 0 -72 50 64 115 47 47 -70 -4 51 73 -78 82 -16 -15 12 -70 -10 95 -68 34 -10 40 24 95 46 -73 -16 -96 -128 -25 -44 -96 85 -21 -86 -74 -45 70 45 -49 -23 13 9 2 -46 6 1 -63 -40 -67 -99 -32 67 -46 -43 48 126 88 -1 80 -8 -46 40 79 66 -123 41 -7 7 -19 -85 15 63 -25 -26 30 96 -61 -12 4 -23 -8 32 23 -28 -13 31 3 -20 17 61 -116 -35 9 9 28 45 13 15 -13 -1 -44 60 45 1 68 -76 29 -46 -17 -9 6 12 13 2 31 -100 -104 3 42 29 -22 -35 -7 -70 74 -88 64 127 7 50 42 -5 43 78 -17 -19 -62 97 66 -5 -89 -8 28 45 -71 -2 -47 -63 48 90 -36 -29 63 -123 7 19 -53 7 50 54 -17 61 73 125 -11 60 -69 -85 -14 47 16 -105 49 -80 -90 -2 -49 116 89 -43 28 36 -116 -12 35 1 34 17 -41 -71 31 16 -16 -31 -23 17 -61 -112 72 -95 -10 -121 -71 -64 -40 -42 -86 -25 -13 120 14 41 12 -5 64 30 40 -33 -54 -108 4 -35 45 -121 -38 -104 -46 -41 35 125 9 8 -20 -99 -90 -49 -27 49 80 -51 -32 -99 -49 -61 -22 27 -66 33 77 -127 -56 29 -117 -27 13 56 -64 -68 -52 -80 -54 21 -52 41 -15 -33 -8 -59 -37 -70 20 124 42 51 38 -20 -21 6 11 9 57 -70 -40 -28 9 3 -124 -86 124 -2 -31 -81 -3 126 16 -9 6 34 -8 -64 -64 83 -80 -46 -14 52 -118 82 119 18 29 -30 -59 47 -40 -75 -15 -81 -9 69 51 -11 -28 61 -93 124 93 29 0 29 72 34 81 122 -96 -125 8 6 18 -62 19 81 15 -52 -26 30 -92 40 44 -61 -12 -21 -56 116 -31 14 65 24 12 -31 -56 25 -60 -107 69 -4 -3 -111 3 26 7 103 54 94 30 76 -2 23 -62 -124 5 72 84 124 -24 47 126 95 49 -3 27 -28 -26 -14 -30 -15 -26 24 20 -15 -55 -127 -22 57 69 -58 12 -1 -32 -71 20 21 -77 -13 17 21 1 -76 102 125 -3 21 99 -44 -34 0 29 -124 72 34 16 59 -48 -58 11 32 -36 38 -28 35 -5 90 -37 89 33 -13 120 -53 57 28 -22 -13 -29 -31 -43 -116 30 -42 -127 72 34 -51 23 -37 -26 64 4 8 39 -51 2 89 -5 22 13 118 -58 13 9 54 5 27 -28 82 -31 119 34 -125 4 3 15 -17 29 -37 -27 66 111 14 -40 74 26 124 38 31 28 -70 -40 77 -78 11 -72 -37 -49 8 28 71 27 24 -62 58 14 34 7 -2 50 34 -27 63 -95 -69 33 43 95 -102 114 78 -14 -30 114 38 71 -33 4 127 127 33 -6 60 127 -22 47 124 29 -95 91 -30 125 39 23 9 84 77 -24 -53 -12 27 10 44 53 126 -20 -63 8 25 -49 13 42 83 -60 -3 37 23 -10 19 15 -6 -68 124 125 66 61 -34 -39 -43 -80 -69 -8 -90 21 67 80 80 18 39 -89 42 19 -13 20 37 -121 36 -67 82 -31 -36 -8 -36 -22 25 96 -26 77 -57 58 25 64 -79 26 22 -8 -100 29 -27 19 -5 50 -13 55 -126 73 26 -76 -91 35 -42 54 -34 15 -24 96 -13 43 -9 42 52 -121 -88 -26 -19 -38 1 -7 85 29 -42 38 42 16 -36 -16 -18 -42 59 -6 56 32 -19 16 -77 47 54 -3 -31 47 9 -41 -26 0 -40 -67 -2 52 39 46 -11 68 -2 87 67 -125 114 -22 -110 4 28 40 -97 -41 -21 42 -21 50 -92 18 -64 -18 -12 -29 -46 29 -97 -54 -7 -62 48 25 41 -38 44 66 48 32 -43 120 -5 89 -127 -65 -8 44 3 -40 12 20 -117 -18 64 -126 95 -1 44 35 110 105 8 13 -12 13 -83 -29 14 123 117 -46 31 36 -16 41 -10 123 8 40 -22 123 -61 52 12 84 -34 118 63 8 -27 42 118 -27 -32 101 -111 60 125 -100 84 26 33 8 3 -100 127 -24 108 46 -80 26 28 76 24 3 113 37 102 91 64 72 -119 101 -33 -102 16 127 -97 21 91 -122 120 -70 -73 -11 -40 93 65 -21 127 -42 -51 -78 28 36 76 45 15 -19 11 -71 123 -127 61 -3 -6 17 30 -67 -9 90 -101 -36 23 43 -24 -95 41 42 -93 24 -31 -2 126 -58 124 -2 -21 9 5 19 -48 29 33 -105 -25 -5 70 -18 10 73 117 -16 65 -23 95 20 57 -10 27 -55 -69 -31 47 53 -26 60 -40 51 42 47 -72 -52 -33 -78 21 1 -80 -7 -22 57 79 111 32 -77 -7 84 -87 17 25 -114 -44 6 123 -4 26 98 17 41 -71 47 15 -5 -32 34 43 -31 -50 31 -40 24 -66 60 -62 18 -34 53 -20 69 3 79 -26 28 -1 -6 -61 76 63 -39 -39 -77 -18 86 -15 45 -92 -114 -20 90 12 -127 -37 -50 -61 -43 -36 11 39 9 -28 58 -57 26 44 70 91 -39 -26 -21 64 65 -22 101 -66 -90 -101 27 -61 30 -80 2 0 -39 16 43 19 -25 -33 2 62 42 74 55 -14 -54 97 57 -91 29 -1 -9 -35 31 2 24 -33 60 -123 -2 47 127 -56 -120 92 -41 20 20 38 6 124 -58 117 11 18 125 -71 -25 -52 -45 126 -57 111 35 -37 -22 -17 -38 -104 127 124 32 15 20 65 -7 65 -6 79 -48 55 -17 -13 10 119 72 21 107 28 91 68 -16 0 122 2 -25 52 -57 92 125 -6 1 124 -26 -68 -22 -98 45 -59 20 73 79 41 124 67 -59 122 -68 80 99 25 -23 -23 -102 119 90 -19 44 120 -72 127 88 53 70 80 124 -84 23 -39 123 -85 64 119 18 -127 19 -52 73 1 19 28 -23 0 -8 15 -21 -108 13 48 -69 37 86 -118 3 -14 -13 -86 33 -24 -29 2 69 31 15 -88 -19 125 -10 20 52 89 -68 -56 -9 -6 -70 42 2 9 0 58 -10 92 107 53 60 -45 103 -49 -93 -43 -28 56 86 59 -14 87 5 -14 -8 -26 -34 -111 14 92 38 -24 59 112 -98 82 4 -25 37 4 9 52 -14 17 -111 -65 50 2 13 42 28 -55 -44 -45 58 17 -40 -50 32 -32 27 64 47 23 19 -37 -33 55 -20 71 -77 -78 -5 85 -59 1 -8 100 9 2 29 69 -103 23 31 -56 15 18 -18 26 -37 -7 1 57 -60 -11 -34 5 55 -16 -9 49 21 71 27 -46 -48 -46 121 17 -44 13 30 56 68 -9 -4 -24 -4 55 22 -58 69 -1 45 -29 -5 4 -5 -1 91 -43 93 70 -25 17 26 -13 13 10 17 46 -20 -10 -15 70 9 -28 -89 -45 -47 61 -63 -61 -12 -27 -75 10 26 67 53 -19 41 2 24 67 -15 -67 -14 -82 -26 -45 74 -58 92 -40 -7 15 9 -14 -27 60 11 18 20 13 60 -40 -125 51 35 -106 -41 92 53 68 -72 81 -94 -30 120 55 -7 72 41 46 -94 114 -45 111 52 -4 28 -37 62 -19 -4 -31 92 -123 -53 -100 -4 21 87 23 -3 10 -95 -52 -24 71 -49 -94 40 -16 24 57 15 -48 -3 46 26 69 101 32 -84 -86 -28 2 -37 -34 -23 51 48 14 -34 65 2 -11 4 -53 -77 -39 -77 -7 13 -34 -85 22 -107 78 -11 5 -8 -27 29 60 2 99 -27 71 11 24 -33 8 -5 74 -76 28 126 51 5 97 53 -36 0 -4 63 89 -72 -10 -40 -71 29 53 51 0 -20 43 -25 -55 -65 15 17 55 85 43 29 52 -48 78 9 -55 8 26 14 -69 -90 64 1 -57 -13 81 -80 61 -70 31 -60 0 -9 -41 -19 20 -31 -30 -9 -13 74 -5 -25 -29 110 8 -24 -36 116 -48 -47 -10 -54 -66 47 -2 -41 42 40 -38 -97 8 37 -19 -14 62 -121 -61 21 0 21 -125 -20 22 -84 -67 15 -6 29 -82 44 -71 -8 -37 -25 22 41 -45 -71 -4 38 -42 0 -61 49 61 -15 78 -20 17 -30 -5 -23 -21 60 -39 -82 -16 32 19 36 -50 17 -29 -59 -3 71 -23 55 -73 -3 -22 102 -15 -46 53 -47 92 8 99 43 22 15 65 -23 -27 -23 95 64 9 37 -28 10 50 -22 67 -52 -25 46 -53 -30 -22 -5 -25 -59 -42 -23 -59 37 -34 -13 20 55 -23 15 50 27 20 72 24 28 -49 29 42 11 100 -4 14 -56 117 -38 15 10 76 1 73 -25 42 44 -15 -4 -38 -92 27 12 72 78 75 5 -125 125 -69 6 49 -3 58 16 107 15 33 -3 -75 26 36 113 8 -49 0 14 -62 96 27 122 20 76 -31 52 -56 -75 -11 37 -86 22 35 89 62 -34 8 20 -58 21 49 -17 48 -44 26 97 -94 -37 -12 22 -50 -56 101 54 -16 -16 27 27 20 1 -27 12 110 -60 -101 -47 -56 49 67 106 -15 -17 -39 -50 126 -23 82 111 -112 -17 -113 -114 -31 27 68 91 59 -8 65 -64 -49 31 -84 -33 -73 121 -15 -113 -93 17 -30 43 -112 124 38 -2 17 47 -45 32 -81 -64 30 127 -28 83 -36 -9 -1 -81 -61 127 -42 -113 -31 32 14 -76 56 -16 64 -17 -125 -87 -40 -54 87 -68 -48 65 -127 -6 -101 21 -95 -38 26 -17 -70 28 75 23 -83 -90 33 50 113 25 5 127 -18 -23 127 -123 29 126 56 -94 20 -100 -93 54 10 13 -127 45 25 -127 111 -111 19 -13 4 127 123 -122 -124 10 6 127 124 105 34 -31 10 98 -17 11 -16 127 100 88 126 36 32 13 -22 -71 38 -45 95 -77 121 90 13 -34 -114 32 -100 -47 68 -54 48 13 116 113 -86 -82 -31 64 -57 19 -30 106 19 -38 -7 17 -83 -5 92 -25 -65 21 -127 -49 80 72 42 19 -124 19 76 2 45 -127 -72 -41 -33 6 -50 -1 -22 -8 -108 27 -41 68 54 31 -117 -11 -1 -18 -78 26 -15 -94 44 -55 125 127 -49 123 116 9 -59 64 -109 -28 11 -105 119 36 -32 18 53 -112 -100 4 81 125 -90 56 -59 41 -91 -119 12 19 -57 -15 -84 -101 -104 -23 71 74 76 127 24 28 -39 -38 -11 -13 22 117 23 12 126 -25 -99 123 -49 13 33 41 -7 -106 21 69 -26 83 -27 -65 -110 27 -65 -39 -56 -19 73 47 -6 74 -23 28 24 -13 24 -33 37 -26 104 -51 37 -91 -32 -127 127 -100 -25 0 64 -8 83 127 -123 -126 -15 -26 65 -114 47 -126 93 11 -49 20 53 31 15 17 -47 14 -35 -87 -31 -52 79 68 -30 -67 25 -6 28 13 -27 127 -31 76 16 -27 123 66 5 -110 -65 47 -15 -62 -36 -3 52 -128 -83 -128 -88 -123 -89 -14 -62 57 -13 -17 54 -107 17 90 -100 -24 127 9 61 -21 82 124 -17 1 46 -96 -29 -36 -30 -18 -85 -68 -78 -41 -97 -127 -113 12 6 -86 39 54 100 -127 69 127 -37 110 77 18 -29 112 -27 -7 127 -41 -45 -10 13 -127 -22 -52 126 -8 99 114 -1 -21 -26 -112 127 -31 95 127 54 -1 48 -121 -68 -4 27 122 14 104 42 44 -15 52 68 -23 3 -104 0 -126 48 -4 -67 47 -38 9 -111 50 16 59 10 54 114 27 -38 52 -105 -5 -8 -88 67 2 -126 85 83 -48 -68 -38 31 31 79 93 34 -118 103 -19 39 -75 -23 25 -108 -35 57 -56 3 3 -29 -24 49 60 -128 7 30 -77 -8 108 -3 -23 92 55 -96 -97 126 67 -32 125 -40 63 6 -39 19 48 127 43 -23 121 10 -7 29 60 103 87 -127 -41 15 117 73 -127 53 -87 90 83 61 10 3 -35 55 -91 -30 -128 -17 117 -42 -70 -54 -5 1 -107 94 1 -74 36 -127 -67 20 -18 -14 -14 108 -122 -127 -20 -124 -105 -45 87 -59 -38 -94 33 22 -54 1 127 -92 -23 87 -23 -105 -54 -48 -10 -35 -62 -52 -118 46 37 4 29 -125 126 41 -7 -23 79 48 -126 3 -43 4 -77 -85 -1 78 -127 -14 -109 5 89 -63 100 42 -3 13 103 -80 17 126 -13 6 65 -38 -9 -66 6 108 -74 -38 49 -69 53 -79 73 12 -20 -105 27 -25 -66 21 9 -114 87 11 -42 -50 8 39 -56 -42 -27 -19 93 -82 34 116 -46 49 6 -14 121 1 -86 65 -22 -3 75 -89 -14 -35 21 49 -38 83 -90 -12 -26 -79 -22 115 -51 -20 13 -46 6 127 48 -96 -17 -98 114 -69 49 4 127 -28 76 -5 21 -75 98 24 -103 61 61 54 -34 14 19 -75 49 7 121 -13 -126 69 -79 97 91 121 71 96 14 -123 -63 28 -71 55 50 -63 -51 50 1 88 -12 20 -122 -82 97 21 -54 52 57 57 8 -125 16 34 -124 -13 -92 -89 52 49 125 -45 107 -34 121 -67 108 -64 41 -12 97 -118 3 94 -51 -42 -52 -93 -121 -36 19 126 108 58 122 95 30 20 11 -70 66 -74 11 18 56 118 79 -77 -73 -48 36 60 78 -92 42 -89 23 58 -83 35 118 -87 70 -32 95 -126 -52 78 89 11 80 69 21 12 -2 33 -86 -37 127 120 -39 123 96 78 117 -53 -120 18 46 -65 -12 51 31 -79 39 -13 106 -97 -17 -57 90 44 52 68 9 -17 31 -34 41 9 122 -20 44 -4 -72 65 23 -27 -5 -69 -107 -11 -45 -59 0 -90 42 112 44 -15 -7 48 -42 127 -27 39 82 -84 -53 -122 -48 -41 13 27 12 -59 41 42 -69 -18 0 -72 92 -41 -28 -4 -85 20 -21 -87 127 67 -99 83 -33 95 -65 21 -87 77 -44 22 5 44 -110 109 -49 -34 56 -91 0 -18 -35 17 -39 -76 46 102 -8 116 79 -74 -48 110 -71 3 9 -22 15 47 -9 87 -53 -16 66 -27 35 8 -51 -57 -63 14 -109 -52 -59 46 -125 37 36 54 7 -82 37 79 45 56 11 -58 64 66 -8 -30 -46 -67 42 32 -8 78 125 -18 21 -35 52 42 11 -30 -19 -23 -14 117 -40 39 -16 -36 36 59 68 41 15 116 -7 -18 58 47 -5 58 7 -52 94 59 -35 33 67 109 24 3 23 24 58 25 -65 52 89 21 -104 81 0 119 78 -22 108 17 2 50 -44 22 110 -27 123 -21 -72 31 -61 47 82 -11 -12 -42 87 -16 16 -23 -35 45 -41 -45 19 -6 -44 59 -11 30 100 18 71 8 76 109 69 18 9 29 64 59 69 59 117 -30 -57 125 22 -30 -20 54 60 -43 55 56 120 -46 9 7 28 -75 -12 18 94 118 2 56 39 60 -53 91 -49 -60 5 12 -58 48 -22 5 88 -22 -25 16 46 -13 -39 -31 32 30 28 10 26 33 -23 0 -16 -7 64 -9 -65 59 -3 37 -67 -15 6 -16 1 66 34 2 68 20 10 36 -26 8 4 25 62 3 -11 56 29 -9 -27 40 -60 100 -41 -16 -24 -15 -13 -103 2 12 21 -61 5 77 -31 9 80 30 31 22 -50 -44 39 -22 37 -5 -57 32 -125 85 -32 24 25 -33 71 22 -47 15 -37 -13 -15 27 -20 -7 63 74 -15 -24 20 46 -122 118 -6 -9 123 13 -99 -94 58 -10 29 42 -2 38 -62 -41 -46 11 -55 -12 100 -32 5 -100 -4 21 19 -126 -65 -51 10 126 -13 -8 -12 -5 -10 40 -8 -22 68 79 -4 -87 58 56 34 9 -126 -82 -46 -115 -63 1 7 27 -24 -119 -33 33 -21 79 27 -40 31 12 -31 64 4 -46 -3 -23 -52 89 -58 -77 3 103 105 20 31 -101 55 41 -118 16 11 36 28 38 13 -38 8 22 37 -102 11 34 8 -30 -39 -6 -63 9 -53 124 -68 103 32 -84 -2 -125 13 88 -55 4 -45 -50 -20 -81 47 -53 26 -58 11 17 50 -113 16 -4 94 127 -65 59 14 -16 117 -128 19 81 4 14 -60 -27 19 18 62 55 46 16 4 -12 -25 -50 -45 73 -80 -93 -21 20 -11 50 -93 52 -46 -44 -7 -37 53 -28 14 14 -4 -3 -21 -50 -76 -7 -46 -66 40 -21 -3 -45 -127 -24 -94 -9 -128 93 -14 14 53 34 36 -15 27 -29 -8 2 -120 17 -101 -10 -20 48 41 127 -46 -65 -11 -34 -39 -12 13 -55 -121 53 -5 39 52 -125 -34 126 16 -61 -3 50 83 -10 52 34 18 16 -55 -38 -5 -3 -29 43 -58 -15 -48 -22 26 1 2 -88 -72 -65 -102 18 26 36 62 -77 -9 9 -12 -49 -82 -80 -31 14 -69 -49 -46 -67 94 -26 79 -5 16 -3 33 21 112 -44 48 -33 63 -115 5 90 80 70 -52 5 -6 49 -16 126 -77 -98 -11 -51 57 114 -50 -82 124 -50 19 -124 -10 33 84 10 46 9 47 -94 127 -127 -34 -15 43 10 52 -103 -14 24 119 -92 83 -89 34 21 -71 94 -64 -24 -76 -49 -43 28 38 -2 28 79 -126 126 -15 -52 -30 -80 -128 -67 45 26 37 39 -39 -53 48 5 41 -33 28 55 61 8 -13 39 51 -78 16 -39 47 -6 -51 23 22 69 -46 121 -8 76 37 -47 -31 -45 -67 -103 17 63 8 15 18 8 61 77 42 16 -29 -10 83 43 -38 103 -128 51 61 -36 75 -13 -45 -20 -37 -25 20 61 -80 58 12 -70 5 -39 -95 -25 -35 -8 127 62 -50 114 -37 55 44 -41 -25 -83 124 -19 9 -1 51 17 21 -37 -8 47 82 31 38 28 -23 -85 -5 45 37 -43 73 0 71 -15 56 27 -71 -115 4 39 73 63 -71 38 98 -60 78 -58 35 52 47 52 -7 -32 41 -2 54 -124 -24 19 -15 40 38 79 17 70 -4 -29 -39 46 -110 -52 0 73 -47 7 21 -48 39 -12 -111 -10 -73 97 -83 35 -96 50 29 -21 -13 -57 -122 43 15 -22 49 27 62 50 127 -127 7 26 43 6 -59 -41 -59 -13 -68 31 -30 65 109 -52 -27 -117 -125 -92 127 -113 9 35 31 -110 68 61 22 50 118 14 48 66 -59 62 -46 64 41 -59 -6 -23 -9 -25 -73 -18 -75 -27 -64 -6 0 -128 -11 73 -54 -51 -33 -65 125 8 20 32 46 18 -30 34 -83 60 -9 12 103 -39 32 93 -123 4 127 29 -18 15 -57 -49 -44 -127 65 -98 52 20 -128 98 -55 -10 -67 8 27 97 96 22 -10 -64 87 18 77 -17 -42 -19 122 -28 23 43 114 74 64 81 86 31 -41 27 70 -88 -29 55 -78 16 47 46 63 47 -17 18 64 -56 -30 -73 -19 -79 -111 -4 -46 8 70 -101 -30 -10 -126 120 -50 5 -42 -44 -11 77 -50 -10 -57 22 -96 -28 -42 37 117 1 -15 35 81 -25 -40 -83 42 42 -66 -39 61 -64 34 37 -17 -118 101 -39 -8 -70 -74 5 -23 -6 2 61 10 82 -20 -63 -56 -53 -39 -6 34 -100 -127 55 4 -33 13 -16 -34 -100 -47 -66 42 -42 -114 -36 18 67 -63 2 70 27 16 -57 107 -52 126 -76 -62 65 4 -12 -124 -31 -2 18 -38 -76 41 -76 84 20 -62 -64 34 -48 -128 38 -95 22 38 1 -28 68 125 -36 -38 79 18 127 13 -46 -17 17 45 -111 -50 75 -127 -42 -61 8 7 -20 -60 93 30 -68 -65 -10 -49 10 -92 63 83 24 23 -47 -94 42 -45 -40 -9 9 -45 -37 -127 80 18 -4 -90 -9 -69 -71 -98 76 -27 24 8 -95 -23 43 -21 -2 -25 112 -85 79 43 -59 16 -55 -24 -10 -53 -11 47 1 4 -43 41 -9 79 -57 12 36 31 -56 54 -57 13 36 -2 88 108 -32 1 34 55 44 15 -54 -4 -98 -9 28 58 -4 -35 -64 -9 43 -70 29 -36 -30 44 -28 -44 -64 33 -11 13 82 -22 -28 59 83 29 17 48 -18 4 -47 36 13 -92 -41 11 25 -9 -1 -75 -54 7 18 57 -35 45 -29 -43 30 -36 -109 14 -127 -75 1 -1 -17 -36 -45 -24 -42 -24 -22 -7 -73 80 -15 -14 109 126 -123 36 67 15 64 15 81 -12 80 -29 4 -49 17 -15 48 119 1 119 21 87 -9 -10 34 37 50 8 26 26 -99 28 73 -82 -14 44 83 22 52 102 -65 -57 114 -25 84 -12 -33 -93 71 42 9 73 60 59 -7 37 3 -27 54 61 -38 24 -21 13 -76 6 -35 23 -75 25 70 58 58 118 -4 -32 7 92 -38 89 32 -83 -25 123 -10 -100 105 55 -48 14 68 35 -55 81 89 -17 -79 31 13 10 -91 24 55 -41 36 98 29 -65 36 27 0 -10 -96 10 -3 57 -5 -3 -48 -25 -1 -30 6 11 28 15 -7 38 -27 -33 54 21 45 -66 2 17 -45 -83 41 -17 5 26 -64 -6 -7 -10 11 67 -36 79 -9 -14 5 37 21 -60 -95 30 -106 -75 73 -1 46 6 -6 26 -59 -39 -29 39 -27 30 -35 76 -50 -38 13 26 22 -7 53 -10 -43 19 -46 12 -9 -16 56 -37 27 4 50 54 -47 54 -18 -79 29 28 -26 -21 -66 22 -54 49 -67 18 -51 -35 -106 24 22 -10 34 46 -21 126 25 -6 -62 -35 17 -37 26 -61 18 -14 27 -3 74 -29 80 -86 37 59 -24 1 19 -91 46 13 -33 14 -13 36 4 -31 84 -2 16 17 -72 42 -51 -106 -7 46 7 36 36 18 -36 -30 -75 31 16 -17 -16 76 23 -14 102 16 -9 3 -89 -28 36 -27 55 -31 52 -30 -23 7 119 11 29 8 -25 -127 -25 -10 95 27 -9 55 23 -86 101 -50 -71 -11 65 46 25 -5 71 4 -40 -85 -69 -88 -56 -115 45 -39 -34 15 -26 75 -5 -4 51 3 -66 -27 -92 47 40 -49 -47 -72 10 28 6 10 12 5 116 17 44 31 21 76 -122 -79 -32 -33 27 -90 33 116 90 17 71 125 -85 101 -88 -30 6 22 11 -94 47 2 -21 59 24 31 38 12 29 76 -2 101 6 122 69 -28 30 -19 -116 -10 -79 -2 81 -35 -21 33 65 -45 -76 -89 38 46 60 127 -43 30 67 63 32 -4 -23 -13 -100 -50 2 23 20 38 12 -38 -79 18 41 -6 -116 -30 36 -38 121 -82 -80 -70 15 3 -107 33 -48 1 5 -21 18 -9 46 79 -14 73 -92 89 29 -73 -79 59 33 -20 28 83 6 35 21 -57 35 -64 -77 -21 21 -17 -60 63 64 -105 8 -17 -18 127 -3 -5 -6 30 31 -54 11 126 2 -37 58 113 -2 49 52 27 127 -29 -72 8 -4 -54 -55 38 -15 36 35 -74 98 53 7 -124 41 -37 77 -33 -15 -42 -47 -48 -109 24 9 -27 -67 -56 84 58 -3 8 -41 51 -29 -99 -36 37 -30 -69 -11 21 23 -29 47 -98 103 88 -4 61 2 -2 46 -13 -110 76 10 25 11 42 -10 75 25 -27 -10 0 42 -4 -10 -16 -4 105 -33 -46 -10 -126 -33 66 -60 -45 -73 89 42 -5 -27 44 -36 40 4 23 -49 17 -87 -26 20 -66 -8 -21 -5 21 -1 -40 68 -24 -7 41 9 31 32 -18 26 -17 21 35 -17 19 -116 60 -101 45 79 -10 0 27 -5 71 -27 6 -15 -7 55 -52 -54 -6 34 67 -11 -47 95 -31 37 -9 -106 -38 -11 -73 47 100 -125 -116 -113 -31 -116 -99 -127 -22 -25 -127 6 -108 32 -122 5 -48 -113 45 31 27 2 -24 10 -86 -9 -12 -29 -26 -74 38 -81 -104 14 -50 0 45 74 0 -35 31 76 -23 123 -36 -3 -17 -77 47 -32 -50 82 14 33 11 -41 37 13 33 -46 8 -41 -93 -127 102 -34 -55 -43 -54 -54 -71 61 56 -80 51 40 -27 -11 -16 75 -10 -63 49 60 19 39 -31 77 -104 -9 -45 -35 -9 20 36 38 -21 38 -10 14 73 13 1 -48 93 -4 -13 99 -38 -3 -51 72 60 -7 87 -22 66 -28 23 -16 -48 72 -2 -65 -6 57 9 74 -48 -27 -12 66 -4 26 -11 8 80 1 -53 -2 24 33 15 -23 -4 3 -33 66 -24 -23 -33 -127 -70 -10 13 -35 33 -26 28 0 -55 1 27 -6 -33 -19 63 56 6 -88 11 19 44 27 9 -46 -5 15 -72 -1 23 -39 -20 79 0 -110 -37 -46 27 37 -69 45 -38 -30 -5 42 29 -11 34 -69 27 -39 83 22 14 -21 12 44 34 -34 36 21 11 20 -16 17 78 -80 19 -126 107 29 8 16 29 28 17 56 89 54 -41 127 4 103 -17 127 122 -11 -4 -77 72 -45 -104 43 35 39 62 -39 27 -11 -16 124 -83 -56 37 112 70 5 32 -5 18 -107 -53 21 -78 33 30 -126 115 -1 127 61 94 114 30 -11 92 -59 -45 -46 120 -40 11 2 27 62 14 -114 -36 -31 95 16 -1 104 121 86 54 11 1 -10 124 -27 -26 53 27 -16 19 52 -127 125 47 122 57 -36 35 -9 -13 123 -11 13 85 -33 18 -127 29 -47 -77 25 10 67 -21 8 -34 55 8 21 -29 -2 127 107 65 122 -29 3 105 -44 -24 -1 -2 1 -54 46 56 13 17 -73 66 -17 30 2 11 61 24 -21 -12 -64 4 45 54 84 52 -18 -80 22 15 60 15 -83 10 -19 -83 -46 -28 -31 37 55 -63 46 -16 51 53 14 -61 47 65 4 64 -127 47 -128 14 31 10 77 23 -56 -68 -111 -84 -43 45 -45 32 35 -33 -25 -14 14 22 -29 -34 115 -22 7 101 103 15 30 -50 -40 -110 -75 55 -3 -72 14 39 42 4 22 -27 59 13 -15 15 -97 63 97 -11 127 96 -95 63 -28 -19 40 -30 63 -4 -38 -96 34 -42 8 79 -71 30 84 -31 -89 -58 -8 47 112 -46 59 -89 127 -86 79 -3 -62 44 45 52 61 121 -25 96 -19 -19 -99 -8 -49 78 -65 38 60 45 22 122 125 8 61 32 -25 -64 21 -42 15 -24 61 -15 -17 -61 -126 -2 -27 -127 52 -29 64 52 -125 122 -128 6 -37 -50 1 0 57 -72 -52 -2 58 71 -106 -78 52 30 -89 28 6 114 53 41 -52 -5 57 69 -55 92 -61 -21 122 62 31 110 51 -34 46 60 -11 -53 126 3 -57 43 65 -31 105 45 45 -48 75 1 42 -16 -4 -127 -39 11 100 28 79 -91 -38 74 76 14 24 -126 36 23 -8 -123 36 19 -53 7 44 63 78 79 10 -76 29 49 -3 126 89 -54 112 2 -3 31 -9 -30 -30 -97 -18 84 7 63 91 -27 -2 -51 -8 38 -49 -6 -27 66 -111 127 102 -68 -9 18 -75 -46 -126 1 3 -75 -80 127 70 21 19 69 -14 120 67 -45 -30 -98 115 -6 106 78 -57 15 11 117 1 41 -31 -11 83 93 -6 73 127 -56 62 -57 84 57 -121 -102 127 67 -25 -110 120 54 -51 110 -57 68 91 119 38 21 -21 97 0 44 3 0 -87 55 -16 -95 -50 71 14 52 -35 40 -62 -14 -1 -19 -55 14 -45 -36 -34 35 -33 -39 -20 -74 -35 15 -80 -33 83 32 -15 -47 58 12 -25 -46 -27 -44 33 22 29 -31 -64 3 28 87 121 -41 36 63 11 -34 -2 -105 33 39 -73 -8 -49 -44 -14 -24 8 -53 17 45 0 13 34 35 28 -85 -56 22 96 -35 30 -98 -54 32 -75 26 -15 -128 2 -83 36 67 18 -68 -80 24 6 93 32 -2 -29 17 -5 -38 62 -14 -54 126 5 104 112 -26 38 18 66 -17 14 -8 1 2 69 72 -60 -10 10 15 1 58 50 -6 -76 7 -14 63 124 39 29 39 93 42 -52 48 50 73 89 65 111 28 73 48 2 37 57 -26 30 29 19 73 42 -103 126 -14 16 -70 -16 48 14 114 108 43 30 127 119 -37 25 106 21 78 52 99 46 47 68 21 -13 -3 -79 45 -23 57 100 65 72 85 102 11 81 73 55 -13 -59 23 -6 -57 -21 -3 -60 3 -11 31 -16 -67 -121 -50 63 -62 -29 75 54 -47 -61 65 0 -68 -32 -64 -31 -84 82 9 73 -49 81 34 4 -19 85 56 94 -41 -59 -40 69 126 0 -93 -49 17 -76 -101 12 12 -47 -73 47 30 30 -90 10 -70 31 64 -127 24 22 54 -10 -14 -22 19 -26 -118 54 -41 43 -7 -33 46 1 53 -11 -6 4 8 -24 32 -31 4 -18 89 -51 66 37 24 -8 -17 -21 40 -2 34 -56 38 65 34 25 8 28 57 -93 -122 -69 -86 -40 -21 85 5 -54 -33 -44 -78 24 27 26 5 22 -17 -11 -34 -6 -126 9 23 -35 25 43 86 94 44 -75 -22 -43 -128 -22 92 -100 75 22 -10 6 -44 -125 -3 -6 47 -99 80 21 8 63 -74 -1 74 -71 8 42 38 33 0 82 -27 1 126 110 -6 8 25 81 -21 -124 2 59 -62 -12 44 -110 42 -73 -32 52 6 29 -9 -46 -29 1 -87 79 -31 -41 36 109 -25 34 47 -125 26 57 34 9 60 36 19 10 -61 126 86 6 -66 8 -2 54 -107 -2 -3 -4 21 -28 61 -21 38 94 26 41 24 36 39 -42 23 33 -40 -18 110 -38 -10 24 -33 -27 -12 32 -72 -7 45 -3 -123 -42 -93 -45 9 -128 -16 -2 -7 42 60 -38 -15 -72 -12 -32 108 -1 -85 -29 39 45 37 -30 67 -123 -18 15 21 11 -2 37 121 -35 -63 17 -29 54 -22 79 15 127 18 126 17 111 -56 -89 -7 -47 126 66 34 32 75 41 7 3 -31 65 -7 -39 23 -110 23 74 43 -87 25 -26 -47 -15 -45 -127 -38 -61 9 58 51 -81 -55 -42 40 83 37 -18 -117 52 -119 -32 -15 113 -128 63 27 -113 -38 26 -2 -40 127 -62 -47 -31 58 122 30 22 -17 -59 -96 -66 100 12 118 -60 20 -115 65 -64 -90 -15 74 -33 13 -28 53 55 -15 22 115 6 -53 35 -8 45 25 21 -38 72 4 -107 -15 32 -7 -24 10 -30 46 -49 -49 -41 -18 63 -25 -7 -16 5 46 79 -52 10 26 -97 9 82 -4 -33 -31 40 22 -36 -16 -22 22 -19 -47 -25 -66 41 -71 55 -44 32 -43 32 28 -20 32 13 2 38 -72 -57 33 -4 81 113 26 -42 31 -13 -14 28 40 19 -68 -34 56 -64 65 31 0 17 8 -12 6 -15 13 -42 -74 4 -20 -19 104 -6 33 12 -92 39 86 -87 27 -34 16 77 28 44 39 126 -13 45 87 -47 -5 17 101 -40 35 -23 127 -101 33 5 -30 61 28 33 25 -70 -127 108 63 15 126 5 15 70 -34 14 -58 -3 28 53 -23 -3 25 20 -15 75 -6 -40 100 23 -20 18 27 79 -23 13 -30 -62 36 17 -96 -3 -51 51 60 -75 -59 118 -20 -11 -66 -10 79 -54 125 76 69 84 -19 28 33 45 26 -88 13 36 -46 25 46 -1 35 63 7 70 -78 5 -20 11 23 -42 33 29 125 -88 -9 -90 31 96 -6 20 -30 78 -16 -12 64 23 -26 -37 29 34 -20 -11 -16 -10 -39 127 43 -39 -14 3 -84 3 -10 38 -16 -9 -59 91 -4 -68 36 10 -109 -7 18 -24 126 -44 16 68 -51 59 72 -39 26 -29 -31 26 124 -47 60 62 -17 -11 -20 84 26 12 -80 -31 -38 56 -82 19 13 -26 -66 42 -25 60 8 -60 -7 23 10 56 11 74 -100 41 24 -7 -93 -50 48 -112 33 -29 -32 -67 127 -35 -13 -9 14 35 89 44 75 -62 -19 -15 -73 -46 81 11 -9 49 -44 -85 39 -87 127 24 -24 -91 127 -47 62 -8 -69 97 -16 -128 -14 93 -39 -3 -21 23 20 -53 -60 -69 82 -105 -31 34 -33 -29 56 -7 5 17 -83 37 -48 113 31 103 -55 -21 22 -33 16 35 26 -38 -68 61 -7 5 36 -47 -19 -65 -90 -42 33 37 -20 -20 30 -30 59 -12 61 -87 -2 -122 36 -78 17 -43 126 -90 -21 107 -74 10 -17 -7 -103 -127 -96 15 52 -115 73 1 22 -2 41 -50 16 46 -93 124 -22 -118 54 88 -39 -27 52 -3 13 -120 64 63 -102 13 51 30 -23 0 -73 -58 4 32 -25 -41 36 -55 32 -44 40 12 -66 -127 -24 -4 -124 77 -46 12 -20 100 -76 -53 22 10 -57 41 -112 -77 -85 -94 51 126 -111 90 -110 -126 -105 -29 -99 -24 30 -121 -39 -103 -16 -125 -88 37 -40 -81 -54 19 -47 2 -76 -70 -85 -62 -22 -62 69 -39 80 -37 1 50 -28 -51 -2 29 33 18 -58 75 -38 15 127 92 4 -72 -76 0 -61 31 55 -117 -62 55 -70 -27 51 -54 28 54 75 -15 -43 31 -5 33 -34 39 -53 -21 -45 -85 76 -40 13 32 4 25 -78 13 90 28 2 -40 84 64 -23 8 28 17 -78 -61 -42 120 -34 -26 9 -51 -49 20 -92 24 7 -26 46 -57 -30 -58 -18 -126 -12 60 57 -62 -12 53 73 -26 -71 70 71 75 -55 -9 37 33 -30 -24 -23 15 58 -17 -126 54 -63 -40 66 -15 -40 -127 -12 8 -34 -105 13 -4 -11 -43 -23 -35 77 59 -8 -20 71 -18 63 -7 46 -114 11 -60 28 31 -77 124 -62 18 -86 -67 -14 -55 50 21 -52 28 -62 10 -33 -10 14 -37 -78 -77 -23 -79 28 7 -30 -12 127 -66 -2 -50 52 -11 1 54 -38 -3 -3 93 5 69 -11 54 96 29 -38 35 -46 23 -11 -2 107 28 -16 111 22 -57 -2 16 -4 -6 -25 18 66 16 -10 -13 69 26 -28 71 -9 56 -25 51 86 18 21 71 -10 60 -4 -20 23 30 31 3 17 27 -13 -37 -23 -41 -92 4 76 9 52 -41 -43 55 82 54 -61 54 62 -27 113 -4 35 -11 10 61 -15 -13 74 -100 36 5 34 19 36 5 97 67 15 83 38 -27 70 20 -10 3 16 -27 -20 25 2 3 13 33 -22 23 -1 -2 17 -26 46 5 23 8 43 -2 -34 75 -37 0 71 44 -29 19 13 3 41 -5 9 -14 -34 -9 10 -31 -40 23 11 -5 18 18 1 31 26 -12 7 -5 63 -20 -8 23 4 31 21 -13 -27 -48 -13 -14 29 -2 11 18 14 4 19 -41 -21 -10 6 -6 1 65 17 -63 -1 -55 -19 -7 28 2 13 40 6 -17 1 15 18 16 47 11 -87 -10 21 9 -14 12 8 14 -22 -17 10 1 -23 1 -20 -22 -6 44 -5 6 37 44 -11 62 13 0 -35 -63 20 -32 -27 -30 20 35 -25 -35 -20 40 -30 16 11 63 -25 -13 -55 -14 45 -13 -27 25 -10 -10 17 1 14 -17 -30 -68 41 -9 -5 -19 -33 -61 -34 24 59 28 -32 43 -40 11 0 -18 14 28 -3 25 6 -37 14 10 51 43 26 4 19 12 -35 70 -10 49 -33 -14 -22 96 22 1 18 8 16 3 3 7 30 28 20 15 0 4 -4 -6 -8 10 9 -12 -38 -34 -31 2 29 14 12 11 5 12 22 26 48 61 67 81 91 99 98 91 84 39 -3 11 16 -4 127 127 115 60 25 13 13 15 5 2 11 2 -1 -1 14 20 14 8 8 10 -10 -36 28 29 35 32 32 36 31 24 24 27 12 13 14 8 8 25 27 0 -8 -3 -6 32 -18 -13 -22 -46 -63 -70 -72 -81 -70 -41 -13 -17 -15 -7 -3 -6 -6 4 1 -9 -35 -52 -48 -25 -1 18 12 -2 -5 5 32 49 65 67 50 43 37 20 13 11 -16 -11 -11 -68 -13 24 27 28 34 35 26 15 8 8 10 2 -4 -12 -36 -68 -72 -21 28 47 54 126 -10 -30 -24 -33 -22 -20 -25 -28 -30 -34 -41 -44 -40 -37 -32 -23 -15 -12 -6 -13 -28 -1 -51 -70 -62 -27 -6 -8 -3 -26 -47 -46 -39 -18 -7 -1 -7 -7 3 -18 -37 -18 -1 2 -22 -23 -38 -37 -42 -38 -38 -32 -8 15 24 22 12 -12 -39 -53 -42 23 113 126 121 107 -12 -6 6 19 17 9 6 9 5 -9 -8 -7 -2 10 36 43 26 -2 -2 3 -12 -45 -71 -128 -128 -110 -67 -62 -44 -38 -50 -64 -60 -60 -55 -53 -38 -18 -14 -21 -33 -36 -38 11 -48 -24 22 40 56 60 77 97 108 86 46 30 23 9 -10 -27 -39 -50 -62 -60 -44 -14 21 31 40 30 35 43 37 22 12 20 28 24 19 19 18 11 8 1 2 17 29 27 14 21 9 7 15 22 28 21 7 -8 -14 1 3 -3 -9 -22 -24 -30 -29 -17 1 23 -86 -106 -101 -89 -77 -71 -58 -52 -50 -61 -67 -65 -67 -75 -71 -68 -73 -92 -96 -82 -66 -55 23 60 82 58 26 13 14 16 20 21 28 32 28 24 43 44 34 -1 -40 -16 24 40 27 21 6 -8 -5 8 19 5 -25 -47 -52 -37 -27 -20 -10 -4 7 17 21 31 64 52 -29 -34 -26 -33 -29 -30 -36 -37 -33 -27 -19 -35 -38 -27 -41 -44 -38 -44 -70 -81 -72 -90 3 -4 -13 -23 -31 -32 -32 -42 -62 -66 -53 -42 -26 -19 -9 -8 -9 -9 -21 -23 -20 -21 -17 -26 -63 -104 -127 -126 -108 -113 -111 -118 -125 -118 -116 -113 -125 -127 -128 -122 -126 -126 -127 -121 -65 -54 -59 -55 -49 -36 -25 -24 -26 -29 -28 -9 5 0 -9 -19 -29 -77 -115 -94 -79 -82 57 76 61 101 85 47 24 29 29 24 21 11 -4 -13 -20 -24 -17 -4 -23 -30 -33 -18 -37 -34 -32 -26 -27 -34 -40 -40 -44 -40 -33 -32 -37 -36 -26 -26 -31 -26 -10 -8 18 46 -4 15 19 36 55 81 84 88 70 43 27 20 18 22 22 6 -3 4 0 -8 -31 22 46 55 69 56 42 48 71 71 27 -10 -20 -34 -20 -14 -20 -8 2 2 3 -4 -17 0 -121 -96 -63 -46 -36 -27 -35 -37 -43 -53 -47 -30 -29 -30 -22 -32 -39 -44 -34 -20 -4 -4 -38 -13 25 41 55 58 59 57 51 48 46 39 40 35 25 21 19 12 16 34 59 39 33 -6 -22 8 21 20 27 37 31 17 12 24 37 39 45 30 21 28 12 11 35 36 -33 -19 -6 -12 -9 -4 -6 -10 -9 -19 -22 -8 -12 -19 -23 -20 -4 12 9 5 -2 -35 -20 -6 -10 2 8 3 -6 -5 8 15 27 24 7 6 8 5 -1 -47 -45 -54 -104 -128 13 15 9 17 36 58 83 92 76 52 34 16 9 -5 -6 23 45 10 -3 -2 15 28 -64 -53 -37 -14 0 -15 -19 -10 -10 -24 -29 -57 -59 -49 -30 -12 12 49 48 14 -32 -43 1 12 10 8 27 30 26 27 16 0 -10 -13 -11 -13 -16 -15 -18 -22 -24 -25 -27 -38 13 12 16 18 19 34 30 14 21 33 30 29 26 20 12 13 13 15 9 12 -1 -27 -44 -41 3 -11 -9 6 -14 -26 -24 -19 -20 -18 -14 -2 6 18 17 16 38 43 27 -6 22 11 23 44 40 43 44 54 61 62 55 51 51 48 43 30 25 33 36 31 19 -18 2 -22 -45 -60 -61 -56 -44 -35 -24 -10 -3 -4 -6 0 -3 -1 6 18 20 18 27 26 -52 -47 -41 -41 -46 -49 -42 -40 -40 -33 -34 -33 -29 -27 -20 -5 1 -6 -20 -22 -30 -23 21 10 16 30 40 38 44 40 33 31 35 32 38 46 48 49 56 88 101 127 127 116 38 29 36 30 25 30 29 32 38 44 40 39 45 50 44 35 34 38 27 32 38 59 -39 -21 -7 -14 -34 -38 -41 -40 -25 -19 -16 -13 -11 -8 8 27 23 -24 -43 -18 32 117 -14 -6 17 21 35 48 45 37 27 41 56 65 92 120 127 127 123 119 112 111 100 87 -1 1 2 -12 -9 -6 -3 -4 -7 -12 -14 -15 -24 -35 -51 -71 -81 -98 -116 -99 -68 -25 -23 -37 -52 -45 -49 -60 -65 -58 -38 -21 -14 -9 -1 5 -5 -14 -6 -11 -20 -13 -25 -127 54 0 -9 23 76 113 125 127 120 127 127 127 123 105 84 59 43 26 14 12 12 -14 46 -4 -23 -13 0 -2 -9 -10 -23 -27 -18 -34 -17 -15 -25 -28 -22 -2 -7 -14 -15 4 -44 -78 -88 -80 -65 -49 -33 -17 -2 -26 -42 -42 -52 -53 -47 -38 -35 -45 -32 -17 0 -20 58 101 107 107 90 69 48 38 40 43 42 36 38 34 14 7 13 15 18 17 5 0 20 -23 -38 -58 -37 -31 -47 -44 -36 -47 -48 -39 -38 -40 -28 -38 -28 22 41 33 39 85 -74 -29 -27 -27 -22 -13 -15 -17 -11 1 5 11 8 3 -2 2 -7 -50 -80 -89 -108 -65 7 -1 9 -11 -5 10 19 16 15 11 8 5 -6 -16 -16 -3 2 -10 -9 -11 -1 5 6 0 -1 -3 2 5 7 9 10 7 7 3 5 2 3 5 5 -12 -30 -21 4 -1 4 22 36 49 44 23 5 -8 -1 6 2 -1 -2 -12 -38 -68 -62 -7 33 9 -24 -44 64 88 66 29 1 1 -12 -21 -25 -23 -18 -27 -36 -53 -76 -92 -103 -83 -68 -84 -89 -50 -79 -50 -32 -23 -36 -32 -14 7 8 6 0 -17 -28 -22 -5 -2 -3 -19 -25 -28 -58 -57 -18 -20 -26 -32 -46 -57 -43 -34 -31 -19 4 -11 2 17 19 43 71 47 -35 -103 -101 -3 -104 -100 -40 4 45 33 8 -15 -50 -65 -79 -93 -109 -123 -111 -116 -115 -67 -70 -75 -82 -56 71 84 102 115 107 110 127 127 127 127 125 103 87 80 52 50 59 52 33 34 31 38 -37 -74 -49 -19 -35 -49 -56 -57 -32 -30 -36 -29 -27 -35 -50 -58 -62 -57 -45 -35 -24 -13 20 22 13 9 18 21 22 26 29 38 38 32 25 25 26 23 21 23 16 13 -4 25 28 2 -20 -30 -19 -15 -22 -23 -21 -26 -49 -54 -59 -68 -83 -82 -70 -88 -62 -40 7 44 -85 -78 -47 -51 -41 -22 -14 -12 -24 -32 -25 -23 -14 -4 -5 -9 -9 -11 -9 -8 -3 -18 59 66 67 38 31 35 31 38 45 46 62 62 65 61 73 87 88 74 68 68 63 14 33 38 33 45 48 43 43 54 62 66 51 42 38 50 70 85 86 78 86 102 112 126 -15 -7 -11 -9 -4 -10 -21 -26 -22 -28 -31 -35 -42 -47 -51 -40 -39 -59 -81 -87 -78 -59 33 47 48 29 -3 -5 13 25 35 47 43 32 21 8 -15 -31 -35 -27 7 41 39 -16 37 -5 -39 -34 -25 -18 -11 -9 -22 -40 -48 -50 -58 -57 -41 -16 10 16 62 98 110 121 -10 -20 -43 -53 -61 -66 -64 -51 -39 -57 -80 -92 -91 -84 -62 -40 -20 0 -8 -44 -65 -114 -18 -2 50 77 75 74 70 77 84 93 94 89 84 76 64 48 41 41 35 32 25 23 -7 20 45 50 44 37 33 45 67 62 64 67 73 76 78 79 88 83 70 86 106 106 5 16 29 42 52 56 58 52 49 48 39 35 39 41 45 51 60 60 64 68 71 42 -91 -97 -81 -71 -80 -73 -58 -43 -43 -33 -23 -23 -17 -6 9 4 -8 -24 -40 -44 -57 -41 -94 -47 -7 -7 -16 -26 -24 -24 -28 -31 -29 -35 -33 -31 -21 -7 10 16 16 -10 -45 -82 -50 -61 -49 -34 -18 -11 -14 -23 -32 -28 -32 -32 -35 -38 -37 -31 -17 1 1 -2 -39 -65 42 40 43 30 31 30 26 15 7 6 18 11 7 -4 -7 2 22 28 28 19 20 -35 -27 -25 -56 -83 -86 -73 -80 -76 -67 -49 -43 -42 -36 -22 -11 -7 -7 -14 -12 -6 -14 -27 12 26 14 15 23 21 10 6 6 11 17 12 18 24 24 28 27 34 55 64 66 82 8 -27 -50 -35 -29 -22 -7 4 24 36 25 2 -1 -7 -30 -36 -18 39 70 23 -43 -37 15 30 37 42 36 28 28 32 34 31 24 30 23 22 22 25 28 43 49 72 103 121 26 7 -6 -8 7 17 26 29 21 26 31 32 49 68 88 97 101 107 94 73 32 -32 26 13 -25 -35 -24 -18 -31 -35 -22 -11 -17 -3 9 16 11 17 29 77 110 120 127 110 -30 7 24 39 54 37 9 18 33 44 56 64 66 72 78 66 67 72 76 41 11 -24 22 59 92 78 72 63 69 50 21 -1 -9 -18 -21 -23 -34 -44 -54 -60 -65 -64 -59 -25 -128 -126 -23 -22 -42 -50 -42 -34 -33 -36 -18 -21 -14 -25 -31 -27 -39 -35 -34 -51 -52 0 -1 14 27 19 13 5 3 -7 -5 0 2 16 23 28 24 42 82 127 127 115 2 -112 -25 -36 -34 -42 -43 -39 -30 -21 -39 -54 -66 -76 -67 -59 -46 -23 -3 19 17 18 27 27 9 2 -10 -8 -5 -11 -16 -13 -12 -20 -18 -25 -15 -8 -1 6 21 35 52 37 16 -3 69 9 -24 -28 -18 -9 -10 -2 4 8 10 15 14 5 6 7 -6 -44 -47 -46 -28 13 -7 16 38 36 39 44 43 32 31 33 29 44 62 60 34 8 4 18 21 14 16 71 10 37 71 59 64 55 56 53 67 75 70 60 47 44 41 47 41 38 11 -1 -12 2 12 -5 -25 -23 -33 -40 -45 -33 -30 -36 -34 -43 -25 -11 13 27 19 -56 -118 -94 -55 -75 -71 -51 -25 -20 -15 -6 2 11 13 15 16 26 35 50 51 44 41 32 29 45 67 46 15 4 14 11 20 32 33 32 31 21 13 16 21 20 14 20 23 18 24 28 54 75 26 37 -7 -83 -128 -128 -119 -69 -22 14 23 3 -23 -21 -1 11 17 15 19 19 29 40 -96 -80 -53 -36 -31 -36 -34 -34 -33 -32 -21 -23 -17 -18 -19 -12 -6 -4 12 14 18 66 -14 10 25 43 1 -20 -26 -40 -33 -23 7 18 17 2 4 0 13 -11 -42 -54 -3 34 24 1 1 -125 127 127 -128 -65 -128 74 103 -128 -128 127 108 89 -127 -128 127 127 127 -123 127 127 -128 -73 127 -127 boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/cb.rnnn000066400000000000000000011113351516712004000272470ustar00rootroot00000000000000rnnoise-nu model file version 1 42 24 0 -7 -20 -22 13 -4 -54 11 -9 -3 0 6 23 15 -20 -5 12 25 3 -22 18 -4 -18 -16 -14 -35 -14 -17 4 36 -42 -30 -21 19 -10 28 9 -4 6 -13 1 -6 -32 1 31 -49 14 19 0 -1 -35 -32 29 -26 -29 -99 -40 -39 13 -25 22 29 -15 -19 8 -33 52 55 44 -2 35 13 9 -55 54 -16 50 -57 60 -31 -20 -66 16 12 50 50 -8 -17 5 26 -51 29 -2 10 42 24 10 26 50 43 67 7 34 64 -12 -6 1 26 -1 28 22 50 7 29 55 41 37 28 -16 -32 -4 -69 -7 40 52 57 -17 58 -1 7 31 13 -48 47 -4 -9 5 -66 -59 57 -9 2 6 -12 20 -12 106 64 65 108 7 -86 65 123 110 -67 -86 107 18 -89 -56 92 94 86 -13 119 -63 -99 3 -1 8 -14 16 -106 40 -35 25 104 -24 -93 -28 51 -119 -125 104 127 -110 -35 -66 -38 7 39 -11 -24 127 65 15 99 -20 42 -6 127 -49 -116 -128 20 -119 -118 -96 126 121 -54 73 115 64 -20 118 -23 118 121 83 85 63 -120 122 63 -58 17 64 104 -58 -120 -1 61 -52 -54 -100 123 -47 -29 -6 21 30 53 -37 -18 -30 -120 36 -4 -6 9 -49 -19 3 27 -128 24 106 -94 4 77 -27 -36 -23 -28 -121 38 92 74 -32 19 35 -112 -37 104 -46 -51 120 -125 -81 -106 5 47 -57 121 0 83 -52 -64 -8 85 23 96 -50 118 71 -111 -84 58 -5 -35 -72 107 -6 83 127 -128 97 -64 48 -97 -13 -52 30 -46 87 73 72 56 10 -92 -39 -4 -128 -101 40 -118 10 32 -38 -6 106 -119 2 -34 -84 -75 -118 -119 -19 -90 -72 -110 -48 -37 -19 -98 -112 55 -99 76 -80 61 105 -111 0 -125 -87 -119 -122 -100 -119 -110 87 63 -5 -117 -101 -59 24 -26 -67 56 -112 83 -1 126 72 -127 127 -107 60 -119 -118 -101 23 26 49 84 -18 -119 -98 -78 127 -128 -128 -37 -122 -17 -55 109 -16 -94 -6 -112 80 -91 -13 -51 112 -78 114 10 109 38 -23 -52 -72 89 -63 -61 34 3 122 -93 1 -62 59 -114 -107 -128 -39 -45 73 56 76 121 74 -76 122 -33 37 31 58 -93 56 -13 -4 59 101 -82 -13 -112 -53 -84 -34 -118 -23 -18 -60 68 32 -112 -4 -47 105 -61 59 -66 -34 -128 -62 24 -22 -45 -63 -88 -61 20 42 -38 55 35 -128 46 -4 -55 -83 -127 -49 -76 -27 -78 127 -51 11 -47 27 88 119 30 122 -115 10 -54 127 32 -128 78 -127 -32 -92 127 88 -104 -125 61 -113 -22 5 84 -26 -54 78 -97 -24 113 -13 52 -49 -119 -13 -36 17 -75 -88 -48 -10 39 35 127 127 120 127 -25 -3 39 127 -16 -128 -120 -78 -13 -120 10 -41 2 -104 -31 -103 -68 94 -45 106 66 127 124 127 -44 -28 36 97 26 92 -101 -99 -95 -122 -114 107 -122 11 -102 -113 -14 102 -35 -6 22 -23 -56 65 -127 57 -14 91 0 102 -96 112 50 112 -110 -37 -94 37 15 -101 -17 -34 127 107 20 5 119 89 14 -46 -54 -67 -25 -39 84 -1 85 11 -78 73 -24 -5 -50 -126 -22 70 -12 -85 -5 84 19 -49 -59 4 -73 24 3 25 15 64 26 91 -47 -46 121 28 36 -84 49 38 -5 -20 -6 119 -84 74 82 3 -107 -81 67 -123 -20 -71 -18 16 113 -89 8 -128 -61 25 25 -1 25 48 -44 86 111 126 -67 18 106 -21 -26 41 71 -96 101 -37 -24 102 -9 68 -10 -13 -22 89 8 48 71 61 37 0 -119 -30 101 20 29 72 -27 -64 -117 1 56 -36 7 -98 75 -6 111 127 67 -51 -92 9 70 66 -66 97 80 -124 -72 67 56 -75 9 44 -5 13 -17 71 23 -57 47 5 28 -126 -15 -70 -107 64 -4 -31 -95 93 -109 17 -1 -6 -22 65 -24 -39 27 -57 -29 3 -36 10 63 18 71 70 11 -12 -14 117 -12 -93 71 0 10 47 -94 12 1 -34 0 36 -4 17 73 11 -36 -22 71 88 -73 -22 -82 -51 57 90 119 -84 6 2 117 -120 -120 -110 127 -128 127 -126 19 -128 127 127 121 116 -30 127 -53 -10 42 121 67 -32 39 -127 121 -120 -120 -21 127 -128 121 -122 -89 -128 127 60 121 -65 127 127 -5 38 11 121 57 -70 -125 -128 6 49 -42 121 -109 -19 49 -65 -120 22 -102 23 16 -108 88 -49 90 -44 -69 74 -21 -98 -85 -6 -14 -1 -86 115 -20 -28 127 0 12 -15 96 -26 -58 -4 39 -51 -25 -89 8 -9 8 -27 92 47 2 87 -72 98 -30 -35 122 -80 -9 8 24 11 12 -12 13 0 -30 -22 7 -33 -78 67 99 53 15 89 65 -100 34 38 -8 99 31 39 -19 78 -36 68 -65 -1 -67 35 -64 -68 -117 -21 -8 99 121 50 -47 106 -121 30 -89 61 65 -12 -49 -108 -57 -66 12 82 33 39 -9 28 49 49 12 19 76 51 -90 80 -61 -122 50 47 12 4 81 36 41 8 21 -26 55 15 -51 -16 -79 -1 -118 -100 122 -52 -26 127 -107 124 81 61 -128 -5 -127 -118 43 54 -77 61 -128 -67 98 9 122 101 21 -44 24 24 0 113 -120 49 -37 121 83 34 -73 -124 83 -114 -128 -81 -112 18 -102 -52 -71 31 -45 -102 67 -107 -116 -15 -60 30 -51 121 -39 -56 -24 -14 -15 -25 -121 -80 68 -18 -33 -53 -75 84 -28 25 115 -43 -79 -13 31 19 26 -23 -23 11 108 18 54 61 29 -56 -33 -12 -43 -16 -11 -33 -5 -12 -46 25 5 -39 -35 0 58 16 65 61 127 -40 63 107 -18 -23 99 -71 -31 77 127 81 127 82 58 108 83 -66 -20 101 -35 -36 80 21 -17 126 -89 -122 61 36 -7 29 114 -9 9 88 11 31 -71 108 -14 54 69 -21 -124 -31 -9 -82 111 -35 13 26 -74 -11 90 -105 63 90 63 11 -96 121 2 -93 -33 117 49 -11 -15 65 -25 9 -21 -11 -17 -46 -29 -67 -23 105 -71 16 118 29 73 36 47 -30 120 -76 45 -10 -86 81 64 18 -41 43 -80 -39 14 37 -124 -89 107 -87 48 56 -48 58 -3 121 -119 -40 52 26 13 -54 33 -111 34 -97 19 -13 -4 13 123 -18 59 41 40 25 4 56 34 -44 -82 -36 -99 -4 -72 114 44 115 -15 -76 127 -90 -53 -63 27 -11 -42 3 -57 26 107 -13 38 122 -112 104 -71 101 -34 30 111 127 -50 35 -8 -120 77 40 91 120 124 18 42 35 -5 95 -100 -43 46 59 22 2 13 65 -13 -31 -35 14 -4 -3 -2 -8 31 45 -23 32 18 -18 36 -67 36 -52 30 94 -3 -121 99 -120 -33 42 -100 28 -77 -128 52 36 25 53 6 45 75 -120 -119 -76 63 -82 65 60 -25 -30 30 -5 34 -31 41 -128 27 57 51 -127 -118 -47 -31 -29 -82 -128 -86 -126 52 -38 -31 -11 -77 57 0 -18 19 62 20 95 -50 35 34 20 7 13 -72 2 54 -35 -1 -36 17 119 11 110 90 -80 -106 127 78 -85 50 14 51 11 -113 -21 4 -71 -2 -18 -125 41 127 30 -55 54 111 -29 54 93 -97 80 10 -25 33 10 8 -45 18 61 -8 -38 -28 -90 -31 119 -79 4 -37 71 -26 87 12 80 -38 23 -21 -33 -25 -57 -22 33 -43 -62 11 32 -7 31 50 -19 -57 6 24 -12 -63 127 -127 69 -119 60 81 -45 -124 -100 75 -52 -118 -74 -127 -47 73 37 -33 71 -122 -49 -104 -112 -53 -52 -103 -98 30 41 10 -38 46 19 -87 -121 -81 -97 35 -72 101 47 46 -44 31 66 121 -34 -34 57 -13 15 37 25 -68 31 -44 -48 58 17 39 9 40 -6 34 30 41 41 93 -57 -38 55 86 99 -113 108 -105 127 117 58 84 -106 123 -119 -122 -107 -112 -26 23 51 -17 122 119 -111 72 -30 -29 -53 -42 -31 48 6 -29 -18 -122 -58 -98 -23 -2 102 -40 20 39 -9 24 127 -8 80 -28 125 -41 78 27 -29 -115 -80 63 -67 32 -45 65 109 -9 -74 119 -84 76 127 116 36 -61 21 9 -78 64 13 -112 16 95 -127 -117 47 124 117 -66 0 -36 6 -9 53 117 -56 118 -2 90 80 41 -91 106 66 -10 66 29 -18 -47 64 55 -10 -39 44 101 -96 -93 -52 -18 -8 -20 -46 48 -63 -95 33 14 -32 -37 51 8 48 -25 78 54 -38 -27 0 75 48 67 -76 93 -39 -50 -10 1 -11 64 33 28 0 127 52 -4 -76 11 100 49 104 117 119 127 -2 112 -98 107 22 89 124 124 111 -119 116 36 80 74 40 24 -1 -65 -31 -56 -127 -27 119 75 91 43 16 -13 127 111 52 119 40 5 59 76 106 -65 -56 -8 14 41 -122 -5 -14 -60 11 -35 -59 51 16 21 47 -68 7 -54 41 15 -108 31 -12 -123 -35 68 -128 -55 -73 50 12 -81 29 61 -41 -9 43 -78 1 -34 -55 -59 -53 92 -10 -107 -14 6 -36 12 -14 8 90 31 -87 52 -27 83 -123 -95 -55 60 31 -115 -114 16 -18 4 14 15 -67 14 -30 43 -6 -61 12 -32 68 20 -96 7 -3 -58 28 -35 -27 -71 -18 9 -71 26 10 -20 1 -30 -59 93 -128 22 -28 1 -36 -29 25 20 116 -19 -40 -100 7 -74 -1 -2 -109 11 79 -48 56 46 10 1 -77 -15 -48 56 -75 21 7 55 -59 6 24 -113 52 30 -37 78 -62 32 34 55 -64 -63 -68 75 -29 -8 0 -81 -7 19 -6 89 11 23 98 -82 -111 -58 -3 61 -20 -29 -10 -6 -75 0 -3 -63 38 21 -34 98 -24 -15 -5 -88 -31 101 17 -24 42 -111 -7 -3 55 103 116 -10 38 20 -58 -39 -23 -57 5 92 -61 95 -84 -13 32 73 79 -50 48 -33 -26 32 -24 90 -107 70 -79 -45 13 33 -10 70 125 6 27 20 -44 20 -16 -7 72 -54 -32 -91 -24 -56 -4 2 71 -38 0 -112 -30 -34 19 93 -6 -23 -11 -30 -2 18 11 32 12 -71 -21 -95 64 1 -49 50 -52 103 30 38 70 -53 -24 53 -51 34 -23 24 116 64 12 1 36 -59 29 -103 83 -11 -5 13 115 -32 -71 -71 -28 46 -32 12 -28 -61 19 -10 58 52 10 28 -12 -24 -64 -65 4 15 -7 9 101 -62 -116 18 -63 -2 -72 -110 65 -123 -17 -100 34 -9 48 -9 58 -53 -73 -15 26 -86 -102 -49 23 28 46 12 -118 92 -55 -128 -10 -9 -53 -54 82 91 37 50 19 -95 110 51 97 12 0 -61 -20 127 -34 -72 -62 80 -79 -36 91 4 -5 -97 58 100 -32 52 44 -88 -60 -52 -65 27 43 -128 -20 -98 39 -121 15 -73 20 12 -51 33 -56 -100 57 -28 -52 -22 61 -86 51 50 98 -11 -119 5 -75 76 111 -103 -124 33 61 65 127 86 96 -37 -65 -42 21 53 127 66 100 -54 8 29 25 -128 -3 103 -11 -23 79 103 31 59 75 -29 57 41 127 88 4 -125 127 4 -83 -80 -35 24 -67 -127 -17 -120 -25 -45 16 19 -113 -99 84 120 127 -73 50 -38 -55 68 7 91 108 121 -77 110 91 119 124 64 18 -10 -61 3 -128 -81 127 4 19 -90 12 127 63 -61 25 59 75 -104 -51 75 87 -128 -40 5 65 -9 -61 -85 28 -5 -11 0 -29 -76 -3 -2 18 -53 -1 -5 19 7 4 30 -17 51 5 -21 -87 67 -70 82 8 -51 43 -117 -47 85 -91 104 -1 62 -91 -21 -76 -111 12 -120 16 -33 30 37 -7 35 -9 17 65 -1 -128 38 3 26 35 16 -10 64 -13 -42 -106 31 55 4 22 100 -50 -36 54 67 -2 -108 -82 83 -14 67 10 10 -54 -35 -85 67 15 24 16 99 3 -70 65 -115 -15 50 53 123 -109 -13 119 9 1 -118 -116 88 54 27 -8 -18 68 -120 -116 -117 -14 -95 -118 -119 32 -25 10 100 -11 -82 19 -28 -53 -24 58 -39 -17 -37 -113 43 49 -89 -111 50 67 -37 -36 109 58 -79 14 61 44 14 -40 -23 47 13 -38 23 -66 -2 -61 59 28 63 1 -44 20 -10 107 -102 14 -41 8 10 -19 27 -73 -122 20 -12 44 -47 -52 104 -37 107 -3 -58 -62 -31 -13 -119 97 102 54 -46 88 -66 25 26 -106 21 39 47 89 21 -12 -18 -30 34 -20 -8 34 -52 20 -80 -75 9 -128 32 -1 0 -8 62 24 44 64 -36 53 -6 -30 53 -38 -123 13 -57 -25 -30 -47 85 -81 25 36 -120 -35 47 25 -80 127 102 -52 -64 -101 104 47 -33 -17 2 94 -65 6 -2 24 40 -97 5 16 34 82 110 18 -56 84 64 63 16 19 -46 -29 -68 103 -9 32 46 -13 85 19 -33 77 32 73 -12 44 -34 -15 -78 -62 79 1 43 -43 59 31 23 -36 20 -63 -12 32 61 28 -3 24 50 5 4 -106 105 -31 -115 19 -42 -10 -120 17 -57 -126 -12 19 -104 14 -42 35 -49 -85 -56 -107 -119 -122 -91 6 -2 42 -74 54 72 -5 -33 -34 -47 -20 -63 -75 105 -25 20 -13 96 31 -125 5 34 -49 -13 -37 -28 -5 -91 -51 75 -14 10 -76 19 -53 -82 -67 107 -55 45 15 62 68 -27 12 -24 -90 61 76 25 33 67 93 44 -94 -120 115 71 12 12 3 -11 -20 -76 30 108 -56 -35 28 -12 -123 35 -96 -64 1 -113 62 127 106 -47 102 90 -68 -31 -87 -49 74 -7 -47 -45 -90 -14 -47 -78 69 -56 10 72 -24 36 21 -52 -80 -46 -67 95 -27 -21 22 36 13 96 -31 -48 -18 7 50 67 -26 -21 55 100 52 69 -61 -44 -31 12 82 121 72 115 -11 127 8 -6 6 93 52 97 126 -64 78 -5 15 94 37 -18 -114 -4 45 -128 12 -75 -50 100 37 27 -52 7 -31 123 95 73 -76 -110 92 -26 127 99 42 -111 51 -40 -120 49 -108 26 -11 -101 13 -54 -49 92 47 -54 23 2 26 103 -65 24 -102 43 -24 -86 127 105 23 -26 -17 29 60 62 55 -42 24 9 -51 36 117 33 -27 58 51 40 -43 31 -36 -4 -28 7 -68 46 90 44 3 29 113 -14 25 -44 45 113 92 89 3 46 27 40 -8 19 -27 10 -110 8 25 -16 -13 127 64 -3 43 14 22 -8 -45 -81 -42 25 -36 28 -35 -2 -41 36 -72 -66 73 -99 -75 -65 -59 -120 98 21 127 29 -93 -122 75 -34 41 -13 2 58 -36 90 -57 56 -45 5 -20 -11 16 40 -60 -40 -44 -21 1 36 -31 2 56 -24 30 -20 -20 -46 21 12 -29 53 -113 -125 110 -21 -48 30 -64 -81 0 -59 -42 58 1 -33 -1 1 127 -86 97 38 -37 33 -98 41 -73 99 127 -112 117 -29 111 -115 -122 83 -87 54 101 29 -106 50 76 -51 21 106 31 56 -46 17 -41 -83 -7 -61 -91 60 100 35 -122 53 -8 -43 -31 -46 -14 52 74 30 72 99 -31 -79 9 -14 36 112 -98 23 89 -57 6 -48 85 54 38 -10 83 -33 -98 -54 -113 101 -56 8 96 -21 107 -127 24 28 -6 34 20 -110 67 105 -28 -94 -123 -36 2 -9 -103 -65 4 -59 2 35 7 -128 75 9 18 -7 55 102 33 54 77 -5 51 -10 -24 59 24 34 -84 -66 18 61 43 3 -94 -40 -36 57 -6 96 21 -38 97 -5 36 -23 -2 51 8 -29 32 -65 -113 -38 -71 0 -17 -66 -2 11 -127 -3 76 -128 112 127 -121 -21 -94 89 127 -73 -15 -119 127 -81 124 -84 -124 -68 -120 78 -19 -4 -93 -26 -91 16 58 -1 -120 76 -26 -123 3 -61 -64 107 -55 -7 -100 -52 80 -89 -67 80 -9 37 108 61 -18 -114 117 -22 76 111 -112 70 -26 -103 -107 111 -72 108 -9 109 81 -102 90 -114 -71 -10 -66 -21 117 -81 127 -11 -19 -88 12 -128 82 -106 0 -34 71 59 -128 -46 94 91 98 81 -128 19 18 28 -82 55 -25 -28 -67 -40 99 65 -41 38 97 -43 9 -9 -17 52 29 -10 106 -47 -45 44 -23 -79 21 45 -63 102 -12 -100 115 -13 108 27 70 -49 40 -84 25 -111 -75 84 -38 -19 93 -35 24 -72 82 -128 46 88 15 -58 -6 34 -66 -128 -46 -21 123 54 -45 -49 -48 -128 -107 -60 -112 -20 19 61 -17 8 67 -57 17 93 13 13 -27 94 45 16 46 34 -64 107 29 0 3 83 -52 76 -6 -77 -60 109 58 -56 38 -57 127 -45 46 63 123 -124 85 -115 -110 -104 -77 105 -71 -118 0 -17 -128 20 -82 -18 -6 -128 -35 -128 -96 -127 -76 80 -5 2 -70 -18 99 46 6 -105 6 19 90 118 -33 -117 -2 -17 36 -31 1 -41 16 -36 24 -42 -24 -8 9 36 81 31 -8 8 -73 23 36 28 7 -5 29 -106 13 -7 -21 104 -47 7 -66 -33 4 -8 -77 13 27 62 -14 -9 26 91 -79 124 18 -11 107 15 -85 14 106 -12 127 15 -43 -37 -75 50 66 94 -52 -50 -90 -53 5 -22 -96 -127 94 3 120 24 -40 -22 76 79 -11 122 -1 41 -9 37 27 7 -11 -21 46 72 -27 -63 -34 45 -7 -123 -22 86 6 75 -56 -85 116 32 0 117 78 -12 9 4 -81 -79 -51 50 -84 -88 22 8 -105 6 57 -114 127 105 8 -70 -4 -40 46 -101 11 -35 95 61 -128 -105 123 119 2 86 -71 -4 -8 49 42 -120 58 76 99 11 66 79 -7 -13 50 9 80 108 -3 23 92 61 118 44 13 25 -51 -62 30 46 20 43 24 -70 44 46 48 59 49 -29 25 -39 -86 -112 -64 47 6 -34 -13 -117 8 -123 123 76 127 117 56 120 60 114 105 4 22 -70 119 63 -126 -86 121 113 -1 18 45 -62 13 -25 -74 -16 3 35 -83 -35 17 -17 33 11 19 -41 -70 -9 -84 -106 32 12 49 39 -14 -67 -33 -74 43 116 88 -63 -30 -128 62 -6 127 21 -7 -45 29 -1 16 -48 -86 127 -125 -35 31 -109 34 -29 87 107 55 90 127 68 127 64 -103 49 -126 54 98 106 22 71 -111 -41 56 48 87 -1 17 38 5 -10 19 33 77 23 74 54 41 88 28 8 -15 42 -30 16 11 77 100 25 -56 -15 -2 -128 -5 125 29 -20 50 -48 109 42 43 78 43 -63 -27 -87 -126 -111 -62 70 -114 -111 87 -60 48 45 46 127 -19 45 127 127 127 -6 -9 118 -33 110 125 127 -38 127 -23 105 116 95 118 -53 -7 20 58 15 10 36 36 96 115 28 4 95 2 -14 6 15 -84 -13 -12 88 16 -87 -23 30 -44 -116 -8 127 -34 -58 -10 -6 64 -103 23 87 127 -16 -65 79 -102 -127 -127 0 -73 -110 35 -91 -27 -121 1 -126 24 114 69 42 69 19 5 -127 -45 41 35 93 -69 53 126 127 7 -104 80 -14 42 11 33 -37 48 23 -70 2 -54 23 119 4 67 -55 -24 25 86 -8 -32 -17 -15 2 100 -74 -10 65 10 3 11 -27 -51 49 -50 0 -85 -92 -127 89 -110 121 79 69 59 -122 -11 0 -102 127 90 -13 77 -128 45 72 -28 -75 66 98 -5 -110 -3 -31 127 127 -94 -107 34 -30 -70 -79 -110 -25 -23 55 13 -87 -1 7 -8 10 51 9 -104 91 35 23 88 17 -19 112 96 7 20 1 -120 -90 -19 -73 -11 104 122 10 71 -73 123 -18 47 101 115 -33 84 -71 -99 -120 -36 125 -73 1 81 -68 -17 -5 -71 115 25 3 -39 50 -9 -53 -6 24 80 59 -62 -125 71 56 86 127 48 87 127 -6 -79 -54 -32 -98 -35 47 -31 -26 28 -45 12 -2 -71 34 8 -11 -23 -45 10 -34 -17 11 59 -35 23 123 -55 -70 -87 78 -96 100 -121 61 28 -19 -49 89 -93 94 64 39 46 -72 86 9 -41 56 -98 -89 -38 -118 -75 -85 -116 -128 -116 -60 -27 -35 59 -99 -74 -102 -41 -5 88 -24 -118 -94 -127 63 -15 -39 -84 13 -11 -26 -23 -29 -29 -20 -36 11 -13 -7 41 91 72 -28 -8 -17 -28 10 -70 44 115 12 117 -35 -12 113 44 -91 -25 103 101 -76 -58 -69 95 -30 49 60 68 16 39 68 -68 85 -119 -108 -22 -128 66 37 -115 -128 -105 -53 -28 -109 -30 -101 -57 -104 56 -110 53 63 -94 -118 -78 53 16 -28 -70 76 27 11 -66 0 6 -45 -110 -83 -58 -19 -34 17 32 6 11 -93 -67 49 -41 33 72 32 37 -127 66 -29 11 89 -104 33 -102 -72 -124 2 103 -21 127 127 49 21 56 55 -81 94 -123 124 -110 -91 -38 -23 -56 -57 -117 -127 122 17 88 48 -84 -99 103 -26 -63 -112 -13 -48 -95 99 -52 90 -1 -2 -37 -119 -12 55 89 -103 6 -15 3 107 -16 -116 -70 14 22 86 12 -16 67 96 -87 127 -118 -121 68 -127 -46 116 -90 -118 -124 -122 -48 92 -66 -3 79 127 82 -110 116 44 -50 52 120 -123 61 -115 77 118 68 119 54 126 80 -101 -72 -76 109 76 -103 -73 -4 43 -58 11 -50 -119 70 26 -50 111 13 71 -15 -16 28 65 -5 48 -31 20 37 46 37 -9 -11 41 1 10 -47 -20 13 -119 18 94 -16 8 103 -114 6 -28 78 118 75 -6 72 14 -38 -42 -126 66 -85 -126 110 -127 -70 104 -86 -34 -5 -116 -75 -52 -128 -45 64 1 86 75 -128 -27 40 59 78 30 -9 -46 15 118 -26 3 29 1 0 -72 -79 32 -50 -88 -1 -77 11 -42 -12 -1 -11 20 -66 5 -83 51 117 -1 104 93 9 -126 -54 -67 -63 49 -81 -2 -89 -64 -110 5 -32 -33 109 91 85 -128 36 111 -49 122 -33 20 -99 26 -4 -57 -72 -91 -86 -127 -72 -3 107 -18 -125 -17 95 113 31 3 -71 -13 -105 20 -33 -23 -84 -13 -81 22 65 -90 -62 -11 70 -78 -71 -65 -61 -69 50 -30 -44 -64 -93 -42 4 8 -87 14 -64 92 46 -18 75 -118 75 -92 31 11 70 6 86 -61 -31 -109 64 41 -106 0 -1 -121 24 94 -85 127 -5 -8 0 76 77 -41 -128 72 -72 83 4 23 -55 -30 -123 -120 5 92 89 19 26 41 -51 -6 -39 9 -53 -53 -23 52 -57 70 2 -58 -123 -45 -76 -85 -52 4 -41 91 30 3 -128 -84 -42 127 -47 -25 59 -51 38 -119 -30 127 84 -108 -1 -72 -45 -85 -118 86 -29 -75 73 -88 -63 -53 -54 -22 -59 -70 -107 -126 -79 -12 -85 -88 115 -26 -128 -107 105 16 45 -105 -121 -119 -93 123 -2 -47 38 -1 27 8 -68 -10 -43 4 24 -76 -51 3 48 -38 35 26 -47 -55 -61 50 27 65 65 26 29 -100 -36 97 -28 0 -63 109 -73 -127 -35 39 -25 31 -11 98 66 -39 55 -70 -91 57 -78 -70 122 -124 127 119 -107 -72 -88 117 127 -128 12 -102 35 -50 -22 -112 76 119 -80 -99 -104 -92 10 34 53 -24 72 92 57 0 -10 13 63 28 127 28 113 83 37 19 127 47 79 -28 55 46 44 -11 -4 59 53 4 50 -53 19 78 62 25 -48 -15 42 -31 -69 8 29 13 -20 -43 10 -36 90 48 2 0 48 -94 -16 -92 -34 12 5 1 -9 37 63 18 21 49 -39 8 59 -41 15 5 47 15 26 -2 36 -16 6 55 -12 45 -44 -14 -74 0 6 106 -4 -11 -19 -59 -30 12 -38 -36 46 27 -10 -53 5 -2 -21 13 22 65 -4 36 -7 59 -44 -10 36 -21 11 24 14 -14 -40 -29 -11 21 7 75 11 19 15 -2 24 -11 44 -4 -11 12 17 67 -9 -73 -2 44 11 36 25 17 -17 24 -20 9 -41 -2 18 -33 15 12 41 27 3 -25 13 49 -27 -25 -42 29 -9 -17 -25 49 0 -17 21 -69 5 73 51 10 -26 9 -9 -12 1 -10 -8 -1 -2 14 43 9 19 45 -53 31 18 -22 22 73 -100 89 -6 65 28 -36 70 -20 -4 -24 -47 114 54 109 33 7 40 56 -25 -15 77 -26 -17 72 48 -115 0 -53 8 5 -46 47 53 -48 -46 10 11 63 4 86 56 26 84 -74 60 32 31 -22 -53 -38 76 56 7 -68 47 19 -8 -52 59 9 -41 49 -33 62 -19 -50 2 35 -49 11 21 18 43 110 -10 70 -20 43 -2 70 13 -10 -62 -98 75 5 -8 -35 52 23 7 -107 29 1 36 -42 -27 13 37 -5 19 -1 -4 -38 -106 31 30 39 26 9 10 31 -11 15 -8 -5 43 31 13 11 -39 64 66 32 -3 -2 -33 -33 26 -42 -49 -49 -38 12 2 -28 -6 -27 -113 -27 22 -21 30 44 56 25 29 44 -82 -15 -47 -55 52 -49 -15 -31 25 -29 84 -6 99 63 42 -20 36 -57 -24 -10 -14 -41 42 45 -24 6 -47 25 -25 43 -21 -36 -110 -70 7 -20 -95 -8 34 -71 73 -76 -5 -58 -9 -43 7 -9 -24 65 44 71 50 102 81 -7 -72 -7 5 -65 -28 12 54 30 57 -13 -19 21 63 91 -42 23 -8 -42 -50 50 -27 36 41 66 -5 61 49 -9 55 47 38 3 0 -11 -79 41 -10 -55 46 1 37 -48 -4 56 -30 12 53 -33 5 -28 36 -27 37 26 27 8 -4 6 20 -20 19 6 -7 14 -13 -5 -46 5 28 28 -22 78 -21 13 11 -39 -7 44 -26 -15 0 -16 3 56 -34 127 -28 68 -41 44 -71 -10 15 -11 -28 20 74 77 43 6 59 20 -46 9 58 -59 65 -4 6 -23 -20 -26 9 -26 -36 29 -70 30 52 18 86 -26 40 19 23 37 92 -53 66 33 10 15 47 6 68 30 14 -5 2 32 -34 -25 -51 1 -64 -53 8 28 -29 22 -100 -22 -32 -87 31 11 -11 29 35 27 -91 -12 95 -41 -49 12 -45 -73 47 8 24 -43 76 105 -17 -123 18 -83 51 -22 6 -2 55 -36 18 35 -13 -5 18 27 -32 50 12 -16 63 0 28 18 17 21 10 -11 30 -6 -1 23 9 8 -28 25 -57 16 19 33 -12 45 3 10 19 37 -10 -41 -61 -3 5 2 1 -49 9 -25 34 -67 4 -10 -6 59 26 -70 -128 5 -36 -76 -31 -39 18 -56 27 -3 -21 10 52 -38 -5 34 -14 25 -40 -48 4 -51 -13 -21 -53 -95 -9 16 -22 50 -32 -40 -123 0 -40 -10 27 4 57 95 14 -16 -2 43 -31 -6 -82 13 12 71 15 -57 73 66 14 -49 -5 -46 -39 -10 -34 -54 -15 -30 7 20 3 -3 -15 51 -9 64 21 6 -23 -52 -8 54 18 -39 41 51 -33 13 7 44 -22 -21 -28 -5 33 12 -18 40 13 18 -29 -22 -34 -11 -14 -38 -31 -31 39 -19 30 -36 -25 31 8 19 -4 24 22 5 20 -18 -3 -3 10 92 -15 19 10 34 -9 21 82 27 -35 -15 -9 14 -37 -7 45 49 48 -5 29 9 -32 16 7 -24 1 33 -31 65 50 6 23 -3 22 32 13 19 31 -89 -40 63 -26 -45 1 32 51 -37 -4 78 8 2 17 -37 -2 -12 87 -13 12 25 8 -26 14 14 -32 0 8 -9 38 -8 -1 -4 58 55 -90 73 78 28 -38 -54 -53 71 63 -23 33 -1 4 30 -20 61 27 -32 43 37 -57 -12 -112 8 4 18 -61 7 -74 0 -23 -10 41 -6 -28 -25 13 11 1 15 -19 -9 -15 -16 -27 -13 19 -3 27 -52 -39 30 31 -28 20 68 -5 26 -2 -10 13 7 36 13 8 -9 -17 -9 29 48 7 22 7 -36 23 -23 -6 -13 -4 13 -8 -23 -15 -5 -46 -74 -15 -8 40 8 -31 28 -6 72 92 -81 -46 18 -34 52 13 6 0 47 -39 9 31 34 -5 54 20 48 -35 -127 -33 14 45 -44 -21 -65 52 -48 55 -48 -38 52 -29 -9 22 -49 -8 -63 15 -12 4 -83 46 -3 -21 -13 18 -7 -111 23 -14 23 74 3 72 -40 -29 64 -5 -24 -67 76 -36 123 1 25 40 10 -4 27 -61 -15 -116 49 -20 -16 2 17 32 16 6 -37 -68 -30 -57 -30 -3 3 -29 -68 -19 64 9 14 -9 50 -26 -34 0 -36 -25 15 -24 46 -22 20 -42 -57 2 -70 -2 3 -52 -34 23 -24 16 13 -18 19 51 -18 -9 -9 -10 -2 -12 13 30 32 -8 -13 31 0 -103 10 12 123 -57 -114 24 -72 -1 55 17 48 7 98 41 14 62 108 8 -33 9 -20 13 99 -10 -21 3 37 -12 14 -18 6 43 -77 -18 -35 -59 5 55 30 52 81 113 -38 -49 70 -53 -9 -35 8 -87 36 -85 15 17 5 -34 -2 -80 -15 -22 -80 -19 11 5 -22 -47 6 53 30 14 63 60 14 -3 30 -18 -11 -99 8 -43 60 -27 120 25 -37 17 2 18 126 73 -40 -39 -17 27 3 -44 37 -18 62 31 23 -41 -49 -38 14 20 70 -7 -2 -24 -63 3 28 29 33 55 -10 -7 -40 7 72 -15 -23 -30 22 -1 7 75 19 -7 52 52 11 -4 1 -30 40 104 -27 46 -31 -17 -19 -30 -30 -54 -51 11 -97 -78 23 -16 -42 6 33 9 79 -15 -31 92 20 8 117 -50 -2 29 9 10 -79 31 -46 14 47 -2 -23 84 -11 -66 -86 -13 45 45 10 36 27 -14 38 20 -76 25 -43 15 19 -64 21 28 8 45 29 33 -6 -70 -71 -81 -79 71 18 13 -15 22 -88 -48 90 45 56 -16 29 -5 12 -17 32 -47 -28 -11 2 -15 -61 -41 42 45 65 -59 21 6 -17 -31 44 -32 -35 -21 35 -26 -23 39 -40 -16 -14 44 7 0 -34 -4 41 35 32 32 -24 -34 -24 17 22 -19 61 7 -79 -21 7 39 8 20 -50 -9 1 -58 23 2 12 1 18 -59 -28 -17 -24 -73 -29 -67 -11 8 33 -114 26 -28 -13 68 -72 101 -49 51 50 17 67 27 20 -60 -6 -1 76 -2 7 49 44 21 -22 -20 -25 62 -96 -61 68 4 17 -56 -25 -2 13 23 30 2 18 -2 -14 53 -15 51 -75 0 -36 -1 124 -49 97 -48 -50 -26 -31 -5 -11 -39 54 -34 -31 -21 50 -1 -30 114 -44 -37 -29 34 -117 -19 -22 22 -75 -1 6 11 50 12 -31 -1 -43 77 -72 51 102 26 11 -48 -30 80 51 -81 14 -23 64 52 44 -75 5 -105 -8 65 -7 53 41 25 -37 -13 46 -26 -3 -7 -23 -77 64 69 1 88 -25 -70 40 21 -36 44 2 -18 -30 -5 -8 -15 -4 119 48 -77 24 -5 55 -34 22 -2 15 -44 15 -7 -4 -22 -1 34 -19 -10 77 42 -122 4 -32 54 -39 20 18 -27 13 -13 17 -32 99 -3 -21 36 -21 54 -40 -54 32 6 -83 -39 45 15 9 8 -22 -54 34 6 2 2 17 11 37 29 30 24 52 -37 -44 38 -39 -84 -60 26 -22 6 -39 56 -50 54 18 -73 2 -18 -2 -59 -13 -27 -2 -41 1 62 -5 15 -46 -2 20 -10 -39 -27 3 5 -46 -24 -43 -10 -3 47 34 32 -15 -17 15 30 2 11 -9 16 -18 -25 -4 8 -10 9 -14 -29 14 -49 -27 -18 23 19 7 9 -22 -29 -23 -26 2 38 2 9 11 9 6 -44 5 -6 29 -35 -11 47 13 16 -18 30 22 66 41 -18 -18 -3 -23 28 -15 -8 -4 -21 10 40 21 -28 17 -38 -27 -14 56 -34 7 -46 -12 -41 33 -28 -20 -34 53 47 36 -24 -8 27 -30 -31 2 0 50 45 -10 -15 -14 4 -39 -25 -76 -6 54 51 -31 -23 38 -20 -44 5 -36 40 -85 1 9 45 4 -23 -84 63 -2 21 80 -15 -4 2 3 -25 -45 -33 -33 -33 -20 29 -55 29 -8 13 11 18 -27 -104 -19 -58 -26 -57 42 47 -25 25 -9 -25 19 44 -26 11 1 21 24 -8 0 15 19 26 -33 4 6 11 -52 0 -3 11 24 49 -29 12 -18 20 -52 30 -8 27 -14 -14 -6 3 0 19 20 -12 -1 -6 0 -9 -12 -10 -20 -88 -72 35 11 23 56 17 22 -64 -58 -94 2 -94 -5 -23 10 -82 -70 -15 -71 112 12 -92 -1 25 -23 -61 -21 22 18 -5 30 -93 -5 33 5 7 2 -73 65 44 -6 -5 31 11 24 -28 -10 -50 -42 26 -22 -20 -96 50 82 -29 -116 -2 -44 3 21 -75 96 -31 -28 -46 -23 -65 43 -23 83 19 47 -7 -31 -93 27 53 -69 53 38 -48 -84 -35 -45 -28 77 -85 14 -14 5 22 -24 17 21 -14 2 10 20 -10 -61 6 -63 1 6 22 -58 -12 -22 59 7 -54 -46 -31 -58 -16 -36 57 24 3 -40 -18 34 16 27 -53 3 1 -38 -49 21 -8 -57 -50 21 -16 -51 101 20 45 17 46 23 21 3 -18 -25 -9 18 78 -27 37 -42 -40 15 -13 -28 -46 -6 19 -109 59 45 -49 0 -38 -52 17 -55 -25 -18 69 -25 -14 14 -83 -23 -10 -27 -115 -9 34 59 -26 -1 32 86 60 -82 -28 -19 8 -25 3 -4 -58 1 -10 49 25 -67 29 -119 35 -60 18 23 14 -14 -53 31 -8 -23 20 -23 -37 22 7 -36 -51 9 42 13 -44 -39 -48 -66 12 -64 52 7 78 -29 -44 23 -19 -55 12 -25 -11 12 18 -5 -26 -19 29 9 -17 14 -4 -51 5 -26 22 32 -10 6 -24 9 -5 41 102 -5 -16 -76 -15 -25 24 -19 -29 -24 -15 -18 -23 75 -68 -27 -14 -17 -4 18 -30 60 -5 4 2 -34 53 -71 35 39 -8 53 37 -32 -7 7 -100 9 31 -14 -3 -59 77 -124 15 -30 -16 13 -91 -35 -1 -16 33 -82 25 -78 53 -66 -68 -107 -11 35 -77 -74 -62 -91 -4 -48 96 6 -102 3 31 -75 14 -40 -58 114 50 55 -62 -23 -34 4 -24 122 13 23 20 25 35 -110 23 -89 -15 -15 10 -27 31 -48 126 91 -46 -62 82 -61 48 31 34 66 -10 -70 -24 3 -31 -73 -15 -37 -64 45 89 42 64 -36 74 32 73 -8 8 -13 18 -95 6 -97 52 -15 8 45 -32 -39 -9 -31 23 1 88 24 -26 -70 -43 -21 8 20 -6 10 86 8 -34 -97 -8 -46 -47 -19 2 37 26 25 54 72 35 -37 -14 -19 -61 -2 -56 47 -30 31 4 11 -84 12 20 -128 71 -8 1 -122 -16 -88 39 8 -49 -44 29 2 71 68 -29 -84 4 23 -3 -41 78 52 -76 -1 -49 52 -45 -41 31 90 -71 20 -14 40 -29 -16 55 -77 32 -48 98 -5 3 19 59 -23 -12 4 -13 -2 -38 -47 67 92 -22 -12 -13 64 97 -7 -17 95 45 23 3 -120 9 53 -14 -36 43 94 1 117 68 3 -14 29 -18 -28 -10 -11 2 -37 27 5 6 29 -2 5 -2 36 -37 -15 -30 -65 -46 -15 -12 -102 47 -36 -25 8 43 -45 49 -2 -40 -2 57 -86 34 -6 21 -15 -55 31 -20 -66 47 23 85 -31 -1 64 17 -72 18 57 23 50 11 80 22 -12 -5 55 13 55 18 68 27 16 43 -57 32 58 9 46 20 5 44 31 -5 12 15 12 -16 -89 58 31 87 -47 -46 -39 -3 21 16 -4 28 52 9 -35 3 40 -24 -47 18 -20 20 -47 17 -21 0 -22 -10 14 -5 29 -19 41 24 46 -16 -38 -13 35 -63 56 14 57 25 -71 -48 -20 7 -1 -5 77 24 -56 -3 -21 0 62 19 -26 -93 -26 -4 -39 5 -34 -59 -20 2 36 -6 20 58 -26 8 -13 -3 -6 0 -7 -8 35 28 -24 55 41 -58 -25 6 8 1 48 8 -9 -17 -33 -19 -18 33 -16 10 21 -16 -10 4 -28 8 59 1 -27 70 -30 13 -3 -27 -29 44 -23 -19 -54 -8 -4 -13 -27 20 20 21 -15 29 -23 45 -22 8 -48 52 70 -17 -1 14 23 -1 -38 56 -58 -21 37 20 1 -80 44 -64 112 14 -36 30 31 -20 -63 68 -58 11 107 -7 44 25 -90 -44 -23 -7 4 -51 33 73 16 17 41 -15 -3 20 18 47 5 -55 34 39 -52 57 69 -103 -26 -10 -108 29 88 8 100 -29 43 -66 50 8 9 49 20 11 40 48 56 75 3 58 20 -38 16 -24 27 45 19 0 3 -13 8 -3 1 -6 51 -13 -43 -42 29 -44 12 39 -6 -35 -45 -40 18 -11 41 1 83 29 15 -4 14 18 -25 -17 1 -31 -56 -59 54 20 23 19 26 -9 -30 36 18 -21 -42 36 -3 67 -61 -37 51 -32 -49 -39 -4 20 52 48 -82 39 39 -25 25 -69 -58 -37 54 11 79 113 31 13 -52 -41 -9 -4 -27 -69 11 6 -40 -31 30 51 82 -16 44 25 -75 -14 -18 -12 -22 22 -11 34 -37 85 0 54 0 -4 -37 8 7 -22 -6 -27 45 -20 -16 -45 9 39 -13 3 32 -31 18 62 -49 -13 12 50 52 -56 -37 19 43 32 36 -12 7 15 45 59 10 -30 27 8 -19 -60 21 -9 18 17 -14 10 -26 12 -30 -45 15 -41 -58 -43 -7 15 -10 13 0 -31 -2 21 -46 18 -15 -20 -25 -30 -8 -6 31 4 -2 8 -50 46 45 -3 66 -13 16 18 -22 56 36 34 -13 -1 41 -49 -18 -45 -69 -9 6 -46 -56 -1 69 -30 -17 -56 37 38 62 49 114 14 95 5 -45 23 127 6 12 -13 -89 49 2 68 30 -69 40 -47 -40 -10 28 42 -25 3 -60 78 -122 -9 -16 23 -40 86 46 22 37 59 -32 63 71 14 38 -37 35 -16 24 -89 23 119 4 -39 24 -20 -123 -42 9 -7 -59 -32 -56 -14 -17 -29 15 71 10 -12 -22 20 89 3 -47 8 10 20 32 -37 19 17 26 16 -26 7 16 2 -54 5 -44 -19 -25 6 -23 -52 41 3 -10 25 -11 9 -23 15 51 -24 17 -49 -28 -57 -16 -38 -64 -41 -8 28 -48 15 -37 7 21 10 -20 -26 -11 7 57 -28 22 4 79 -4 -50 -25 43 -88 -29 47 -72 -57 23 13 -12 -16 -48 81 -78 7 -5 7 -89 -53 80 -94 -35 -11 35 -60 -40 27 53 41 3 -51 -59 -14 -38 75 0 8 91 -50 26 -58 -58 6 -16 4 -25 -24 28 10 4 127 48 -5 7 -7 71 -27 55 14 77 79 -49 -14 17 67 -23 -25 16 -2 -10 -2 54 -9 86 -32 28 -1 12 -25 -26 12 6 26 42 50 -58 13 50 -21 -19 18 36 -7 -37 38 14 4 5 49 -3 -20 -21 -41 -9 -15 37 -45 -12 20 -27 14 -54 5 20 53 21 22 -2 -29 9 -6 5 -61 3 15 33 74 25 -16 41 33 19 -5 -22 31 20 27 23 5 -34 -52 -9 23 101 -2 -2 5 -42 51 58 -29 38 35 -68 11 118 -8 52 -36 -28 31 -1 -19 -28 8 79 -47 25 -43 0 12 57 -18 -35 -103 -96 45 -40 19 -35 -68 69 106 31 15 40 24 -22 -1 26 -4 33 -32 26 46 -25 1 -83 4 47 -27 -14 -61 43 6 -3 -6 -14 -40 24 -9 -1 -23 51 -6 -37 12 -46 16 -29 -50 17 47 4 8 -29 -31 44 -40 -23 -29 -14 -55 -35 25 4 -53 32 20 -12 -48 37 -21 40 -5 -54 -5 11 12 63 27 10 4 -64 -9 -62 -42 14 -19 10 -13 3 11 1 -13 -17 67 -26 -27 10 12 32 -14 -7 -69 48 -33 -40 47 118 -6 34 36 11 25 -55 0 30 63 -33 -16 14 10 -26 -15 39 -19 51 -6 44 11 -20 40 27 30 21 63 52 5 -57 12 13 -6 19 68 50 -45 42 0 13 -17 35 2 3 -14 -40 -13 2 -25 17 43 -42 -25 -27 -15 -18 0 29 4 -59 69 -10 27 17 -8 33 -4 37 -50 5 -47 23 0 -50 27 -32 27 39 40 -72 -16 27 114 -5 -14 65 -53 -10 65 10 -35 13 12 53 10 2 54 -4 -33 -41 -42 -29 -11 61 23 -2 -36 32 0 -34 -31 44 -15 -25 -4 -7 4 -43 10 -17 -4 17 -11 4 35 -5 -7 13 -10 -13 17 47 -7 50 -10 -24 -42 -11 -16 -34 2 -35 -5 -1 -10 76 9 102 -29 -27 -10 0 0 54 10 -104 80 89 -56 67 -12 117 -40 21 29 -48 80 20 -69 22 29 31 -2 120 -84 61 2 -48 31 62 55 38 55 1 69 62 70 -54 27 65 -103 55 18 9 32 68 1 -17 25 12 64 -56 -14 40 -36 -5 -27 70 3 94 -38 -67 49 -39 -13 -19 -31 -57 -67 -28 59 -45 23 46 -66 -25 55 -56 27 51 47 2 72 119 -13 -6 51 14 5 42 -16 50 -67 16 28 -2 -70 16 5 63 -38 3 15 78 -11 -97 4 38 17 26 0 -37 -97 -44 23 2 89 -42 -39 9 -31 -45 -30 -40 -27 -29 14 -18 -25 -36 -50 55 -19 -23 -12 5 -79 52 -4 -57 7 -24 -11 97 -16 -15 9 -21 -37 1 7 -11 22 0 -29 -18 -27 -46 14 1 7 -11 -9 -17 23 -15 5 -51 -30 15 -21 -22 10 -11 15 0 28 51 26 -18 7 -6 -27 22 -75 1 -49 37 13 -13 49 -13 15 13 18 33 1 82 24 13 68 8 5 45 -27 39 28 -16 -17 0 20 53 8 0 17 31 -15 20 0 -35 -36 36 -38 -13 -7 -9 60 34 38 6 49 4 21 17 -1 5 33 -45 2 5 -24 -29 -16 29 28 -15 21 -2 23 -4 -25 -8 7 -19 -1 -47 -19 12 21 16 -39 -7 -4 9 -22 -12 -20 -13 11 -4 -9 -12 -10 -15 9 -8 17 42 12 -2 30 -27 -11 -6 -19 -18 -41 9 12 -34 -10 -47 0 -10 -35 7 25 -61 -10 -82 -9 -15 18 -51 4 -21 8 31 -27 -4 79 13 -11 36 9 -47 39 32 22 36 34 20 19 17 -64 47 -17 19 10 -70 36 25 3 0 2 -12 33 -55 -16 -7 35 0 -17 11 28 55 -33 57 21 43 -41 -4 25 11 -2 4 12 -25 39 -29 31 9 23 -39 -9 -17 -2 16 -8 8 -57 -42 45 23 15 -29 23 -7 34 25 6 -41 1 7 31 -4 1 -13 26 -5 -9 34 2 7 -28 -41 -2 4 -21 -33 -33 30 -7 9 15 66 19 17 -32 -25 2 -30 -12 -28 -55 -29 8 -40 10 10 3 -44 5 -38 -8 -22 35 -46 6 -16 28 33 -4 -61 -3 -59 -3 -89 -2 -32 -33 -38 56 -64 -14 -10 77 -31 -8 -38 68 -78 27 25 65 35 -41 -98 99 -83 -2 -19 0 1 -6 -7 7 15 -36 -63 100 -7 -57 6 -70 11 -29 -7 43 63 7 69 91 9 39 7 -71 13 8 6 -64 34 -46 -105 -29 -17 -49 -20 54 43 19 59 29 61 -1 27 1 -9 37 2 14 -2 34 -20 56 -43 15 -46 32 34 -65 5 -2 -11 -8 13 12 39 26 30 37 23 -58 70 57 -62 -10 -22 2 -23 31 30 23 48 -24 6 -41 -3 -10 -17 -45 5 -23 0 -33 -43 23 43 29 15 -12 -2 12 49 19 6 40 8 0 1 10 31 -18 -39 38 -47 14 -43 -32 -29 23 -24 5 -20 24 -27 21 -42 -12 50 29 25 -38 2 19 -28 -9 -21 10 -8 -2 -18 -23 -31 4 -21 20 15 32 -49 -47 4 11 40 18 -16 -40 10 34 26 -8 -1 15 -9 9 35 -2 -25 12 -24 -37 -38 31 -35 -13 -83 20 -48 23 -40 -16 -32 -28 43 -38 44 -19 -21 -25 -26 -27 15 19 23 -6 23 -19 18 -4 65 -27 9 46 -32 -33 -10 -38 44 24 -20 -7 -12 39 -32 -23 42 -10 50 21 11 1 13 -24 12 16 40 32 -6 -8 8 -19 -3 5 -21 -39 18 -42 -24 -17 -49 -5 -5 -30 9 -1 -2 -1 -21 -14 -29 9 19 -14 51 39 76 -2 -57 57 20 -62 106 42 8 22 89 103 37 -1 -14 25 53 105 25 30 -22 -10 5 58 -91 6 70 -45 -64 91 106 5 33 42 -11 -101 51 -45 62 16 -38 -23 62 77 -35 -38 83 5 0 -29 -30 -15 -79 36 -30 -79 -42 -10 -45 -16 30 -37 62 39 -86 56 -56 18 -20 -13 45 74 -66 1 46 -19 -8 -58 -58 27 94 -70 -49 -3 36 -16 -20 5 27 48 21 -85 3 -34 10 -23 -12 -12 -36 25 4 -15 -5 14 -14 -26 -58 -37 -25 11 57 -12 -10 19 -21 -23 -5 -51 21 38 -22 4 113 -8 -8 0 94 41 -20 5 -56 30 -15 22 -11 -43 -48 -14 -76 -3 20 -50 -55 22 -25 -111 30 11 99 8 -57 34 -31 30 -84 -40 33 -26 38 -42 -24 33 -81 -6 -53 53 61 47 -5 12 40 33 32 93 -36 -10 -34 24 -11 77 67 31 47 -20 16 28 -18 26 72 56 0 4 -3 -69 -13 -30 -20 -8 -13 -17 53 1 -66 -7 6 -94 -37 -82 43 48 85 -52 43 8 18 -38 -45 -29 -20 -28 -61 -26 74 11 -18 -21 -1 6 -1 58 -43 28 -42 23 90 21 4 -4 27 -35 46 5 -7 25 -4 -63 -72 -5 -38 44 79 20 -3 -33 16 -51 0 54 -13 26 -20 41 -37 -46 -15 12 9 3 18 21 -10 -13 -29 46 -27 -20 -30 -28 47 -20 -6 0 39 -8 -9 53 -45 43 38 9 44 3 11 -4 26 0 8 1 -29 41 41 36 1 22 -88 -1 -31 1 -30 -96 24 39 -47 -68 -2 -12 5 10 -27 15 -50 -42 -25 -5 33 36 -3 51 15 3 26 15 -17 7 49 -5 -4 -29 -13 41 -83 4 -16 19 -13 -7 -37 -24 -49 10 22 -16 -23 13 -32 -94 29 -54 -24 -1 70 55 -12 11 10 7 -22 31 4 -59 12 -64 -39 -6 18 -27 0 32 -8 28 -74 20 15 5 -3 29 -3 -18 -7 -13 -30 51 -32 38 18 52 29 -14 44 2 -26 -20 -45 63 -28 -9 -20 -54 8 13 -19 -26 26 -26 44 10 -14 16 5 11 19 -54 -9 -24 -63 -24 -23 5 -54 27 24 15 -50 -12 -15 10 -1 36 -60 0 30 -16 18 25 -2 -15 -8 -75 -10 -17 12 4 42 22 -40 -18 -15 0 -1 0 17 -9 -74 -36 -51 -29 -24 -18 -41 -58 -18 -27 -23 40 -37 17 -27 24 7 -7 -35 -21 7 -16 78 35 25 21 67 39 51 -4 -17 -13 27 34 13 -8 -11 -4 -29 20 6 -4 51 -7 72 -15 14 17 13 -6 6 -51 26 69 15 7 -33 60 -20 44 -6 4 33 -27 35 -36 6 -3 32 -9 32 19 -2 -14 30 -9 -10 13 -24 -24 7 13 -6 19 -19 -8 -23 -10 -5 40 -13 29 23 -18 35 -49 -16 15 15 -17 57 22 -16 -5 25 15 1 -6 29 -43 15 25 -2 -48 -53 -13 -25 23 1 16 -26 -22 -57 25 31 -24 -6 -10 -45 50 32 -20 11 -45 0 -25 21 -49 -32 -6 -8 37 -51 -45 -9 11 -19 35 19 23 39 -22 20 -27 34 -48 33 -7 -27 -3 -7 -12 5 4 10 13 -19 -44 6 -47 -20 -29 18 2 -38 -14 -38 30 -17 32 10 -32 5 24 -81 46 56 44 37 32 4 -18 37 48 30 34 -26 -2 1 1 -8 -32 -19 -14 -15 19 12 3 -3 -13 26 -12 -3 -19 -19 -12 14 -23 -26 19 -9 18 22 -12 -8 -18 -32 30 -23 -28 -19 -39 16 -12 26 3 -15 9 37 25 8 -29 9 5 18 1 42 -20 -38 -19 -11 -14 12 3 32 18 -14 -33 92 42 57 5 25 3 15 68 63 -39 0 19 38 19 116 38 23 -52 20 69 31 49 57 46 -5 31 84 92 43 36 46 -22 26 40 16 71 60 78 7 47 75 -47 -7 -1 8 1 -11 -37 3 38 36 9 -11 -30 -33 51 -7 -43 -87 32 -44 -6 10 -36 47 20 49 -6 -38 -10 -38 63 4 8 7 -12 30 -16 52 -13 54 31 -66 -22 -24 -45 35 44 33 8 64 3 -12 68 -8 -22 -26 16 -9 -46 -28 27 -3 20 0 2 23 -1 -24 -80 -7 -71 0 -4 -10 -1 13 -29 -43 -22 18 54 -16 -10 2 -24 32 -52 -28 -27 4 -32 11 10 -18 13 22 81 -11 -9 -19 14 -26 -20 7 7 8 44 4 -8 8 -38 28 -87 82 34 53 24 -23 20 16 18 4 -29 14 -21 -39 35 63 4 9 54 8 43 46 32 -16 -19 -16 -41 -4 6 -21 5 -27 -32 -2 12 6 16 6 6 -32 55 38 44 -26 19 -12 -68 36 -32 2 17 -9 60 -57 30 -10 -9 -24 12 -13 -44 3 48 -11 -3 47 19 -41 -1 20 47 -5 23 26 -12 -37 16 -61 69 -2 -12 -23 103 48 9 11 -41 -45 55 40 -19 11 58 -4 -26 26 21 20 -65 22 -24 15 -10 -39 16 -26 38 38 -9 40 -8 -12 -47 -5 -6 19 39 -16 23 25 -23 34 -24 -10 11 8 12 51 59 -27 -43 -19 -24 -11 -39 21 -15 77 -5 5 49 33 -23 -25 17 14 -13 -18 -23 -22 39 -24 36 0 36 -7 47 9 -15 -39 -27 42 -22 10 1 18 -7 -23 31 -16 -4 -18 -3 -28 2 32 43 16 -20 -63 0 44 3 -50 -22 -15 -8 27 -60 9 0 41 -23 30 14 -23 -1 -40 21 -17 -11 -39 31 58 23 14 47 -28 43 23 -33 -24 -13 18 -45 -24 21 11 -1 32 9 44 -4 -30 21 -40 -4 23 11 -14 30 -12 -17 -1 11 0 0 26 15 -17 21 -9 -11 3 -14 -41 4 -21 23 -10 10 -19 19 15 26 -15 20 -10 8 -6 -15 -10 -7 -14 -6 7 -13 -45 -16 8 -6 7 8 -18 -7 0 -26 56 32 12 -15 57 -7 -75 -6 -9 18 37 2 41 13 6 -40 22 -33 112 -22 17 -43 41 18 -50 1 0 34 6 -12 57 29 4 36 64 -37 -6 6 -19 -9 69 10 -16 -22 -28 29 41 30 14 9 -48 31 54 -28 -41 35 -42 6 -21 62 35 -27 -2 12 -5 38 -11 40 20 -26 55 -75 -26 13 -30 37 53 -18 41 -23 -43 -32 -32 51 19 3 -7 -44 50 20 7 6 -15 20 -10 56 -31 1 7 14 -9 -33 -25 8 14 11 5 29 -37 -35 49 12 26 38 4 -15 0 5 -6 -7 23 38 23 -2 29 -5 -14 -33 -25 36 26 -28 -14 -45 6 -46 -18 -6 -40 -19 11 1 -28 29 0 -45 33 -45 -26 -22 58 -6 -47 41 -48 -17 25 3 47 -7 -10 50 -28 51 -35 2 -67 -24 -55 2 -40 -2 -12 10 14 28 -19 -83 -12 -31 -21 -4 -9 33 21 -34 -31 55 -28 24 29 36 -40 -6 -1 10 51 -22 19 -29 14 5 -56 -15 1 -41 -26 22 7 14 -12 49 -54 27 -84 0 76 13 44 -10 37 -22 -26 -62 22 -37 66 0 -13 -45 10 -1 -19 94 44 -3 -53 -36 -78 44 -54 -40 -38 12 -19 1 -24 27 -38 42 19 15 -18 -26 -6 63 1 -7 25 8 -4 -19 19 15 0 -42 -40 -3 10 5 20 -19 45 25 75 -43 85 8 53 17 9 -43 -2 30 -75 31 7 61 41 74 10 29 40 -33 16 33 -7 38 57 31 -59 -11 7 13 -11 14 -34 22 41 -24 33 -33 -36 27 -6 -38 -13 15 -4 70 -28 26 17 13 47 -21 12 -24 -18 -6 62 26 -33 7 15 -32 -14 -42 71 -41 -39 40 -78 4 -11 -113 20 -12 -26 21 -2 3 -57 4 -18 40 31 12 -16 -45 14 42 -69 1 11 34 -6 22 -14 14 5 -27 7 -46 4 59 -19 38 8 15 -3 37 -33 92 9 -21 37 -37 2 -16 -20 -27 37 -18 17 -8 53 -48 -13 -45 42 -7 30 -15 18 1 -20 7 -21 16 -30 5 -30 25 -33 13 35 -8 36 -16 31 -44 6 -11 -11 43 37 -45 -21 -10 -20 -38 -9 -31 36 9 -20 -17 0 18 10 -19 18 47 38 15 -51 -9 -22 85 60 -9 -44 51 1 29 3 -21 75 11 -20 -45 -23 -12 11 73 8 15 56 22 -50 -65 3 10 11 18 -21 -19 -16 22 2 -19 -6 17 36 2 102 80 18 -9 -31 -9 7 30 25 -30 -7 13 30 -15 -12 36 12 -1 67 -16 -8 -23 26 -54 23 5 -43 -72 14 5 26 21 69 -19 -32 33 -27 -6 -13 -63 46 -83 42 45 19 23 11 -27 7 -5 -25 -32 2 -37 -52 -23 -40 21 -23 4 -29 63 29 -1 -37 22 3 -9 3 14 44 36 13 -25 25 9 27 -51 -5 -37 23 14 55 31 30 1 6 56 17 -58 18 43 -45 3 10 23 73 -3 -23 -37 20 -12 4 30 42 -67 -31 -19 -14 -19 -66 10 -9 47 -55 18 -31 -12 28 22 29 -15 -31 45 -47 48 12 -14 -41 -32 -47 10 29 10 -53 10 -7 44 13 7 10 -8 -4 43 50 -23 16 -54 20 -25 31 -44 21 -12 13 2 44 -37 -21 -24 -37 25 45 -31 -18 26 -57 -49 -21 10 0 30 38 -64 -1 -21 -20 83 27 -25 86 -17 6 -6 -46 -36 -41 2 -10 17 2 29 32 -22 6 -1 26 1 24 33 35 36 -43 8 27 31 -6 27 29 11 4 -11 -11 12 -24 -38 31 -23 15 -46 1 -39 -14 18 13 -24 10 -3 10 16 -8 12 23 41 30 -2 22 -15 19 49 42 9 -11 22 -2 9 38 18 -18 33 -5 17 17 29 -38 -3 33 -34 -28 21 34 -13 24 -28 26 19 -2 -30 2 -51 -22 -12 -1 -25 -8 8 34 43 -15 23 -13 36 16 -35 22 -14 25 15 41 1 8 -46 2 26 11 -1 2 -14 -11 -7 57 -59 32 -41 24 18 18 3 -2 -10 16 -5 36 25 5 21 29 -101 2 22 -23 10 8 -21 8 39 24 4 -1 5 -41 21 -9 -12 12 -20 -29 -14 1 -28 46 -21 35 -15 -7 10 15 -49 -27 20 -19 42 -1 3 -20 23 10 17 -19 6 -22 23 -36 -35 -5 17 4 -37 18 -25 -28 23 12 14 -10 34 20 -23 -113 12 -14 15 21 37 -52 26 -16 35 19 -5 46 -20 -45 -37 22 -12 -55 -1 61 -34 -52 -43 63 5 -7 -3 -65 9 1 -23 50 -17 32 -7 -37 21 19 -7 19 -11 14 27 -9 -21 -36 -49 -17 33 42 -35 -26 -20 29 -40 6 64 -1 17 23 -54 -56 32 53 -29 -11 22 42 16 8 -18 10 -6 31 10 -7 32 -49 47 -36 53 96 11 -7 16 26 42 89 -18 -24 -1 10 17 -20 9 32 2 -27 35 12 -16 -29 -15 31 11 -24 -14 3 24 -2 -57 8 23 37 15 -11 21 -14 -8 5 -1 -19 -24 -4 -1 -12 13 -22 41 -31 0 48 47 -4 46 3 -9 -15 12 -47 28 -9 3 -18 -2 2 25 7 -3 15 -19 -30 51 -67 13 8 71 -31 34 65 -32 0 30 -22 3 42 -46 -72 -24 91 39 28 2 -32 1 -5 -40 -25 -48 -4 17 -76 -2 -52 -10 38 -43 10 -67 31 24 -23 71 -68 33 -47 -24 -52 -19 2 -47 3 31 -62 44 26 20 -25 49 -19 -42 -92 -8 26 30 0 25 -3 0 -34 -21 -61 -13 -12 -33 -56 -21 33 -25 20 -42 -16 21 -16 -20 -25 -83 -19 23 19 -2 46 -28 -15 -15 6 -8 -38 0 -33 -34 -42 -39 -13 -39 -44 13 19 -13 4 28 -32 10 -9 -9 19 3 33 8 15 -7 -18 17 -4 15 -2 20 -12 24 -45 -38 -5 15 -65 -7 -31 -2 11 70 2 21 43 -3 14 6 0 32 -21 -32 9 -25 4 20 -22 -8 0 48 22 18 16 -32 5 -42 -18 31 12 21 29 -5 -67 -8 -45 -39 -5 -15 25 -18 73 34 17 -4 -40 37 -10 -9 -38 30 -33 -22 32 11 35 -27 -3 48 16 1 25 29 21 22 -25 -38 13 -18 33 -18 -36 29 -1 1 -3 21 7 7 14 -36 32 29 -8 -21 26 -12 47 3 6 -21 9 -2 22 -39 36 18 18 -35 -41 -1 32 5 26 -23 16 13 18 28 5 -9 -26 -13 9 0 -42 -5 -5 14 -9 26 17 17 8 28 -10 -8 -20 -13 18 -18 -21 -9 13 -6 -5 3 5 -2 -26 -46 30 -38 32 -7 43 1 -34 33 -31 -10 47 -49 6 -17 10 -15 -11 -58 -48 -9 -21 1 33 -57 -29 -33 30 27 -6 -42 61 -17 25 -27 62 -42 -33 3 39 33 -76 94 1 -4 17 -5 3 -33 -27 -42 -28 40 -3 17 -26 13 -31 12 25 16 7 -35 0 -85 -6 27 5 46 3 14 69 -73 5 -33 -47 -17 -1 0 -39 -36 4 9 12 16 38 -13 -18 -31 45 33 -15 -8 2 33 -14 4 54 -52 9 40 5 -22 -23 -19 -42 -32 -14 14 8 -1 -45 -11 3 -40 29 -5 11 15 41 2 -26 -1 -9 -14 0 -11 -38 -4 28 37 28 28 -52 -3 -1 27 10 2 2 -35 41 -5 4 17 38 2 -19 -25 -16 21 -51 31 -36 16 -12 5 33 9 33 -57 -4 -35 0 -46 -25 29 -37 -49 0 -7 3 43 13 -32 56 -49 -21 -54 -39 8 13 -53 -27 -45 -67 -5 24 -54 -34 25 44 38 1 -25 -17 6 -17 59 -44 -21 -24 6 -42 -17 -3 -6 2 -62 6 39 -46 -44 -65 34 -46 1 -54 -59 30 -31 -4 20 42 6 20 -8 -32 -19 -28 12 -18 40 -22 -30 12 -51 0 -33 -8 -7 31 -78 97 -52 -47 -8 -4 15 12 12 24 1 -16 -40 22 -13 -1 58 -15 4 -45 -34 8 21 2 54 19 -7 -23 23 -4 -9 -3 23 32 11 42 -7 2 64 12 -18 35 -17 2 -14 15 89 74 5 10 -1 -2 -28 -5 -13 -18 22 48 -35 41 -28 6 -21 -13 -7 -11 12 21 50 -24 -58 11 10 -56 -30 36 23 -62 -6 6 45 27 38 -24 -29 -19 23 -34 -7 50 34 -40 -22 30 12 -27 -40 -60 -4 12 -65 32 7 8 31 22 -62 -22 53 6 -48 11 -37 -46 0 12 13 38 21 20 -31 5 -14 -44 -13 10 42 -61 -36 28 -18 -37 25 -32 -65 -19 13 -39 38 40 -24 -18 -24 -22 42 12 5 -5 0 38 -13 30 -20 37 -4 2 -22 -24 16 -11 -30 22 27 -3 -19 4 -32 2 11 25 19 -2 -1 32 -2 10 -24 -11 14 -33 -16 7 -32 -25 9 37 -42 -4 21 -4 22 23 -29 -11 -38 -8 -9 -21 -3 7 -23 4 30 -8 -11 -1 -5 -6 2 10 -10 11 37 -9 -31 -45 1 7 -8 -7 12 -20 -36 8 50 11 -20 -29 -1 -19 -2 18 6 -1 49 -18 4 16 -20 -6 4 18 12 34 -2 -23 10 10 18 7 -24 -11 7 11 -3 28 -4 -7 -22 -9 -9 -94 -11 -59 4 -13 2 40 28 4 17 -1 -19 11 6 13 11 -11 11 8 -5 -14 38 -7 19 13 -25 11 13 1 22 -9 -6 19 0 1 -11 2 11 1 -7 2 9 22 7 -11 -9 -17 -5 -13 -5 20 17 9 8 -7 -17 8 -1 -20 -9 3 -8 -7 -10 -3 13 9 -16 -2 7 -10 5 26 8 19 -3 5 11 -47 43 -2 -43 1 16 20 15 -36 -31 -23 -27 -3 -19 -15 41 -17 28 -20 13 -15 23 -17 -20 13 1 -10 20 16 -1 13 20 23 -59 21 16 25 72 -31 -18 -28 -2 -26 -9 30 12 8 -19 50 -62 -10 12 19 -38 0 1 53 14 23 16 -53 43 43 70 38 -42 -26 -35 3 -18 12 24 -115 -43 35 55 9 -4 43 21 -48 -21 29 43 -27 -73 -24 -4 -64 72 34 -34 38 52 38 -21 33 -35 6 -30 25 -5 15 -5 -10 7 -16 2 -9 -44 18 -12 -8 -24 27 19 2 -22 -7 -18 -42 -13 -19 27 32 48 -33 -13 25 11 -25 -8 -24 10 -1 24 -32 -3 21 4 8 -15 -30 17 -18 40 8 -39 -10 -26 -7 -36 -53 8 -11 -30 2 -5 -28 14 -43 -51 -30 22 -8 7 -39 -23 -13 -10 -20 5 -18 13 -35 -28 13 -40 38 -4 39 52 0 17 13 24 -50 -39 36 0 15 -50 -16 -25 -8 39 10 -46 5 58 -18 -9 -16 -69 -20 37 23 -36 -39 58 20 -3 -14 3 -21 36 61 37 -128 4 -52 5 56 98 -3 -4 62 -21 -44 -105 -55 47 27 -21 29 1 3 10 27 76 42 23 -26 -48 16 -6 39 10 19 -31 5 -20 16 -44 -7 -24 -5 18 -5 -48 -15 -58 0 -8 2 14 8 24 32 53 -6 -19 -19 0 -45 -20 -21 32 -11 10 -64 -9 -19 4 -13 -12 -39 13 40 2 -21 6 -18 62 36 -40 -75 22 16 -29 -69 67 -64 42 37 -29 13 -23 15 37 55 -50 -72 9 15 -15 -32 25 -45 -23 59 48 82 37 43 -14 34 12 21 59 -4 92 -10 -56 -48 -84 43 -74 -19 73 -28 30 -8 -23 5 -12 -72 51 49 30 28 -102 38 -24 -24 -15 52 49 44 15 22 -51 1 -27 -25 -33 56 119 -31 42 -8 -61 -7 -1 11 -37 -32 -82 -16 -28 -73 -31 -6 1 -39 41 15 -24 -43 6 40 49 -6 -46 29 -44 12 35 22 -4 -35 12 -27 -10 -36 -3 22 11 52 29 9 -16 -13 27 -40 -36 -50 22 -9 0 -22 -39 0 -5 -10 -1 -71 -24 -4 26 -18 15 28 -54 2 -29 0 12 39 -20 -26 17 30 -42 56 115 -44 12 -1 101 -15 12 -34 13 -13 -55 32 -29 37 -25 -36 -31 29 12 13 -7 34 5 29 2 32 51 -19 30 15 45 10 -28 -124 -78 16 -91 -5 66 56 4 4 121 124 -29 -125 -51 -20 -81 13 78 8 43 -45 -61 6 -89 -80 2 -15 -21 84 11 -25 -118 -21 109 40 -48 -5 14 50 72 31 -5 13 14 9 -32 -35 54 -15 -1 -45 -32 2 0 -64 -9 9 -32 -26 -63 16 5 -60 42 20 34 -12 66 -29 -37 -28 13 46 -4 -33 -10 -29 12 -26 -21 65 -30 16 12 10 9 29 -20 9 -34 48 -19 15 -22 -16 21 71 14 -44 -3 24 -9 9 -54 23 -68 -72 -1 -14 -96 19 22 -11 17 -12 -20 24 61 33 -5 -80 -23 37 -33 -38 -43 -7 54 -2 -2 -12 77 5 -27 -35 -18 -22 15 -27 -10 1 -9 -11 70 -18 0 32 44 2 16 38 42 85 2 -45 -43 -13 7 111 -69 0 98 76 -25 59 -23 -26 -48 -51 25 13 35 -30 -47 54 -11 16 -3 -22 -6 67 -106 -29 32 -93 -69 9 38 43 -32 -61 72 -68 -55 58 18 0 -21 -32 11 -33 -17 28 -28 0 59 -38 -17 2 24 16 -49 -22 47 -3 3 -9 -5 -12 -9 26 -23 3 24 -81 -62 5 13 -15 -41 32 -36 -11 -10 27 -13 49 91 -30 -41 90 -2 10 -120 33 87 -27 -120 116 -17 75 -53 -49 -16 -3 -121 -62 -22 8 0 13 71 6 34 -40 -38 -47 -59 -73 5 46 70 -128 3 45 23 63 -117 45 54 123 78 121 74 -66 10 69 124 100 48 -24 -87 -79 58 -52 89 -127 106 87 63 50 7 -35 -127 -92 -123 37 -124 -45 1 120 -60 -64 90 15 24 102 -111 -15 -28 123 -89 48 86 127 -4 -71 -125 6 19 -46 -119 125 51 -70 31 -125 12 20 -14 -30 18 40 31 -121 55 -91 -80 127 127 66 -36 3 91 -65 20 -9 19 -38 -44 10 -88 127 79 94 19 15 -31 127 -66 -26 60 9 -100 -1 -82 79 -56 13 -18 -10 81 -99 -128 81 15 49 -117 50 -28 12 -13 124 -76 -41 34 108 26 52 -115 77 18 41 53 74 -49 0 -89 -126 -85 3 26 -92 -126 65 -66 -25 -34 -24 117 20 -121 58 65 117 123 39 123 -26 -22 -1 -85 -48 25 -79 -52 -77 -21 -112 106 -124 127 78 -48 126 -20 -128 114 -109 -72 -33 -125 65 -73 -85 13 -33 -31 125 45 36 -15 60 -37 32 -62 -66 66 50 20 -89 127 124 -46 -70 -79 -69 74 -90 124 33 -55 -62 68 29 95 -117 -3 -127 79 35 -41 8 123 -103 61 92 14 77 28 16 12 -35 81 -12 -3 -87 -31 43 -32 31 -63 -128 -59 -67 -38 -63 -52 -125 -33 125 11 -36 -13 -32 -8 -54 127 -120 -2 -27 -113 18 -26 -7 -74 21 -117 -72 -96 56 -98 -31 -60 52 -19 4 15 36 -70 -58 -25 -125 -5 18 -5 -109 -44 -86 -25 -6 -126 -58 39 -32 -87 29 -99 103 70 117 127 -110 -90 -10 16 28 33 82 -66 58 -66 28 109 -119 127 108 63 127 68 30 -41 20 -63 110 -15 31 57 9 -38 -55 17 -114 37 125 -52 -104 -3 61 -127 88 29 -121 -68 14 -93 126 -9 78 -18 5 126 -10 -58 -102 -10 -32 36 -31 -40 -16 53 -78 113 -28 11 40 123 0 77 68 127 55 20 52 -18 51 -18 3 40 41 -10 124 -15 89 -69 52 -18 121 -81 -74 -18 -30 22 124 -95 -2 -47 27 -23 59 108 -127 62 68 -43 125 20 -53 -41 -32 -59 40 56 -39 -98 -29 62 39 -46 29 -65 28 -20 -118 17 61 9 62 -20 62 -30 -84 -62 -43 -47 40 122 -108 -52 51 -128 39 127 -62 126 -42 10 35 -20 127 -44 127 39 49 38 2 -124 -124 -19 37 -7 -3 127 -125 7 -127 -106 39 -76 -68 -93 27 -127 82 123 29 -100 22 26 46 -20 17 4 122 -22 -11 -18 106 -107 -28 -67 71 69 127 -63 77 -39 56 -26 57 46 1 19 127 0 -127 -59 92 0 32 126 -64 -23 15 95 -68 23 16 83 -53 -45 102 104 -20 -43 126 -9 1 48 -27 -126 -32 7 4 -52 127 -5 79 -50 -14 -126 -67 70 -117 -59 -54 70 -19 112 -115 -118 -126 -125 21 -16 -127 -36 126 118 -106 13 -80 -98 9 -55 33 -93 -24 41 -17 26 107 7 -32 15 -127 22 108 -81 -113 -128 28 -113 -58 10 -29 -101 -106 85 -4 -125 -114 -108 32 -113 23 -92 44 -102 1 -81 -125 12 39 -94 127 -122 -53 -108 28 -58 -83 -128 55 -48 -123 12 51 83 9 -127 45 27 127 126 127 57 -12 124 21 -54 27 67 126 -109 85 23 -72 14 -60 124 118 112 20 119 -67 38 44 124 -127 27 12 -40 -122 -15 10 46 -88 122 26 -45 19 18 -23 1 127 45 69 -102 94 -50 -44 -24 -11 -35 32 21 63 -80 -22 18 109 -29 114 -118 -56 120 4 -45 21 33 -27 75 76 -95 -14 -120 124 -35 -128 -55 127 54 2 41 -77 -3 -91 -55 -102 51 110 -41 -69 88 104 -80 -1 2 89 26 119 -12 63 -128 37 39 -76 59 -107 126 10 -127 125 -68 19 -45 18 -94 -1 123 126 127 -9 -20 94 39 -121 31 -1 -114 5 127 125 80 22 -45 33 -42 123 48 4 -16 -127 -56 -119 30 -116 -5 -33 65 40 -2 125 22 112 6 -78 67 -119 127 -73 49 62 127 -104 25 -21 -127 -81 40 12 -62 -119 -20 42 83 -96 -128 92 -40 -43 24 75 19 38 -41 -59 -98 -93 -99 -51 -18 -33 19 48 11 -6 -42 31 94 127 -72 84 -123 127 -47 108 93 57 109 111 111 126 53 -82 13 -104 87 127 -115 116 30 21 -8 78 29 -19 -38 116 -31 -46 63 111 41 -44 -48 -71 -33 6 -63 -4 -99 65 -23 52 27 -82 -110 26 26 104 96 -76 60 -100 -119 -118 -124 -128 77 81 -77 -93 121 -101 88 -74 55 -25 7 -44 26 31 -79 39 -2 29 -1 112 42 -3 127 -54 38 -50 102 -125 -95 -79 15 -106 6 -18 -92 127 -87 16 -6 127 6 24 -55 -45 -125 52 69 5 -45 -128 74 45 122 -56 52 2 54 -59 69 23 5 17 -44 62 36 -52 83 39 -94 2 -16 12 0 -127 -110 -128 -15 123 -18 41 68 -105 -104 82 -23 88 10 126 -124 -36 1 2 -6 120 119 40 88 95 96 -62 31 107 70 123 -107 127 -123 58 96 19 106 56 -111 -125 -47 61 79 -82 -26 -124 -8 -47 -128 71 62 125 -47 -66 79 127 124 -106 2 70 -5 -127 28 -1 80 -128 -14 -83 -115 113 122 127 -128 -52 76 61 -127 82 -34 11 120 115 -109 119 -127 127 60 40 -9 -51 84 -20 -122 123 -43 -57 121 22 24 127 72 88 -21 -7 -121 94 -35 75 13 119 37 -127 8 -128 -127 40 65 -90 -128 -127 -51 -126 -99 -118 110 -52 121 11 -124 -80 -11 121 -9 -102 12 89 56 -68 -25 67 -79 71 6 57 99 -51 -18 127 23 125 18 89 -40 123 -45 30 126 -15 -124 21 61 -5 -125 -73 -51 -27 108 76 -42 -2 -126 101 -20 56 -44 -14 117 126 -127 -122 48 -127 12 -49 -109 -102 35 13 -39 -49 108 125 35 -104 95 68 -57 22 -122 34 119 -94 -117 92 -64 100 -2 21 -127 -84 -2 -100 95 24 22 5 8 61 88 72 -128 12 86 90 25 -10 23 76 2 100 -18 24 -20 -127 -2 -14 -88 -30 21 -2 65 36 -96 -128 121 -66 -91 126 123 -11 -19 -117 -53 37 -116 -123 -73 -122 -128 -50 -18 -62 108 -44 -128 -125 88 68 126 -126 23 40 -62 -121 -20 11 -37 -48 -117 -34 108 -90 -121 -24 115 -21 27 -7 24 96 24 41 -128 -80 -55 2 124 -127 -103 31 32 -127 51 29 -9 126 -77 -13 -30 -24 -73 117 -123 94 19 29 124 -90 -56 -126 -12 -71 -114 -74 127 -121 96 -111 -117 -47 -128 30 -125 -45 -17 84 127 120 -45 88 95 20 -126 15 30 -87 33 -61 -68 127 70 -117 -77 64 110 127 -68 -41 -126 20 67 57 -1 -123 43 -62 80 121 -17 -124 -20 114 123 11 127 39 -46 -59 34 54 -69 33 96 91 127 -120 -64 96 -63 -15 -68 -95 49 126 -58 123 -72 4 127 99 -115 -87 -119 45 64 76 127 112 -117 54 -125 117 50 -122 127 127 -56 -128 -17 17 1 -8 16 -58 104 -120 99 -9 -27 -122 61 126 34 41 -4 -100 -66 101 118 -119 127 -123 -123 54 82 -126 38 118 -98 -30 -29 -11 37 39 -77 127 -38 5 -17 -127 94 -55 10 113 -75 127 53 -7 127 -3 113 -111 -62 76 5 -99 -112 -81 -94 -21 108 -126 -31 -106 125 -49 -98 -128 90 -35 101 -39 -76 114 74 60 -18 56 127 78 -81 -43 -106 114 117 -124 127 -26 86 -22 6 48 44 -108 23 120 114 80 -70 124 65 -19 48 35 -127 -96 15 10 127 -106 -118 97 58 41 127 122 -128 -127 -98 62 -22 -127 127 -18 61 -120 127 -101 32 -12 92 -80 -127 -82 -43 -62 127 -4 29 59 5 -79 -113 119 118 -29 12 69 94 -16 47 42 -95 -127 -45 -88 -123 13 12 69 -12 124 17 -62 3 25 -127 -45 104 71 -94 119 16 24 117 -66 -122 -78 31 55 65 127 -30 -1 127 23 26 111 -115 -21 71 -66 127 6 112 46 -127 -101 127 -59 34 -123 127 -115 74 -60 37 82 17 71 35 126 112 -26 -92 126 83 38 -81 75 -68 63 6 53 71 17 76 -10 70 116 -44 -87 80 26 126 -36 27 41 -6 127 -48 44 -51 23 16 -86 14 -49 -50 -49 -47 -103 127 -128 -60 97 79 127 123 124 7 -90 -4 126 -18 -108 -29 22 43 -121 -127 127 119 -123 122 -128 -43 -125 -30 -78 124 -18 82 126 83 -86 -126 126 114 -127 29 121 127 78 63 -38 13 8 -101 114 120 -127 -124 127 55 -2 -54 61 -35 123 -63 -38 126 -7 -106 69 111 -28 -86 109 -72 -65 5 117 30 -108 77 26 -38 55 125 41 13 -113 -64 117 119 44 -48 -115 -118 -22 -15 -12 49 98 123 -29 -31 46 -123 -83 -71 -119 67 80 57 -53 -106 106 -9 127 -87 -9 72 33 5 -117 -19 -38 -45 29 81 79 34 -2 -126 95 80 60 14 -49 -11 119 -127 -5 -48 -67 67 45 82 -64 -73 -120 -48 -88 63 -46 -69 -58 -10 120 45 117 -125 -16 10 127 91 85 90 60 -110 -1 3 -50 36 -20 117 -38 69 -125 53 -125 101 -113 90 -126 5 -19 -69 49 44 -19 85 73 105 70 61 -120 62 -17 59 82 117 -69 71 29 117 -12 15 -31 13 -74 -47 50 -23 -52 57 90 -58 -65 40 106 -53 14 72 -87 53 55 114 119 -96 -128 97 -125 -53 117 -113 15 127 -1 109 -59 -107 127 -125 -8 126 64 27 127 127 27 -49 -73 -83 99 98 -116 85 -102 127 104 -40 127 -18 119 -9 30 123 -77 -81 -73 5 -11 103 -36 74 -23 -127 42 29 28 -70 87 -56 23 116 39 -80 -120 -80 23 124 68 95 -37 127 -107 127 62 -68 27 -66 -126 7 -15 11 126 126 117 -8 -110 127 127 38 -127 -83 127 20 -20 -25 24 71 44 -53 -49 -42 98 111 123 112 -128 -2 -7 124 -78 48 89 125 -122 127 -74 126 84 87 85 -67 -20 88 -25 118 36 -41 87 120 -40 -122 66 66 -78 -1 127 -123 -60 -103 54 -56 -128 -61 -117 -120 -45 103 85 -105 86 -118 -35 -122 -126 -122 99 127 -51 73 118 -125 127 -60 -66 -41 -28 -86 -35 41 120 -39 126 -122 56 -104 -39 -95 -19 6 118 -91 42 39 77 -50 -41 10 -96 18 38 42 79 -35 -122 21 49 -118 -124 -109 -61 94 -126 -30 127 -31 -103 109 -76 40 -69 5 24 34 42 -3 125 59 91 -12 124 -121 -72 13 -82 -17 90 49 11 -25 -116 127 123 0 1 -57 50 16 82 81 -121 -122 36 73 -126 12 -111 14 26 126 -37 -9 127 -24 -127 44 29 22 -21 14 116 73 107 -38 127 39 -7 -92 111 60 97 -94 -78 70 119 -124 -118 46 1 -25 77 -10 -116 -122 -125 35 97 39 -125 -86 -128 43 -14 127 -94 -70 -8 -87 127 -121 26 79 -32 -105 -8 11 -43 -16 -73 -31 6 -24 -112 66 -25 106 -73 -7 -127 -98 126 127 113 -127 -123 -102 -125 -65 20 -60 -128 58 74 -89 -53 -106 -59 52 22 -127 -35 127 115 -51 -8 -39 -6 -90 117 -127 22 -32 127 25 -128 46 -11 -11 -127 -107 21 -51 38 118 -27 -12 100 10 -42 -111 -54 28 -63 -22 38 -43 -67 40 -86 123 -125 -33 -90 -64 -107 -127 -124 -125 47 118 -14 -40 -55 45 -54 -26 -111 -93 -124 -122 51 -128 -12 116 18 -121 -21 67 -15 -83 -128 68 65 -55 127 43 107 -45 -128 72 90 -128 -6 -118 -128 36 119 127 -125 -128 -98 -49 -65 127 -46 61 60 34 -24 23 80 92 -41 -5 -79 -95 -26 -38 -87 -37 -1 76 -127 -44 -14 121 -12 -122 2 47 -21 47 5 -26 -29 -24 -63 11 20 85 25 -92 -18 73 28 -57 74 -53 -2 30 36 -19 -107 -18 -79 -25 16 118 32 22 -118 71 -41 38 -62 1 71 -17 1 1 94 94 -59 1 -17 107 68 39 -49 24 0 -91 33 20 11 41 -32 33 -9 0 39 -13 -115 -52 -83 -4 12 68 -50 63 16 -29 -29 127 -12 127 -58 119 -46 -5 -128 76 -27 18 34 -47 22 21 -121 -63 -23 -39 58 40 21 -5 36 15 25 -77 72 16 4 -18 -14 -81 54 -16 -128 -16 -127 64 -16 -15 28 126 25 8 7 10 53 26 -95 -106 -7 -62 -69 127 -13 54 52 -101 -21 -7 -27 -32 -76 82 8 -97 -17 -127 28 22 -41 12 122 49 31 -32 87 -22 -18 -37 -16 14 -16 -57 75 114 -92 33 127 64 -53 -56 -127 -32 -47 -1 -53 -22 4 -96 50 91 112 24 109 127 109 100 -67 50 111 85 -88 43 -71 -50 -33 5 127 7 66 -125 -61 52 -44 14 -49 57 -54 -127 -27 12 29 59 -128 -117 -52 -81 -28 -97 12 -127 -20 106 88 -100 45 -62 121 78 -107 16 -113 71 -20 46 41 18 -34 21 -8 55 -44 48 -22 4 -119 50 111 30 -65 115 -47 15 74 -101 8 55 -68 72 -54 101 10 26 18 62 -63 56 -40 -35 4 -27 -58 -6 48 56 21 20 63 -91 21 -12 79 -53 3 -14 12 -99 -23 -127 -17 110 6 44 15 -28 -111 2 -42 -90 -39 -27 67 32 66 47 -66 -16 -52 37 -53 12 21 124 71 -81 69 127 -113 21 13 -117 -5 -45 99 -4 -30 -39 20 -17 62 -1 -126 75 -32 43 55 -12 95 -40 -13 -17 -26 -20 -65 53 11 127 -60 61 122 -110 -26 52 65 108 83 12 127 67 120 -47 47 27 93 -47 -26 27 55 28 15 -126 74 -69 122 -69 -64 1 -88 112 13 8 73 -7 -96 -27 -108 -74 -78 78 109 87 53 -11 -3 -36 -52 -35 -17 -65 -15 -9 30 -45 -17 27 102 -120 -27 -118 -71 17 -76 100 64 -80 54 16 81 -37 -118 -30 63 27 53 119 -74 -57 -88 -92 -52 -16 64 76 81 104 -26 -4 68 -54 -127 -48 -113 4 19 25 51 -63 17 99 47 -74 127 64 -73 -58 16 -5 80 -127 -57 27 57 115 122 -59 -6 67 127 31 -120 -44 -52 -126 28 -51 25 115 97 80 -107 55 65 41 71 19 -9 20 -104 35 -99 127 72 115 23 -42 -128 3 45 -55 3 45 -126 -125 -120 51 126 -40 42 110 -60 -95 -39 49 45 52 -71 -122 113 -100 -98 127 -78 -102 31 -20 -63 -128 -57 79 -4 -17 88 57 -32 -23 -117 15 -45 124 -67 56 -16 -50 -39 -79 14 -86 9 -3 56 -112 41 -102 -43 127 -48 -108 -29 -95 88 -46 127 42 71 127 76 54 -104 84 29 -123 34 -13 -44 92 76 -86 -99 15 -68 -120 -119 -99 -128 25 -20 -25 84 -62 59 -48 -34 35 -55 -114 2 67 -128 55 -69 29 -122 -10 72 -125 -31 56 120 -113 79 127 127 -85 -62 39 69 -107 83 126 -11 -106 58 -73 109 7 -25 -52 40 63 11 -101 -50 83 111 13 123 -35 34 72 83 93 78 -50 -40 127 -71 -94 -46 -29 55 67 35 -120 -70 126 94 -34 -9 52 4 52 -11 26 -8 29 -10 35 -22 -34 -24 -19 75 41 -56 55 26 -122 47 -119 -123 36 127 -45 -106 42 28 -90 -9 -76 91 -8 -19 -28 124 -120 51 61 59 -10 -90 -4 15 16 70 123 57 113 44 -16 89 -47 6 -19 37 -80 -25 48 92 83 2 -119 67 -41 -6 127 98 42 -121 -93 -7 -72 -14 -121 125 -58 4 80 -101 -27 51 42 14 73 54 69 -127 127 -128 127 -80 118 91 5 -116 -48 -1 81 -11 -2 -127 -126 -32 -99 42 121 -25 -114 96 -64 -63 126 -50 90 50 -54 81 41 -22 -114 123 -107 -99 -125 37 6 -52 115 110 38 127 102 51 -56 71 12 102 90 32 -47 -3 31 83 123 -75 127 77 110 127 37 115 -58 -61 25 -47 124 -2 -61 50 44 64 -8 95 -78 -95 -36 -127 -123 7 21 124 -3 115 -58 -25 -120 124 -12 127 33 36 -83 54 115 -13 6 108 -10 -4 -28 -9 -47 -14 38 -24 -78 33 37 24 -76 61 5 8 95 40 -53 -22 32 11 9 -45 64 -68 -52 -21 17 -51 -89 67 -34 116 -127 -4 -35 -26 -53 -2 72 33 8 42 23 3 50 -114 19 46 6 -84 -17 -111 44 117 28 -30 -29 -127 -41 -5 -31 50 78 91 -65 -11 20 1 -26 -36 79 -9 -14 -7 127 26 -126 33 59 33 28 -51 46 42 -6 -40 30 40 -63 -15 8 -21 95 64 101 46 11 -57 -103 50 -1 -54 92 47 -37 -37 -43 -42 -113 -58 100 -26 -38 21 87 -17 108 -64 -45 -27 -118 97 -15 7 3 25 52 47 -121 94 -28 -119 -73 44 -70 -66 42 30 12 88 125 -80 13 18 -4 -28 52 16 -45 -88 -21 115 -83 61 -41 98 -5 -41 -42 61 22 -58 -122 -16 9 -38 -36 12 -87 39 92 88 -71 -23 36 1 -19 7 14 61 30 34 -77 -10 -17 -18 70 18 -78 -104 88 38 -115 11 89 81 -104 5 32 -15 -2 -29 43 -100 90 35 13 -102 78 123 -65 57 63 12 8 72 -71 -101 -38 -1 -5 -64 -30 5 124 -42 -34 16 56 69 -5 -5 -46 -27 78 -17 43 -21 50 54 -60 61 96 7 -59 111 62 13 12 -2 -3 32 -37 48 28 -8 75 -25 50 19 52 87 9 -62 43 -25 69 126 -37 -45 48 -37 -10 -20 -52 56 -23 -4 18 66 13 36 72 -13 9 66 28 -124 -1 36 -76 -36 -65 56 41 -35 -10 26 -22 -69 22 -97 70 -54 -1 12 26 92 -38 109 -85 83 -12 -29 1 20 -51 27 -27 -106 33 5 47 43 19 -103 -22 -12 63 -62 33 -61 -104 -13 32 -38 127 -27 4 -46 -3 -115 -74 -27 -50 45 2 5 -4 -51 -92 -102 29 -15 -14 29 -42 68 43 -10 15 -19 56 -37 114 -9 51 -65 -114 45 -64 -101 -40 -45 -10 -69 28 5 72 -101 -118 52 123 -23 8 69 6 12 3 14 -16 -33 32 -62 34 -13 32 122 -81 -72 -7 -64 -10 -5 89 25 -19 -20 70 -10 -43 -88 8 -56 -34 -90 89 -68 -25 12 45 121 16 21 46 24 94 74 44 -37 -40 -60 50 19 28 -112 -82 23 -4 127 41 118 16 63 -35 44 -86 47 -94 -103 10 -11 -48 -56 109 -39 16 54 72 127 30 90 125 18 -127 -46 -7 -83 -19 -43 -92 69 47 -12 -111 -45 120 67 108 126 -55 -107 5 -116 -89 -120 38 -7 -106 15 -8 6 40 32 34 125 -19 -75 -17 123 -24 32 24 -107 109 -105 55 -32 88 61 -83 -89 -108 31 -65 -28 -28 -22 -70 114 127 100 29 -11 16 48 20 64 -45 109 41 -38 42 16 79 -54 -40 -50 127 75 58 40 60 39 -100 -26 -20 -57 -55 -32 71 123 -23 21 21 -10 75 97 -112 -26 -16 98 6 -14 26 -43 -13 13 -12 36 -80 10 5 25 -90 -47 -48 -54 -55 15 36 -81 89 83 1 91 -69 67 -62 -126 -15 -26 33 -125 -22 127 24 -73 -117 8 81 -53 -13 -8 48 33 9 26 102 -66 -9 35 127 -95 -19 6 -5 -1 -20 94 -19 -29 -41 47 -8 -120 -53 -36 -70 8 120 -125 -8 92 -75 126 -40 65 67 24 100 24 -3 -45 -87 -48 -20 10 19 127 -42 60 -49 64 127 114 79 3 8 -127 124 -69 -62 21 -20 1 -62 44 -24 -10 95 12 44 85 -36 27 -3 62 -31 -41 105 -77 -47 7 -45 35 -70 -20 -10 -27 -13 121 -9 14 -64 -95 -105 -8 -7 -98 -48 -79 -62 52 94 24 -88 -43 -80 120 -39 -114 -4 26 108 26 63 18 10 -42 2 -74 13 -52 -54 -79 0 -120 50 79 -118 75 5 56 25 4 -97 0 -108 -125 -42 70 87 -64 43 38 16 42 24 25 -28 105 30 52 -93 62 -52 63 64 72 19 -80 -7 -54 99 44 79 -96 29 -33 -106 43 42 70 -56 4 97 44 -128 -9 116 -57 -27 -72 106 22 -26 -67 -8 120 -22 38 24 -72 20 65 62 -128 -94 87 -97 -4 -6 74 -116 -63 45 -2 -71 6 76 -6 -5 33 -98 -40 114 -98 95 37 104 70 -1 10 34 -18 68 120 -64 38 58 15 -14 -29 -5 22 90 31 28 -78 21 -30 -49 -14 120 89 -92 33 -48 -25 4 15 -57 -111 41 102 1 -6 -81 75 -38 -65 122 -128 29 53 -60 127 -96 -64 -84 -80 -125 -128 -39 -124 -11 -121 -59 77 -110 0 21 -117 24 64 6 -29 -123 32 36 -57 -30 5 17 -106 35 62 -128 60 -16 -57 -123 -32 -10 80 -74 -22 -24 41 127 -128 127 -128 44 69 116 93 -118 -30 -74 -125 -42 61 20 -45 -36 16 -127 71 31 38 15 88 -124 -39 69 123 74 -120 27 63 -10 -64 -98 53 118 127 -83 -101 39 127 -23 -30 -113 -105 -124 10 9 -127 -75 -11 29 -77 127 3 -5 -46 -105 -127 26 43 -70 -128 106 -96 -13 40 107 27 57 9 -90 65 127 95 35 -42 -96 -34 -86 123 7 85 125 -126 -33 -128 126 41 -127 -128 8 -3 -117 -45 127 -122 79 46 -50 28 -101 4 -19 -44 -116 -128 30 -77 -38 -80 67 33 -121 -43 73 -119 98 70 39 29 -22 -46 56 -10 -24 -18 116 6 1 26 -128 75 -32 -22 -35 13 -36 -26 59 111 -73 3 126 -128 126 -122 62 -3 22 0 -64 16 101 15 10 -62 34 -38 -82 -14 -127 37 -12 -56 -93 42 -115 107 -42 34 -120 -98 -50 29 -79 92 -121 -89 126 127 0 -115 101 127 -13 26 -123 10 -61 115 85 -126 17 -23 125 -13 127 47 -48 -51 -123 -124 -38 104 -62 -127 -89 -90 -9 13 89 -86 -44 48 -116 21 127 99 -70 3 -8 -21 4 -84 125 -127 121 87 54 -128 122 107 -56 -75 93 -16 -118 66 56 127 123 26 10 -29 102 25 -47 85 -4 64 33 115 -44 83 3 12 92 28 52 -49 61 -33 -52 87 127 9 8 -45 89 65 124 121 -128 79 71 -66 0 123 -34 -92 101 91 127 0 123 -9 126 -58 115 -69 13 -34 -108 -111 -67 71 115 126 79 68 81 123 72 -60 53 -119 -15 -37 -74 -22 102 113 -128 -127 96 123 -103 -46 -50 -52 117 111 -30 -88 19 -49 127 28 20 79 95 97 56 68 100 73 122 -109 109 34 -53 110 -2 15 -27 117 111 -24 -39 113 -105 88 29 -53 123 -124 -15 4 127 57 -126 -59 -66 -5 -22 119 127 -126 54 33 -127 17 100 107 -127 18 3 11 -28 22 14 94 116 20 29 -20 123 37 -3 -42 -24 85 -55 72 26 -78 29 -5 -100 126 56 105 -23 -66 -10 -27 49 120 59 26 -47 -101 -127 -104 127 -9 -110 -32 121 72 124 124 -95 -128 95 -107 -28 -111 -77 36 127 -127 1 -68 -62 78 6 -126 -62 -74 -110 -34 -106 118 -52 84 -43 19 -34 -124 -119 127 101 25 -23 -9 -127 -39 123 91 64 -51 -56 -122 61 72 -70 -48 -9 -17 84 76 -128 45 101 21 -119 126 30 44 -27 -21 -122 22 127 55 -54 92 31 -28 38 -27 -47 60 38 48 70 -21 46 -27 34 -14 116 -30 -109 102 108 46 54 90 120 120 -127 38 -127 -33 56 -1 -125 34 -33 8 -5 -60 30 -1 121 93 30 69 65 14 -128 104 -15 -41 84 -29 -45 -10 94 -29 -37 -28 57 37 125 -110 44 -56 123 17 -7 -33 -84 43 -127 38 93 -128 33 -125 121 -85 27 62 -62 -128 -53 -42 -36 -123 105 112 127 -94 -39 -92 -37 67 18 -122 -56 55 -92 36 5 96 -45 0 -120 -24 -62 -90 -119 3 28 -1 -126 -28 -94 -96 109 -93 -2 -34 -74 77 -66 127 126 13 -31 -8 -86 -128 12 55 -58 -37 78 86 8 -30 48 26 -74 35 127 -16 -51 33 -9 -3 54 11 81 -19 18 23 41 6 22 13 16 -8 -81 -118 47 26 55 -70 -59 -82 51 66 25 67 -59 16 16 0 32 -1 4 61 26 -90 -39 5 32 105 -47 50 33 -118 104 -33 -118 -5 -49 120 22 94 7 127 -124 -115 49 -100 65 -116 -49 -58 5 -14 -18 0 -111 31 50 -40 -53 -128 63 31 53 -120 32 -19 74 -77 -12 9 -111 -68 119 -62 127 -67 89 -115 40 41 99 -75 21 116 -28 55 49 -50 -50 9 -37 21 81 -6 53 125 -30 -69 36 117 -113 -101 18 26 -44 1 -117 -38 -95 126 126 53 78 127 -60 -58 127 17 5 -23 55 -36 24 15 5 41 -96 35 54 0 -22 27 86 41 13 10 68 -24 0 114 118 38 17 9 54 -60 -31 -56 -8 -47 -74 63 35 73 -17 83 -36 -33 -44 34 -27 -30 -94 66 38 30 30 -14 32 -1 -27 -32 -97 8 -51 -6 -13 6 -15 38 71 45 110 -16 34 -53 73 23 31 25 -14 19 -29 -76 34 40 -3 -21 61 -9 127 -14 -12 126 47 10 71 37 -8 6 127 -36 41 -32 16 -17 15 -45 6 35 39 -63 47 23 -53 11 104 2 32 95 10 106 -38 -14 -120 35 22 93 21 77 85 -7 -36 33 5 -37 -33 29 28 -25 -86 -110 65 41 -7 -66 -3 49 11 -17 106 41 -29 -13 -3 13 1 37 56 -28 -29 -1 -35 62 2 -21 76 49 -122 -39 -3 -23 -66 88 -19 15 35 14 -29 -4 -41 32 -20 -13 -48 51 4 8 -22 -123 31 -17 19 8 2 -3 -110 8 2 55 23 -59 18 -49 4 -21 89 4 41 -16 -27 14 -12 -57 23 63 19 41 -12 5 -72 -32 -17 -27 -73 -42 22 86 -78 -125 -20 31 -12 -3 -51 13 -53 -102 -51 27 -21 13 12 57 -30 -82 6 -28 28 16 -69 -15 12 -18 45 35 52 10 -55 -122 -33 -29 8 -54 -8 -9 60 -49 55 -62 26 38 8 -22 31 -17 -22 -48 -18 22 0 33 68 36 -32 -2 -24 2 -27 120 -26 2 42 -28 -14 25 -20 -20 7 -10 -12 33 -67 -42 7 -128 -5 -7 10 -15 42 8 7 43 -1 -39 -39 -16 -45 -15 1 31 36 -7 -88 1 -64 21 -19 6 -40 -11 2 -28 -16 -24 -25 -11 -50 46 -1 61 -45 -15 62 -65 -18 10 -5 -42 31 -1 77 22 -4 82 6 -64 -31 6 -7 89 -78 -119 -45 20 -93 64 17 -17 99 -39 -30 22 29 -55 92 23 33 60 43 68 115 -38 49 -8 86 61 -25 5 -59 -35 -6 -18 8 -6 28 37 89 -44 51 -22 -23 -20 -68 -38 104 12 4 40 13 87 71 -91 99 -29 -23 48 52 38 -2 -76 -45 -39 -28 -92 -2 -8 103 -27 24 77 68 -27 58 2 -26 62 22 -27 22 -33 -14 74 48 53 -13 45 94 13 -27 -4 -4 93 -10 -75 -19 9 94 -39 -10 30 80 39 -35 -61 -55 -39 -39 -65 12 67 -59 74 -19 53 40 -61 115 -61 58 -127 -7 -33 -44 58 3 46 29 -65 -1 104 -8 -18 7 -75 55 -13 82 42 -37 22 29 -82 3 -63 51 -31 37 45 48 31 -48 26 -7 -5 19 -60 83 -3 29 -50 -20 12 -128 -68 -24 18 -73 -56 29 32 -55 30 43 11 -5 93 -32 105 5 43 -6 66 15 -11 -38 70 -15 13 -66 -77 -40 -85 -44 -7 120 -31 46 -43 26 0 -13 -13 -45 -116 -49 -6 102 28 -19 -58 -10 19 -29 -27 -51 -8 -128 -56 -14 -127 1 -9 55 95 110 -4 17 103 -18 -38 25 43 -102 -20 48 -127 29 -18 48 56 -41 -36 -1 3 4 -46 -67 69 60 42 -12 0 20 -67 31 -110 3 93 -17 5 -91 -21 33 -15 15 -28 -61 -55 -60 -31 -40 71 -34 95 7 -12 84 8 7 10 93 52 27 37 77 5 -2 -28 -23 -1 110 127 82 -41 75 67 71 65 55 29 -82 29 70 87 -23 22 -14 23 -62 41 -39 -17 20 -16 33 -1 9 -25 -35 -27 -49 5 -97 -33 23 -8 59 56 12 -75 -26 -26 69 52 66 57 29 -18 -25 -11 25 -40 29 14 -52 -25 -85 -27 -24 -36 -74 -19 -116 -71 53 28 33 -37 58 8 -25 -18 95 7 -27 83 35 -23 -26 -10 -35 54 58 21 -78 68 10 47 41 -81 48 12 51 -18 20 -9 61 19 -26 16 -98 18 40 -11 -65 36 -67 40 33 -14 51 -26 -52 0 91 59 -66 93 37 -69 -127 -25 -35 -16 -110 -10 -69 -23 -54 5 -58 29 115 -29 -18 -28 -34 -25 -6 31 3 39 16 -32 1 2 70 -20 -24 -4 122 15 4 100 117 -64 16 22 40 -34 82 -18 15 37 94 23 8 99 50 -20 42 27 7 -23 -34 58 -64 -11 34 -23 43 48 104 84 -22 -63 7 23 27 -28 -93 19 -29 67 -69 9 -20 -98 6 38 31 0 22 35 9 2 16 7 16 48 -24 -86 27 -45 73 -116 26 16 -21 11 42 57 -125 46 11 52 4 -46 14 -69 16 69 30 6 -23 -82 -31 109 -39 -63 -30 -127 -30 -68 44 -89 -47 -24 -3 8 9 31 -43 -54 -40 -51 30 21 -63 15 6 -107 11 -88 -128 -22 -122 -17 67 71 4 94 -4 -36 -31 20 -22 -50 -5 22 37 -65 34 22 -44 7 39 57 67 -5 -9 65 21 -31 -99 28 105 -115 89 -59 1 66 -46 52 -57 18 -35 -47 31 -27 -24 7 -80 -33 57 54 12 -15 -4 -60 -81 9 -5 -23 41 63 -122 -77 3 -57 74 -5 -9 44 -102 39 18 -8 0 -31 61 18 -18 -87 -36 -31 33 -106 -13 52 -80 -8 -14 37 14 -34 -8 -22 -45 6 -58 13 8 59 7 16 6 12 -5 57 -53 -44 59 -13 -92 -28 18 -28 11 64 -51 -7 34 23 -72 38 56 -21 -91 -44 9 -25 52 24 -39 7 -35 11 11 -7 -24 13 -4 -23 24 24 -87 -17 -59 -11 43 22 -84 16 -39 6 3 72 -20 47 82 -10 -54 -11 -55 83 -28 -5 -29 67 60 -38 -83 -120 14 -46 56 14 69 4 -57 44 16 -8 15 -23 -35 -55 -65 -21 9 50 86 -54 69 124 114 -128 5 24 17 -46 -3 -105 29 91 14 -7 -32 -46 69 33 -12 78 -3 -25 19 27 38 85 33 -61 43 54 45 -93 30 47 9 -26 -68 -58 33 2 -61 -95 29 38 -19 -2 90 26 48 55 -48 12 42 50 23 -80 59 -10 75 -31 19 -125 46 -74 66 -6 44 -115 86 -67 0 2 -87 -37 -53 47 13 23 46 -70 10 -37 -45 -66 -2 -38 -9 -14 -74 -1 22 28 -36 -48 -1 -31 68 68 44 46 -63 1 89 44 114 21 2 17 -16 -61 -24 53 -38 -33 -4 25 39 -52 -61 -15 -72 -42 -41 71 -65 20 63 91 16 9 -38 13 -40 -39 25 42 48 1 31 -97 46 39 -17 64 -56 -1 -42 46 2 67 18 -15 25 -6 -61 -13 -45 24 0 -71 -128 -21 -83 -31 60 -25 40 -24 63 -50 -116 29 6 9 -38 36 39 28 -20 -17 34 38 -56 18 29 -75 -28 -25 50 12 46 32 21 -1 123 -50 16 -13 79 79 53 -32 -50 24 -1 -5 2 -6 -13 15 -125 1 19 -6 0 -44 85 9 20 -65 0 -23 -25 84 61 -4 87 39 69 36 40 32 16 -2 -8 52 -46 32 -6 9 -24 -8 9 -60 -34 27 -65 82 -9 106 96 -106 -49 -94 5 -12 -12 -19 -12 102 23 -72 -36 3 49 2 -39 101 -11 -27 -73 -102 -46 16 -102 -56 59 -111 88 92 32 113 97 -80 43 105 53 63 -40 24 -51 113 -54 -121 -41 127 9 22 73 127 77 -36 -45 -76 -73 3 14 58 4 39 58 43 -33 43 46 41 -43 -111 -82 -59 -28 -83 -123 -30 26 8 36 -15 -44 -4 127 49 -24 50 63 17 32 -56 38 38 22 -26 49 67 29 -25 51 8 30 -36 1 3 54 44 -29 -104 -104 -128 -3 114 2 -120 48 -114 6 41 64 35 68 23 -49 -6 12 -22 -52 -22 20 -126 -5 -11 67 -23 -68 -59 47 -35 -55 3 -10 25 -38 92 -28 -16 3 38 16 97 -59 -49 21 -127 5 104 45 -72 39 113 -21 115 3 -93 -16 -102 -42 17 43 -60 32 -71 78 62 -8 89 59 13 51 -4 20 -33 -3 -106 42 8 -18 105 -79 34 94 34 10 31 67 48 4 122 21 -46 24 22 1 48 59 11 60 14 5 23 3 -17 7 -43 -72 6 -1 -62 -87 -9 -28 -25 57 92 -36 -11 -38 31 19 46 -27 32 -11 4 35 -59 53 15 51 -33 -33 13 2 -24 -16 38 -50 -4 -12 -41 -117 -125 17 -116 -10 -55 -45 -32 32 -8 -50 -69 53 -55 49 28 -41 -9 29 91 98 -57 22 -24 -15 26 -20 8 57 21 -123 -32 86 -60 31 -38 52 58 -18 23 -47 127 -9 -59 -45 121 -44 24 -32 24 12 -53 56 98 39 71 10 55 -124 107 105 84 48 74 51 45 -37 -3 59 26 -14 27 -69 9 -32 71 -80 -42 10 62 7 -2 -36 81 5 -25 -8 33 -76 -36 3 -127 29 -44 -6 -45 98 -1 -58 -118 -99 -60 -4 -21 -15 -25 -124 -19 -44 -46 44 49 2 31 -54 64 -66 -19 23 -87 -69 -25 -12 88 53 -13 -27 77 55 21 -48 62 33 18 -71 6 1 -11 34 -40 -35 -20 45 5 -48 64 14 -32 -111 -18 -35 -68 24 -38 43 1 -97 -109 -43 -30 -123 42 60 24 -44 -82 -67 -9 -32 -34 -91 -25 -20 -54 35 -24 24 80 -34 -22 -70 22 -56 102 5 90 18 -39 7 -46 89 -32 -57 39 -33 31 -48 127 69 63 -30 24 -17 -127 30 28 -84 -17 85 20 41 -26 -12 61 7 95 39 96 10 -45 38 -25 -6 -20 -13 51 11 -50 11 54 -9 -10 33 -19 12 64 57 19 -76 -34 -38 51 -13 11 -21 108 -18 45 -19 -31 32 -4 19 49 48 -6 -120 112 55 -56 26 41 -105 20 16 -101 -22 -13 -14 49 -58 19 -102 -59 -32 56 -17 4 41 -82 40 6 51 -71 -6 58 -33 17 -24 -50 -64 101 -21 -80 23 90 -2 10 49 41 -53 -1 -13 110 -46 10 -26 13 113 -61 32 -31 -75 -94 -24 106 15 42 -24 -55 -14 -33 21 -48 -9 11 24 53 -42 0 16 125 -19 82 -1 -83 -72 -33 -36 -19 65 -35 43 -53 56 -14 -36 -16 -56 53 125 -22 20 -5 118 55 46 -95 -24 4 -60 -21 -13 21 -27 7 -32 -2 -17 -2 20 -23 79 114 -10 -18 -65 15 54 -11 108 84 -7 50 -35 31 -89 -12 23 -20 59 -21 -78 56 22 -12 50 24 -48 -24 40 -60 -60 31 -11 -17 97 102 -9 -77 2 32 5 28 -16 -62 34 -109 39 1 -17 36 0 28 6 49 -46 -127 36 -29 61 -35 43 -104 43 41 54 -20 44 -6 -17 -6 48 -8 -65 44 -7 22 8 -30 -62 -24 71 31 -17 -35 -40 19 87 -58 64 110 -48 -33 -4 -68 26 6 -42 126 -119 95 11 50 41 48 -13 -46 31 -17 -24 73 -69 -35 44 57 -61 78 70 86 -76 -44 -22 75 44 50 -41 12 -49 -10 56 114 44 61 -13 6 -24 -23 -2 14 -27 25 29 9 -26 -67 -39 4 47 -3 11 -23 -127 -95 -17 36 -34 -20 -38 12 -84 -45 65 62 23 6 -28 -57 7 -34 3 90 46 32 -68 -6 -39 -16 22 41 -12 -32 57 13 -13 74 4 65 -15 -13 -12 -62 -9 33 97 -50 9 -26 -31 38 14 26 31 39 71 37 -9 -76 -39 86 -9 -58 10 -4 -11 -31 -60 -92 -23 3 94 -8 75 73 0 -27 44 30 49 -41 -34 -61 -59 34 31 17 -41 25 -27 -70 11 7 -13 34 -127 72 19 -43 -66 -5 32 37 19 -55 -20 -2 -69 -44 -85 2 38 45 -2 54 -33 -49 -25 -4 -67 -111 85 -27 101 -5 -24 -102 -62 47 8 13 112 -72 86 37 24 -28 -25 22 61 -102 29 52 -21 -46 44 -11 -58 71 95 106 -10 2 -11 105 -23 15 -41 47 68 9 36 53 42 33 -75 107 -62 58 -43 -42 -11 5 -54 12 -82 39 -20 -80 12 -23 14 -107 33 14 12 -7 24 68 -27 73 -58 -31 -27 -25 16 62 32 -20 -34 -66 30 -21 -8 20 -8 -43 -16 31 -58 30 -7 7 24 -105 -44 23 78 26 75 -97 9 -1 -53 8 -13 -37 -27 -1 6 -85 -2 17 80 -38 -20 0 42 -7 -71 3 -27 -31 7 38 13 -35 -18 -72 -47 26 -14 -72 -57 4 41 -21 17 -16 -38 -38 6 -74 -28 -89 77 -6 43 64 -42 -55 2 17 -22 -3 -9 -103 45 -13 6 28 -63 -77 13 -80 115 65 11 -22 -61 -45 25 2 7 80 60 -5 48 3 -48 -5 24 -52 -57 -7 -85 30 43 -15 28 -40 -33 36 -8 -94 -40 -34 -34 4 -46 -2 15 -84 -5 3 8 -5 -19 40 -33 -96 38 -2 -28 -13 -26 -76 46 -32 22 66 92 18 -45 7 12 -49 -42 -12 2 7 38 -6 -85 11 -22 -20 31 -64 -21 -31 76 46 -41 -92 15 -46 -81 -124 -32 -31 -21 -56 -32 -42 49 60 -72 30 31 24 -14 23 13 -41 -2 35 19 81 -28 -77 -54 46 -38 -126 16 21 -65 25 -65 -5 -13 43 87 -15 -63 27 94 -117 -6 5 -125 -40 27 -98 41 16 3 18 -62 45 -33 -92 12 18 23 -96 -31 76 69 -9 -70 -51 75 18 -17 5 -83 -44 42 31 49 33 -56 -72 -37 -31 -10 -35 -85 -68 -63 -11 -70 49 21 119 24 -113 -25 -52 47 -5 38 43 63 79 -40 23 127 25 -47 -21 62 -19 -49 -35 -77 -77 37 -32 -20 -45 -80 10 -104 -22 -22 -70 32 -6 -64 -55 -5 37 17 -16 -46 34 -12 -10 66 -49 -51 -16 -29 -15 -33 -69 32 -20 -39 11 -41 67 2 -26 -96 -18 61 -31 -38 9 -40 9 2 -31 -33 -25 9 47 19 15 123 66 -48 67 -64 70 -22 0 -10 29 -42 -56 6 27 -6 30 -66 -10 54 -15 57 -45 26 16 19 -4 -74 -28 53 77 68 12 111 -27 23 59 -32 -115 44 -15 4 9 41 -46 31 28 15 -13 -127 12 62 -19 -71 2 22 -19 41 -15 -65 52 -48 -51 -30 16 -44 -14 27 -2 -46 39 -37 18 -29 -36 92 -37 24 -128 -7 -20 -82 -88 10 127 -9 0 -11 42 45 16 -44 106 -9 -11 -14 -109 34 25 33 -49 37 -9 -24 23 -50 -51 -71 -10 -18 -9 40 -74 -4 30 -30 -6 -11 -92 -51 9 -37 27 -55 18 26 32 -64 45 -17 -69 41 27 87 -2 -30 -28 74 13 32 -16 -28 -15 -26 52 10 -48 38 -79 -1 10 30 48 12 58 -37 56 -21 67 69 -41 66 40 77 -1 -25 4 -46 17 14 84 -5 37 29 20 -68 8 -17 49 10 19 -14 -15 -8 -37 -12 -20 -40 -3 -51 -10 35 -22 0 63 127 -14 31 -14 -28 -46 -34 -63 8 -14 -117 32 -9 41 45 19 -17 33 12 -18 26 -12 -19 -16 46 38 16 -60 -19 43 16 63 27 54 -81 28 -2 19 -65 29 -54 119 -13 -6 -29 39 46 -45 9 12 -25 -8 -35 -36 50 -56 -56 -40 -128 4 -65 1 11 -128 -40 -3 -6 26 57 1 58 19 7 -30 26 74 -44 -13 22 -12 -25 -10 -49 42 -22 5 40 -13 -4 95 24 14 -16 26 112 79 17 85 -83 -86 15 36 25 103 40 -10 -7 30 22 -41 32 -15 47 -16 13 54 9 57 -4 -43 -27 79 76 57 60 0 41 -126 55 61 -67 -25 -20 119 120 -37 27 -47 -3 6 -36 57 16 95 35 47 12 -116 39 11 72 -2 6 14 -63 39 72 21 64 26 -87 108 -6 -47 19 9 44 -2 -26 -14 120 -21 -40 18 -12 41 15 37 26 26 31 73 17 4 26 51 -5 2 68 32 60 68 -91 16 30 -125 -18 11 -45 -66 -10 -58 -3 -95 -128 2 42 -71 -29 -27 51 27 -63 -4 52 15 -81 29 105 24 -84 8 13 -1 16 91 -49 -11 -20 33 -28 96 -97 94 28 -27 97 43 51 90 41 -64 34 11 30 64 6 117 0 -32 -125 -106 42 5 28 116 -18 26 60 106 -41 41 81 -31 43 87 -20 39 40 12 13 -19 -23 32 -66 72 -69 26 2 71 -110 -63 -54 -13 4 27 41 0 -69 25 26 30 -43 21 110 -37 -121 13 9 29 23 -58 12 -17 58 67 -83 -69 48 127 73 62 6 40 61 -16 -39 28 -68 -3 23 44 22 -93 99 54 18 55 -34 -60 33 18 6 -8 120 -2 -68 99 -85 -33 -102 29 -3 -43 -18 12 37 2 -27 -4 -25 -18 -38 46 65 -33 13 -62 -94 -36 -46 -57 5 40 13 -72 -10 -111 49 127 15 51 49 -29 46 49 -124 34 -28 -49 -4 -33 -37 -42 -49 23 89 1 44 -19 92 78 -14 12 39 -9 4 -12 47 -94 -28 -126 73 53 40 29 -60 43 -100 -7 -8 -14 41 8 37 20 -76 -56 -90 0 60 -15 13 127 -1 -25 -69 33 66 126 43 -23 -42 43 -27 25 47 -2 39 -34 -67 65 50 26 16 -18 38 54 45 9 -121 54 -12 -33 71 28 13 20 -14 -5 27 121 7 78 109 33 8 -25 -21 -20 55 39 -22 -39 -8 -11 -62 47 -38 38 -55 23 45 67 29 -41 -13 -4 -1 -106 -30 119 -27 28 3 -34 87 -41 106 18 108 42 31 -2 116 -41 86 -53 -35 -35 6 46 -3 43 29 -53 -52 75 -58 -1 -10 50 -3 -16 -18 -107 27 19 8 -49 -55 37 -81 -34 14 126 50 114 28 46 24 -62 1 -28 3 -94 -36 35 -25 31 13 68 26 14 86 -38 -29 -1 -35 -101 -16 -16 47 11 -39 -72 49 -12 3 -64 -12 9 -100 25 6 -33 -4 6 95 24 3 -31 -44 98 -21 -93 -85 -44 -7 -127 25 127 107 60 -126 -7 -9 -7 -2 13 -7 -69 -12 -46 -69 9 -48 76 -11 -10 31 16 -10 67 14 31 -44 -35 30 41 44 -39 -48 -21 35 43 -93 -27 -3 54 31 -78 17 -14 -64 -18 -76 -18 -68 10 -5 -42 19 6 -21 0 60 5 33 4 -40 -36 109 84 42 22 -79 7 -38 -9 26 -48 -106 31 -32 19 25 -18 47 30 22 127 -12 14 4 64 -3 -26 90 28 -27 -60 -43 46 66 -52 127 -50 68 28 -47 -8 36 48 -53 32 1 47 31 -16 -27 120 -26 -21 37 -20 3 39 -43 -77 60 113 -14 96 -66 -6 85 -20 6 6 -45 -7 39 -66 -6 -3 -38 -35 6 12 -38 -48 51 30 -40 3 -50 46 33 -18 -25 -31 -23 24 121 -1 -12 -19 70 -37 60 -18 -47 -20 -33 -13 36 4 0 -9 -42 2 16 -21 -21 -15 42 -67 -18 -35 -72 -40 -36 -10 -16 -36 -126 81 -61 67 14 -49 14 -32 2 19 -22 -6 -22 -65 51 -16 -100 -7 12 -3 72 4 -51 36 74 -1 73 -20 -53 18 62 70 -34 8 16 -21 -51 -97 21 -21 54 50 -22 29 -38 37 10 -7 45 -43 41 -19 -36 1 41 17 53 68 15 4 86 -9 75 -21 -28 43 -72 10 -16 42 20 -33 -3 -45 -49 4 -30 23 7 75 26 -31 -28 51 -16 -2 5 26 -3 -46 -3 -28 -28 -61 10 -76 56 -40 -43 21 2 -15 -10 9 -53 82 66 -77 28 -37 -28 -2 -7 -18 -6 48 34 -21 19 55 -36 -71 72 -18 8 -1 26 46 -27 34 -7 1 -11 106 23 0 -8 26 32 3 -23 -62 7 -55 40 -55 6 -58 17 15 67 8 82 114 66 32 5 -35 -15 -2 -13 -92 20 -46 -98 16 38 -16 -110 -28 -52 -79 -56 60 5 83 -57 18 -28 -28 20 89 7 112 38 23 -15 62 61 6 16 -51 -7 -16 15 63 27 65 -17 -95 47 -43 77 -28 -47 -67 -18 50 -14 -48 -73 28 76 18 3 -8 40 -12 108 7 30 -36 23 27 24 79 -59 -55 39 -60 -16 52 48 -23 -25 56 -58 -61 -24 -20 27 -10 35 -16 125 -13 -38 -8 -6 -117 -70 -58 77 -22 -19 -1 63 -43 -30 -14 -47 -4 -76 21 -53 -62 -45 -108 9 -81 -47 56 -34 76 42 -29 -102 -12 -38 -37 -12 -4 8 -42 -1 -19 -12 -72 -2 -12 -44 -12 13 41 -3 55 41 -13 16 -37 -68 54 8 41 19 12 -36 -6 22 3 75 -18 -59 -77 -79 -49 34 -29 0 22 -45 -36 -55 5 5 63 75 74 -35 47 1 -27 -11 -96 24 64 -43 -34 65 3 46 12 -22 -39 26 -115 42 0 -65 -8 25 -48 53 -53 -21 73 61 -13 -3 -67 21 -20 -38 -127 66 41 -5 29 -31 -59 11 -17 49 -7 -36 -53 24 -47 -60 54 83 0 13 -29 27 39 29 8 9 -15 -31 15 7 -8 1 36 -19 7 -14 -14 75 36 -56 -54 -34 40 26 -75 59 -27 53 20 16 0 -14 -39 -106 -17 -82 53 -23 -18 -104 18 23 -99 -5 17 -9 5 -44 -71 -39 -16 -51 93 81 -72 -20 -4 -21 18 63 0 -65 34 32 -9 -63 13 52 -16 2 -19 53 -59 34 44 17 -5 7 -29 -31 -111 2 72 39 17 15 6 -15 -21 -53 20 82 49 -7 68 10 18 -2 110 -11 -56 49 -106 -35 -21 12 0 21 -27 95 76 -61 37 33 -28 10 52 -52 -57 41 -63 14 -1 -13 -55 -29 -10 64 45 -5 -20 -9 -3 -68 -43 28 14 1 27 -26 81 31 83 -14 40 -2 106 3 -7 50 -8 -38 -40 -9 -26 -98 -128 -66 14 -65 71 -9 -17 -3 20 -128 -39 -44 -25 -60 -24 -65 -44 20 -74 67 -68 -38 -87 21 -59 -16 -58 62 10 -29 126 5 -48 -10 52 62 17 -52 64 -66 -46 -23 -11 24 67 -19 33 -27 -29 -15 -7 -22 56 -5 -33 19 11 40 -11 68 59 -53 -39 -53 9 7 6 13 78 -120 49 46 -41 97 -88 64 -125 -19 -41 59 -44 -12 3 -95 61 -25 47 -82 40 51 -118 125 11 67 -123 -77 86 46 14 -35 29 -84 16 68 -48 51 55 127 -17 -4 104 -85 66 -25 -42 58 42 62 11 32 33 73 -18 3 -28 60 -10 33 -57 -25 -80 -35 64 71 -24 -32 -1 -10 -35 -1 -1 21 -47 6 -63 -7 -11 -30 63 -28 -55 9 -119 -4 -24 5 102 -2 9 64 8 -1 -71 -33 54 54 -34 38 66 -42 28 46 -74 -48 24 22 18 43 -35 -108 22 -59 17 -3 45 54 -45 -50 36 -41 -77 -17 -55 -9 29 16 4 18 -41 22 1 74 -36 -8 -73 -31 52 -68 -40 14 15 61 26 -31 12 47 -22 -39 82 125 -19 -11 -76 -57 -122 -1 21 -26 4 7 -61 12 18 -20 -71 57 -3 58 -97 -63 41 33 16 -6 18 3 8 5 14 8 -51 -1 -68 1 67 -65 -91 50 -75 33 -60 10 -12 -12 36 110 -18 -124 -50 121 -116 -41 -40 -53 38 48 -31 8 39 -92 -48 41 -35 33 23 43 84 63 8 10 17 68 4 72 -35 55 -28 -55 28 119 -5 82 10 -30 -32 -21 46 28 30 -4 11 31 -8 34 -77 -24 -52 29 7 84 -50 31 -27 -103 -13 -20 2 -63 58 58 85 97 -22 -69 -18 0 -63 -8 -3 -65 42 -47 -9 -8 55 -61 -40 26 39 73 73 -44 62 50 41 47 -12 127 -36 103 127 -4 31 35 83 -2 4 -117 41 -39 44 -10 0 -13 -21 -128 124 -126 -71 -10 0 24 -20 19 -30 78 -63 43 79 -62 84 48 122 50 113 30 96 -19 100 -21 -22 56 81 34 87 73 29 55 106 22 26 -105 -54 17 -87 -21 -101 127 -27 -5 -29 -43 53 8 19 8 13 43 -56 -52 2 6 6 -23 33 60 67 25 15 41 -13 -34 16 -15 72 105 96 -59 -17 40 -41 -39 39 11 2 45 -26 -52 -66 34 -27 -117 -53 24 39 -121 -53 53 44 -14 21 -90 -114 -81 -59 -11 -102 -28 41 57 -29 13 41 40 85 -125 -96 -62 -18 1 -41 82 -62 25 -73 -79 -74 44 30 -122 115 -21 90 36 65 73 14 -15 -25 68 -122 -9 -24 16 -48 57 40 -24 -70 11 25 -38 -32 -54 -98 -67 14 113 -16 -21 26 56 -4 -33 3 1 34 21 -6 -17 -19 48 22 24 -83 53 27 49 41 -128 -103 17 51 -23 -112 16 58 -30 22 1 40 -23 -3 2 -23 64 19 -9 -54 -98 -68 -25 23 6 38 -53 -10 -120 25 44 65 -23 61 -105 9 100 27 15 -12 30 -43 -8 84 61 65 51 -25 -69 -34 -7 -4 48 -93 42 -70 -86 -2 118 -19 4 -11 17 67 36 12 -7 -28 -14 30 -95 36 -10 38 63 -49 -124 54 -12 36 72 -16 -5 -96 12 -20 42 -3 -127 -100 -19 -54 -3 -36 8 17 82 58 -37 -35 12 -78 23 -73 19 66 -88 15 27 -118 48 -23 10 -7 -40 10 43 14 -20 61 -13 -50 -18 49 -32 -74 43 11 100 -32 32 44 7 -85 7 -2 -24 30 4 97 -24 -51 12 19 21 -55 -59 28 -46 -3 -66 42 19 24 55 -30 37 -78 45 -33 -85 -36 -23 44 28 -38 67 20 10 -20 -103 -9 -36 70 -30 -63 62 81 -23 -14 11 -38 33 -48 -29 -18 26 16 14 2 47 55 -96 32 -116 -24 24 -5 18 -84 75 -22 -29 -1 -22 -7 127 -108 -2 -20 -55 -39 -48 -3 42 -66 -28 -128 -35 -19 85 18 -18 -10 19 -43 -2 61 -39 -33 39 -128 -36 -42 -75 -52 -80 59 38 69 26 117 100 -8 35 63 77 -24 76 45 -30 32 33 6 -29 39 49 -39 -23 44 22 -71 36 21 80 -7 -34 20 -25 -77 18 -14 11 59 -73 43 -3 56 36 -31 -12 17 -49 -31 -16 -4 24 -19 -55 -65 -6 33 72 71 2 -78 67 -41 49 89 -13 20 10 46 -19 30 -7 -103 31 -41 -11 84 2 75 -36 -1 -97 -63 32 -21 -25 65 60 -57 24 -21 -44 2 20 20 63 16 -20 0 -36 70 -45 -60 -17 -27 28 -55 53 -45 41 -42 57 -65 -13 25 68 12 64 -32 -43 -32 18 -50 -99 -43 86 -53 -45 4 -14 12 -55 -26 -44 -26 59 35 -39 -3 -29 58 -35 65 -8 65 -19 25 -86 62 25 35 -63 29 41 94 97 -2 7 -10 -66 -46 -54 47 57 2 5 -52 36 10 29 37 -22 -11 91 -64 7 69 10 47 -38 34 -73 -34 9 -14 54 -90 39 19 20 33 6 -32 14 -70 50 -4 -5 9 46 -72 54 -7 -34 -33 49 -110 -67 5 47 42 -6 -72 -47 18 -33 55 47 -71 -13 -6 -28 46 -7 45 -46 11 47 34 -18 -4 43 -27 24 5 -66 8 -49 -40 1 3 43 -34 27 -2 -41 -127 30 70 2 -37 16 -58 33 24 51 82 100 -39 17 6 -27 -18 -86 98 113 -37 -80 3 -44 35 8 -36 16 102 5 27 2 -95 66 -40 87 -35 -100 -50 21 40 -26 118 32 -37 21 -77 -39 10 -14 20 94 -111 -87 107 32 4 -12 50 -8 -60 124 10 16 -67 -49 52 -31 13 2 63 59 30 3 -25 -57 16 0 92 -31 39 -77 0 67 -45 28 -45 -36 -61 -42 9 -73 -29 31 -10 -72 -11 21 -74 -11 -1 57 7 -32 12 54 -16 -5 24 -69 -90 -74 -5 0 91 39 -25 -57 57 10 86 -44 -5 -126 3 -59 -52 23 -38 14 26 29 16 77 -96 -57 -79 -29 -44 58 44 -85 50 -122 -54 -14 51 31 38 70 -20 -97 -7 33 -12 -127 -46 -12 -6 -3 14 -40 -64 -24 37 57 -107 -28 40 18 31 -27 60 24 -34 6 1 24 24 -57 -25 -4 -108 -28 -11 46 122 -126 -27 -6 118 38 114 44 -66 -20 9 19 101 30 11 -34 18 -82 -2 1 49 96 117 68 24 -79 40 16 45 34 -77 -42 -68 -71 -13 89 63 69 -17 -21 -20 -118 39 -30 -9 11 -78 -53 3 41 -2 -11 -90 17 74 -56 -27 -128 32 -3 45 -10 38 13 16 28 -10 123 -26 59 -70 -101 26 23 -69 -45 34 39 -8 2 30 7 31 45 46 -19 63 38 -52 96 -38 15 21 56 19 41 -45 67 -9 2 31 4 20 30 -20 -45 32 7 4 9 33 -11 -40 -13 28 -3 -38 -23 119 -16 -31 -31 -97 -51 13 3 29 -8 -25 -101 35 -25 -16 17 9 -41 25 122 81 -29 42 -30 -2 -43 -64 31 -14 -24 48 73 -35 -24 88 69 50 -44 19 43 -70 -73 90 -99 68 95 50 -12 0 -6 -44 -10 40 -28 28 79 -12 31 29 -24 4 -12 122 124 54 -35 -27 -96 -11 23 -26 18 -24 -72 119 -60 72 69 -17 -41 51 22 -40 -32 -6 11 -108 44 -56 18 23 4 -124 36 -57 66 -33 -5 -100 -76 -58 -56 -2 102 17 -7 -3 127 11 13 57 15 42 65 -30 -71 -42 64 -16 69 -88 -45 42 -36 -109 27 98 -10 46 -40 -16 44 26 -44 16 -19 55 -4 17 -101 49 -117 32 -55 -88 24 -69 2 -29 -123 -24 66 36 70 28 -87 14 -47 80 127 35 28 44 -8 47 -48 63 -3 -10 43 15 -31 -31 -122 -44 -15 12 -41 -57 -17 34 117 6 23 52 58 22 106 -3 -78 -21 81 -6 9 15 70 27 -9 -9 75 -61 18 22 72 40 19 16 1 13 91 77 2 -40 -108 -30 39 -8 -32 -97 19 -7 -11 51 36 40 -21 41 38 -20 30 -19 -19 16 5 38 -80 19 24 73 81 -24 36 51 34 46 -11 41 62 33 -25 63 -36 63 -58 -74 -3 -10 65 -18 -45 -127 -15 27 14 88 -103 -7 -47 -21 9 -9 12 79 -5 -16 0 8 85 18 -47 -22 -75 -20 -53 -34 -13 -71 -30 0 32 -30 -38 92 76 -20 -60 74 -45 -21 -16 -22 4 -98 -71 -40 102 15 9 25 -12 -23 -20 -4 12 127 -2 22 127 10 -64 9 -3 0 53 15 36 -4 55 -35 41 -75 -34 -32 15 13 -5 42 0 -69 -34 -9 7 -27 1 -28 45 -103 -29 -32 62 -52 -15 68 -59 26 47 -24 -19 -15 49 8 59 -23 33 68 57 32 26 -19 -39 -5 -59 -11 -13 -8 11 -2 -4 -5 -67 -8 -69 -36 -94 -51 -64 -32 43 32 32 33 -92 111 -8 -9 -17 -80 -19 -3 -70 9 37 -12 -65 -19 -38 25 -59 -6 -18 -41 -11 62 -62 -99 -48 -121 -27 -21 -7 -7 40 -44 -49 -28 19 -61 -22 -7 20 -30 -61 29 11 -127 -127 -14 8 -48 25 14 26 14 -24 -22 84 61 -23 -66 -71 -20 -69 16 -8 -5 -98 -10 -46 -120 32 -70 -48 0 -41 67 6 46 34 65 -40 73 60 40 6 80 -53 12 126 59 0 -1 9 85 61 17 -51 -8 -69 118 38 70 77 -127 99 127 44 78 62 10 -17 15 -3 32 29 38 -40 23 -56 44 -33 56 65 -30 10 46 -35 -35 -24 14 -58 8 16 -30 45 -126 -73 -50 -51 1 -23 63 60 -58 -47 62 -4 -30 -37 21 21 -68 -29 5 -41 -75 54 -60 -38 -60 30 -27 -40 -84 -2 55 -43 -6 -37 -7 -35 60 24 -18 -33 13 50 -42 -24 -36 28 -36 -79 -8 -24 32 35 8 46 -125 -19 27 -22 3 -110 -19 -17 -56 44 13 41 -23 -60 -74 8 -33 57 20 -52 21 0 -13 -57 10 8 -71 76 96 -76 96 5 55 19 -36 49 23 47 47 -6 -36 81 25 -29 79 56 -5 11 65 -50 26 -3 -46 16 3 1 -65 -21 -55 19 27 46 3 -6 -125 23 -52 -2 -82 -73 -4 21 20 122 -76 12 -44 10 -111 -65 -14 -14 34 -14 -7 66 24 35 95 -27 -6 13 -4 -48 -63 -25 81 40 -90 -41 -14 61 69 -42 -13 21 -34 -46 17 -81 -29 3 52 36 -29 -12 41 0 -29 23 -76 45 -41 -2 -66 26 30 -52 -56 26 -24 -83 -39 16 -47 -70 -11 -107 -4 -77 21 -95 -51 -86 -126 -5 -5 22 -3 39 53 38 -94 -30 20 36 61 -20 6 -58 -6 40 -39 81 35 -102 -26 6 -22 8 -39 -29 -19 -33 -57 66 51 -21 107 115 49 -15 -83 26 49 22 72 -41 61 -24 -1 66 4 11 -17 -11 36 61 -41 37 95 60 -56 80 15 -32 18 -44 -4 -2 -9 34 -78 -46 121 6 -20 -49 26 -3 59 -38 11 47 11 14 -58 -8 -79 27 -16 63 18 100 -45 -14 -14 -20 11 67 49 -65 -39 -87 5 84 0 93 17 -85 -107 -16 -110 113 -59 65 55 22 -37 79 35 56 -114 93 2 -18 -18 21 26 -68 29 -50 53 2 -32 9 19 22 -29 -11 32 -14 -53 -9 69 -104 -10 -13 4 44 17 41 7 -127 -84 13 -90 -78 -32 -73 -30 27 42 61 39 31 -19 -81 17 28 -25 -25 33 -91 23 127 20 -58 35 84 -23 -62 38 -11 15 6 18 -18 -31 6 7 37 127 1 69 -31 -17 98 -59 26 5 22 -6 20 -5 -61 -45 5 39 18 81 -14 56 82 -36 57 42 -62 -12 33 40 -29 6 -2 17 86 -11 50 45 -6 87 -9 16 -12 29 101 13 -40 -21 88 -62 -47 27 -31 -118 43 -64 56 -1 37 29 -54 63 14 32 -73 -51 -92 -56 101 -5 127 35 -36 58 13 -26 -33 25 69 20 -31 32 71 -24 -50 21 14 -25 65 -5 5 112 -26 -17 37 37 27 -112 8 40 -25 -16 -15 -16 -83 -11 40 -5 89 -67 -31 120 -64 -6 -55 15 -39 29 40 81 -23 67 11 -4 28 -40 -35 -30 -9 64 48 -37 -47 17 -52 76 4 50 -11 -95 -65 1 -100 40 19 -28 -78 11 96 -88 53 -1 4 37 -73 2 -59 99 -5 -9 -4 -66 123 -53 -1 8 -128 -7 24 16 -54 -17 10 -23 13 88 44 43 -86 28 74 17 -58 -24 46 -15 1 19 53 86 -30 -52 2 -86 26 64 -23 5 -53 11 -15 -18 -128 3 -92 -45 121 -4 -7 -33 -40 24 6 -8 -95 -120 -18 36 48 -22 9 117 120 19 -18 14 -31 36 -18 2 35 -56 -15 31 0 22 92 -2 -110 36 117 59 -54 21 -33 -1 44 62 61 -20 -27 -15 120 31 127 -4 -110 -21 59 32 -10 28 -2 15 8 -107 17 -95 -39 -17 -115 6 23 126 41 -2 24 -23 -1 1 81 -22 102 57 12 -43 -62 -40 -3 -83 121 29 -65 -64 62 69 84 -27 25 16 26 -15 68 -56 -12 8 -35 23 -29 -19 -5 -44 -40 -85 11 -22 7 -26 -11 50 -36 79 -38 -23 -6 38 -1 37 43 -20 -15 43 -54 -59 99 -52 -9 -3 27 -16 32 7 -16 10 -45 0 25 37 63 63 -9 -38 -42 -27 38 -20 -38 -107 50 -47 39 67 68 29 -43 -11 -42 85 -49 126 5 -3 -13 -24 30 81 50 47 5 -54 4 7 -51 30 4 -3 -1 -66 -55 -116 -40 16 50 57 -81 -73 24 -26 47 26 71 10 -111 91 61 48 -44 -104 15 0 -6 41 -41 3 -48 -2 -19 -23 -43 123 42 -3 17 127 61 -31 19 -100 34 41 -16 -33 24 90 23 -88 122 -22 -55 35 -23 -25 63 -5 90 1 66 -13 -20 22 -48 22 62 19 53 -4 40 -3 -76 -3 -4 -14 -10 13 -39 122 11 19 -37 -19 44 53 65 51 45 -9 9 -20 79 -36 9 12 45 11 -44 74 -15 58 8 39 -49 28 15 -40 -95 41 -12 51 5 10 -8 22 -45 -15 56 -15 5 -86 64 -45 -25 -18 -55 11 18 30 106 -100 8 -78 62 3 7 -20 49 36 -26 17 23 -23 71 22 -86 -65 -70 -11 -12 -71 -2 -13 33 -36 -86 -11 19 25 -40 -69 -27 16 -11 36 3 -19 64 -21 33 -22 0 11 4 29 -81 61 70 36 -24 18 60 75 36 20 51 119 -10 13 82 -57 -58 -42 46 83 26 10 -25 22 55 -75 -1 80 -23 -34 -5 53 30 50 90 29 73 14 30 32 28 53 26 -23 -2 -9 -76 -18 -5 12 28 -47 91 72 -72 22 103 1 -23 47 -1 3 2 -42 30 60 -12 17 56 -11 -56 -20 6 -48 62 -11 -107 -4 13 103 39 25 1 -24 10 24 70 -51 41 58 -12 -38 68 -59 -20 2 -7 25 3 -57 2 11 8 -4 4 14 -102 -10 -31 -58 -23 -27 58 43 -23 -74 47 76 59 82 30 -39 -7 -19 49 -41 24 17 59 7 43 6 -18 -81 -82 66 60 51 15 -107 -116 0 15 66 -23 -5 57 -1 2 -4 50 59 -102 -21 8 -38 -111 62 25 41 48 -52 119 -11 -34 3 -52 -56 83 1 -33 -45 75 13 93 86 -2 -57 -57 112 -13 42 24 23 84 -67 -38 -9 -58 121 33 57 5 -50 70 48 19 -51 81 -12 10 -27 5 15 -29 -64 -11 -21 11 -74 16 38 14 -3 0 2 77 1 62 37 10 24 -59 4 -95 -39 45 -76 -3 8 21 -27 -48 -9 71 -100 -82 -34 45 -1 -19 12 -77 78 -73 57 -73 35 -18 9 -12 17 -10 103 31 114 28 10 -12 -62 -22 -22 -6 -8 119 0 32 58 -78 13 -28 36 98 -5 -43 -31 -8 -11 -40 -38 -7 50 -59 57 -23 -36 -30 36 -16 99 -2 2 36 22 -5 11 -1 49 -45 19 1 -11 29 109 -2 63 -31 14 44 16 48 19 58 -22 24 62 49 -78 45 73 32 8 91 20 18 -28 62 -8 39 61 -64 40 -50 80 78 24 -27 -24 11 -4 -14 -30 23 5 -23 27 0 -41 -13 -32 21 19 -9 1 -32 29 -16 -16 -17 10 46 23 -19 18 1 -13 2 -22 -5 38 48 -16 -4 -26 8 24 39 16 14 15 10 -18 18 28 -44 12 18 -4 -33 -35 25 14 18 37 9 -11 -84 -33 -31 -8 -18 10 21 -38 -19 -11 1 -66 -12 26 10 -6 -8 28 19 -17 -17 -9 -27 31 18 9 10 -12 -3 -10 51 -8 -11 -43 -17 114 96 0 13 9 -28 -63 23 -8 37 1 -40 14 -14 -2 -47 7 32 -33 -9 19 26 81 -15 26 36 47 22 -26 27 -3 9 -22 34 -57 -18 71 -3 38 -42 -34 -10 47 -15 9 6 5 -77 12 -37 51 -20 2 28 18 27 -33 -38 15 -29 -8 43 18 4 -72 22 -18 44 -22 27 22 -7 21 4 -40 16 -9 18 -2 85 10 -18 74 14 -23 5 -22 4 21 14 -25 -1 -5 -2 42 -29 10 -53 -23 13 33 -12 28 -18 41 45 7 3 -35 13 -39 52 33 35 -44 1 -31 -7 -22 2 11 -10 -19 -20 26 12 -32 42 5 -6 -7 9 25 19 -17 15 34 -20 5 2 2 28 14 -36 35 14 17 24 -19 0 -18 2 40 0 -10 0 21 41 1 24 4 48 18 35 7 -14 6 -14 20 26 -8 32 15 -5 -1 -28 -27 -12 14 20 28 14 30 3 8 25 -34 21 43 -17 19 -17 4 -10 36 -24 -20 10 -5 -4 -3 10 3 8 15 6 14 -8 16 14 19 3 12 18 2 -6 4 1 19 5 -17 14 -10 -19 -20 -6 3 9 20 -7 14 -11 -4 -19 -2 -44 -14 0 22 10 -16 34 -21 2 -7 -8 -40 -21 -26 -5 -2 20 18 -16 -18 -14 -6 -2 2 5 25 12 -6 -6 18 -7 6 8 -28 -22 -36 2 -23 -24 10 2 39 15 0 -14 -2 -32 -18 -33 34 -13 16 41 10 33 16 -15 16 -5 -7 13 -3 6 -23 35 -34 -15 -3 10 31 -16 45 29 -13 -30 -55 6 32 23 -12 7 19 3 -39 -41 77 48 -7 -9 52 -19 -10 -3 -38 -30 9 -38 -20 19 3 53 -25 -25 20 32 0 8 -2 -19 42 20 -33 -35 -45 -2 3 54 24 66 -68 22 -79 31 27 11 42 -17 27 9 21 -6 -6 34 -9 -33 44 0 39 -25 96 -54 -8 -10 56 -30 -31 28 31 21 15 92 -59 -1 25 8 14 -10 -1 -28 -12 0 4 7 42 -21 -14 55 24 -26 12 66 3 -10 26 -5 -3 11 46 -28 -14 38 -22 10 -7 -3 -50 40 12 22 1 24 30 -16 32 11 -24 -11 -14 11 -17 29 26 -7 -17 27 -28 4 -9 6 7 -26 -30 8 -24 -34 31 5 17 0 -27 -4 29 6 -22 4 38 19 -19 19 34 55 1 -18 -9 -19 -35 -21 15 37 10 4 -44 15 -2 27 -3 12 34 -21 -1 38 30 6 -3 -54 33 -5 -6 -8 -24 6 -19 -4 -5 1 27 10 31 -26 -3 -25 -33 32 -10 16 24 25 -39 20 -3 -25 -53 45 12 -32 -30 7 0 -5 -20 -21 -18 -1 29 -12 -13 9 14 -10 21 -2 -25 11 24 -13 5 -16 -12 9 14 -4 -46 -12 6 -13 -13 6 -30 -1 -27 -16 19 -20 -6 -14 28 25 15 24 -9 9 5 4 27 0 16 22 -21 16 17 -30 36 -21 -13 -28 27 -78 23 -17 -95 -26 54 -30 -44 5 -14 -43 -74 48 -24 55 -5 -2 106 -77 -29 -59 -21 -12 14 45 18 -91 42 -2 12 -25 13 1 -5 -31 3 -2 40 -72 18 16 -13 35 -4 -43 -13 -17 5 40 -5 -50 -16 -121 -25 35 -35 4 -23 22 -9 115 -19 58 72 -113 -32 29 -27 29 -34 -31 -8 -14 -44 -50 25 -8 -15 0 -57 -8 -84 44 -15 10 -75 -26 -63 -71 2 -15 -71 12 -26 -60 55 -1 66 2 5 -23 37 35 -78 44 31 80 -8 -53 28 15 7 -22 -48 5 -41 -5 37 51 1 39 0 13 42 19 17 -1 30 25 25 14 -16 -1 10 -24 4 -46 29 -47 10 47 -17 20 -44 11 -24 4 56 23 42 19 19 33 39 0 10 46 52 -66 91 38 11 33 30 4 21 36 -20 26 48 27 19 41 54 4 -7 7 -34 36 25 40 -65 28 22 61 31 -23 21 12 45 -6 -15 -16 -22 18 15 -18 18 0 17 16 55 11 34 -48 16 27 -5 -27 -14 -12 -45 -11 -7 23 7 -67 12 52 23 -13 -1 -52 -38 10 10 -46 -4 -13 -11 -40 6 0 35 11 11 4 -17 -27 -8 8 -8 -18 -17 27 -47 -7 -44 -5 -31 -4 25 15 54 -46 0 5 -10 4 -24 11 -32 -1 -2 5 -10 13 -17 24 -1 44 -18 10 -20 -5 2 -6 -1 -26 29 27 22 45 11 26 7 -14 -21 -41 14 18 -25 -34 30 -1 -29 -6 -21 -36 -26 -19 -21 20 0 -18 -39 19 -16 26 26 -18 9 -22 -18 0 -9 -6 -8 27 23 -30 -4 10 -6 11 11 -8 -17 -4 5 -8 28 6 -29 -15 -28 -15 -14 -4 59 -31 -5 -14 -15 -13 -12 1 34 45 -49 -10 10 8 -13 22 -4 17 19 -31 5 33 -30 16 17 -4 16 -13 -15 -11 -42 -18 -15 -36 4 -57 -17 -13 -20 36 -7 29 17 -16 -26 -25 34 -6 -7 -11 6 -6 29 -6 30 4 20 -11 -16 -6 -16 4 9 -4 -7 38 -25 40 -14 2 2 -8 -8 25 -19 -56 16 28 -29 -29 -42 -16 35 42 -16 23 -16 -10 16 18 -18 -52 -38 -16 -55 -21 2 -11 10 -11 12 7 -10 -6 -10 17 11 -26 31 -9 39 -14 -54 52 -7 -41 24 17 -3 -12 13 22 -15 -3 6 -5 -26 -39 -20 16 0 -19 0 -3 -19 -16 -9 -9 2 2 21 16 18 3 -4 -15 8 -17 -6 -2 15 2 -7 10 -5 -31 -16 2 19 -22 -45 12 20 -10 -20 -33 -6 38 17 8 17 -28 15 -47 1 35 4 9 -13 -23 -19 21 12 1 -22 2 -27 -7 25 22 -22 -4 -11 3 -10 33 8 3 6 14 12 24 10 18 -25 -2 -23 15 -26 -33 -1 -8 -29 -25 -32 -20 -10 -22 7 5 -30 -17 19 -10 -1 3 -12 -17 5 14 29 -13 27 7 -19 26 -2 -50 4 7 5 -33 -9 -29 0 1 -4 19 23 -34 19 8 70 60 7 24 -34 -25 20 57 28 11 47 62 -60 -27 67 19 -48 84 49 16 90 7 23 -25 -76 26 -47 -38 41 61 29 -18 6 -20 40 61 8 123 -66 23 34 -37 78 -44 -9 -14 -37 20 -28 -20 14 20 -1 67 15 -49 35 85 -21 33 -11 20 -28 -3 109 30 58 59 -21 7 51 17 53 44 24 62 -49 -67 93 -47 -20 18 -19 34 -4 35 -38 -40 42 -21 1 -76 -5 42 52 -35 15 41 100 -10 -107 -27 20 -1 41 -35 -33 10 105 -15 -55 91 15 10 -17 -30 75 40 -72 19 -40 -10 14 9 13 -19 -64 40 -23 -59 -11 -32 -27 -120 -8 87 -33 -80 7 -2 -14 39 -27 21 -9 38 -64 -19 -28 89 -4 -46 -8 12 -54 -23 44 11 48 52 -32 47 20 45 83 12 28 34 26 7 -28 45 -19 -33 -15 -6 14 4 -15 -38 -76 -33 5 -38 -45 -59 -23 -12 18 16 -2 -25 26 16 22 -16 6 -12 15 2 22 1 -19 6 -91 29 -9 22 -31 -22 6 24 16 34 45 -44 26 51 16 -26 -21 -8 -15 -24 14 54 -9 29 28 -15 7 -19 23 22 27 -37 -28 -12 -16 43 1 22 9 -11 44 -15 -28 -24 -2 -18 15 11 -43 -21 -12 -17 -13 -29 -3 12 23 -4 7 23 -9 19 42 -51 -17 -7 -97 34 -29 23 -32 12 22 20 -54 -11 -93 13 -30 37 -20 -11 -19 -48 -6 -1 -12 10 33 39 -21 -83 -26 39 -34 11 -69 30 24 10 -14 -56 11 -46 -17 -2 -12 -6 16 27 -23 -27 -1 -65 30 -8 -31 16 -31 3 -52 47 -27 -2 -22 -39 38 -2 -19 -29 8 -64 -26 -11 -31 6 -10 69 10 -6 11 -23 -6 27 25 -7 21 7 18 -9 9 -29 41 -3 -12 -49 6 -23 -15 23 -12 -47 -64 -2 -17 36 -57 11 -28 -95 8 0 1 11 -20 3 4 -23 41 12 -16 -25 -71 0 13 -22 11 -46 -10 37 -14 -76 26 -4 -42 -7 42 -16 13 -32 16 31 29 -43 0 -7 39 -37 -17 -26 2 21 -1 37 46 -14 -7 89 30 -13 -20 24 34 19 4 55 -15 39 -16 -34 34 -14 16 21 11 24 -35 12 -33 -58 -55 -41 25 35 15 24 -34 10 -14 81 -42 8 76 4 -34 -16 -15 -3 -5 11 -25 21 4 -40 -27 18 12 65 14 -10 -13 -1 -8 -20 46 7 34 17 -17 -9 -35 -10 18 12 11 -22 33 49 -25 43 11 -17 16 23 5 28 27 -21 -34 29 -19 -27 25 12 41 8 6 12 -30 48 -4 13 19 2 -37 9 -17 -35 13 5 -10 -17 15 -1 13 29 -18 -37 8 -5 -56 25 -17 16 -15 -29 -34 6 10 -5 -60 36 18 2 23 14 -24 -40 -15 -5 4 24 32 16 -16 -14 37 -6 -2 -52 -73 -22 -53 -11 21 -6 35 16 -33 -6 46 29 -46 -54 15 22 1 0 -47 -6 54 2 40 -30 11 11 17 4 7 -9 -41 -41 -66 11 9 22 -17 29 16 68 -14 -15 -65 24 6 7 11 -42 -20 -9 8 -51 -4 -48 15 16 -18 -19 4 1 16 -34 23 15 -14 26 13 -4 4 -86 42 0 -41 37 23 3 17 0 -34 -30 39 7 -27 -40 -26 7 -29 -28 -10 26 -106 -34 -2 5 -6 44 -7 -24 19 -15 -49 -17 -21 18 18 17 4 -1 14 -9 -36 10 -28 3 -64 71 -19 -43 -14 -33 12 -26 -12 15 27 6 -18 25 9 2 12 15 -52 -74 1 -39 -35 10 54 -13 8 -15 -14 14 -7 -5 -9 -15 -5 14 19 -13 -45 -6 -15 -8 5 7 3 51 -77 8 3 -22 21 42 -23 28 0 29 -53 50 12 33 15 35 66 -47 -2 7 8 0 8 -7 15 16 70 -2 -6 11 12 9 26 13 56 24 13 19 -4 16 22 -7 38 9 -12 9 -15 -24 4 -36 -32 24 -19 23 -36 33 -5 15 42 -10 -15 6 -21 -32 4 20 -36 35 -15 12 30 -20 -11 -15 0 -18 -1 7 40 -22 1 8 21 -19 -12 -13 0 6 -15 -30 -64 -3 -15 -19 13 -18 28 6 39 -8 6 -1 24 5 24 -7 -22 -7 1 -16 -13 -33 13 55 13 -52 -39 18 49 -19 24 -24 -48 -23 -10 2 -50 65 25 -15 -15 -14 21 32 30 -43 -31 -14 2 20 1 -15 74 -40 -6 -17 -38 10 30 -31 4 10 0 1 15 20 -25 27 -2 26 -21 -12 17 16 51 -47 29 36 -7 -3 -8 4 0 -12 -7 -11 -27 -34 11 27 4 29 -14 -32 35 -8 -34 -17 42 29 22 -26 8 19 -46 -55 -25 1 10 -39 -36 -8 48 12 -47 6 -48 30 -15 4 0 -19 -21 -9 -42 -8 9 -7 3 29 4 27 -15 8 -27 17 8 -17 -13 12 -18 10 4 23 8 -10 -26 -7 32 7 -34 -49 32 -7 -42 11 17 15 -42 -24 -25 -25 -33 37 34 21 -15 -50 -16 12 -7 -38 -4 6 14 -7 42 -23 26 -15 28 -24 19 -5 0 8 -7 19 -6 11 -20 43 -20 -19 20 3 30 25 16 4 22 -1 -15 -15 -11 -2 4 -2 81 40 30 -34 7 31 -29 -4 33 13 51 -25 -31 -20 54 -25 0 -12 -3 25 33 15 -34 14 -17 -23 -26 17 -1 15 1 -8 11 7 -18 -1 7 15 -13 7 3 -10 19 -23 -4 6 2 -43 2 23 -13 -45 -30 -10 -2 0 -23 24 10 17 0 15 13 7 -8 -5 -2 29 -3 12 1 -11 2 15 -13 2 -17 -4 -15 -4 74 9 16 18 17 5 34 -26 -40 0 -23 6 -15 -28 -4 10 -5 -20 2 -14 18 -22 -1 24 -31 -17 -11 -2 21 11 13 -2 13 -13 12 17 -9 -16 16 -6 30 -7 27 20 46 -52 29 -14 10 21 5 14 3 -12 42 12 -14 -23 0 31 -12 -19 -26 -4 21 -6 -9 -46 -19 -4 25 -7 16 -28 4 -10 5 26 36 -36 13 -14 -6 -7 10 -10 -12 43 -39 4 -7 -43 43 -37 -10 -10 -15 -32 -35 17 -8 -14 19 -52 16 31 25 -4 0 35 10 36 -12 -5 14 -4 -6 -36 10 -6 72 1 9 -13 8 38 -5 2 2 12 -28 12 -29 -7 19 16 -40 -17 -7 -25 -2 12 -5 15 -3 43 -31 12 -20 -23 5 -13 3 -35 -27 -10 3 -37 1 15 23 -5 33 32 36 -31 11 29 -29 10 -21 5 -31 29 -6 -5 35 8 25 29 21 -2 18 -10 -9 -12 -7 -3 9 40 -28 4 -5 3 13 -6 -29 30 -4 -7 -7 -17 6 14 8 51 -64 -9 -12 -10 -21 25 3 6 17 7 30 27 -36 -23 43 14 5 26 5 -24 -12 32 17 -22 -20 24 15 -28 -16 4 -2 4 12 -15 14 -7 -13 5 13 13 -29 -27 1 -13 -10 -3 -27 -3 -4 25 -3 24 -10 11 -7 12 -11 9 6 1 -8 26 5 42 34 -5 -10 -25 2 -8 -11 -19 -9 -10 -48 41 0 -13 3 8 -23 -19 10 -21 33 -4 -8 33 7 5 -4 -3 18 26 2 -16 42 50 -16 19 -11 -13 11 -25 30 34 -6 -20 -25 0 -15 20 2 -4 -15 109 2 -28 -38 -90 30 7 -48 -8 2 -85 11 -68 14 50 37 -36 55 -23 -2 89 -9 -15 -25 34 28 -3 33 1 -5 24 -5 18 37 52 29 15 -55 -7 75 14 14 26 23 9 -17 -14 7 36 -66 10 50 -7 50 23 66 3 -25 70 19 -23 2 69 -32 8 23 -25 41 29 0 1 3 27 -3 -38 -30 -79 67 39 29 57 -18 11 -17 71 -34 0 -8 -21 -30 0 5 61 -3 29 -6 24 51 -11 -19 -25 42 9 -11 40 -5 -8 -69 71 37 8 28 -34 64 -50 -54 -2 -37 30 -31 29 27 10 -52 -6 -35 -10 -13 7 -5 23 -17 -1 44 4 11 -38 50 14 30 -48 -22 10 -65 -14 -12 -6 -31 -7 38 54 40 5 -26 31 24 12 30 35 -52 -10 33 -23 -34 51 76 -3 -2 -2 14 9 69 -28 -3 -7 -8 -15 -14 9 0 -10 -15 7 -38 -18 19 12 12 -24 18 32 35 10 27 46 -30 5 16 -6 16 20 -9 -26 17 5 19 -9 -14 14 -2 2 29 -36 -28 -23 -9 -17 19 24 10 -15 10 30 25 -6 -17 0 -3 -13 -3 -2 -3 -26 -36 -10 -33 -9 29 -12 11 -31 25 1 17 25 24 13 -5 -14 -47 -4 15 -17 -21 5 -34 0 -5 9 -10 7 10 7 -22 -10 37 11 -22 12 5 25 -21 18 6 35 18 -14 23 -2 -28 12 -9 -7 25 1 -6 -4 -43 -19 28 -32 -26 0 48 27 63 8 -7 35 30 -69 32 -20 -12 29 -14 8 -20 3 26 -27 27 13 29 10 50 6 -6 4 -23 49 27 28 45 40 -30 22 59 42 40 -73 75 -25 -18 -21 -31 51 37 -51 20 2 -26 -55 14 7 10 37 30 -13 24 -11 -12 63 36 57 -15 9 -41 -2 20 -42 -18 -9 14 31 19 49 14 7 -12 71 6 28 -13 -23 -61 35 6 6 -23 14 -12 19 -17 -5 2 5 -14 7 1 -11 14 41 -28 25 -13 6 5 45 -14 28 -19 -55 39 -25 21 -18 1 -8 -19 31 4 -12 38 1 42 1 16 9 -24 -60 63 33 -14 -18 22 32 -20 -25 12 -17 10 6 15 4 -38 15 50 49 14 -63 -5 68 -20 -36 17 70 27 0 20 11 -25 15 -2 47 6 -7 -41 -10 55 27 23 -5 -12 10 -7 -22 7 -9 17 4 0 6 -13 68 44 -31 20 20 -19 26 -10 41 -1 -3 -15 15 14 3 5 9 46 5 13 -5 0 49 -39 -25 -11 -46 -14 12 5 -5 -24 -4 -8 -18 -3 -13 12 -6 -30 -10 -18 -31 5 -18 -9 -17 19 36 -22 -22 -33 9 -7 -10 15 33 17 3 1 24 -5 0 -11 8 -8 -5 -2 -21 -21 -1 30 19 -23 13 -14 11 -30 38 9 11 -28 -7 7 -26 0 -5 41 23 19 -16 11 -15 -7 -8 24 -19 -16 18 -19 -2 31 -28 -15 8 -19 10 25 20 -12 -4 18 -51 18 9 33 3 29 11 -45 -19 42 -4 27 25 -47 6 -30 -15 3 -13 22 23 -23 -19 -24 10 -9 -17 -9 -25 -36 28 44 3 -14 29 7 -9 11 -18 -55 36 -16 -1 -33 -26 19 -12 -2 -45 -5 -14 -25 -36 -1 11 -4 27 -2 -7 -3 23 -39 -26 30 -16 12 -92 -46 13 79 23 0 -13 45 5 -12 -14 -22 25 1 24 17 14 39 -16 -11 -28 4 -17 -13 -15 -10 -26 5 -20 -27 34 -26 9 20 29 -26 9 -23 -9 8 -13 13 32 17 -6 -13 -19 -37 -28 3 25 27 0 -7 3 13 -31 8 -30 16 -2 21 -32 17 17 -28 5 -38 -48 13 -1 -36 -34 -27 29 -25 -6 12 -3 13 15 -29 -37 -33 6 6 24 -5 -8 21 11 -22 -6 -7 -33 -25 30 19 -18 -1 9 -14 -34 -8 18 -9 1 16 -20 8 15 -28 14 -14 -15 5 5 -11 -25 15 15 -21 -20 -18 19 10 -8 -1 2 0 -19 17 18 31 30 16 20 23 10 -27 -3 1 36 28 21 20 -8 13 28 -12 5 24 -5 13 -20 6 6 -8 3 -9 5 8 -6 14 2 -14 -6 1 0 26 21 27 7 -9 -1 -25 -25 -10 -22 16 22 13 19 -6 -23 -4 -6 5 -13 26 -14 -14 7 18 10 29 2 -5 -9 12 -22 -8 -6 -30 3 -6 -22 28 2 2 -6 11 19 22 -3 -50 7 11 14 4 -22 -34 11 -6 -31 -2 3 -1 -24 51 0 9 37 61 -13 -55 47 29 83 8 24 3 -13 30 -36 -68 -31 91 8 3 -47 36 10 37 2 27 5 33 1 -45 2 43 52 6 9 -54 -2 -17 64 4 13 -45 -30 -36 -33 -49 -23 12 22 6 -13 -9 9 -33 -16 -15 16 -3 22 27 -13 -8 14 -13 -19 34 74 -22 29 43 29 10 -13 -9 -35 41 9 54 38 -6 -21 35 -26 33 -7 26 4 42 5 25 27 20 2 1 -14 9 -6 26 -37 0 44 -31 -26 -3 -35 -39 -4 17 15 17 -33 6 -47 18 10 2 12 -11 -22 26 34 32 -2 -66 19 -1 -27 -21 31 -38 3 -2 33 -26 16 2 -44 -29 -6 -14 15 -17 -20 15 -8 24 46 -4 21 -13 26 45 -17 42 -10 19 -9 1 28 -42 -27 -16 -13 -43 6 6 -14 40 11 -25 64 32 0 11 21 5 2 -27 11 3 -12 -17 27 22 -21 -7 -20 -35 -14 1 50 17 -13 15 -7 32 -1 3 -20 8 17 0 -35 -21 37 -25 24 -2 12 10 25 -12 -2 12 -3 6 -25 7 -6 -32 -2 18 -14 -14 -23 9 12 3 -21 40 -7 8 6 -20 -6 17 3 40 -1 -18 9 28 27 -16 11 -31 37 -13 11 25 -1 1 34 -13 7 -23 -25 8 12 -4 -13 -16 32 -3 10 20 3 -30 -35 -2 10 -18 -53 -1 -70 42 -3 -6 -7 -8 17 12 -77 -2 -2 59 30 -26 14 -6 -25 -40 3 -38 21 11 21 29 46 -3 2 38 15 -12 -2 49 -18 -61 -95 21 52 -11 -53 52 -125 32 -36 -66 -48 -29 -15 -9 -48 -85 18 51 8 6 10 -1 -56 -17 -69 101 -7 -9 47 -69 11 30 -29 -8 -42 -15 10 -36 -80 11 15 -5 -1 14 14 -1 -50 -100 -8 -17 34 50 17 -47 -40 -61 -18 -11 -29 23 -35 42 -33 18 -8 17 -47 6 -15 -34 32 -4 -56 0 -42 -2 -18 -21 6 -18 -7 -15 15 -30 0 -89 -9 25 -32 -19 -19 -18 -23 12 44 8 -90 34 -19 3 -30 23 -4 2 25 -3 4 -6 34 -40 13 3 37 33 -23 7 25 -38 6 -52 -28 -25 2 20 27 27 -5 -20 18 -5 -2 -1 -45 -14 -43 -2 -10 -28 -48 -27 8 4 42 -2 0 -27 -7 12 11 7 3 15 -28 -11 6 39 -24 18 -15 -8 -36 -1 -15 -7 10 -15 19 -9 28 16 -6 -13 12 -15 45 -41 -25 22 -47 -32 12 27 14 -3 0 0 16 -22 11 4 55 49 3 -18 -9 4 -8 -12 -31 15 54 0 -1 -9 -3 -26 14 -34 -13 40 41 -12 14 -11 4 8 47 -73 36 5 -20 -8 34 37 18 29 9 -56 13 -5 -47 7 -29 16 -19 -42 8 -19 -56 -9 22 -6 6 -26 -6 8 30 -7 -61 2 15 12 6 22 9 22 17 -50 23 30 13 -16 43 26 32 -39 0 -36 -32 11 3 28 37 -48 -30 -5 -32 -12 16 32 41 -39 -20 2 -26 -18 -29 7 44 -28 28 9 46 -42 32 -76 -24 8 30 17 -17 25 -12 9 -9 -5 11 9 7 -38 84 -41 96 19 -45 -24 -17 -17 -38 21 37 -8 25 -33 27 8 33 2 -19 21 57 -8 4 18 -19 32 -7 42 43 13 -37 21 -31 -25 23 -6 -5 -6 -53 15 23 -44 -20 7 36 25 -17 -36 -4 4 21 -8 7 20 19 -54 -25 -35 31 -62 52 -29 21 18 -2 21 42 10 -31 68 22 -7 52 -27 1 41 -10 -13 5 -1 -24 -24 10 14 -47 -29 -5 22 4 -24 24 22 -25 -11 19 21 -5 22 20 29 -33 -35 33 -32 -9 13 -5 46 67 28 -16 10 25 -7 30 -2 40 -11 0 -5 -1 29 32 1 -12 -15 52 19 17 -32 26 -17 -26 -13 1 -8 6 -24 8 22 -34 -1 10 12 20 -2 3 -18 -17 -28 8 15 -12 -2 9 -5 -9 29 41 11 -7 -2 21 15 -1 30 -19 17 6 6 20 10 4 2 -24 19 14 -4 13 30 16 4 4 44 2 12 18 -33 -12 8 -3 -9 6 -9 25 -28 21 22 -18 -16 -17 7 -19 21 -6 17 -7 4 -21 -6 -11 -6 32 -12 -7 1 -4 -10 0 8 32 -16 14 31 12 11 1 20 25 0 54 26 33 57 29 65 -16 -36 34 -44 -57 -37 27 6 -5 30 31 50 -30 -19 -72 -61 4 -16 -40 15 -14 37 9 4 7 10 16 -14 38 45 14 40 63 -28 19 3 -29 11 -31 -21 -11 -29 -30 -10 20 57 -23 5 -5 2 65 -12 29 12 23 -3 34 84 -37 -41 21 -12 57 13 -23 -11 38 0 -6 -5 -12 -13 -16 -11 -7 0 -36 -65 16 24 4 1 7 -15 46 -55 13 17 27 11 -10 -32 7 18 -21 -31 12 11 10 -34 17 23 32 -39 -40 43 -1 -11 30 30 3 9 1 6 -16 -14 2 17 14 -36 -23 -9 -13 -15 -16 -43 44 -42 -12 21 38 -5 -13 18 -8 -62 26 7 6 -21 -59 20 -31 -45 7 33 -48 -26 -22 -19 29 -6 -34 96 18 17 -23 53 30 8 -11 -24 -26 4 7 60 -11 43 30 1 -26 -25 -29 -44 24 21 -23 -10 32 6 7 -31 21 15 8 19 10 9 12 -10 10 -15 2 -5 -12 18 28 19 -29 -32 -23 6 7 -3 44 -2 -31 -8 7 -17 -3 -8 -45 8 10 -12 -13 -5 -9 35 15 -2 -8 -36 -29 -9 -62 -18 -24 -18 -32 4 2 -18 -14 36 2 17 2 9 20 12 -28 -16 -1 20 17 34 20 -1 -41 -13 23 21 3 10 -14 -25 8 14 -21 -20 -9 -20 -20 14 3 -18 -21 0 -53 -3 -12 56 15 -5 -16 -5 -27 -3 8 -11 -34 7 -20 0 -2 -11 39 32 -22 -10 14 66 9 30 -21 6 1 66 -23 -24 11 -59 -44 20 -15 -15 -29 21 -14 13 -7 -11 -10 -5 13 -46 -45 -5 9 39 3 -6 26 18 6 -27 -28 -33 38 -24 66 -23 -24 -8 -37 12 13 -26 -19 17 21 39 -14 -1 -12 42 -25 17 7 -35 9 -15 10 4 10 -16 38 38 80 -61 -28 -27 28 48 -13 13 37 -22 4 -21 53 -13 -8 12 0 -14 -20 -6 32 4 -16 5 28 -12 7 18 -16 -16 -43 5 40 -19 9 -30 -10 9 -4 -1 0 -42 34 22 17 52 31 34 -1 -19 -24 -49 -18 -40 -75 3 -25 13 -12 5 -6 24 12 25 7 -7 11 -5 -40 5 -26 28 -18 -17 31 13 28 -9 60 -11 19 7 -11 -29 12 4 -17 3 21 21 -43 31 36 -5 7 41 -20 -7 9 -26 6 -23 -11 15 4 -5 34 -6 -19 -35 -5 -45 34 -15 -27 -28 -9 -13 12 -17 32 30 18 19 -12 17 16 4 25 1 -9 -5 -40 7 13 -15 -14 -21 -5 -16 19 49 -25 27 -10 31 2 23 -8 13 -19 19 9 -23 5 31 5 -17 7 -4 -12 -14 9 -23 -11 -16 -22 -9 15 10 20 5 8 10 -11 12 5 -1 -16 -7 -13 0 -10 5 -14 19 14 -11 -7 7 22 -4 -10 20 0 7 -27 -4 14 -34 -25 -3 17 29 4 -10 -6 -19 0 -5 -2 -8 -42 19 -13 -32 -38 13 -91 2 26 14 -4 -29 -44 -2 -25 15 19 18 -15 -30 -18 13 46 11 7 -14 -17 14 12 -79 -15 9 14 67 -37 -5 -28 6 -5 31 -44 6 -21 -83 0 -37 -7 -7 9 -12 -42 -1 23 25 4 -7 5 -24 -21 55 -32 39 29 -7 -52 -11 -27 -25 -32 -21 -43 16 -30 -35 54 -34 -4 -8 -24 1 59 -5 -11 -55 25 9 -13 -18 -39 -5 -40 1 -34 -3 -37 15 -9 29 5 22 -27 6 -30 41 10 44 -15 -47 18 -32 -15 28 33 14 -33 37 17 -30 4 -19 33 27 -4 17 10 7 -43 -24 26 -17 18 -27 28 -6 -38 10 -14 -21 20 6 42 -10 4 45 2 -15 -5 -42 -41 51 -2 7 -24 -36 -18 2 11 0 -12 24 -9 11 12 13 13 -8 -33 33 23 28 -21 6 -13 -6 16 57 61 -32 -31 10 -10 46 15 -2 -8 -11 41 5 -8 25 -8 4 13 -1 26 8 -8 -34 -28 12 21 1 -23 13 -10 12 5 -2 31 -15 -10 8 -9 21 20 -11 -54 30 4 16 30 24 18 -18 10 12 -37 22 -1 2 46 -4 11 -16 -9 2 -19 -10 -3 -24 18 16 12 14 11 -10 -8 -17 -19 -24 -15 22 6 -2 27 46 -26 -32 -7 5 5 13 -1 13 20 -29 -1 22 17 -34 3 -15 -16 3 3 -19 8 -12 -11 -3 26 1 -30 -1 2 0 10 42 -21 -70 10 53 -12 9 47 39 -16 59 -7 -37 -22 -12 -7 -21 49 50 -6 -2 -47 -8 -7 32 16 -52 -1 -7 28 -22 -64 -14 -27 50 -6 -51 18 -26 -15 -62 3 -28 -64 -9 -2 54 0 -36 -18 14 -52 54 -24 27 -24 -40 12 -3 -19 -112 -22 -11 64 -9 -12 -30 -37 24 -5 -8 -11 -31 -36 -11 -1 26 29 75 1 43 -4 22 -14 9 -12 -6 -12 14 -41 -29 -24 -1 35 -45 30 -37 5 48 -32 -7 16 -10 -13 7 59 72 16 -36 8 32 -44 -10 -43 18 8 -2 -58 -49 -5 3 -3 -33 -13 2 -24 -15 -47 14 2 -11 25 -1 17 -7 13 4 10 -2 -3 14 -2 -29 39 -24 11 16 24 20 -38 15 7 -23 -29 7 -60 -23 1 -29 -37 -67 -55 -32 -21 -32 19 40 36 12 -21 -51 -31 -62 25 0 -2 80 1 0 -9 -19 0 -13 -28 -5 1 -45 -3 44 20 -6 15 -3 -18 7 11 5 1 -8 -14 -8 -1 -28 17 9 11 -35 15 -4 -26 -52 13 13 -27 12 -4 -19 51 1 19 -25 -32 -5 -14 -8 -3 2 38 -20 13 19 3 22 27 33 -18 12 5 17 11 19 -22 -19 36 -21 10 21 -10 30 4 -49 -17 -12 -5 -9 -8 -22 -22 3 -11 5 3 -24 -3 15 -8 -10 -3 -9 12 -35 -49 34 24 -15 41 1 11 -25 -20 25 -4 -29 11 -5 -16 -50 3 -2 -59 -53 12 -17 -27 -30 -20 37 -30 -58 -15 -17 -2 28 20 19 -32 33 -22 78 22 -59 4 13 19 -26 9 -25 6 -7 3 -28 11 18 -19 -5 33 -55 -73 11 0 10 -30 -19 5 26 -30 -10 -61 5 5 19 23 4 -14 9 5 -30 -15 74 -40 16 49 19 -37 -27 -54 63 -33 -9 -44 11 -64 -6 -17 -56 -22 53 -45 28 -32 -20 11 28 -3 -18 36 -30 -28 -7 -8 -27 -53 42 -2 20 12 -3 17 8 -36 30 31 21 14 36 -2 -17 -25 -10 57 28 -42 -25 23 33 -15 -18 19 8 -9 -26 25 -6 4 -7 -5 17 -48 41 -36 -29 60 -7 14 -1 -6 8 10 26 -1 -2 12 -36 -24 -33 -57 31 -10 -24 -52 -29 -15 -18 -3 -32 -34 4 25 7 -26 -32 6 -21 -38 19 -11 0 -10 16 9 -24 -31 -47 19 24 44 18 13 -15 -20 -15 -43 12 -15 -24 -16 1 0 3 0 -8 -29 -2 0 3 -31 -19 0 -29 -5 -17 24 -7 -44 -5 22 7 -21 -16 33 26 0 -17 9 -4 3 -22 -8 -2 -1 36 32 -16 -15 -3 -2 -9 -21 0 32 -8 0 -9 -19 16 21 0 13 -5 -23 -12 45 29 -19 14 -16 36 11 10 8 -52 -2 -14 -27 -9 1 24 4 -11 -11 -9 -7 4 -7 -17 -18 23 17 -7 -39 -8 4 -4 -23 -10 19 -26 -1 20 -4 -2 -29 -12 -11 -9 -5 -8 20 33 5 -4 45 -26 4 -13 36 -12 7 10 21 1 -24 8 31 -3 -17 5 5 8 40 27 -13 24 -27 15 -21 36 21 13 -9 -31 -4 -18 -46 31 -23 -2 3 -49 -33 -51 -23 19 -6 55 -24 -35 -11 6 29 -53 -20 5 25 7 7 36 14 4 14 -20 -50 -19 32 30 -44 -10 -10 -4 -10 -13 -16 22 -50 -21 46 -5 -60 12 11 6 5 -9 32 -7 -82 30 48 14 5 -8 1 -16 11 20 -11 1 7 -29 8 10 -18 -52 25 2 -4 -5 -12 -9 -8 -18 -19 13 -16 -1 22 -11 -21 -12 9 -4 14 -18 21 -27 -12 29 -41 -6 -15 -7 -6 44 7 -23 37 11 -18 -34 -35 41 54 -37 41 -7 -11 13 13 38 16 40 -9 -8 44 0 39 -27 -22 -16 0 2 18 1 5 -24 -47 -41 1 -15 -14 25 22 -9 6 25 30 21 -1 14 -7 -15 -21 -4 -11 -49 -32 23 17 -14 60 -2 -4 30 20 19 30 32 -31 27 13 22 9 -12 -7 13 10 -5 43 -29 -9 -33 -24 -26 24 -22 8 7 24 4 6 14 34 17 0 39 11 4 -28 -5 -40 -14 1 -23 14 -5 32 18 10 -29 -6 -18 -15 -10 8 5 -2 -2 30 -29 7 -16 18 1 -26 22 17 -10 -7 -1 4 -5 -22 33 -6 -27 6 -11 25 27 -7 -12 -12 -6 -2 19 9 1 -31 -23 1 16 9 -16 5 -42 -24 -3 -17 20 -20 14 -29 2 -14 3 19 27 -19 33 -3 -4 37 -2 33 -12 -17 -71 12 -80 -68 -6 -14 -15 -43 -8 1 28 -66 57 1 -9 14 -13 -3 2 -13 39 29 19 35 14 19 -40 13 8 39 3 10 51 -2 31 -47 -87 -22 -43 -49 22 -22 28 22 44 8 -92 46 -4 10 -11 -29 25 19 -28 11 -20 -8 23 47 69 -4 -31 37 11 -38 -16 15 14 15 -13 1 21 7 28 -1 1 -26 10 2 0 -9 4 -9 17 0 -28 43 -5 -37 54 -19 -31 -24 -23 34 7 -9 -5 -11 -16 12 17 0 9 19 67 -1 -32 13 12 -23 44 37 -25 -8 -20 -7 -31 23 -10 -19 1 -3 -5 16 -26 15 46 -4 59 9 -21 -11 44 1 -9 -9 -4 13 0 -6 -10 -44 -30 4 17 -14 37 1 26 4 -26 -41 -23 25 -4 -11 4 -8 -16 50 -6 5 -3 -2 41 -16 -22 -6 3 -14 18 24 -7 17 8 -5 5 1 -4 -25 3 22 18 8 8 -11 11 25 10 -10 18 15 4 18 4 7 2 -5 -6 -33 23 9 -11 -4 -11 -13 2 -19 26 9 -43 -23 0 -20 -3 -34 19 13 18 -9 13 32 20 -12 11 -11 21 -11 14 18 -8 1 -19 24 -10 -49 0 20 -10 11 5 30 36 7 10 24 25 -29 6 18 -16 -8 -36 29 -20 -20 25 3 14 16 -4 -65 -57 -6 -45 -59 44 62 -43 -8 -10 -53 27 101 33 19 -55 -63 24 -16 -14 22 15 -32 0 -54 10 13 -35 -18 34 -48 -9 -48 -8 3 -15 -3 5 -49 -34 -15 -32 -38 3 19 -25 -42 -93 3 -21 -19 1 68 19 59 100 40 3 79 6 64 8 -18 80 -24 36 10 26 -60 24 -19 -29 -26 -16 -42 -17 31 24 10 5 9 -37 -21 68 36 37 -14 -46 40 -37 -34 -13 -51 -33 17 20 28 51 15 -44 -51 -33 -9 -11 -26 13 -36 32 -6 -31 9 -54 17 54 -8 -37 25 -15 -17 22 -26 9 37 -46 -11 -44 56 19 31 -31 -12 -21 36 3 -56 5 -35 28 -18 36 -40 21 17 24 -14 -32 -20 5 10 -18 21 -47 -12 1 3 17 -28 29 -20 -40 -28 14 26 11 -48 -5 -67 -27 10 -2 25 -33 -1 19 2 -22 -3 -19 -5 46 11 3 -23 38 8 32 22 -13 -64 7 31 13 -19 -5 18 -2 33 -10 50 -30 22 29 31 11 -11 43 -2 22 33 -5 22 -4 -23 22 39 23 3 54 -28 -6 30 17 -44 11 -47 -30 -45 24 9 -39 -22 -2 0 -22 -32 -6 -20 -12 -31 -44 -4 14 4 10 -15 -22 0 -9 9 9 -27 -29 13 -27 26 1 27 -13 -13 12 -11 17 7 -23 -5 -6 22 11 6 12 40 -17 17 25 -23 3 8 -6 -20 -8 -1 -12 -18 14 -6 19 -38 57 -71 4 4 -42 -20 -50 -6 4 11 -6 34 30 30 13 -57 1 -30 -61 -25 -55 1 101 62 34 -21 11 16 -1 0 4 -2 -12 -33 -19 -58 -26 3 -56 -2 -26 5 6 -38 -47 -1 10 -16 -1 -33 -5 -26 -26 15 35 49 -40 8 -36 -72 -8 9 30 39 17 12 12 -47 -34 -17 -15 -16 -4 4 -20 3 22 64 2 -13 -49 22 -9 -6 -6 -25 33 -44 19 -10 -32 -56 1 -20 16 18 4 28 6 -5 -32 -36 -35 -4 -2 1 -24 -6 -6 14 4 -39 26 -4 -39 12 -10 9 1 -28 29 -25 -27 5 -35 17 -8 7 5 -8 14 12 -20 32 -14 -39 1 3 -13 -20 -21 4 -28 21 42 31 36 23 15 -17 -31 -56 -2 6 -58 22 -8 5 -27 -23 8 12 0 -15 33 -1 -31 -1 -17 8 0 28 -34 21 0 28 14 -5 15 7 -9 -21 54 39 -49 18 -32 21 -4 26 -2 -23 24 15 -22 -10 -3 6 10 -12 7 17 24 8 -16 -26 -13 -16 -1 28 -11 19 15 -9 22 -17 -16 9 15 -19 8 4 6 3 -2 -21 -8 -23 -13 5 3 33 -6 13 -7 26 18 15 -8 6 9 1 7 -9 -31 -25 -3 -20 -13 -26 -1 8 -13 4 -25 7 -36 -28 1 -5 14 4 -21 17 28 3 6 -29 -14 -2 23 49 12 6 -18 -28 5 20 13 -31 40 20 -37 26 -20 -14 -20 -15 17 18 47 17 33 -9 -17 6 47 11 -6 4 36 56 62 61 -101 94 -51 11 15 41 104 21 27 31 46 -4 57 4 -5 23 11 45 -10 37 -2 47 -86 27 61 22 -24 -115 54 46 19 54 -2 5 -17 -45 26 23 48 39 30 -47 -36 61 39 15 67 20 91 100 -24 64 -79 -52 -77 -28 91 -16 13 6 -8 10 -41 17 -4 -36 -49 37 -26 6 -25 -4 29 34 -27 22 29 -1 3 75 -19 10 1 -14 0 47 -29 12 32 -3 -21 -8 -17 -13 27 -22 -39 54 25 -15 75 -2 -13 80 -18 -31 97 68 -1 110 20 82 43 -4 -41 24 24 -33 -70 17 -35 -79 19 -7 66 -48 83 38 11 38 -83 8 -7 36 22 24 -20 -17 18 22 21 -7 66 11 -51 -52 -25 27 -72 1 -7 19 -6 19 0 -10 69 22 7 43 -23 52 46 15 -50 -14 -13 11 -3 -29 -6 -21 -28 -40 36 73 -21 -5 4 58 -52 -7 -10 18 13 -59 26 25 13 8 40 14 11 -75 -34 16 2 -44 -37 -14 -5 40 25 7 15 13 26 32 25 17 -27 7 -11 -9 4 -23 38 -6 -13 -22 -13 -36 4 1 -32 6 -27 -1 30 16 7 4 -22 -15 -12 3 -8 34 18 -3 90 -5 -18 -4 -9 11 -15 -4 3 37 -12 -39 -23 -3 6 6 30 -3 10 5 21 -57 45 -10 -20 -17 -2 1 3 31 38 9 -5 18 30 17 -31 -54 32 55 -14 -16 66 32 4 4 34 -6 -115 -53 38 -25 -86 -80 45 -62 92 7 109 -34 -31 18 -65 52 39 -46 -25 -72 -28 62 35 27 44 -1 -54 30 -39 -124 -21 -13 -62 21 -16 -25 49 42 -3 -47 -67 -44 14 61 -43 -26 56 2 95 22 64 109 -52 -3 4 26 -16 6 125 14 -18 6 -60 -13 14 16 24 -26 0 12 -4 -74 -61 -31 -4 -16 66 25 -29 53 -41 85 40 -42 15 -89 14 7 1 -10 19 -24 29 -57 56 -35 -71 40 -11 31 69 -2 -10 11 -106 -31 47 -103 25 -9 -23 -3 61 119 -18 -8 36 123 -65 47 -4 16 -52 -54 -10 -20 -43 -73 23 -30 18 21 8 -98 29 -33 13 -48 18 -47 -60 -91 14 -16 22 26 108 -12 6 -6 54 -12 -40 0 -12 48 31 -33 -36 88 35 66 -37 -67 51 -39 20 -67 -57 -16 51 -16 -4 68 -33 -8 0 12 -12 39 4 17 -51 71 -59 24 -11 -1 29 47 -1 31 -27 -54 -4 -21 35 -11 43 45 25 -19 -15 6 17 35 -21 -19 36 9 -9 -5 -25 -2 48 19 14 9 7 81 -26 -48 -51 17 38 22 20 -39 35 53 -15 -6 16 -15 26 32 -17 -40 11 -18 -59 5 -51 16 25 -3 7 -42 -68 -11 -35 12 3 8 -15 -30 9 -9 11 2 -73 -27 -36 31 -3 125 29 -30 9 -38 -11 36 0 7 26 -3 -31 -56 -23 -25 -11 -9 40 -72 -16 57 94 -26 -28 -21 32 -49 -9 42 37 21 -51 5 -12 13 16 59 -78 30 -8 15 -29 34 -2 30 12 -45 0 17 -18 39 23 -45 -6 32 -5 -13 47 31 11 37 -38 79 72 51 24 -36 -5 -33 43 -38 -49 -67 -25 24 -18 -14 83 22 -75 0 47 36 -2 5 -21 1 19 -9 65 -46 40 30 -37 27 113 14 15 50 -23 0 -1 -1 1 13 -28 -7 -34 20 83 -51 -30 20 46 -61 -7 -22 23 40 -4 -43 -64 -31 8 47 -25 -116 74 31 -36 -53 -56 63 11 -97 -43 51 22 -32 19 24 -32 47 2 26 -61 19 4 55 -24 17 -3 78 -52 28 29 -42 -126 -22 -21 42 30 -31 -14 -20 -41 -120 -59 37 -20 11 -29 21 11 30 -16 -22 -13 -39 -15 -10 -18 -49 -33 -38 13 -19 75 7 4 9 -22 -38 2 5 -21 24 7 -56 18 -19 15 -50 53 -10 -31 -45 -35 14 -37 -60 -3 -8 -64 61 7 -58 8 2 -4 55 0 -19 18 -11 12 18 -42 -11 -51 12 -51 41 -23 11 16 4 -17 19 43 41 17 -8 -24 7 18 10 -4 -6 28 -16 -10 25 11 -24 41 13 5 40 44 -15 -40 -16 -39 5 9 34 54 13 -28 -9 -26 -26 -49 14 36 11 -16 5 -4 -30 -6 -19 -24 11 8 -6 18 23 -22 25 -33 -28 -42 -46 -71 -7 5 -69 -28 -50 -37 33 0 67 69 -29 52 29 -17 -4 -1 -45 8 -9 4 31 25 106 35 -75 -15 -4 -66 1 -6 86 -33 36 -112 -10 -53 -39 -51 25 38 15 -26 48 26 -6 86 -2 -24 4 -12 7 44 -56 -75 -65 36 -3 -70 -61 -6 -42 15 84 44 8 -31 33 33 -17 20 -13 60 -51 25 1 42 -4 76 9 58 -3 26 -27 17 6 8 4 18 -81 -6 -29 50 55 27 -41 29 17 46 -46 -7 -9 -5 -3 80 -20 -9 -22 -15 49 -42 -28 68 -31 41 9 41 -2 3 21 13 36 -43 39 21 15 13 -17 22 -55 30 -34 -47 -65 -81 98 27 -48 -15 -41 23 -9 5 -12 -14 31 17 -18 6 -4 -40 -15 37 11 -11 27 7 30 -53 -26 29 24 -9 -60 16 -3 -32 3 12 79 11 -59 8 59 26 57 8 6 -29 -18 -37 -28 -4 -5 -31 -11 -1 10 5 37 53 15 30 -35 -31 8 -31 7 25 -37 -5 -5 -18 8 0 -15 3 -12 14 47 5 11 22 -39 -21 -28 -4 39 -17 -8 -4 -1 19 28 20 25 1 -9 11 -45 -12 37 13 -34 8 8 -1 11 13 11 -4 45 30 26 13 -10 -41 17 -40 -8 -21 -64 34 11 -8 -34 -29 -17 27 -9 -25 32 -38 37 21 6 -63 26 -15 -21 -16 33 37 37 -9 -10 -21 31 27 -25 -6 62 -23 16 -14 7 -8 -8 -25 7 36 91 -31 -28 -13 12 9 -47 27 24 -11 37 -5 51 -42 51 -7 12 -36 0 3 -45 80 37 90 -18 86 126 -9 -16 -7 -26 -19 27 1 71 80 31 88 62 -35 -17 109 126 -70 75 -6 -28 -40 -23 108 10 47 67 44 51 41 2 44 -28 31 -121 10 84 -2 68 43 -72 97 -8 42 119 6 39 58 63 13 3 -77 -27 -4 14 -52 47 -1 54 4 -39 67 105 -24 -51 -59 51 11 36 -28 58 16 -4 89 -6 43 -73 29 -37 -4 -112 4 32 35 15 -54 4 50 34 14 -25 -57 55 29 -61 85 16 -73 55 -23 28 -85 -4 -121 -55 -89 70 -2 16 -2 57 44 -36 -4 28 -15 -30 -28 37 92 66 -32 106 34 -6 -53 49 -47 -88 40 -20 -60 54 -93 53 37 25 13 -4 -14 56 4 -18 -33 -14 -54 14 25 -44 -30 -47 -2 16 -36 11 -42 -12 -50 -5 -71 -73 -84 59 -52 29 15 -19 1 2 -49 -45 -14 -35 -37 -3 -13 18 -59 28 33 -45 2 -36 -1 -11 29 -3 43 -20 11 50 -15 9 -35 17 -14 21 2 -7 -21 23 21 3 87 -9 39 -25 -70 -45 20 33 -6 19 -7 50 -84 37 40 30 21 -5 11 15 -11 8 18 10 -87 -28 31 41 51 -37 57 3 -39 15 -10 -23 -9 11 16 -58 -14 -30 -46 -4 50 -6 -38 -28 49 0 41 19 -23 12 11 -28 10 -65 20 -22 -6 50 53 -7 -18 10 -53 15 -8 18 16 103 21 24 -33 -18 -31 45 85 -28 88 -60 0 42 8 17 53 26 12 -14 -30 -27 2 -8 32 43 34 26 -45 7 24 -15 0 -25 47 -2 43 78 -30 28 10 80 81 -34 16 -15 26 1 37 -40 115 79 71 -36 4 29 69 55 4 11 -1 -29 -90 -1 47 58 17 39 -44 -12 55 -38 52 -20 49 126 -12 24 1 97 33 44 73 -99 70 -1 -23 -2 4 2 24 10 20 51 2 5 -44 -21 -81 8 -8 -15 6 -1 4 19 -13 12 56 -12 -33 85 -25 -49 3 -96 -52 -66 -6 35 54 -22 -8 -65 29 19 -5 -18 13 24 22 39 -50 -69 13 38 90 13 31 20 -6 -44 42 29 33 52 -45 5 7 31 -37 -13 62 -28 19 -7 44 -23 -39 -16 -5 5 -9 50 19 -38 -105 -16 -28 9 -31 -40 -5 14 18 49 56 -26 -24 -22 4 35 7 30 62 63 19 -38 32 -11 48 -10 35 -1 3 45 25 2 -8 -25 -31 -10 8 -2 55 -16 9 14 83 -13 -14 -27 -46 -42 5 26 1 -15 9 29 -14 19 -25 -36 15 -17 9 10 14 -24 -11 -15 -20 45 -19 11 -15 -15 19 -11 11 26 -4 -72 -23 11 -35 45 18 75 -4 -26 12 23 -15 19 3 23 -15 44 28 -1 -4 -7 18 1 -16 -2 -16 22 16 36 38 -11 17 -6 34 109 35 -35 118 79 64 -66 78 19 49 -37 50 64 -47 3 83 15 -12 123 -68 -11 -11 3 -32 13 19 3 77 99 -45 27 -73 18 91 40 100 -6 3 85 -95 -37 -4 59 16 34 -60 -67 8 23 10 124 -56 14 -38 -37 44 -31 31 8 48 36 39 9 28 41 21 113 -2 102 27 27 -24 -24 -25 -47 -3 37 -27 -26 32 3 117 49 -78 103 -19 30 24 -19 41 -54 52 86 19 87 -16 17 -58 28 -43 -2 -16 47 10 -38 28 -26 -41 -5 89 -28 -49 -35 82 -11 71 44 13 123 38 -11 -10 -21 18 65 5 17 38 52 44 -7 6 25 -7 -21 -12 23 117 42 117 15 14 2 -55 -39 102 -7 11 -19 29 -3 5 29 -99 -9 25 -1 -26 75 4 25 -83 -17 -27 9 -38 20 -16 14 -14 11 -42 -88 -33 22 -5 -18 -29 34 33 15 32 13 63 -32 -25 -71 -16 12 -65 -1 -51 32 33 -24 -28 -10 55 63 -14 44 67 -5 -47 23 41 28 27 1 -34 -19 27 1 37 -3 -16 22 3 42 -13 48 -5 -38 -16 -11 -27 28 12 -39 -4 -2 23 -12 15 12 -44 -4 4 -34 24 -37 -10 31 9 -47 14 27 20 32 -4 -21 -35 -3 29 39 -9 17 7 -14 40 6 55 39 14 -17 22 46 64 7 17 11 16 -17 -6 -66 -28 48 44 5 3 28 -26 4 22 44 2 -17 54 122 -19 25 19 -22 32 48 83 -78 53 1 35 60 -7 -57 120 42 6 -3 32 49 54 35 63 -73 73 -84 10 10 4 49 -40 -16 -25 42 23 -80 1 18 -18 59 -9 44 40 73 -34 50 51 -4 -16 -9 29 97 36 18 -1 -8 -13 3 58 58 -16 -30 -27 -5 51 30 70 26 24 -18 28 -34 97 39 -27 9 -16 -43 91 49 27 -40 -74 4 32 100 39 -20 50 25 29 -4 -41 -55 -77 49 43 50 5 -24 -36 7 -16 -9 -6 -46 31 36 -6 35 44 -31 -18 49 31 112 -23 28 7 -8 -15 34 -6 80 9 33 29 -23 -31 7 59 24 -48 60 44 40 -13 54 23 -14 -112 17 19 35 6 -16 62 -113 51 -25 7 34 -36 -10 -46 -15 28 12 75 -34 -10 -2 -41 22 0 17 36 22 7 52 -4 18 -73 24 27 -28 32 34 -44 -10 -20 -75 -4 12 7 -42 -36 52 78 0 22 -54 1 -21 -17 -28 34 20 -29 4 5 -5 1 -4 -4 2 31 6 -7 -38 -2 4 -8 2 -11 0 -37 6 -17 -17 -11 33 0 8 -28 53 -8 38 39 -17 -28 16 20 -16 -24 17 22 7 -5 13 8 2 -8 20 10 8 20 2 12 2 -13 -50 -81 7 2 9 3 -21 -10 -10 35 19 23 -15 -24 9 -6 -24 48 -46 -28 -13 26 19 -7 -10 15 51 -13 20 -13 -6 -20 -17 -15 -7 -64 69 127 -35 17 26 47 55 51 96 6 -79 72 13 -53 2 125 14 66 24 25 -9 -27 81 14 43 95 11 49 -15 16 -22 41 31 42 -16 97 0 87 14 7 -30 19 -24 18 60 -59 84 -10 -10 15 96 8 14 -4 9 39 127 66 1 51 20 23 127 44 54 74 107 -5 1 -14 4 55 42 0 -9 54 15 -77 -11 -16 58 106 9 -60 23 -19 62 -1 -49 81 -2 26 15 114 -16 -20 33 7 39 -31 9 60 22 -16 39 -29 -45 -9 51 18 47 22 -5 58 -49 25 29 -55 -53 36 24 47 11 -8 72 -6 -24 -20 -65 -22 -25 38 91 -29 -9 25 39 57 24 87 -28 -59 7 -14 -22 -43 18 39 37 36 37 20 -17 31 44 26 21 -84 3 -42 -53 37 71 -37 22 9 48 -13 33 -2 -33 37 24 10 23 29 -20 -52 33 30 -14 -60 -46 34 -56 8 23 -16 46 -15 37 11 -24 -49 12 -14 26 -22 -11 15 -28 -6 -40 26 6 -50 -28 45 -23 -41 14 24 -21 11 -11 -2 24 -16 -14 -5 -5 -14 -41 -17 29 -23 14 36 -1 -10 14 6 -42 1 -51 6 -50 -2 -48 -32 -31 6 -17 18 -14 40 30 -8 -14 20 -16 44 -6 -89 73 16 5 26 45 -1 -6 -20 -38 38 -10 -76 -19 -12 -50 -3 1 -12 29 4 -17 -5 -10 -25 28 21 -51 20 -29 48 -58 -23 42 31 -68 31 -30 -14 45 -82 8 -39 -24 45 22 34 11 5 -1 -1 41 22 40 34 83 35 -14 -37 -7 -58 -1 -38 62 -57 8 -30 36 11 2 46 6 -22 -30 -9 -41 -38 -87 37 41 15 -16 34 -94 -13 -21 -8 64 -44 63 57 73 6 27 36 -14 59 -31 67 -27 52 -56 -65 -21 -25 13 16 -20 44 19 27 52 100 -30 -15 35 79 -17 94 74 123 33 -31 70 9 25 -87 -27 -69 -36 34 93 7 -40 47 81 -24 41 80 -87 14 47 22 -35 -69 -56 35 -12 -33 -76 -37 30 -54 71 18 26 43 67 107 51 31 -22 -1 94 15 18 -33 -29 0 19 3 -52 5 49 45 -8 -9 63 0 100 11 22 23 -9 -1 -66 -53 3 7 36 29 7 -16 32 66 27 12 -88 -35 23 -19 -50 0 52 -40 -27 -10 79 97 -116 -47 9 -45 1 -9 71 -126 -4 -46 -48 -58 -62 -65 -13 -53 -17 -58 9 -16 -11 -49 17 17 -94 12 52 -52 0 41 27 -15 -29 -24 47 18 25 -38 38 48 28 12 7 -13 8 19 -28 -41 9 13 -9 44 1 -7 23 -12 11 -3 89 0 5 3 -55 -46 -25 -8 -12 17 -38 4 55 -14 7 -12 -29 -8 17 -17 -54 -126 -5 4 -23 8 29 -41 16 34 36 46 -23 26 24 29 -22 -6 27 29 -33 -23 58 2 44 63 46 -36 25 -46 56 60 24 30 96 93 44 -5 19 69 -23 85 -35 73 38 91 41 26 -35 1 47 15 11 -22 15 -29 15 48 47 -31 6 -30 50 -76 6 2 26 44 -7 14 39 93 -42 91 19 52 -11 75 2 3 99 -16 24 47 0 -27 22 15 -38 15 50 83 60 -26 116 52 67 3 -9 -72 40 82 -53 25 -3 -36 -7 -1 92 29 24 49 -59 44 73 37 31 18 66 -12 127 10 5 39 26 31 38 63 -45 27 -24 9 25 -30 -17 39 -88 -71 19 20 -62 32 48 41 31 23 -68 58 33 -22 12 5 89 5 30 3 -39 7 45 -18 40 -13 -77 10 -24 123 49 28 46 -18 49 46 40 -1 -3 30 14 39 102 4 26 56 -3 40 21 -15 15 35 -66 -25 50 30 42 -38 7 -3 33 -9 -60 7 14 22 21 46 9 28 33 -16 -41 -20 17 18 16 -54 3 -3 22 -25 -31 73 -72 -15 -49 -17 19 11 -93 -59 40 -37 -9 10 -48 -37 -21 -52 15 -30 6 12 19 14 -35 8 17 5 -23 13 -18 14 -31 13 -5 -38 4 -50 -13 -11 -16 -19 55 42 20 2 -15 -31 -14 -19 -36 12 -9 38 35 27 -24 19 22 -2 -22 57 1 9 -18 18 -4 -22 -19 -19 16 -25 13 13 -52 24 -27 -10 5 -19 -19 16 -13 46 25 -5 28 24 34 -43 -46 -61 -6 31 31 12 -40 26 -37 12 26 -4 28 -31 -21 126 -50 3 3 -97 -44 26 74 25 46 55 26 72 22 32 -17 31 -81 -24 -18 47 113 -7 41 55 0 78 61 90 -9 -27 -33 -23 3 -10 49 102 -30 115 90 19 -2 24 0 -28 106 -7 2 -42 121 10 39 -120 24 -12 -61 -77 -6 -40 -58 -13 -124 -46 19 10 47 -37 -2 3 8 -48 45 -18 12 -65 28 23 13 -96 -60 -8 3 -25 69 -16 97 -49 -57 64 81 71 -9 -12 95 -8 20 -36 -21 -34 -38 -23 -77 97 -29 -99 -5 27 -107 16 32 63 -16 -24 11 -11 -9 -66 -2 -33 -45 68 25 5 -14 -31 46 58 34 64 -14 8 -35 -108 -18 73 -70 50 -74 -43 -57 16 56 49 -29 -31 31 -9 62 32 -5 3 81 24 -5 -32 58 60 -43 -81 -30 48 60 -38 75 -62 -17 -70 -1 102 -51 -32 49 -29 34 18 47 -40 -63 -18 93 -14 -45 -36 16 -45 -28 23 -30 42 -25 -65 59 -32 54 18 1 -42 25 31 -6 -24 14 34 26 -38 60 -11 -47 -30 -22 -28 -107 -72 28 20 -4 15 9 35 22 -36 29 -54 45 3 17 -30 16 56 6 36 -25 9 30 4 14 -10 -11 27 39 -24 127 -19 42 -42 -26 1 17 16 35 0 5 15 -21 -55 -6 27 41 2 -10 44 -18 -55 36 -3 7 0 21 31 20 -75 -35 10 11 4 -126 12 -24 14 58 69 -13 5 -41 7 48 25 35 44 -9 17 -23 81 -5 81 -42 33 30 64 21 -48 -51 -18 7 37 -13 -36 86 -28 -8 -108 -18 34 -39 51 30 21 82 59 -90 -56 37 60 -54 26 -20 41 34 -27 34 -86 -30 10 5 26 54 -73 106 -26 27 -39 27 61 -90 79 -13 27 38 89 -14 5 -44 -32 19 -22 -47 -12 -41 -13 -33 -73 118 -8 1 -11 -1 -23 53 27 -19 -46 35 -27 41 -51 -13 34 81 51 -41 27 66 41 -53 -30 -41 -70 -11 25 15 -21 58 31 35 11 20 -8 -3 -45 23 13 -8 17 -25 5 -13 -43 28 -3 17 23 -20 48 -44 -26 -13 -53 31 7 7 -62 16 3 22 72 -14 -29 -28 7 39 -22 28 1 -7 23 -62 21 27 -26 18 27 17 32 21 1 -44 -17 -40 -68 -9 32 2 77 -38 -15 -6 -3 -37 -40 59 9 17 46 9 -2 63 33 -14 -39 54 -17 -30 -48 41 59 -42 -28 41 -35 13 21 -39 28 -8 -20 -34 -31 -21 -7 -7 -8 17 -27 42 -39 -6 6 -34 -33 -39 43 10 -47 -44 -21 -22 -11 -23 -26 -10 -20 -13 -27 75 54 6 -3 9 -10 29 5 38 -20 -48 -17 -2 24 -42 12 -4 -36 4 25 -44 -5 15 -7 -12 2 -8 6 17 -27 23 -25 6 5 -19 39 -52 -44 4 -15 17 8 -18 14 -13 0 -6 -7 -10 -4 -8 -8 26 12 5 -39 54 -10 -10 -29 -32 -22 -9 17 94 -27 29 38 11 110 -86 7 41 -23 13 60 45 39 45 37 10 59 62 -41 -104 20 31 -37 -5 28 18 37 -34 -8 -32 -4 63 39 70 6 -15 126 -20 -73 40 30 15 21 62 -25 -63 -2 35 1 10 -5 13 48 -66 1 -2 64 15 54 23 -30 53 61 -5 18 -77 123 -43 65 39 15 74 -41 -109 11 18 -4 -6 24 1 9 -61 18 51 54 -70 66 -17 34 16 -19 3 -14 -4 -98 40 -1 16 1 -69 2 4 18 62 -33 -4 -36 31 42 1 -75 -92 17 27 7 -30 48 -61 38 -1 6 101 74 -40 24 -17 -19 -20 -94 -17 2 -19 16 2 -20 -18 32 46 2 -11 -30 10 -53 -40 19 -66 8 7 72 -16 -53 94 -55 12 71 -93 -20 72 7 18 -20 -2 23 -83 25 -22 33 12 9 20 -14 -81 -77 14 84 -105 -54 -49 -71 67 -58 -12 28 32 27 18 -24 20 -51 21 -44 10 -24 -3 -68 -36 -1 -45 -10 -3 9 41 -1 -57 6 -5 1 -17 -23 34 -23 27 46 -29 -35 -10 -8 -27 -20 8 0 -36 0 51 18 41 -14 -37 66 -20 12 -40 -4 -4 -44 69 -16 -18 -15 22 -25 42 54 -64 -24 -13 21 42 20 -15 20 -9 52 18 -14 5 -19 24 -3 -17 3 -13 -12 3 17 4 -51 12 37 7 16 32 42 -15 31 -21 -32 34 44 12 41 -32 -34 42 -3 77 -11 26 -29 45 27 -4 2 -34 -18 36 -118 48 3 31 -31 -1 -22 27 15 -45 6 -34 56 -16 28 45 25 87 61 -35 28 91 -12 84 62 68 -35 -3 18 -25 -35 -48 43 53 39 59 -34 -44 -30 -4 7 30 68 2 120 -21 -14 54 21 1 47 39 -3 70 64 62 -7 -71 31 15 101 3 36 15 8 6 10 21 31 -14 -3 -60 0 16 16 38 -25 -3 17 18 24 -4 -39 -26 21 -35 -6 -22 -14 46 -50 -16 50 -8 -49 -35 32 -26 9 -12 -9 44 10 -15 29 39 -15 11 60 -5 18 0 -52 -46 -10 1 -26 8 1 -30 50 1 -14 47 -74 -17 26 23 41 16 58 0 -19 7 4 -46 -22 38 23 -48 -20 18 -41 34 -26 -19 43 21 -29 16 11 1 -16 21 28 -36 17 -2 5 21 43 -3 20 9 -26 32 -2 -12 -39 -14 5 -61 39 13 39 64 25 51 12 23 -12 36 49 -4 -24 8 -4 -43 -50 59 -18 0 -4 46 -53 22 1 -34 5 -5 -11 -12 -5 -26 2 -5 -12 -33 43 -36 11 -1 -11 35 25 -23 -5 54 33 -11 -15 -29 -4 -7 -42 -12 10 15 26 5 13 -4 -49 -4 -9 -49 -9 13 16 -26 -6 -12 44 19 -54 31 -16 59 38 -14 19 -16 7 -14 -50 19 -41 23 -18 -43 20 -12 16 44 13 -45 11 18 -14 -4 76 6 16 -33 -11 -7 30 75 -56 21 -3 29 -16 95 15 -32 -9 22 -3 103 2 -104 21 -79 80 -27 70 11 33 68 -6 -43 27 10 20 -29 15 15 10 10 -11 12 21 -4 -47 -22 26 86 -29 65 46 84 -39 -103 -33 -8 32 107 25 32 103 37 55 65 -6 -2 19 -38 30 -110 -15 85 -35 -26 -53 55 85 43 -45 64 67 -54 42 -1 -3 47 63 -1 66 -3 51 -112 -23 -4 -9 -62 26 16 66 1 -31 26 1 5 40 -6 -67 -14 57 -59 37 52 71 -27 27 -15 -23 -32 28 -36 -46 24 49 -11 34 -51 -24 29 -29 -19 46 -53 31 22 43 15 23 -14 -8 5 39 18 45 28 43 7 -40 26 20 35 -25 33 17 23 -78 -30 -31 -3 8 18 34 -25 42 18 0 -25 -28 10 -6 -3 -105 -23 -7 7 51 17 84 -41 -8 -22 9 -2 -74 -2 -61 -40 12 6 26 23 -26 -57 -8 20 -8 38 -19 -11 3 -11 -12 11 36 -2 30 -37 -8 29 52 -20 33 9 7 25 6 -7 -4 33 22 -30 19 -52 42 9 72 -5 -11 2 27 40 -8 -30 -17 -23 -21 -65 10 -25 -12 20 -19 -26 10 39 -41 36 1 23 6 -20 -10 -30 29 -28 -39 31 -7 -11 46 16 -29 9 12 -39 2 -9 -27 -8 5 -15 7 -20 -69 -7 5 33 -1 39 1 -38 -30 -16 -5 29 64 5 -32 39 -33 25 21 11 -13 -2 10 66 32 29 26 -65 11 -23 -47 44 -63 24 -27 11 -85 6 10 -19 -40 54 25 -13 48 -33 4 -5 32 42 21 -4 30 -35 -16 -9 35 71 -1 -2 -57 43 6 -15 -10 -41 118 18 6 -26 2 33 -51 52 55 -44 43 -26 54 33 -9 23 6 -14 -65 37 7 99 -14 -27 15 1 -62 24 -34 -5 24 15 -23 50 31 16 -7 15 7 -28 -7 -25 -31 13 -97 -16 24 -25 -37 48 -24 23 -22 -38 -44 -21 38 5 -33 -19 60 115 23 32 -31 50 61 -31 10 30 3 19 -59 -12 0 17 -98 74 22 26 30 50 -79 31 18 -78 67 -59 -4 -22 83 -16 33 -72 -61 -51 15 38 24 34 -28 45 23 27 -37 6 16 29 -9 -43 -76 19 48 12 56 26 2 -30 4 -31 -3 -19 28 -21 -50 52 -17 5 -20 86 -59 25 7 63 25 -22 -65 -36 -8 -33 57 -73 -31 -9 7 -15 -3 21 -20 50 -46 25 -12 19 7 29 41 -51 9 58 -1 9 2 -15 -31 -30 -45 -24 -15 -67 -6 -57 -31 -6 -30 -13 44 -2 59 1 38 -77 -15 -13 12 29 14 -26 6 -41 -6 -9 8 15 -2 14 -16 -6 3 35 -11 7 -8 41 6 -38 -75 18 -42 4 34 28 -9 -33 14 36 -7 52 -3 20 4 53 -17 25 12 -22 -13 -25 -29 43 26 27 5 -8 -4 -44 -11 -1 -14 25 99 37 50 -4 14 10 0 28 8 -108 40 71 29 121 23 13 63 -40 -12 23 31 -65 -7 -24 78 -63 25 27 54 -11 12 -52 2 -20 31 7 -40 19 26 48 6 27 -8 -31 -54 3 -2 -48 -28 -21 100 21 -3 -3 -27 -21 10 -26 -35 -32 -6 -89 5 37 -30 -64 72 38 50 37 -30 -28 23 58 100 2 -37 -49 -91 10 63 -61 75 -23 2 65 16 -31 24 24 56 1 53 57 16 36 79 21 0 8 66 27 -52 1 63 15 13 -69 21 -5 35 -23 -1 -36 -69 15 11 14 -2 1 -28 15 -18 -89 20 97 -32 16 34 112 31 34 -19 -5 -26 -22 -60 -16 0 37 74 52 -12 17 -9 30 -15 47 15 113 -42 -15 40 25 23 35 -38 -8 -3 32 -32 -31 -9 -34 -19 50 -22 25 53 -75 -17 -15 44 74 7 -33 6 -67 -49 -5 76 36 -48 -20 -1 -7 -71 -18 -12 7 4 37 -38 -56 -49 -26 13 31 5 -32 -5 9 -29 -5 2 23 -20 -22 6 10 22 -8 -25 19 19 9 0 2 8 47 -13 -53 7 9 55 49 -1 34 35 -33 -23 12 -22 11 25 -25 28 3 -21 8 43 -1 -2 -17 18 -28 15 -17 -21 45 -16 12 29 -7 -11 -12 14 5 -38 -2 41 -23 15 0 18 -13 34 26 -41 18 51 -6 3 -20 10 19 18 -29 2 -18 -7 -26 0 8 102 -7 32 7 -32 -17 -51 47 31 90 -17 45 61 -44 90 11 47 85 46 31 54 17 21 54 2 37 26 -1 32 -30 26 52 36 16 83 -32 59 -15 -19 -19 45 16 38 82 13 20 -16 60 41 27 -24 127 69 69 -31 -11 -76 35 -10 -9 64 -28 16 21 22 23 19 7 45 23 44 -3 40 17 39 15 8 -21 50 26 61 48 46 79 -3 4 23 85 3 11 59 84 52 84 -106 26 101 54 -4 -39 70 40 36 89 52 -34 -23 13 -28 -35 -9 15 -24 5 -11 42 -56 -8 -20 11 12 21 -18 38 -40 21 46 21 29 32 -1 -12 8 3 -18 20 -3 50 -4 -18 -24 22 14 45 -42 -12 -13 18 32 -17 81 96 -45 63 15 -48 16 -46 52 7 -37 53 22 -35 8 13 11 36 -39 29 41 104 -38 -22 20 -30 -5 44 -31 -6 11 -37 71 -26 -33 -58 -35 -53 -1 -6 -2 31 -11 10 -9 52 15 -50 -8 -22 -13 10 1 3 16 -13 -48 15 -26 -6 -23 8 -39 25 -4 -10 5 -48 -33 7 28 -5 -21 19 -6 -11 34 4 1 -57 36 10 34 33 -20 -6 -11 0 7 -24 -11 -19 5 19 -20 -11 -8 45 27 -25 -5 -10 23 18 20 -51 -23 4 13 18 21 24 29 10 -17 9 -23 44 4 -20 42 -72 5 21 -63 33 -63 -12 -14 -9 20 -11 -38 6 15 -8 7 -54 -9 43 86 -17 -22 21 -21 -23 25 -2 3 -81 -5 58 -64 -29 55 -61 59 -32 127 -19 100 65 -44 37 -2 24 90 -2 11 -17 44 -39 88 30 88 20 87 -39 -75 22 -24 -11 16 75 -19 -91 40 39 -25 0 72 -29 11 -14 -42 -34 74 16 9 13 -28 27 93 36 16 50 90 0 27 49 28 -46 7 -28 25 0 7 20 -17 1 27 57 2 26 -29 18 31 5 67 -55 60 62 17 0 -71 -28 -10 -13 -12 58 67 38 -30 40 -4 21 -18 20 -42 5 -24 -5 22 41 -4 96 21 5 -31 -38 -7 -64 -128 -13 -47 55 76 9 -47 22 -58 -18 24 19 -6 21 39 64 1 45 -33 -55 94 40 -7 91 -18 -23 11 35 27 56 64 -10 -21 26 0 22 69 34 -21 -11 -49 8 37 34 42 -37 -13 -6 -99 67 -16 21 -1 -65 39 35 5 -39 -52 -51 65 -27 7 4 -5 28 -24 24 -12 -15 -1 2 33 25 -26 -48 15 -50 0 13 -67 -26 -9 -35 -48 -16 0 -26 -31 27 7 -21 4 15 36 -14 -14 1 12 -26 20 17 19 33 11 -28 4 -3 -23 -20 -10 -47 13 3 7 42 2 31 2 7 2 23 18 -4 27 -8 -42 15 25 22 34 -25 30 5 -4 5 67 -6 -21 13 -76 19 -17 13 53 -12 -58 43 11 24 11 24 58 7 14 26 -59 17 -17 29 39 -4 3 23 9 -107 23 -24 6 -30 34 -22 8 -56 -34 -53 0 -7 -51 -31 -35 -91 15 9 -11 -85 63 -28 -35 8 -39 -13 -74 -19 -15 -14 -25 -20 85 4 39 55 37 -22 0 -56 42 62 4 56 12 -29 74 -78 -12 -58 68 -25 44 23 -71 14 -22 -51 6 -30 2 4 -46 15 60 0 -6 14 1 -48 -33 -50 -33 21 14 -57 -36 55 -42 44 -4 100 -73 39 -1 -23 -17 -15 59 -33 83 67 -22 43 -19 -78 18 97 -54 -5 12 12 20 29 42 -17 -31 20 35 -44 -5 78 10 -15 4 -61 23 -30 89 1 -17 -28 92 21 -33 -23 32 9 14 -26 -12 1 41 29 -21 38 -33 -5 -86 35 43 6 2 -22 -39 -49 -29 8 10 40 -31 55 -16 -18 8 -37 20 66 -40 32 9 7 -25 -36 4 -41 17 53 -68 -28 39 -1 15 -10 -22 2 -40 39 -23 6 16 -9 14 3 22 -3 17 19 73 8 -23 44 8 22 15 22 43 -47 73 25 25 -12 -11 -13 -1 0 -38 -29 -52 -52 -3 15 -22 16 29 1 7 -15 -3 -6 -28 -24 5 8 -24 -9 54 -13 -17 -2 -4 34 1 31 -22 3 -40 34 25 47 30 48 -19 -27 15 -22 -1 -12 29 1 -14 -26 4 29 -34 36 20 8 25 -13 1 27 -31 6 0 1 19 -17 -24 1 13 1 27 21 -22 -9 51 -60 12 -3 -25 35 46 14 -22 14 -39 -5 39 -38 -19 26 8 29 36 -28 38 120 34 -34 -42 42 58 26 -17 74 71 -82 -10 50 -30 14 97 15 -9 28 51 26 21 -17 -10 -13 59 -4 20 25 46 -85 12 3 24 11 60 -24 -22 39 -4 -10 24 33 58 48 32 29 62 0 -56 -11 9 -49 10 -30 50 2 56 -15 33 33 5 -49 -14 58 50 37 -3 106 46 42 -79 93 52 47 63 -32 47 -6 37 26 -54 -38 56 86 41 43 74 7 79 -42 -2 34 -23 -65 -4 24 -2 25 -70 24 -13 -6 15 -45 -26 -47 91 -18 -25 -40 -7 -19 17 -12 -3 68 -16 29 -25 1 49 11 34 4 -50 -2 -20 -25 44 23 2 -3 86 34 47 -29 -30 -13 18 22 2 54 -1 2 4 -42 -1 -61 18 -9 42 11 24 49 -9 -96 -21 -20 -11 30 59 -15 -19 -79 4 30 -1 5 -33 -6 5 -1 -18 -53 21 45 -15 6 -9 -5 -43 -20 12 12 -78 -27 37 4 25 32 35 -8 22 13 -21 -8 -36 31 -22 -3 -2 -11 -49 3 -12 -36 -23 12 -43 25 -16 -19 -13 -7 14 -31 -11 -9 -30 -16 -35 -13 10 19 6 18 -13 22 -14 26 -9 -9 -24 -4 -4 -27 -7 -34 33 -5 -3 -2 29 -1 12 19 26 8 32 -46 -8 25 -44 4 -7 18 10 -5 -12 -48 35 -47 22 -29 37 -12 -31 -5 0 -24 -19 -28 13 -23 -17 52 17 40 -48 -32 -32 5 17 -24 4 -24 15 25 33 -43 -8 25 4 31 63 -20 45 -34 4 24 22 -77 -14 -61 -124 -31 60 97 -6 -11 -12 1 -46 0 52 66 -22 -15 -15 -20 -31 27 -39 -4 -57 -12 -51 29 0 18 85 37 -4 -31 32 116 -27 64 1 75 -38 16 -13 19 12 15 -4 -16 31 3 7 -63 -82 74 60 27 34 25 38 61 27 -12 36 -36 19 -14 47 16 -15 -35 52 25 -43 14 15 -4 41 -32 21 36 68 16 15 8 -36 15 -19 16 36 -20 -36 -87 62 -82 -58 44 112 41 51 -67 -5 -11 14 -3 5 -6 -17 7 -4 37 37 71 95 -27 4 25 66 -65 -18 30 42 -20 -17 -22 -7 58 33 -27 10 58 -55 30 69 25 61 5 -51 7 2 -14 39 -2 -10 18 -12 -24 3 -28 -79 47 -13 28 -6 -15 39 12 0 -8 16 -22 9 89 8 -14 -45 -16 23 -2 32 -22 43 6 -39 48 38 32 23 -28 -15 -8 32 -7 16 6 65 -18 -9 40 -13 44 -3 15 17 -6 -20 12 6 29 13 68 -8 38 39 19 19 -49 2 -1 1 -20 -22 -2 -12 42 -19 -10 -5 23 -17 18 -35 21 -14 -9 19 23 11 27 -2 9 16 -10 -31 14 -9 -43 51 31 -20 -16 10 -23 -22 -6 -2 4 -26 3 -65 -19 36 8 20 -8 7 18 -20 15 -12 -15 -50 7 6 18 65 38 -11 -15 76 -27 -44 23 -32 -43 53 -58 -54 -70 -67 -61 -32 46 14 -17 -52 21 -3 -13 19 29 24 -89 -47 -37 -54 96 10 -15 -39 4 -6 -59 -25 39 -38 46 51 -1 -33 -46 3 -40 2 20 -38 78 -97 -127 122 -47 57 35 -31 37 -5 -45 -24 9 -33 -87 -64 -58 -9 -89 -74 -65 -51 -60 -53 -23 94 -15 -60 42 -47 -17 -12 -18 20 2 -6 -48 -5 29 42 -6 33 -1 46 30 6 -13 8 -77 -48 5 5 26 6 22 58 -3 -5 -13 -4 -45 29 45 37 -2 12 -9 -10 -24 45 -14 29 -76 -55 -9 46 -20 42 -40 -12 -12 50 45 -5 50 -103 -16 -59 9 37 11 -21 55 57 38 9 1 -35 30 46 -18 -68 98 31 6 71 0 -56 0 2 15 -23 -35 -51 -6 52 -78 -32 4 -16 -48 -48 24 -74 -4 33 -53 39 -19 -19 -13 -94 -8 -14 9 -17 56 -40 20 -15 -12 10 -18 9 -24 88 30 20 -10 11 42 -28 1 -14 -10 14 -24 46 13 -23 -36 2 5 7 -11 19 13 15 11 11 -27 47 -16 4 36 -14 -29 -44 2 -30 18 -16 -16 -14 -23 34 -12 1 11 36 -27 -29 -39 29 4 -11 36 19 -28 22 -39 25 -6 -4 28 13 -28 -18 11 9 -35 -58 -12 52 -45 19 -16 67 3 -41 11 -11 25 53 -8 36 15 19 19 31 20 24 -23 -7 52 -7 59 -2 23 -51 13 -16 -33 -2 25 -52 19 -47 20 15 -29 -1 -43 -2 52 -16 -1 -14 91 -7 32 -51 15 -8 -32 90 -39 -50 15 -16 0 52 22 75 23 76 17 2 41 52 -33 23 77 102 18 -3 14 -19 -29 0 -127 23 112 -19 9 -19 4 84 49 -52 58 38 27 69 1 55 52 -7 -53 16 -38 45 15 78 -69 -35 -12 61 14 85 7 7 4 -44 57 43 -11 8 -9 35 -26 -70 -3 -42 -8 14 38 -23 20 -14 -43 -63 79 -24 -81 -21 -71 4 24 35 33 60 -93 -65 -34 38 39 -1 6 -2 -49 -35 -70 0 16 -18 43 85 -7 31 -72 5 27 -13 50 -27 8 -31 -2 -49 -3 5 -5 118 11 87 -8 9 36 54 23 -32 49 118 -57 -5 -21 -33 -28 27 -29 35 -26 -6 -29 -47 27 -71 -7 23 -11 -76 -93 32 26 -25 -41 -50 15 -68 8 -68 34 67 -8 53 22 -78 -4 43 -44 92 -69 12 -27 48 -14 -49 -15 -46 2 -35 -8 -23 4 -38 -25 23 -3 15 74 -13 -5 13 -27 -20 9 -13 -58 27 18 6 -7 7 72 7 -49 23 10 12 17 37 15 -52 50 28 10 -26 45 -23 -27 -26 -6 -71 -44 -11 -3 -28 31 -16 25 -1 15 36 17 -16 -27 -10 62 8 -42 -15 22 7 26 24 23 23 19 -86 6 28 -35 13 7 -15 -8 17 0 -24 -13 -66 -8 13 20 14 82 -26 -28 18 32 39 -21 -1 7 -29 27 -40 -9 -24 -59 -69 5 -51 28 48 -19 -7 33 -62 20 -24 -41 -26 -5 -6 27 -43 20 4 40 36 -17 11 27 -21 4 4 41 -2 4 20 -1 14 -23 -14 -68 46 -10 98 3 30 19 -39 48 58 -13 -27 70 19 34 23 46 -18 -46 -26 -70 81 -36 14 -24 7 -36 73 34 0 -8 -4 37 -86 -11 20 -1 4 55 -18 -84 5 -44 27 43 -19 -110 28 -46 -72 -9 -75 63 -28 -34 -13 -60 -8 -4 -21 8 79 36 31 -26 -39 20 3 -44 87 -35 -25 0 5 -62 -37 -3 -6 71 -42 -10 -21 46 -36 -4 7 -63 22 10 -48 45 1 -37 6 -6 -33 7 -9 45 20 37 52 34 -29 18 44 1 -45 5 15 24 -72 50 65 18 54 -27 -13 42 1 10 11 41 43 -25 5 -31 31 15 39 47 -50 -26 15 55 -6 -45 4 -22 -24 19 -18 43 -26 -25 -23 -23 59 -8 -32 46 1 -5 -24 -8 -55 -26 40 -19 -5 22 14 -39 -35 7 39 12 -1 -14 11 -19 18 50 3 -24 -16 -26 34 5 -20 13 -1 -50 25 -19 -39 -29 7 8 10 -17 -1 -48 21 20 -3 -21 5 -37 -1 1 -14 -13 30 40 -17 2 -99 6 38 3 44 -21 5 0 17 27 -51 18 -7 19 -46 34 12 32 9 -17 22 14 24 17 40 -22 -27 5 4 -24 9 73 27 13 43 8 59 23 37 88 78 7 22 89 67 36 15 42 43 -37 -23 -71 -5 -20 -23 -17 65 36 20 63 -55 16 40 38 52 63 -16 -4 66 120 -38 20 -5 20 18 72 20 -42 14 42 -20 1 23 -69 -42 85 -12 4 23 31 -20 -19 -37 -8 -32 -26 38 0 3 -27 12 71 37 -12 -11 25 15 20 -83 -50 25 21 -71 -13 35 -35 -14 -6 10 -20 16 9 -15 9 8 46 11 1 61 14 33 40 33 25 -33 -70 -9 -39 -27 -6 102 -18 -46 83 1 -17 -22 121 43 -39 33 23 -1 33 20 3 3 71 24 -14 50 26 -5 44 22 43 -9 -28 14 -16 125 20 -12 16 -69 -4 31 -23 33 -94 35 40 10 22 -22 -11 46 -13 71 116 -41 67 3 -3 0 -34 15 16 -21 -53 23 -16 6 -30 84 -27 -43 38 23 -26 -33 32 3 1 1 55 -1 -21 -14 45 -21 31 18 -18 30 -60 -52 -45 46 -13 19 -54 -18 30 26 4 7 33 48 -28 -58 3 21 -4 -24 31 -19 -13 -24 -22 -22 1 12 24 -33 -31 -10 57 40 -49 -1 -32 -12 -2 -15 0 27 16 62 -7 -21 -13 -11 12 -4 -10 14 -20 -5 -14 -45 -20 3 4 -26 6 -79 65 17 43 -34 -11 -50 -15 -54 42 14 46 9 37 30 -9 -27 11 -55 10 -1 39 -19 -26 36 -31 -51 -5 -6 -44 -26 40 -7 39 -1 -52 6 31 -25 51 -43 30 12 74 57 3 0 -5 -27 6 -21 43 9 -66 107 55 -11 90 32 7 -23 56 88 127 -33 5 29 8 89 93 17 16 -12 -39 -9 43 27 44 11 -4 53 78 46 127 77 1 27 62 -34 51 77 49 44 6 121 77 60 18 6 60 -2 37 57 60 4 3 4 28 -23 45 66 39 19 5 54 -66 57 -36 -4 -17 5 6 39 -14 53 -10 -28 86 -4 -1 49 -2 56 42 77 36 -28 123 71 -25 62 -42 36 66 -15 55 -2 44 43 12 -16 1 20 -14 -31 23 3 -3 -31 -54 -54 -34 16 -1 3 24 30 92 59 21 1 -8 -64 -68 -56 -16 -66 1 -58 -17 -26 41 38 23 7 -15 -11 -42 21 18 60 19 -7 23 22 -82 -12 25 2 90 16 17 66 49 2 19 19 20 16 0 16 20 44 17 -20 7 -24 -9 -83 -18 -81 -25 -10 16 -39 -30 -4 -40 -8 -55 -16 -6 -15 -61 -2 60 7 -19 -17 -20 1 14 2 -4 -10 -39 35 -7 -43 3 9 3 21 -20 -24 6 -13 -30 -52 -23 21 37 -6 -24 -2 -21 -21 29 -43 22 -10 1 49 -21 -12 35 17 -6 -39 21 -1 -12 -13 25 -2 -2 9 -12 -21 -4 0 21 3 -2 22 33 -42 32 -3 10 -5 -10 -9 55 -27 -8 15 -14 -40 -27 8 -12 -7 15 -33 12 12 -29 -5 -20 -11 21 26 23 7 17 9 29 2 -3 -8 -29 -36 -86 -25 3 19 -80 54 18 78 -6 -13 39 13 8 58 18 87 24 30 31 -21 -30 42 42 -52 -12 7 30 11 34 -26 -38 -55 -54 7 -11 -75 20 -2 84 -22 43 32 -3 -10 0 14 58 6 -94 -5 29 -28 46 -60 -62 50 -22 -85 -15 47 -33 45 28 -19 56 -16 -28 40 28 10 47 40 32 36 -10 7 16 34 -18 -28 23 -12 20 28 -52 -20 74 83 29 -50 76 -38 126 -24 -39 -2 -30 33 7 29 -12 -8 -9 -34 3 37 -31 19 -8 14 17 -16 -38 -10 25 4 15 6 20 22 89 20 -31 -11 -22 5 29 51 6 -10 -57 49 48 -30 36 -40 -16 13 -6 39 -21 -51 71 40 -65 16 -14 63 7 -52 -26 36 21 -10 47 -22 16 -27 -12 1 6 -11 -23 1 20 -37 17 -20 -101 1 -17 18 61 24 3 -78 -25 28 37 -5 -77 -40 42 9 0 58 -23 6 -7 37 11 13 -30 -28 32 24 77 37 -15 -45 -10 10 -43 -8 12 8 -9 10 -68 -17 50 8 51 -36 -23 9 44 -6 -9 -15 -40 -7 -10 -35 -44 13 -47 -33 45 -21 17 10 18 29 20 -2 17 8 -1 27 1 1 29 -45 1 -34 -3 -14 3 25 -17 -10 14 21 -9 -6 -3 39 48 -7 28 61 17 -16 -28 5 31 -5 0 -15 -19 -11 1 29 -10 41 33 0 19 -15 5 34 -19 10 8 -17 -95 43 20 -70 40 52 -44 11 -25 18 -32 -1 24 -55 23 13 -1 55 -3 23 12 -1 21 -59 -20 -11 36 21 116 2 78 21 -71 17 -125 -43 40 -2 22 -103 37 -46 -116 -27 -37 2 54 -9 21 -21 6 20 -9 84 -20 46 46 -12 -31 -82 -38 82 -44 20 -27 -6 125 24 21 23 48 -26 -18 34 -28 28 33 -43 67 55 -54 50 -10 38 -5 -11 -48 -43 86 49 19 8 120 -59 -46 2 43 -50 35 35 -21 -19 -2 -34 23 30 26 32 14 -20 52 -19 -52 -11 -66 3 -3 6 48 12 76 29 76 -69 35 9 23 59 50 -32 -80 -45 -46 18 115 -103 39 21 -87 54 14 58 -8 -91 10 21 57 -6 112 32 -38 7 4 19 -65 20 -3 -26 -26 33 -2 22 6 27 -24 103 -48 -42 -22 -27 32 15 28 -104 -30 14 1 0 17 24 -26 -28 -16 36 3 -13 -18 45 114 -14 5 -40 15 8 -3 -32 47 -23 46 38 22 40 -42 19 -22 -11 24 31 22 -21 -40 25 34 -5 -20 -7 -24 51 -9 -22 -18 -7 -5 -17 10 -18 -25 -6 -73 -47 24 -9 117 3 35 -4 -38 -41 -24 -15 46 23 23 -13 -20 -24 -27 -8 -7 8 -18 -47 -15 -67 -43 -9 -23 -16 -13 -23 -2 1 -2 53 -11 44 -1 1 36 -12 -18 -27 54 22 -17 5 6 -7 52 20 -19 -8 24 3 40 -16 -71 50 80 34 -80 -124 12 -20 -63 74 83 -28 -74 125 53 15 -61 -35 43 -85 95 37 -62 -9 64 19 54 23 124 -32 52 -83 70 -71 76 8 -8 -1 57 44 15 3 57 58 -52 -11 62 -48 23 -87 -118 -6 -16 -37 -1 85 -10 44 -13 -6 -30 33 -40 -108 57 -2 23 36 18 25 -80 29 60 -63 125 -13 12 -31 35 -2 2 11 -35 57 38 -54 -13 -14 -39 -16 33 15 -41 31 67 6 42 -33 72 -35 112 77 -10 23 -40 0 67 -121 -7 36 9 -119 63 63 49 -91 -77 -55 27 37 -35 53 -52 12 45 5 -71 -61 28 49 -100 86 17 -68 -14 -18 38 7 -66 57 -14 4 24 -117 43 47 33 -13 42 41 125 89 -30 -16 47 -5 -56 39 -33 -99 19 -41 -40 14 16 -85 -100 -44 -19 -18 51 -121 -57 -8 21 23 -71 10 -11 27 -54 -8 -45 -6 9 21 -9 -17 37 120 -59 23 -16 72 1 -4 26 33 6 -6 -24 -24 -96 -41 40 -72 -51 -10 12 24 -27 -39 46 12 -26 -35 8 -1 5 38 46 -46 -5 -8 -6 13 25 17 -25 55 -15 46 118 64 4 7 -58 -35 -11 -4 -13 -51 18 5 22 -28 42 -7 -11 3 6 118 -22 27 7 -82 28 51 -57 28 11 4 29 -51 16 -14 -25 49 -12 -19 -14 -47 8 -16 29 89 -2 18 27 -119 -7 3 14 -32 -19 25 80 9 43 22 3 -84 -7 -17 62 16 64 -33 -3 118 65 -1 -50 -8 -91 67 -11 -19 55 71 37 24 49 -8 40 12 79 -101 8 -6 19 -40 -5 39 40 -31 44 -12 -15 26 -34 12 -62 -13 9 -36 33 51 58 -40 -22 -76 18 36 19 -43 -15 1 65 -54 31 6 123 -78 -63 8 37 -12 -12 -30 -58 13 2 5 65 79 10 -76 24 -52 19 -72 58 -1 28 30 124 32 -36 14 -33 16 16 -5 -61 19 -116 45 -19 85 3 -1 100 -32 39 -31 -81 7 -12 -34 24 -64 -25 -9 -70 68 -33 26 -22 106 20 45 -56 -10 18 39 -10 -28 27 62 38 17 6 -57 112 32 35 56 -35 15 -19 81 -6 75 -11 13 82 -72 -28 48 80 32 44 67 -25 73 25 -51 40 11 21 -9 -36 -22 -108 -24 35 -19 15 7 13 13 -25 -32 36 -55 -2 -45 -27 -31 13 21 -53 18 -2 27 -109 42 79 -69 34 28 1 -35 -29 -27 -72 13 -48 1 -11 7 -23 2 20 -40 2 -24 5 40 -7 14 10 56 47 58 -39 -1 -49 27 -38 12 39 -15 -17 -41 -2 13 -14 33 -6 -23 -50 41 6 19 -18 -19 -3 -25 -16 2 -3 31 14 -7 28 49 28 23 2 23 -5 -27 -15 -1 3 -39 33 4 -72 -11 -27 17 -18 -3 3 16 34 7 -42 -3 -10 -61 -2 -21 -26 24 28 2 7 27 -5 16 30 -16 12 -36 50 26 127 47 36 4 34 43 21 27 -25 22 67 13 23 64 17 19 34 80 84 -42 -7 48 28 6 23 16 13 26 33 22 53 -3 24 -28 32 -36 52 -66 4 6 -11 20 33 6 -29 -49 90 18 67 56 3 -18 30 9 3 49 8 1 2 40 49 -6 5 99 7 104 43 -18 -2 5 21 -7 -46 -38 -24 -33 59 25 -31 28 7 9 -26 80 40 -44 -27 66 7 54 -8 1 22 22 -34 -13 47 -11 -3 -50 38 -19 46 -3 15 7 4 19 -21 17 49 95 3 -19 12 -22 -7 -20 -19 -55 66 72 -23 6 67 -50 53 16 80 22 21 -21 -58 0 84 75 32 40 39 -10 59 -41 -9 -3 -8 -31 17 2 28 -102 -36 -62 19 31 7 36 20 50 61 -48 -13 29 40 -97 54 38 26 28 -29 -32 65 -17 -25 -17 -14 -45 -3 -17 -77 23 55 -34 5 59 64 -4 -29 18 -29 32 81 14 65 14 -33 -8 -14 6 24 86 -3 -66 8 35 -17 -24 -10 20 -50 -50 -18 -33 -35 -2 14 -3 -28 -1 16 15 -23 -25 -81 -21 -36 23 -33 14 -12 1 -8 2 -33 -4 -6 14 30 -11 27 0 18 -27 -31 -30 -25 -25 36 -65 -12 27 -20 -18 -10 11 48 3 -22 -25 -22 0 -43 -22 -29 -11 -39 -4 -16 5 6 -13 -26 -7 -30 22 12 -17 -3 12 13 -7 -2 -17 -37 2 46 -14 -25 -12 -28 15 -61 34 42 85 7 -48 61 12 102 64 44 -49 -4 52 35 -42 106 -43 -61 86 24 -24 -2 41 29 55 30 24 79 -19 10 98 56 -2 -38 39 33 -37 35 45 21 -33 12 -19 -57 64 2 -48 26 41 22 -17 24 10 48 29 57 -28 41 15 -21 -14 -20 -18 82 82 19 24 21 10 -13 -5 83 -10 -94 42 23 69 11 -3 29 -47 -125 -47 2 49 11 -9 63 -34 45 31 -8 -6 63 -25 -67 51 -22 -15 -10 30 4 31 -4 -18 -50 1 -2 18 7 15 7 -7 -48 -4 4 10 -51 6 -41 -8 -12 -12 -22 -49 18 89 59 13 -57 1 39 23 30 -31 62 6 -30 -61 47 -29 20 -45 -13 5 1 12 18 -2 12 8 22 -17 32 5 45 4 -68 -23 -5 50 47 -8 22 -5 -24 22 -3 5 -30 57 0 -1 -48 26 52 -13 -64 31 -33 -19 38 -44 9 -41 16 -31 -31 27 11 -58 1 4 49 23 -1 9 16 -27 2 -15 -21 27 -36 -5 -3 -37 16 -2 -9 -17 25 5 11 -21 -14 10 -37 -31 18 -2 32 -9 9 46 -6 21 37 16 -13 29 -17 30 -35 -5 3 -40 32 -2 17 -22 9 10 23 5 29 -8 -29 -78 3 11 52 4 7 -3 10 -16 23 -19 3 -13 -51 28 -11 -36 -6 -5 27 33 -53 -23 9 -50 64 1 -9 27 -2 -21 35 7 -69 32 -10 -18 -9 56 18 -10 -33 9 31 -87 12 -4 -24 -25 -5 9 -7 7 -38 15 49 1 -27 2 14 -43 14 -22 -7 -18 53 7 -23 70 -53 -6 -76 24 -35 -11 -22 19 -10 -113 38 -1 15 -27 -21 31 -74 -39 9 2 53 23 -4 12 -16 -81 -32 -7 40 -37 10 3 -30 17 28 -12 -43 67 -13 -7 7 22 -1 32 15 -17 -21 -20 -7 19 57 14 -32 -14 28 39 69 40 40 33 -43 -40 -6 66 24 12 -11 -52 15 45 -10 25 -22 -16 -14 45 -5 -17 -69 101 -23 1 43 -28 -13 32 -32 27 81 11 -4 33 18 -49 45 49 -15 106 -33 -11 49 6 97 66 61 -3 2 -1 79 -36 -1 -4 25 -53 39 1 -7 10 -6 -77 -24 62 9 -23 76 -41 12 12 -17 50 -20 25 -6 -2 -13 -5 13 -5 -12 -16 21 -19 31 -86 36 -38 72 47 -31 -16 13 -64 -31 43 -3 -14 50 -10 70 -13 1 -22 -31 31 20 3 -4 -45 -31 9 18 -54 19 -57 6 16 28 0 -20 -12 16 21 -20 -20 19 11 -13 9 1 30 -2 -23 -29 -11 -5 -17 -53 -2 -33 -38 -33 43 5 0 -12 6 -33 33 13 -3 -22 -10 -5 11 -40 24 7 -32 34 -1 -60 -20 -28 -27 -9 -43 27 -25 -44 -8 -9 -8 -3 -8 -30 5 -1 27 9 -19 13 -14 -18 -28 67 36 19 -33 22 -4 48 18 78 42 55 2 38 30 14 59 22 74 4 34 -11 59 -90 -3 -35 44 30 40 -12 -41 -16 -23 -2 26 -1 6 -1 127 -39 66 16 -12 -41 18 57 85 -41 8 2 -5 25 -27 -42 12 -3 17 23 27 -35 7 40 -23 32 9 3 47 51 59 -35 -6 -6 33 78 23 61 83 38 -2 33 86 10 -13 60 -25 3 22 -15 -19 51 21 34 -21 2 54 43 -1 39 116 46 -13 2 13 61 -19 14 -32 6 35 31 24 15 -25 -12 63 -39 28 47 -20 6 11 -35 -24 15 2 -52 28 -38 85 2 -11 5 -8 34 55 -15 -51 -11 -30 -21 -19 20 12 25 34 -2 40 -8 -7 -5 26 -12 -12 76 50 -2 33 -21 -12 77 -31 -39 6 16 -4 79 -6 39 -16 125 4 19 41 -38 7 -4 -26 38 2 -15 0 4 8 1 40 -91 -15 35 2 -49 -44 58 5 -47 4 16 -44 -14 -9 -46 -7 -24 5 -28 9 -17 15 -45 -15 -9 -37 12 -10 2 10 47 -1 -23 8 20 -25 17 10 33 -42 -23 0 14 -7 -49 1 21 -22 28 -1 32 27 32 -28 6 35 23 38 48 -22 22 31 48 18 18 14 3 -35 24 -23 1 -33 26 -44 9 21 -2 -21 37 -41 -7 -5 35 9 24 -41 -5 17 -17 -25 -17 17 -18 11 12 -12 -33 -46 -6 -21 -21 -47 -19 14 38 -10 40 -61 11 -20 -46 -12 -82 4 -17 38 -32 8 38 -56 52 -8 38 34 19 15 126 98 -46 56 -6 124 127 87 35 31 -33 -30 -23 39 21 41 69 -128 -42 -12 49 -8 -33 62 -28 -69 71 -29 22 -19 24 -7 -16 13 36 0 62 -15 -25 8 0 40 13 57 12 17 23 -9 -42 5 -9 -3 67 -36 39 69 45 46 10 -14 18 73 15 39 61 49 -52 -53 11 0 3 35 -36 1 43 65 -3 4 -17 -62 21 72 9 86 -46 17 -50 69 4 4 -15 51 86 28 100 65 47 -23 -31 -15 -27 -43 -81 21 58 -12 56 -23 -3 33 15 115 -14 90 -8 118 37 62 80 56 2 102 -4 -4 -57 11 -5 -14 89 42 -80 5 18 -19 24 12 82 -81 -21 -73 7 12 32 -36 36 -84 5 27 83 -79 -30 36 -12 22 28 -7 0 42 6 12 66 -12 23 23 53 7 73 43 -11 -24 -30 127 26 3 30 -50 36 -10 6 10 12 -23 -45 -26 -1 62 16 108 8 22 -44 -12 -30 14 40 -8 -2 -6 27 -27 -12 -7 9 38 -34 -11 -22 -7 3 -14 -66 21 26 18 -28 -19 26 -46 -6 -41 -4 8 8 -39 -67 -27 -48 3 48 35 -24 10 -3 23 14 29 -30 -27 9 -24 -67 27 -18 -7 -9 -9 35 17 -36 9 24 60 -45 13 14 21 0 3 0 0 -21 -61 -11 1 0 51 0 -36 11 -1 17 32 -18 41 8 1 -35 -27 3 25 -45 -17 66 47 -40 46 9 10 24 -56 34 70 -12 116 7 69 -6 -2 27 88 -10 3 38 38 14 -52 30 -65 62 -28 34 16 83 -50 -43 -38 8 -8 26 -17 30 74 29 -25 7 -10 91 36 -24 -19 43 11 -41 24 -26 4 -47 60 -62 -52 -45 -22 30 37 56 -28 9 61 -7 -29 29 76 -53 -45 23 -18 22 3 1 20 9 104 11 35 -43 -51 -12 18 102 -40 -36 23 42 -61 12 -10 -29 9 10 47 -38 -12 -61 29 -2 -27 -11 24 -59 -9 42 11 45 -66 -43 -14 39 -77 -15 -4 -18 -77 4 19 34 -40 4 -34 38 23 75 -57 49 75 -21 57 42 -12 -5 -67 51 32 39 43 -71 -39 -37 51 -5 -1 -9 9 -93 12 -2 -11 -72 5 0 9 -17 54 16 -76 57 31 35 44 -11 63 -21 38 -8 17 -58 67 -75 -32 72 24 -99 -34 26 16 50 0 -23 15 -29 -31 -47 -38 13 7 6 29 -51 17 21 30 -8 -11 -3 29 -24 18 -14 -19 8 -26 3 35 48 4 13 0 39 30 -8 3 -7 -2 4 41 15 -4 -13 36 -4 38 -23 6 48 -26 -11 24 7 22 11 -11 -25 -21 14 -26 -1 32 -8 -14 -3 6 10 -2 19 -15 11 -39 -26 -13 15 -8 -47 29 -33 -29 -6 -12 27 16 30 16 -8 4 -27 72 -9 46 37 60 2 31 -31 13 90 48 12 20 -9 58 -66 -13 -5 71 -2 7 13 12 -48 -36 15 44 -29 -40 -9 13 -13 -10 -1 -96 40 96 9 46 -1 -26 -2 -7 -1 2 52 86 -113 -15 96 -9 4 23 46 41 -5 71 4 -19 73 54 122 -76 35 42 -61 23 75 18 23 85 -58 -111 90 41 58 -51 17 -21 10 -32 23 25 15 -49 5 -103 -11 -16 16 -3 -95 27 17 48 14 -58 -45 87 56 30 26 -21 41 13 -9 -12 -19 -89 49 48 -28 -1 20 11 -23 1 19 -47 -77 -6 -37 -11 -18 19 1 4 -36 14 -12 60 -33 -2 55 -3 5 22 -23 -8 -38 -17 24 -47 -32 -27 126 23 -89 -21 13 2 -8 -42 35 -36 -64 -76 53 -80 28 10 37 73 29 66 84 -16 -33 0 13 -39 0 -30 -56 -3 -18 -34 44 2 28 5 42 -34 -65 -10 31 -90 -17 -2 -6 58 -9 -36 -12 11 -7 -62 -8 -6 -38 45 -45 -13 -2 -51 -2 -67 -10 -18 -38 -12 -71 -24 17 24 63 -8 -39 8 -13 -5 -5 9 -8 13 -18 5 43 17 36 -69 13 6 -42 30 23 -43 35 40 -31 27 -21 -15 -21 13 -9 -10 35 11 -9 -7 23 -6 71 -24 -19 40 -19 4 17 34 -36 -9 -21 -49 -31 30 35 16 -24 -33 -9 -22 4 -63 74 50 43 22 57 -14 22 -21 -28 -53 -69 21 41 -35 6 12 1 -34 -4 -41 -17 -41 83 60 -51 -3 -82 -31 36 4 74 41 -6 65 -6 -2 -9 -35 -45 -20 5 -72 3 48 -36 -26 -50 24 -21 -8 62 -32 -21 28 49 -76 -7 -41 25 15 -65 22 23 -19 90 -30 -18 107 33 -11 -16 108 -5 17 -69 43 26 15 -1 13 -44 28 40 71 43 69 56 7 21 40 -10 -26 -8 61 12 55 -9 16 -31 -9 14 24 -1 3 -44 -39 -9 -23 58 72 127 94 82 60 53 20 -25 2 -32 -7 -24 -21 -8 48 72 -55 34 18 48 -12 10 -56 77 -39 -19 -5 22 49 -14 17 124 -18 27 10 -28 -4 103 17 67 57 12 76 -4 8 -6 -84 -5 18 25 -6 35 -23 32 47 -5 -27 12 -85 13 -2 -28 -64 -6 -57 5 7 36 -53 -86 -9 10 -14 -20 19 -44 -75 -62 -46 48 53 -50 17 -29 -19 -1 -9 56 -97 -9 -93 -47 22 -18 -68 11 -50 -25 12 -31 -37 -12 -57 127 25 2 -11 29 -22 18 16 -38 23 5 7 9 -14 -32 -34 -7 56 -4 -4 3 -4 -102 8 0 11 32 5 43 15 -40 -38 26 22 7 24 -45 -1 -35 -16 5 2 -8 2 -10 -9 1 -35 20 -15 -32 -18 -10 -12 -45 52 3 16 -9 25 -26 -1 -1 15 -2 48 34 3 -22 -39 -18 -1 -34 -23 7 23 15 30 2 8 27 24 24 -38 -26 8 16 15 -32 16 32 38 28 29 -32 44 46 -7 -46 -46 -82 16 -97 53 42 3 -21 122 -27 51 -7 -10 -6 36 48 -26 73 -60 -34 25 27 99 28 -17 66 84 -4 55 56 23 125 -62 11 11 50 46 12 34 55 9 -45 22 39 1 28 10 -8 -61 -4 44 10 -72 6 31 32 -46 11 -29 -26 -3 -54 -95 4 -28 90 -13 -41 -22 -53 60 -14 -15 -24 45 26 73 -26 -12 -18 50 -54 53 29 48 -37 -7 23 -89 44 89 17 14 39 3 33 107 3 0 -9 21 29 -72 -57 17 -37 36 31 -51 -25 -42 -6 82 -85 120 30 -14 42 -29 -24 23 -55 -4 23 -40 34 41 38 -19 46 34 11 -72 29 -48 67 3 118 16 6 -80 -14 15 23 -30 36 7 -6 -78 -23 -17 50 104 -49 41 -12 24 -124 -8 -23 -29 -61 59 55 -14 20 -41 22 8 56 1 31 83 -55 -82 -15 -30 -44 -10 13 52 -64 40 -29 -35 -19 10 -80 -10 -74 0 28 -24 21 -35 7 -13 -4 -2 15 -61 21 -25 -27 -12 23 10 -37 -5 -23 -10 -17 47 8 -22 -58 19 51 -9 1 -64 41 32 -34 -10 34 -45 44 32 -1 36 -37 -10 -8 -68 16 -115 28 9 -46 39 -37 1 64 33 7 23 15 7 54 -7 18 -26 -31 -20 -2 17 -19 8 30 -21 21 71 -3 1 -28 19 23 6 31 -30 17 -19 -21 -54 -34 -23 10 2 -16 0 -54 11 7 -10 -13 -18 -28 -66 -106 -33 -60 -39 -2 -109 59 -5 -17 -3 -127 -8 64 -77 -39 8 42 -58 86 -30 88 4 -74 30 -9 -11 47 -18 92 18 49 -48 -39 -40 40 53 71 32 9 -27 61 -7 -30 21 35 -27 48 9 100 -28 -33 -44 -5 -65 0 -56 -22 -73 38 -52 -10 64 -33 -11 -6 25 38 -25 56 -62 1 1 27 -66 47 30 -24 -48 56 66 -50 7 -17 75 -34 10 -30 30 -24 36 28 -27 -66 -44 -41 -12 -45 52 -20 -8 -29 43 34 9 27 -31 30 4 -26 15 -47 -60 -13 -34 -11 14 103 -40 10 -64 46 -93 -12 85 41 -20 -41 127 -31 60 7 45 49 -66 -47 -124 0 20 -2 29 34 103 53 -55 -39 -64 27 109 -20 -21 -2 -44 -19 8 9 -22 124 45 28 26 -8 -101 43 24 11 41 43 75 29 20 -21 -14 -22 -2 108 63 -85 47 -50 79 66 -13 -11 82 38 29 -13 23 2 -49 -2 -10 -15 -1 -47 36 -44 33 -17 14 6 15 -45 0 5 -11 22 -12 5 18 19 -30 24 26 -6 3 -29 -6 51 15 -5 13 -7 -15 2 2 9 -21 -17 -9 -54 -5 -28 45 12 -24 -25 32 33 -29 -13 -7 -14 28 -10 -2 8 -6 -9 1 24 0 -6 -5 -6 3 22 -60 35 -36 -20 3 9 34 -24 5 -11 -12 -6 -13 39 14 -19 -3 -4 0 -9 17 -34 -6 10 -9 23 13 14 -7 -14 101 114 -2 33 -23 33 79 9 -3 5 26 26 -48 -15 10 10 30 2 19 -37 66 19 -6 5 28 -31 -2 36 33 11 50 54 19 62 49 4 41 -68 51 18 14 -79 10 -6 -22 114 -5 10 42 26 -17 34 6 -68 -114 35 18 -47 16 -17 20 32 17 36 17 1 29 74 16 13 -7 -14 44 51 79 27 -48 -34 2 16 -44 36 -14 26 -57 33 77 81 17 14 10 -12 30 -14 24 -14 -59 1 32 -18 -39 42 -127 61 -8 21 2 -9 34 -81 -9 -49 43 12 -14 -12 -15 53 -34 -31 55 -57 31 22 -40 -34 44 -61 19 4 34 52 -128 77 -28 35 -44 -16 -67 13 -69 84 -28 9 21 -17 -25 7 15 45 -58 7 -12 -7 -3 2 -15 11 5 -43 -31 -2 28 72 -21 -36 -48 -14 -27 9 -43 -17 -11 -2 9 70 4 -14 63 -25 -36 -54 -26 -18 66 15 127 50 -60 -4 52 -41 9 -68 12 -3 16 -37 -20 -51 -42 -3 -20 16 -24 47 25 -27 27 14 -15 -11 -11 25 -46 -9 -17 -13 -30 22 -41 -3 5 46 36 30 31 14 -14 9 37 20 37 54 24 -13 3 34 7 17 15 3 -14 -13 -3 -44 60 -2 26 27 -9 -12 -32 -17 -110 19 -9 10 33 -13 -6 33 66 -5 -38 12 -8 -24 3 -15 26 -33 -15 -19 -6 26 -27 11 2 29 27 -21 1 -25 1 -64 -20 31 31 9 -3 83 -29 12 22 -20 43 -20 123 -32 -15 26 78 -85 -6 -18 -11 115 -17 1 -18 -37 -20 -60 -49 -55 -55 -16 5 -55 97 -37 -69 -104 -28 14 -52 -16 -87 60 -116 -104 -43 33 -49 38 -11 65 -70 -28 -17 22 -62 -100 -37 -26 2 -21 38 -57 44 -40 23 -20 -53 -65 -17 41 75 -66 2 23 29 0 106 47 -9 27 -69 -14 -58 56 21 65 28 47 16 -70 -11 43 88 -85 -28 73 -6 75 7 7 40 55 -9 -5 -19 -38 59 0 -38 17 -31 40 -17 -46 -85 -81 -15 38 49 -64 -45 -6 28 -60 23 12 31 6 -22 -15 -26 19 97 -28 121 16 25 -25 -18 -6 3 121 -11 -22 13 -34 -43 23 120 -81 -13 40 23 -50 -128 -78 12 -43 -46 -15 -61 72 13 -81 -82 -9 -35 -109 -48 44 -36 30 21 -23 -32 -4 -35 104 -5 9 59 39 -29 -86 53 -83 41 -50 25 25 1 -9 12 -37 10 -2 28 11 -2 -18 -46 12 2 -27 9 -6 22 -10 33 39 -17 2 35 15 -7 28 39 -47 14 13 -7 6 -23 -21 -30 20 -45 0 59 -36 -5 37 -4 4 -3 17 22 -101 -12 -1 13 13 40 9 23 10 -52 20 37 -13 29 21 -3 -28 -83 53 -2 -25 64 11 12 39 94 28 56 -24 20 -35 -13 -5 -33 10 17 -28 21 -12 8 63 18 20 14 -13 26 53 16 -96 45 25 11 41 23 -39 52 -12 24 17 -47 25 23 -33 -25 20 -40 -23 36 -22 6 45 55 122 -42 18 -57 -46 22 39 1 4 -27 -57 22 -11 -5 -66 -11 65 -3 85 -33 -31 4 -7 24 -35 -17 26 86 58 37 18 -117 4 23 -31 32 -14 26 4 7 -65 34 -15 -62 47 -76 17 -42 41 -63 3 -58 3 -3 3 -3 54 -24 21 36 -28 -9 -10 49 37 31 5 52 -28 87 -25 11 -19 -19 -59 -19 23 -42 46 -26 -8 -23 92 50 -51 66 22 9 60 27 -8 17 -16 6 -89 -22 8 -35 103 -58 -33 35 37 78 18 24 -64 -41 -53 -11 10 17 12 62 -5 -47 108 85 14 63 37 20 35 -39 29 23 73 13 -71 2 2 -26 22 -17 17 -2 22 1 28 9 -60 41 -31 10 23 -7 -38 22 82 9 36 46 -41 6 34 -119 -36 -60 -22 -3 13 42 -21 49 2 -2 -63 36 11 -28 3 19 26 17 -14 -17 37 4 5 -27 7 -21 1 -16 -27 29 0 39 2 -5 -8 36 32 1 7 -1 -11 -15 -47 40 25 -36 -61 16 14 -11 -12 0 -16 7 75 25 -24 0 5 48 -42 6 -54 4 -37 -4 -30 30 -51 17 -27 -10 26 -9 -26 24 18 10 30 1 -18 -36 29 -8 -11 -13 -31 -63 36 44 4 -4 30 23 -13 34 -32 -29 -12 37 -37 -22 -35 -25 -19 -39 -15 17 8 -11 44 6 39 17 -55 -15 -11 -58 -38 24 -22 -65 -10 12 -37 -1 -43 -30 -63 -12 6 -20 -79 42 -70 15 -30 -4 10 -55 20 -37 38 49 11 31 -33 -116 41 71 -10 -42 -51 -21 12 53 -20 29 -22 -14 92 65 10 -31 20 -37 -88 -18 -94 7 11 32 -12 46 33 -40 3 19 18 16 -8 51 40 26 -37 -1 4 -85 26 32 18 -7 -55 23 9 -12 95 -1 -88 13 -27 16 -19 -22 35 31 72 -21 -60 -65 -39 6 -40 23 -10 -36 50 21 -29 -33 -44 34 -16 2 27 -11 -35 11 -17 42 -6 26 40 7 1 -23 21 38 69 30 39 -41 33 13 33 23 -19 -70 -4 47 -47 -1 -7 -27 31 15 17 11 -60 -43 3 8 -80 -42 61 44 -36 17 7 19 3 -83 107 49 58 -17 5 5 -18 86 52 -19 14 -3 98 12 102 10 2 4 32 32 -19 30 -10 11 17 -30 -49 -4 54 14 66 -10 -18 48 -29 -30 28 96 -14 45 -14 -20 21 -30 43 -35 -23 -4 -1 11 -61 -10 -70 -21 63 1 -27 67 19 26 35 -7 -53 48 7 -54 -32 19 -9 17 -17 24 12 10 -28 -32 45 15 21 -36 4 15 -55 -83 25 -16 -32 -64 -20 1 -49 9 11 -39 -8 -5 12 -28 -21 33 -10 -23 1 -18 -21 -41 -20 25 -48 21 33 -13 13 20 38 65 18 18 11 0 -46 -20 -9 1 -29 -7 0 15 -25 -59 -8 -71 -30 41 49 11 -87 36 38 -11 10 -43 -42 35 -33 -26 29 127 14 40 13 19 -2 35 34 -48 100 31 45 -17 -20 15 26 -49 -42 15 47 -14 37 -47 -62 18 3 -62 -41 69 42 9 -29 -41 -8 -53 -40 -4 35 35 90 32 18 72 -74 1 -15 1 17 26 -1 -16 -32 123 -22 15 15 -21 80 12 39 -15 2 85 43 -27 8 20 67 49 -9 19 24 -69 10 9 9 85 3 10 -2 38 23 15 -10 -31 -18 15 -9 -40 -25 -1 -36 89 -50 17 -9 -5 47 72 58 -95 11 -28 8 92 50 -8 61 -50 98 19 -43 -41 9 2 0 -2 6 76 57 14 23 33 86 -1 46 23 0 84 -8 10 -54 -64 47 -46 -39 62 -4 -21 -25 -35 99 -112 80 1 -18 0 16 23 29 -31 61 11 88 -1 37 7 -41 -24 41 30 30 59 -2 -14 -22 21 4 19 -45 -11 -52 25 -22 21 -19 -5 15 92 -28 -66 42 -14 -54 22 10 51 -26 -32 7 -1 36 9 -15 -4 -9 12 11 -25 41 7 18 30 3 27 -22 -4 -39 -40 0 -39 8 -37 3 -19 -4 -64 23 -17 9 -8 -21 -11 -46 3 44 0 -68 16 -33 -1 57 4 -47 43 43 -2 -17 -83 7 38 -20 38 51 22 -30 -29 22 6 22 37 59 -6 -38 -4 58 5 54 -1 -28 16 29 78 27 -32 32 29 63 15 -8 43 -57 15 -17 10 -50 40 9 -4 -22 -2 -26 -59 18 14 63 12 -56 -20 52 -95 -5 -30 27 9 -37 73 3 2 -33 -74 -16 47 -6 44 -10 -37 -48 -29 -12 38 -55 25 -18 3 67 8 6 -29 21 -9 27 -40 0 42 9 34 0 13 17 8 29 9 1 -71 -75 -21 -30 10 6 60 24 -53 1 -58 1 -15 23 -34 -32 -9 56 -84 12 -28 30 -37 -41 -44 45 -25 17 -51 -41 25 38 -10 -16 34 57 -74 -7 3 2 9 121 50 15 -46 57 -21 -12 -86 -21 -17 113 -74 18 -43 -12 -45 50 33 54 -25 -80 40 -37 -38 4 61 98 -73 53 2 28 48 27 25 -32 25 28 -8 24 -32 15 13 115 -43 45 63 67 34 -37 -48 36 -22 26 -75 5 -69 11 42 -94 15 42 25 14 -13 -22 -1 32 -27 49 -3 -1 8 2 -67 82 12 -5 -25 -73 -8 39 76 70 -2 -4 -21 -24 -6 -52 22 2 -2 -63 -13 3 0 -16 46 -16 13 0 -17 -11 -2 -33 10 7 -8 -42 15 -38 -40 9 15 -26 -30 -5 -8 2 28 -24 -11 -4 -2 -6 -19 80 29 37 49 1 39 23 35 1 36 0 19 -4 -2 38 -11 34 -52 10 2 -78 19 -21 7 -23 -17 20 -21 42 -51 22 5 -1 52 20 -13 1 -4 37 -12 -31 -12 58 -30 12 18 20 -59 5 67 17 -2 -62 -45 7 -4 -8 2 1 2 -9 -11 9 -19 3 -2 -8 -5 14 0 6 -19 6 17 -10 5 -1 10 0 7 17 -6 -6 5 -3 -6 6 18 -1 -2 3 -16 12 2 4 7 -5 7 8 -2 -19 4 0 -17 -6 12 -10 11 -9 5 -7 -15 7 0 1 -17 10 21 17 8 -13 -9 8 -15 -4 -8 0 -3 -16 -16 -8 19 2 4 10 -14 -5 -11 -9 6 -9 -9 1 -11 -15 2 14 -12 24 -5 13 21 -2 16 -1 29 -1 16 40 -10 9 -7 11 -18 -12 3 10 14 -6 -10 2 0 16 -8 0 6 21 2 -14 -8 2 9 -13 0 8 -9 1 37 -29 5 -33 4 -24 6 -14 2 -3 8 -9 15 -7 -4 13 16 19 4 -8 -16 14 13 2 13 18 10 -6 10 -3 -2 4 -1 3 8 14 -10 10 13 -7 2 3 39 9 11 -7 -32 -5 8 3 5 36 6 -1 27 -1 23 4 0 -2 -6 14 -10 8 4 13 7 -22 12 9 10 -2 20 -13 -4 13 -8 -3 5 -8 -14 -8 -4 3 1 -9 11 11 20 4 10 -16 -6 -7 -4 -6 2 -18 -7 -20 -4 -25 4 0 0 -1 -4 1 -14 15 5 0 -8 2 -12 -2 -16 -7 -9 7 15 2 6 -15 1 0 -11 9 1 16 -26 9 -2 10 -12 -8 0 2 1 10 9 13 6 -6 5 -13 -10 -13 11 5 13 13 13 7 15 -10 -19 -26 -24 -22 -24 -3 1 -8 -30 35 -4 -21 6 18 13 2 17 -9 -28 -40 -7 -12 16 -6 -8 0 -8 14 -27 6 -14 -12 19 1 3 7 20 -17 21 -14 12 -4 -7 -22 -27 -18 44 18 8 14 13 -34 1 -20 -6 -11 -15 -23 20 -15 4 1 -5 16 -11 -9 9 -21 -27 -28 27 4 -3 0 -23 6 6 6 3 -12 3 -10 11 -15 40 15 -11 4 37 -12 3 3 -17 -42 7 -24 13 6 2 -43 19 -14 -4 -15 16 24 -46 9 2 10 -12 -18 -51 6 -16 62 -4 21 4 21 25 18 55 -8 -8 7 -31 -1 55 -13 14 -7 3 -31 4 11 -15 -21 9 -20 44 -1 11 -3 2 12 13 38 28 40 63 25 16 28 23 -17 18 29 -41 21 -38 7 -6 35 8 -40 22 -10 -3 10 17 29 -30 -14 -50 35 11 -14 13 -4 -46 38 3 24 24 -21 40 11 12 39 -30 10 -10 0 -7 -31 0 10 27 9 11 -5 -37 -13 -7 -17 -32 17 26 -13 -2 15 5 3 -8 6 2 -17 6 25 -10 -13 -24 -8 30 41 10 -17 -19 -10 -6 10 2 -35 -13 -7 17 -8 -11 -19 4 3 12 -12 25 -6 3 23 5 -18 22 0 -1 23 1 11 -3 -3 -16 43 10 -25 6 6 22 -9 -10 3 -14 -6 -2 -13 5 21 -2 8 -3 -2 -3 -14 10 12 12 1 10 23 17 29 -17 2 -33 39 -5 -4 -11 -31 -28 18 1 -2 -16 27 5 36 -7 13 -2 -54 -10 2 26 -19 -18 -3 -31 34 -22 -26 12 -15 23 19 13 4 23 -5 13 -45 -7 -1 -20 -31 -35 -31 28 -12 33 0 11 -58 29 6 -19 8 -13 -36 10 -5 33 44 30 19 22 13 -2 -37 -16 47 -1 39 34 -20 -30 -15 1 -1 -6 -55 0 -20 -7 -2 31 -8 8 -50 1 -8 24 -2 -9 5 21 -3 -64 48 -48 -40 -12 12 -33 -11 12 38 37 -6 -21 24 -6 -74 -94 57 -12 12 -7 -18 0 32 -1 -12 64 26 -18 2 -17 -31 66 -9 -7 -24 -22 42 -44 32 -23 0 -13 -7 46 -51 14 -7 -17 7 16 -3 10 41 37 24 -5 -7 -18 -52 -39 10 29 -34 40 -31 -76 -50 -22 55 -8 -61 -4 26 -4 28 -20 -6 28 -22 -106 -25 -26 -32 -35 27 -10 0 38 -53 4 -4 -38 -3 0 -8 -30 9 2 34 18 -14 -11 0 20 -7 2 4 -16 -42 31 -3 67 3 22 38 24 -16 -7 13 22 -9 1 -1 5 -39 -39 -5 18 -27 18 -6 -28 -15 8 30 8 -9 -46 -12 10 -18 -14 -7 34 3 21 -20 20 5 13 18 31 -10 25 -23 -10 22 -12 1 16 29 21 9 -2 3 -26 -39 1 -5 16 14 -21 -6 4 15 5 -6 9 7 6 5 -7 18 -12 31 -5 -39 -11 41 23 -1 64 34 -10 -3 -7 37 -8 -8 -19 -5 18 8 3 49 -57 48 12 -16 -23 0 43 -35 32 -33 -18 21 -68 24 -5 28 -8 14 -15 34 -14 19 -45 -28 -29 -8 -2 29 -49 -29 -7 38 -22 -28 37 -27 -26 -43 62 -11 16 21 6 -5 -13 -14 21 26 23 42 23 -7 -13 -1 20 -34 -6 -7 28 -27 13 -27 -32 -4 -33 -6 -62 11 -8 25 -11 -3 -48 -31 -65 -13 20 -8 -4 -3 -12 58 9 48 19 91 1 -56 14 24 9 -3 -27 15 -6 -4 -53 -50 1 -13 -8 25 -29 9 -9 -1 42 2 77 -31 -40 -16 49 -6 17 -7 39 55 47 45 43 8 -13 23 -30 -25 -52 73 8 21 1 13 25 -45 17 61 -22 -84 -39 -18 -3 -35 1 -15 -66 2 11 46 -41 -60 -23 -42 114 -46 -6 54 0 8 -20 44 -13 8 87 36 -25 -72 -49 4 -9 -10 27 -20 39 6 -13 0 -46 -27 -24 51 -18 4 9 -32 -14 5 11 8 -1 44 26 -34 34 -30 -21 19 -5 32 6 -15 -24 25 4 4 10 -30 -9 -52 6 10 1 33 26 -13 18 -33 29 -3 2 25 -17 0 -31 -25 -25 9 12 36 -6 -11 -30 -4 11 -66 -18 10 -45 -46 -15 2 -9 30 14 -13 35 -51 4 -10 -36 -33 -12 21 30 -14 -26 -19 34 -14 39 -47 1 14 -1 24 19 26 -13 18 39 6 -34 5 22 13 73 -20 27 -74 10 -43 -4 9 -39 -21 7 50 25 16 -61 47 0 9 -7 13 -23 -31 18 -14 26 3 -36 -16 12 30 -27 33 -23 -37 -18 12 -40 -10 0 4 -4 -8 -2 4 4 20 -6 -24 18 21 -28 10 53 16 15 30 36 83 3 40 -8 -29 61 -15 -36 -15 5 -18 -34 -4 -24 0 23 -56 6 7 -13 30 -13 14 -19 13 -11 3 33 -33 -33 -31 -35 28 3 -25 -48 -9 -39 11 47 52 -17 -110 33 -52 24 -43 -15 -23 -66 27 29 -13 -3 -26 19 -88 58 44 -2 -11 29 39 32 66 59 33 -48 17 -3 -8 1 -16 11 1 9 16 101 26 37 -13 -30 -14 -11 -2 -15 15 15 -18 -52 -19 30 66 33 -126 25 28 24 -27 37 -35 -42 -33 -117 12 -41 5 25 -10 75 -40 14 -25 19 21 16 46 -42 -35 -49 66 -10 16 5 21 -10 -12 20 -51 -12 -26 16 -19 -29 -12 5 -32 -18 -44 -30 -36 -52 -36 -9 -28 -57 50 -14 -9 -19 -8 -43 18 -1 19 8 22 10 0 38 21 0 0 -4 -39 -11 -2 -8 21 10 15 -3 18 21 10 4 9 -42 15 -34 -4 0 -7 -18 -15 -28 15 -13 8 6 -102 -25 -1 13 1 -12 -33 39 4 -62 -29 40 -38 -12 9 -20 -31 -25 -12 27 10 12 -2 11 -10 40 -44 14 21 -10 19 4 5 -27 -2 -1 10 -23 -3 17 44 30 -17 15 47 56 -16 28 60 -22 3 -21 18 -38 -46 19 8 -25 -19 -23 -8 -17 77 -18 -1 -1 23 -18 -24 13 -53 -38 39 32 25 1 41 -20 29 51 21 17 -42 50 -12 -9 30 11 15 -11 25 -3 -17 -14 -8 17 20 -4 56 5 55 -12 -7 -34 28 9 -34 -7 -14 -7 34 -19 27 20 23 -27 -52 10 10 10 -18 2 2 -17 -12 31 8 35 45 34 13 29 34 -40 -13 3 -35 32 -1 33 1 16 -64 18 70 22 -14 108 70 -17 -11 -13 5 -51 -47 59 5 -17 -79 -3 64 0 19 55 -31 -31 -57 -14 -63 56 14 32 25 23 45 -47 -19 9 3 -37 -49 -15 -21 -73 26 14 18 -99 29 22 27 21 0 45 71 20 29 31 13 53 69 45 19 24 77 13 -7 19 -15 21 74 -4 23 18 -17 14 11 80 11 -13 36 -31 -15 20 -16 12 -34 66 57 -21 -24 0 -14 29 -27 18 44 -49 -20 -16 -44 6 -29 35 -10 29 27 50 17 -6 -27 2 49 -9 45 3 -34 3 -22 -7 17 -2 -17 -1 19 16 -40 19 -26 -4 28 -2 11 26 17 -22 -11 1 -15 11 12 4 -2 -32 13 47 -25 -2 -38 10 -15 38 75 24 -48 29 -8 10 -4 26 53 13 -49 -20 27 27 -22 -21 -2 36 22 6 -13 17 7 6 5 -2 35 19 -50 16 -39 15 -40 -21 -25 7 38 50 -117 -8 91 -9 59 93 11 -89 108 20 -7 -34 -54 -32 101 -84 57 37 -10 -60 88 -126 -6 -33 127 -61 -87 126 -80 -84 127 -107 85 -49 -21 22 -5 85 -85 60 -54 101 -120 -40 32 -77 14 -124 9 -25 -91 -118 -37 -24 72 -41 127 109 127 72 54 -36 71 126 38 -24 2 -12 -48 27 -22 1 66 -107 -73 54 -29 -58 -72 -5 31 9 126 4 102 -99 49 127 12 46 1 -72 -34 -11 -96 -68 8 98 -23 -35 -74 -91 -93 3 -128 -128 121 -8 116 56 -30 17 124 33 -76 -46 -95 42 -93 49 47 29 -34 -45 -3 -33 -125 47 -68 -4 44 -8 -94 -42 -4 7 -91 -66 78 -95 120 -32 -12 22 -100 10 8 -115 82 -38 127 -53 80 12 86 -28 -44 -73 89 -74 29 87 -117 -98 -44 -90 16 98 -120 -88 77 124 15 -121 -124 -99 -58 -123 68 -128 70 67 -32 23 31 -41 -128 -63 -114 -18 -64 30 -81 5 -72 -17 -64 -127 16 53 34 -122 -64 -51 45 -116 -66 19 -127 -123 124 53 68 0 -75 -35 10 0 18 67 -51 36 46 62 127 -6 58 127 20 -16 112 75 -39 3 -91 -30 59 -1 25 -32 20 -48 59 -12 17 55 127 54 -1 45 127 20 -126 -35 81 56 44 -32 59 -16 65 -3 37 -90 61 -42 74 68 33 70 32 -95 64 4 -95 -89 -56 72 54 103 4 -23 82 -60 -9 -33 -41 50 -44 -56 -100 -79 -17 -95 -36 74 -32 31 -62 -5 -17 -72 -12 -108 81 107 80 -34 -127 6 -36 -33 9 -68 30 116 10 30 125 103 35 16 -7 -127 -21 66 51 57 -70 125 -2 126 -20 -65 61 -12 45 50 -18 8 18 20 -96 -46 106 -39 -87 -47 127 -128 30 -4 122 1 34 99 119 -63 -53 -54 -127 11 -106 127 -41 8 11 11 57 -37 126 -54 122 -99 63 8 -90 -49 21 73 -69 33 -14 -103 -85 77 17 -69 33 -45 10 14 -39 99 123 19 -21 -98 -32 87 79 -34 127 93 -45 117 -114 -1 -7 8 112 36 -60 127 -12 -8 -27 -6 -23 -55 28 21 22 75 -116 38 -125 -100 -75 -108 -35 -127 33 95 -128 -57 88 -108 127 56 20 22 4 -89 -126 51 96 101 -128 0 96 37 127 116 -99 25 125 124 111 108 80 127 124 -89 -63 -76 -73 -16 13 -43 -87 0 127 40 -55 66 123 5 88 -34 -21 1 -11 -33 70 -53 3 -16 15 67 51 36 24 -21 25 -59 -96 126 34 -22 -48 -17 3 -42 -1 -15 -94 24 -109 28 24 -91 -127 -4 73 104 -33 90 10 -5 2 20 26 -36 64 38 55 -37 -24 -91 92 -100 -59 8 126 -5 10 -51 -82 -45 -69 -5 -28 -43 78 -105 -32 -5 -40 -116 -82 -104 61 18 99 120 74 49 -23 -30 -74 -60 -43 -87 24 -29 127 2 15 -76 -124 -118 -73 -37 18 86 -107 119 -72 -38 -83 -94 21 5 -12 27 57 43 26 -13 -97 -54 84 127 -51 36 -121 -128 -45 58 -89 -15 -12 122 -85 -64 -4 -127 51 -11 19 8 -112 -41 69 42 13 127 122 -37 -60 19 20 -42 10 19 44 -124 43 19 25 38 69 -34 -121 -16 -50 -72 124 -32 -38 26 -17 4 -37 -58 -15 -20 -120 -87 -23 43 79 -40 -35 -1 54 -9 76 -2 125 -25 117 -5 51 17 -65 -15 21 86 100 -22 -62 -35 105 3 -88 -23 127 -102 -114 -8 19 77 53 86 65 99 -78 72 -27 -104 -14 -18 127 -44 -60 50 81 1 34 95 -111 -68 -127 -46 55 93 -93 -6 53 -87 9 -67 125 -18 94 -126 95 89 24 9 108 -34 -127 36 -96 26 18 -81 -127 55 -56 -7 -95 18 -103 -107 -39 -62 -97 33 -83 -10 -127 -3 -18 85 22 -128 -96 -36 -81 37 125 -119 -124 -67 -15 -71 -100 -7 -84 -23 -78 125 -65 -27 -123 55 65 40 -10 20 35 -97 -37 10 125 -72 67 74 34 -5 -50 -109 0 75 -70 91 -29 44 80 -4 -6 42 0 -69 -52 -11 26 -28 101 74 -51 14 -29 126 -39 70 32 -4 24 92 -4 28 1 -45 74 -91 -15 36 -7 -85 51 5 -128 8 62 58 45 -43 19 103 -20 2 -45 78 -69 15 -4 42 127 116 -78 -2 -30 -128 25 -53 1 -116 51 -40 4 63 -71 72 38 -74 -66 29 -58 123 0 52 107 -24 -78 -8 -1 47 -97 -92 61 -23 43 120 31 81 -43 123 -19 -57 -13 -128 -34 -24 -107 -43 -44 88 -29 127 -91 -125 111 45 64 112 -128 -52 121 25 -117 -117 -124 -72 123 -48 -30 -97 31 -20 71 54 9 63 117 62 33 -105 -126 5 27 127 59 50 -52 -39 0 14 127 -68 -27 79 -67 -87 -88 -66 40 -90 -126 -73 50 127 79 -113 8 -127 52 -23 -114 -124 7 -9 -40 -13 72 127 -110 90 -125 63 -121 -12 -127 23 -128 -36 -122 -112 -16 -18 53 -105 -127 115 -121 26 14 2 -39 70 115 124 51 -92 -56 -16 40 -73 -19 39 41 56 -69 40 93 1 -60 51 -103 21 -117 -70 -117 -117 -96 65 -49 48 121 -100 -127 -22 8 -51 -127 -89 97 -128 38 120 -8 -13 44 40 0 -63 -55 -50 123 127 70 60 124 125 -4 -128 -103 1 127 5 64 112 13 -128 -112 -57 127 -35 10 59 -58 24 10 116 39 35 92 -93 19 -46 94 -16 127 123 -1 -47 66 65 59 -124 41 -40 25 -56 34 -14 105 -41 79 33 -17 -56 105 -53 89 5 6 55 -82 -35 -8 97 29 -53 -37 32 -19 97 39 -22 20 4 114 30 102 -71 -86 -34 -38 -43 -47 -15 63 119 -41 -40 24 -17 62 25 115 -38 37 -6 5 59 120 105 -8 -72 -109 -121 57 53 -84 5 106 17 -43 100 -125 37 -30 -62 -36 -87 -13 33 12 -17 55 4 35 76 -43 55 -74 30 20 -47 -125 65 36 127 -75 87 3 29 116 -120 0 -62 -126 -84 -17 -124 -109 100 -121 -20 -38 123 93 7 -122 16 77 -113 -101 -63 -79 47 120 -107 49 -77 -116 56 69 -127 5 34 -99 -74 127 25 -32 23 -125 41 -75 -127 11 -114 -20 44 -111 -111 11 124 -127 101 -128 68 -67 106 40 -122 -20 -11 -41 -48 28 -22 -73 -16 18 -32 -32 12 -85 -3 38 64 -38 -119 108 123 -69 121 57 38 -34 55 109 -128 -42 -104 68 95 -60 -57 127 -97 47 -3 -127 127 -103 91 -5 71 -41 127 60 -50 9 -6 -121 -27 7 60 -8 90 -22 -32 127 -53 -77 -114 2 -79 98 7 53 -32 -116 -42 -70 12 126 35 -39 -75 -103 86 31 118 -123 -29 -59 55 116 55 113 -53 28 -85 114 -124 -95 -42 -128 68 106 -44 93 -31 -125 -44 -106 -128 -84 -83 -127 109 -119 104 9 -70 64 -20 -10 37 102 -33 34 -25 39 63 -40 53 52 118 18 15 120 77 127 -127 110 83 22 62 127 -64 -55 -20 -75 -33 -23 -106 -95 64 115 -6 -27 90 -54 126 125 -85 37 7 72 -41 52 109 55 -38 116 -60 -60 -73 118 -3 -38 71 127 -6 -78 120 60 -49 109 -47 91 -17 -128 -14 51 4 124 33 126 18 69 23 12 24 120 -79 -106 -6 87 15 -35 -91 -56 90 -67 -13 -32 42 -31 47 -17 -125 -128 10 -18 53 -96 -46 -122 -50 -17 22 -57 -69 -60 0 94 8 -125 31 83 -75 50 -15 -42 32 -111 -127 30 -46 -127 -117 -70 60 126 126 -128 -9 -88 -52 72 -47 100 86 -6 -126 40 -38 -25 86 -37 -117 1 16 -125 62 21 124 -31 99 -19 53 19 -18 56 -100 -11 36 6 -24 -1 -89 -40 99 -128 113 -82 -124 -66 -37 15 -43 77 22 104 -29 -98 -34 80 25 -124 -124 19 4 127 -128 -125 -70 -127 123 -74 -128 -7 -16 58 -89 122 127 12 93 -98 104 123 -5 -127 -99 -85 127 127 -127 -75 15 117 43 16 -109 51 -49 -128 -113 23 -16 -97 -127 89 126 -70 118 -87 -109 14 -79 -36 87 -46 8 -79 5 26 119 121 28 -29 127 -37 49 97 127 17 -126 114 127 -77 28 2 -120 -55 84 71 -103 53 27 7 -81 72 -60 119 54 46 127 126 127 -38 -58 87 -34 106 -12 80 86 10 -93 -77 -82 -83 118 -59 42 -12 5 35 -91 -128 -88 45 -126 110 19 59 -101 127 36 -18 34 -20 -26 127 -46 -125 59 -18 -88 -42 18 125 -119 79 -121 -80 10 -99 36 74 5 44 -49 -108 -46 -61 4 12 -34 58 -77 38 8 59 -8 -12 87 86 -102 -38 -25 -2 14 -40 -17 68 55 75 37 127 19 -19 0 92 120 24 -106 50 -106 -11 -19 -49 127 -62 -94 -128 61 -104 -61 25 -71 -16 98 -57 98 121 -22 83 120 2 46 -123 125 -2 -12 76 -63 -41 125 87 103 127 14 -41 20 -91 -127 -102 -3 85 -127 19 -128 -29 -103 76 89 -125 25 -86 125 -79 -95 -84 79 -60 17 127 -127 -26 -128 -53 -122 -64 50 127 -11 -42 7 104 -9 62 -109 -122 127 59 -11 39 101 53 122 18 5 5 -1 -109 43 -128 43 -128 -114 127 -127 -26 -121 -84 -121 49 -105 0 -102 -127 -106 8 67 60 -128 127 118 -15 -39 -128 19 11 26 -68 -116 -121 -38 0 125 -101 15 -13 -65 -18 -67 127 -22 27 17 -120 11 127 -128 -49 101 58 43 11 -49 127 -55 127 44 70 -128 -126 34 15 89 -38 102 70 28 98 127 27 122 53 -12 -88 -24 -56 54 -34 -64 -50 -111 -39 -86 19 -100 -127 -90 127 -121 -1 29 -106 -126 42 46 -34 -89 -57 62 125 43 -7 -62 -122 3 7 51 -10 22 58 -127 -128 -105 52 -64 -87 127 -31 25 84 61 36 121 -7 42 -56 -86 82 -21 -126 91 47 65 -48 -21 -124 127 85 -71 -47 34 0 -101 9 73 124 87 13 32 32 -49 -107 -86 -26 28 -70 -101 -42 13 127 65 91 25 -16 -39 108 127 -58 30 -39 -11 1 51 -122 17 37 -127 -67 17 -35 127 -55 70 -27 66 -13 34 -94 10 -12 85 -38 5 127 -10 -124 34 -64 -54 -62 -40 -10 -33 83 9 -7 -97 -95 -33 49 -88 14 48 44 108 -66 3 5 119 24 -125 9 84 32 -51 127 82 -59 -69 -125 -122 99 -54 -22 -21 127 -62 -60 57 -47 36 -43 -122 -34 -13 -6 75 11 88 60 104 -70 -20 -19 -126 -57 -125 -104 -28 -41 -31 69 -66 71 -76 -15 -40 119 3 -8 -88 112 -33 49 -94 127 -112 59 107 1 127 -3 114 13 -68 126 126 -36 -112 -128 -127 87 -128 -74 -126 109 -53 18 -64 106 -10 6 -104 -81 108 -55 -98 -104 -30 95 125 -75 75 -93 126 -100 -114 86 -68 43 -29 -125 42 110 120 -53 127 127 6 -128 7 32 37 -124 122 -126 36 127 -73 121 -121 77 -14 39 97 127 16 -13 -14 117 -34 -43 -122 56 -77 -98 127 -13 -102 -96 123 -124 -49 10 42 -10 8 -11 -103 -90 -64 127 -77 32 -128 72 -89 -128 70 127 109 103 109 52 -86 110 -49 56 -127 -54 -27 -104 83 85 -50 127 108 76 -101 50 100 -126 -128 127 -66 -29 14 26 20 23 81 -18 55 -33 -26 -78 -43 -46 22 -33 23 -22 104 -127 33 -128 -60 82 126 98 -27 51 74 21 33 28 75 96 30 -124 -84 -33 38 -102 -120 36 49 -114 -38 22 -38 83 -104 127 -114 23 79 -8 -127 -24 -95 -3 13 -75 91 -128 43 -7 -29 5 16 -89 -101 -122 -9 127 24 -60 -37 31 125 127 11 -99 -35 -127 -55 -51 -126 -4 127 74 15 14 60 89 98 74 55 4 10 125 64 -127 123 -128 101 -128 -54 -45 -109 105 127 125 -43 -128 -128 110 75 -127 -106 -127 -52 107 74 -59 108 -1 58 -19 -128 11 3 -63 -12 -62 11 -26 123 -111 -128 16 5 124 55 -47 52 63 -56 125 -118 56 -127 -96 -124 -126 -126 -128 -17 -12 -125 -87 9 94 -127 15 127 31 40 126 -21 -83 -121 -13 123 -107 -113 -128 -97 -56 -119 18 -14 -17 -45 127 -127 66 40 -82 -107 46 126 28 14 94 -128 123 -23 -128 19 -36 43 121 -10 106 -72 -122 -108 -127 117 -50 53 -124 -128 -127 40 122 79 -107 127 123 -87 -126 8 24 32 -39 -124 -81 -37 55 75 -123 -68 -1 0 111 -64 -124 -122 -123 64 -11 127 105 72 87 126 125 86 127 -93 -91 121 -110 31 79 -58 -3 118 -67 -86 -126 -108 32 -120 -110 106 -118 -126 121 -9 127 102 -39 -88 -119 -115 19 126 127 127 -9 86 54 43 43 127 -122 96 57 -63 3 38 -74 -20 -112 33 25 -39 -12 5 80 -6 -64 88 95 57 70 122 127 61 41 91 122 125 14 3 30 -79 19 7 51 127 21 53 -12 -126 10 -81 -100 -33 10 51 55 -114 -90 -46 88 -16 14 43 -5 66 100 119 -122 -52 126 -47 62 -122 120 -101 42 23 71 113 96 -15 109 -77 -127 -37 63 -91 46 127 127 101 127 39 -71 -124 -121 -79 114 -40 65 -52 -128 -20 125 -23 52 47 32 -69 121 108 127 124 -14 -30 -3 45 -127 69 -94 -32 119 -127 -37 -28 33 48 -128 -114 -5 -49 -57 92 -113 26 -10 -48 7 -118 44 3 -72 -126 -128 -26 122 -122 -117 -128 62 12 -119 -2 55 13 21 -127 92 -1 -85 -99 112 -120 68 -128 -124 12 68 127 -126 -12 98 -97 71 -126 121 -8 95 126 124 118 -122 -75 -40 -42 -117 -9 -32 -55 124 -20 17 74 127 -67 16 -68 69 -101 -116 -19 -39 127 -24 -122 -66 53 -120 -119 -123 124 44 9 117 -121 -127 -77 -127 120 -84 -39 -101 -4 -128 -75 -72 123 30 126 28 113 55 19 46 -55 72 -61 -128 6 56 123 -127 -43 -30 -56 -86 76 95 85 -80 121 20 127 105 -106 11 16 121 90 -4 -24 -121 125 -19 -126 127 -32 118 -123 21 127 -85 -114 85 -36 81 -58 -114 -2 73 123 124 -103 -124 -65 127 5 127 89 127 45 -122 125 -90 127 64 -51 -122 100 124 111 -91 127 31 -75 -17 42 -1 99 -23 -125 2 -1 92 65 -43 102 -42 86 125 41 -87 120 112 126 118 97 24 -127 127 -37 -121 -51 -48 -120 50 -57 14 -128 -75 -83 4 4 52 15 78 -110 -23 2 17 -10 -77 -12 97 -88 -20 28 61 7 -52 127 127 -60 12 111 122 -52 -47 -21 40 -12 127 -7 5 -44 36 125 125 127 127 125 126 -65 -38 127 -54 124 -2 21 -95 -106 61 46 -74 29 127 12 103 127 70 -118 -74 10 126 -36 108 25 4 -109 96 -70 -124 -94 -126 -9 -43 -44 -34 104 36 -29 7 -125 -12 121 -5 -5 -8 -123 -57 17 -18 -81 0 91 -125 27 -58 114 -65 123 30 100 -111 -103 -124 61 54 -122 33 37 75 46 52 -90 101 -19 -74 122 127 -50 106 127 124 48 121 127 64 -27 18 -42 127 -68 -121 113 31 -15 -124 -55 -17 61 -115 -43 122 -125 53 -81 -2 94 2 -41 117 -128 -72 10 -24 102 -33 77 5 123 -128 76 122 -5 -72 126 17 20 -21 28 126 116 -2 58 -87 -91 127 -8 127 26 -23 -127 89 -3 -128 -57 27 -30 18 77 -19 120 -54 115 -124 -32 -128 -26 -121 31 28 -22 -17 -23 85 10 -89 -21 -59 83 127 127 54 -27 122 -97 -126 22 82 -9 57 -63 -95 -122 52 -31 13 -36 12 17 63 -31 114 35 -44 -19 123 -4 83 105 34 -124 102 -35 68 58 -128 105 -116 -40 21 16 64 102 97 -27 95 -107 -117 -43 65 -119 78 62 -93 63 10 -50 -34 49 104 47 -118 -63 -122 31 127 -79 -35 -56 32 17 11 -107 -64 -34 -75 -18 33 28 -74 -60 126 -57 20 -101 16 -1 72 -103 -59 6 88 47 -127 30 -86 26 93 -24 20 -27 52 4 -116 -47 -63 -8 -82 62 8 -49 -55 -39 93 119 40 -55 -122 81 -44 0 -88 124 92 -68 -65 -108 90 25 121 124 -35 -120 107 127 39 4 -118 -8 2 80 -5 100 -21 27 42 13 -48 -128 -106 83 127 93 37 19 -22 -123 -47 89 119 103 110 96 -67 -61 16 95 -89 43 96 119 -127 127 -128 -91 -121 127 77 -85 -69 -19 -128 82 62 -49 10 -114 -128 -41 115 13 127 -128 89 45 127 -17 -18 127 121 116 -113 15 -11 -28 38 3 -128 -97 -126 -112 92 -54 33 -11 -128 -110 -73 78 114 -13 54 127 8 -33 5 -126 126 -13 119 85 -13 102 -127 50 -96 34 -87 126 -35 87 -121 -27 -31 121 38 -78 127 15 53 119 -119 30 -9 -122 127 126 -101 -128 -10 -110 96 -59 -113 127 98 53 78 95 -116 9 -18 -128 -66 113 -39 6 110 -128 61 127 -124 -75 -87 126 -125 -119 -115 -127 -127 127 124 -128 23 -124 -99 116 47 -32 44 47 81 124 116 -42 12 -81 127 127 62 27 -127 -111 -57 -82 -57 127 98 9 -25 -117 -98 66 108 -15 -50 -41 33 109 18 127 104 -77 -32 -45 78 40 -85 -18 126 105 -12 -27 -126 118 -40 113 -81 127 -123 -128 -45 57 -125 -12 59 103 20 125 -93 -83 73 -39 -86 -71 126 -27 123 -10 -91 127 100 124 14 63 -30 -68 -51 0 124 11 -126 -3 68 -110 -72 -27 34 107 -127 49 -127 -60 -58 -12 127 13 37 19 127 -21 126 53 11 75 33 -128 -128 -78 51 102 -11 -23 -23 -85 -27 63 25 -20 1 -97 125 -99 -52 -128 44 51 -50 -73 -1 27 104 -8 19 -50 -8 -3 -40 -69 115 -43 -105 -24 22 2 69 27 30 23 27 -120 -124 -29 -113 80 -48 39 56 -116 -119 -85 62 -14 -89 127 -3 103 -33 -121 -107 120 47 -35 -4 10 49 -109 -83 -87 121 -116 4 -69 -66 -85 127 -128 43 61 43 -110 -110 -29 -127 -121 -11 -115 -80 -124 124 -68 73 127 -67 -101 -101 46 43 -58 -52 127 36 -24 84 123 103 35 -17 -87 -128 22 -20 78 -63 36 41 76 -65 22 121 43 9 5 65 32 -44 122 -73 112 -33 -101 -118 120 -126 -73 -21 -97 -2 127 30 -25 -71 -6 -33 54 34 -59 -39 -27 -60 -99 82 -66 86 -22 65 86 36 -20 100 -14 -106 127 56 -46 119 -83 -2 -6 79 61 -65 -33 17 37 -65 125 -70 79 3 -17 -118 126 83 -114 0 13 49 47 15 -75 88 56 -35 99 -88 122 116 -42 -25 20 40 -39 20 -22 45 -94 -60 -39 -28 53 -74 0 -85 -127 69 62 8 46 32 11 -63 27 -76 67 -32 125 -126 21 -19 -84 -14 -11 9 -45 -9 57 -12 17 53 -76 18 -33 44 33 127 -36 -58 54 27 60 -66 104 -9 -15 42 -124 -3 120 53 -29 45 33 -110 127 10 -1 -50 -42 -24 59 -128 104 -127 -36 -112 -52 14 5 115 11 -100 20 -63 -97 63 -40 22 121 12 124 -36 17 52 -89 41 127 -20 -20 21 -124 124 37 9 67 -126 -24 -126 94 -45 127 60 119 -64 -122 110 -107 -128 -96 -1 -122 -50 -107 126 -84 -92 -50 -122 101 -35 102 -112 -126 -78 -79 126 -25 -118 17 127 127 -26 103 17 -101 32 -75 -71 124 66 -35 -74 -41 -30 -101 55 -118 78 111 -127 -127 -128 1 127 107 -44 -62 61 61 122 107 37 8 -76 54 14 44 -122 -123 -58 -40 -20 22 76 47 126 -112 127 -41 117 -127 4 127 -83 -127 1 -126 38 -42 5 54 49 126 91 3 47 -90 -127 -3 7 -123 27 -52 -128 126 -68 127 -123 121 127 127 -110 -126 -16 -71 109 127 26 -76 -15 -123 -124 89 -53 -12 -127 -100 -20 -1 -71 27 40 123 63 -12 37 -127 105 47 34 127 106 127 -101 119 127 -39 117 35 124 79 -122 -34 -115 -61 28 -40 -116 -123 -128 -115 81 -125 -126 83 -11 99 127 12 127 116 -126 -14 12 95 118 123 -44 -120 -53 15 -87 7 -18 -87 67 -5 70 -45 -94 -8 -115 -84 125 -50 -1 -6 -77 11 89 -22 -128 123 -57 125 111 127 -96 8 14 -85 18 -127 -126 99 35 -86 69 78 -128 5 -44 115 -4 -110 127 65 84 -109 60 57 -101 -84 17 -128 -122 -20 127 -81 127 44 127 111 -2 -17 107 27 127 92 87 127 -29 -127 -123 102 98 107 127 127 124 -88 -14 -19 -72 125 -38 39 127 -6 -128 40 -18 -100 35 126 72 -80 111 -19 115 -127 2 34 45 78 -125 -128 -119 -67 117 -88 -128 -127 127 -83 -8 3 67 -127 -45 -123 -128 1 -16 73 -128 3 -54 -71 -23 127 -72 -91 113 107 -18 120 -96 127 -3 -26 82 -98 -71 -110 -2 -90 67 60 -1 -38 -128 53 -46 59 -47 -104 126 -127 -128 -128 -115 -80 -126 -86 -72 120 80 5 73 -12 -96 -51 -125 -7 32 -97 125 -30 99 43 115 112 118 30 -40 26 -69 -35 -20 -68 41 110 -27 -123 58 -59 1 16 -125 90 -66 -78 -9 8 15 -127 -64 -14 126 98 75 113 42 -69 -89 10 32 117 -62 122 -94 15 -128 72 5 117 -13 47 -82 90 87 127 -73 -33 67 15 -128 -19 120 -12 50 -17 -14 127 -124 26 -103 -38 97 -39 -58 -76 126 113 127 4 99 96 -101 121 -127 67 -25 -17 32 -96 55 -34 -127 90 17 97 8 64 125 -122 62 -22 -126 90 9 126 -25 -10 -59 -38 44 -1 127 -82 74 11 -83 26 -27 -46 2 83 12 -34 60 33 28 20 122 -79 60 76 -125 -26 33 124 106 -12 6 -78 -128 89 -120 -57 -97 -4 17 -40 125 123 9 -28 -71 89 114 -59 -41 -28 -60 0 -50 68 58 -85 -32 -127 22 8 18 -37 -40 87 127 -71 -113 115 -39 -123 127 127 -23 38 -88 -98 48 -61 127 -36 72 29 45 -11 122 -79 -2 -63 127 58 -123 108 101 88 -18 -111 53 127 97 125 -52 -34 116 -31 -77 -39 -88 -124 -19 124 54 127 -128 127 29 -124 34 -127 127 1 104 37 8 -77 -127 123 16 -9 -40 -54 37 6 97 -121 126 9 31 -1 33 -124 34 -33 78 11 111 74 -78 -127 -23 -38 -36 124 -128 42 59 -22 -23 -36 121 -128 -6 -128 72 -107 29 127 49 83 125 -100 -17 65 110 -126 127 71 -80 -35 7 60 -40 -48 -116 113 127 30 101 -30 -123 -50 -63 114 61 -127 120 40 99 -15 -127 -21 -71 -25 52 -73 -69 -84 126 -5 127 60 17 -64 -50 -127 127 -7 126 -95 16 82 33 -128 -122 -78 89 31 62 -125 -128 106 -95 -122 -34 56 105 -83 59 -101 -37 -59 122 -86 -127 30 -111 -76 58 11 121 -121 -36 68 123 27 123 -128 -128 -128 4 127 -105 -126 -4 19 24 29 25 24 115 -117 111 57 -62 126 127 -107 124 123 29 -111 -27 -126 127 -80 -30 127 118 -6 -54 127 -60 -72 49 107 67 -13 -36 26 -128 127 32 65 -72 25 -128 -77 17 29 122 -125 -127 105 -11 -116 122 -35 -127 -127 -95 -113 47 -30 -52 74 123 14 -56 27 -65 -126 13 -124 -127 -29 127 -116 33 7 75 -30 -78 -126 -122 54 55 111 -102 108 127 127 -49 -98 -128 26 -79 -127 -10 123 48 -119 -128 -59 -127 1 120 61 55 127 103 -90 -102 3 79 127 -125 -64 122 74 -127 29 121 49 -46 127 48 91 73 123 30 0 17 -127 -45 -66 -86 18 -40 -10 51 18 -6 -48 74 -8 43 -59 -15 -32 -31 -4 28 -76 -36 -65 20 34 -20 11 31 49 4 -53 -1 24 -13 -4 40 -14 -58 8 -47 -32 28 14 -8 -21 -50 20 55 22 -47 -13 -13 -19 -20 -41 -79 49 -41 30 -7 -7 -54 15 5 1 -45 78 -38 20 16 -12 -48 52 7 -65 -54 -11 -48 -33 -65 -10 -63 42 -58 14 -24 -51 -11 -79 54 28 0 -51 -24 -47 18 -9 93 85 9 126 127 117 16 39 35 -20 -1 28 127 -31 -35 -72 -37 -75 -85 54 -1 -21 0 42 -39 67 17 75 -69 -43 42 -102 -8 -115 -60 110 -127 -85 -48 -48 -126 -60 70 68 -38 92 -55 17 43 -66 -3 -50 -5 -101 -36 52 28 48 89 65 110 69 -1 -17 46 -9 27 40 -48 97 57 -127 -50 -8 127 9 35 -2 -66 -111 -31 115 69 101 15 -42 84 81 118 127 43 -107 6 37 -78 127 52 -65 -3 124 0 14 83 -76 -4 32 -54 -12 40 80 -25 -20 -24 -56 50 -126 54 -26 11 28 34 110 -65 9 -6 8 -25 -51 60 -75 26 -21 90 3 -103 -69 -4 11 48 -34 98 -10 78 51 -15 -118 127 -26 -1 -120 -83 -49 -9 1 -40 12 -49 -127 -3 -4 -4 -18 -40 -7 74 35 -56 -127 -38 58 -66 -10 92 36 13 52 53 11 -22 -56 -2 -76 43 -56 25 73 68 74 84 -61 6 66 -17 107 123 24 15 13 91 -9 -20 125 116 -50 -19 18 54 -41 -1 65 81 -54 -80 3 -62 15 3 38 -112 -41 -42 -124 -12 50 1 -20 -55 124 18 -22 -44 104 -33 -28 34 1 -121 -56 -67 45 -71 -72 5 51 -10 -88 -128 -9 -11 6 68 87 38 48 33 -7 -7 59 -27 -23 26 -16 -78 -29 51 41 -36 -55 -52 68 -12 -47 -107 -16 27 49 -3 -63 -85 122 -49 50 -73 -56 -23 -26 97 -56 -126 -41 44 117 -109 -30 107 -120 -35 -10 -15 31 -108 -128 25 -67 12 -26 44 10 -4 122 34 127 -15 -127 -74 -66 8 55 -77 -24 29 103 2 127 127 19 -80 -14 -25 125 9 -32 -86 89 11 44 38 -36 118 127 23 126 113 96 -13 127 9 -87 42 -127 110 -76 -23 48 -67 32 18 23 42 110 24 -84 -5 58 23 8 -78 41 -114 -116 12 73 28 65 -100 90 -78 52 62 -127 81 -85 -89 -120 -73 -76 -82 41 18 -70 -51 117 -22 6 14 -34 -14 -108 -17 17 -71 -30 11 -101 127 -113 -35 23 42 8 -47 -112 26 125 25 -39 50 -110 -49 -47 -127 27 39 0 -10 114 39 -64 94 6 -67 92 -34 127 -74 -115 67 -10 -127 6 30 25 -83 41 36 127 93 -14 -32 127 23 -28 -77 -2 -49 -95 15 -60 -126 -76 -15 -45 49 66 75 -64 -4 74 -13 -120 59 61 2 -29 36 83 4 -42 -68 127 -7 60 -16 37 -80 44 64 9 35 -102 27 20 127 83 108 31 45 -19 10 -98 8 -20 44 4 -47 10 85 26 48 20 -8 -67 -56 -127 93 51 106 63 0 -28 50 -89 -21 8 15 51 -7 123 -78 -27 127 -11 40 127 -64 80 7 42 110 -6 53 -78 -9 28 21 31 -86 40 21 59 -21 5 4 59 45 -10 -6 30 -37 -52 -122 -25 86 -73 104 -42 -128 17 24 59 -82 -55 -101 -115 127 -118 54 48 -93 -42 -51 64 45 126 -109 -10 121 -28 -128 -127 127 97 96 -100 -105 17 -68 -103 -61 127 -122 124 -37 -53 -68 125 5 -1 6 -116 4 82 -29 -46 12 70 64 127 -110 -108 60 31 48 15 -59 -4 108 73 -70 -78 -81 -114 -54 -119 -46 -5 -92 127 29 23 -96 -55 124 -55 -70 110 54 127 19 -101 -125 75 -60 16 -83 -126 -126 91 127 77 -127 -5 -69 64 21 -120 -60 -99 106 -122 -118 -81 126 -21 -37 17 12 -10 -111 -128 20 -16 5 52 -34 -128 25 37 30 87 70 -120 32 30 11 41 2 -79 63 -87 -35 34 28 -71 12 -124 -76 28 -114 4 -83 -51 18 79 114 -4 8 79 -38 110 21 13 -122 -55 49 56 -25 105 -80 30 43 -69 15 4 17 63 65 -48 122 85 -106 -78 -73 29 24 -121 21 46 10 -102 -33 53 45 -46 -108 -51 14 -57 18 -35 -72 3 -111 89 -120 -33 126 -122 -25 -118 -82 -16 27 67 -124 14 -69 -52 -40 -67 -13 -4 26 6 13 -108 22 -90 29 -120 -42 81 18 29 86 40 -85 64 33 -72 -71 40 -11 -127 -72 5 -37 -122 39 34 -32 -55 -37 -44 63 101 81 -119 -125 -92 -35 121 15 -115 -101 -23 -46 -25 -29 -102 -27 -34 49 12 105 -52 -51 44 -32 9 -32 -32 -71 -74 -10 127 50 -34 -126 -123 -126 -89 8 -33 -8 -5 118 67 -60 -66 78 127 55 108 122 33 -128 57 118 127 -2 -37 116 11 127 -123 -1 113 105 80 -49 -66 -57 -128 -77 126 61 116 -38 -48 -43 127 63 -100 -19 -37 122 -94 15 -127 28 -44 28 117 -16 -128 -98 -40 -69 48 61 89 41 127 78 -125 -128 -127 32 118 -127 -82 -82 -72 30 89 -58 9 -128 14 -128 121 -75 -66 -24 -77 -62 -73 -41 -82 19 127 126 54 -119 -28 -10 -127 -100 -80 -102 15 -88 21 -38 -79 -15 -80 32 127 5 -79 -47 105 -54 -94 40 -5 127 53 67 46 19 125 27 -14 51 -30 95 -127 -105 -114 -113 -37 87 -65 -128 127 -29 -38 -36 -94 74 25 -58 114 123 20 -22 70 -58 78 123 4 64 16 -73 67 -28 -46 -80 127 -128 -46 -82 -96 -127 6 -33 25 -7 -43 -66 -14 -30 1 -100 94 96 90 52 127 -13 -22 53 89 10 -109 -54 -115 -17 -83 119 -27 48 -62 -109 16 -33 12 -70 89 -95 -42 98 40 -127 5 103 5 -5 -68 1 51 102 106 125 -35 -126 46 -100 16 96 -72 -30 -128 103 70 83 69 72 55 -80 -119 92 -127 -124 -53 -45 15 49 62 4 -17 -6 95 -41 -99 -114 -70 -127 66 4 127 80 -127 83 0 -6 106 117 104 127 22 -105 86 -127 58 -16 10 -8 -8 -2 101 34 29 -5 -44 -48 63 76 11 -98 -64 2 85 -88 -74 24 -5 -104 56 115 -18 -96 -123 -74 -70 122 76 67 -127 -128 38 -121 -6 -127 -77 13 -123 -78 127 126 96 120 70 -107 -6 84 17 -71 0 127 -42 53 125 -20 21 79 -85 -125 -121 -100 101 4 -121 46 121 -28 120 -2 -3 100 39 52 -122 -127 39 -45 72 -92 40 126 54 -128 -29 125 -78 -126 -15 -128 -110 -127 -128 124 -57 -21 -128 68 26 -78 -127 55 58 2 114 127 56 -84 -54 127 -100 127 35 2 -24 -35 36 -27 -51 -65 -96 -126 -125 -27 29 108 -53 -126 68 -67 -18 -106 19 66 5 93 -11 -24 -39 72 -34 30 14 77 -63 -120 -122 -30 -6 -25 17 95 8 116 -36 -86 12 -71 -62 52 -53 -39 16 -3 -26 17 48 91 -6 -11 50 47 -126 -47 95 31 -72 64 -85 -127 -28 12 50 60 -32 -128 -15 5 -5 -63 -13 -81 28 -48 -54 -127 -85 127 -70 -13 41 77 -15 11 77 -44 127 81 -55 -41 -25 -80 33 -128 -22 -10 70 -112 35 -77 91 -77 57 124 127 -89 -63 -126 -1 11 -8 98 -22 -15 68 51 28 -20 3 -20 -85 42 -65 124 35 23 56 -12 41 52 -21 127 113 -95 35 -119 -53 3 -67 -24 124 -47 -125 -5 125 67 8 -2 40 34 108 -8 -127 79 112 19 29 11 -65 127 -36 -87 -20 57 -98 56 1 -74 0 -125 31 41 -49 -46 -23 73 -23 -54 40 7 -128 -10 88 39 -38 104 -23 44 52 124 51 11 -121 18 9 -66 82 -78 107 123 -1 5 -23 127 -59 -18 127 21 -42 -29 -70 -25 -126 -25 94 80 24 -84 -126 96 -22 114 110 68 -118 -113 -101 -123 7 126 127 124 41 29 -128 5 43 -29 75 4 15 -128 37 -19 -2 62 -118 119 9 -40 -82 -58 23 -104 127 125 -122 -127 79 -80 127 43 -63 127 -72 55 29 -11 -104 85 127 61 -19 -114 42 18 59 -39 13 111 -72 72 47 -102 88 42 127 127 -47 107 -117 95 79 -73 25 127 -5 15 47 -125 34 -42 -73 -60 -71 -65 127 10 33 -59 21 44 -31 100 -128 -123 124 6 -25 127 30 -47 41 -122 -112 43 -5 127 95 15 127 29 37 48 -72 15 29 -28 -16 -7 50 -5 63 -62 83 -82 56 -29 -5 -92 -55 127 -104 -79 -4 7 -48 -112 -18 0 -88 -86 -59 -118 12 -18 33 -4 110 43 65 60 94 10 -81 -68 -81 -8 -65 -63 -38 -126 40 -48 -39 -126 28 26 6 -11 -72 -99 -16 -14 29 39 8 3 48 -19 -9 -109 -73 -24 -48 -43 -24 122 44 -94 -4 31 9 -73 29 -38 -54 34 52 -3 13 -61 -32 24 -36 -61 48 -20 -2 60 -6 -48 -22 -24 -34 4 49 -1 44 -55 -35 -7 -4 -37 -117 56 -31 -15 29 -95 75 0 -13 -1 -48 -35 -18 -9 -4 -6 37 -36 -18 -50 -73 -22 -28 16 12 -11 16 27 50 -40 -64 -74 -51 35 -16 -25 -25 -6 -45 60 -9 -12 9 67 5 44 121 57 -28 34 57 20 -29 34 -51 -19 -7 11 -34 99 -7 1 16 -15 -6 57 44 40 -81 38 43 -38 -84 24 -75 -16 6 -11 95 -107 118 -77 83 -16 -16 -10 40 13 108 -32 -25 -4 -39 -8 19 0 -25 -37 -13 31 58 -93 59 74 -16 30 -52 7 17 28 51 -19 24 31 -17 66 60 74 65 -21 58 86 -59 26 7 48 58 70 -40 86 105 125 25 40 -31 39 123 -21 74 46 -49 31 26 45 -15 80 -27 -21 42 55 -5 38 29 -17 -17 -12 -61 114 -28 1 -54 18 -11 46 38 -1 -6 -30 -12 -4 -98 -15 -66 4 -78 -27 -11 28 -60 5 0 108 -19 27 -49 30 -4 -42 43 -39 36 5 -87 -52 -6 6 -7 52 -35 -26 -126 -17 4 2 70 -72 52 -43 -4 79 -61 -32 -17 -58 -2 -11 34 7 -64 35 27 127 -125 32 76 58 -29 -23 -9 9 21 19 6 21 -6 115 -19 32 -85 6 70 9 -3 87 -54 38 3 -112 -43 -42 -47 127 86 -7 50 10 93 -54 -72 39 -2 30 -11 -33 8 -16 -73 -74 -67 -7 -7 -34 24 -6 -2 71 52 60 22 -104 -32 16 61 -56 -16 6 33 38 -61 -127 113 -9 33 -25 -56 -113 -12 -63 -8 49 1 -25 39 5 -64 5 -69 -19 101 36 -42 54 15 -26 2 30 -42 71 18 62 16 -86 6 2 84 81 7 -18 95 84 46 -78 -2 27 46 -25 -11 17 -53 -80 15 -36 13 60 -22 -17 6 -38 52 97 -74 -66 33 125 117 -103 -74 -22 67 31 -109 14 -55 -73 22 25 74 42 7 127 -18 35 64 1 -1 4 -19 66 20 -72 69 -43 -69 2 -40 -109 4 15 3 -48 39 15 57 49 92 -67 -124 -7 18 72 -96 1 115 125 -9 -7 51 -2 -24 27 -26 -44 -126 21 127 15 48 -18 103 -74 -11 -29 -88 -3 44 5 -15 -74 -50 -67 -33 1 11 -95 126 -44 -49 109 18 34 -90 -3 10 52 -31 -79 67 7 -45 28 -21 31 5 -127 -85 -3 81 -120 -86 -52 -102 11 -32 82 1 23 78 9 68 -55 17 72 -7 3 -21 -30 42 85 -18 9 -43 -80 -45 42 -4 21 42 112 127 97 -60 -18 49 41 18 69 -128 71 0 -38 -82 -57 -92 12 -2 25 40 102 -24 25 8 26 49 29 -57 -29 3 -34 35 -53 -55 40 78 -53 78 63 -56 115 2 1 109 45 15 -71 15 42 0 68 13 107 63 24 -34 109 -60 -8 24 -71 -21 39 2 -37 -56 1 -58 74 -42 -17 -5 21 20 68 17 114 7 -85 54 -43 23 47 109 12 -12 94 17 50 122 0 24 74 -127 69 43 -50 -30 0 -41 -62 -37 32 41 -25 -46 -12 4 -77 57 124 -29 -12 41 10 -42 53 -49 -23 38 125 8 -86 -19 -24 47 107 -37 -80 29 123 9 24 53 2 -116 47 25 -91 108 -117 43 35 -76 -106 -118 83 -83 127 -38 -119 -52 56 -30 -120 87 46 -56 -13 -57 -3 117 -76 126 -14 2 -63 65 6 -104 52 -118 31 67 20 -63 -76 65 14 29 -45 60 65 103 7 86 -24 -55 -35 51 4 -24 -122 -1 -118 30 60 13 10 46 101 4 40 58 -60 52 -56 -38 35 51 -113 -42 15 92 57 -126 -32 39 -101 91 28 -118 -124 -81 -117 -119 65 -55 67 -3 -3 23 -90 15 -78 -28 -6 127 126 -24 2 -3 -5 15 8 54 -37 67 -83 18 33 47 106 -4 120 6 -42 57 2 -115 -28 -37 4 -53 29 11 -61 67 3 7 -93 24 14 -19 24 42 68 67 -23 -71 55 31 36 41 -77 -53 -11 -60 -15 -33 -14 34 6 -76 -33 14 -12 -2 68 52 32 -114 37 35 -17 -78 -4 -53 25 -45 7 11 21 -43 -40 -64 15 -11 -128 12 54 1 101 -110 -26 -21 -55 84 53 -52 -7 9 -24 -45 -108 -74 -10 61 25 -94 88 -26 10 59 10 -128 -98 4 -122 -30 -68 123 -30 -106 76 -122 14 40 -56 20 -23 22 -13 -50 -78 -60 100 34 91 54 -16 125 26 28 -21 -121 41 100 -60 -41 29 10 31 -9 -9 38 34 96 36 -33 26 -122 -52 -51 -125 -66 49 -125 -51 -55 -12 30 21 -13 10 -36 30 83 -58 -21 33 7 -42 121 -23 -90 31 108 -87 127 -17 -32 -66 -57 2 7 101 3 81 60 -121 -38 -2 125 -14 10 -38 21 -17 -27 -120 -21 127 86 -71 58 -13 22 -75 -48 17 77 -9 -4 -111 60 -23 111 -113 -87 13 -123 -102 -84 -40 40 56 22 -51 89 -59 -108 -120 -41 -127 24 -118 -122 -62 -2 -112 41 -41 -52 -127 -51 3 29 -43 16 -59 61 61 -64 23 -125 -70 58 41 35 -47 -20 3 -119 -33 7 -18 -41 -44 -73 35 68 -127 -128 -31 97 15 -62 -28 3 18 9 71 33 77 46 57 -1 52 -45 13 3 -60 21 -2 19 -49 -79 -105 -9 29 43 77 37 127 15 1 -86 126 -22 -38 -83 39 10 -28 122 -57 21 -28 39 -79 52 -16 74 -28 -69 30 9 -20 12 -4 -30 -51 32 -57 -20 63 -37 -63 -30 45 -60 -121 31 117 -49 -28 17 8 2 0 28 22 -38 -23 10 64 -49 -26 22 -25 126 10 -78 -9 35 -97 4 38 -63 7 55 16 -101 125 -27 -20 21 7 16 57 76 -17 -52 59 25 -54 -16 73 105 -73 21 19 -78 57 -41 -54 127 -76 -43 -88 7 27 -54 34 -64 69 -106 55 -64 -12 127 23 20 24 -9 36 32 36 100 -35 -104 -70 -36 50 -35 30 -1 -18 15 -32 24 7 -16 96 98 67 -7 27 -51 24 42 -45 -12 -39 -43 -60 29 -80 22 -61 88 -14 21 126 -57 -127 8 0 52 -91 -63 94 -61 6 -36 59 -116 9 -53 13 5 -29 37 21 -18 -81 57 80 23 -40 30 14 -111 67 -17 -71 -37 122 -40 -98 103 48 -8 39 45 -33 46 -67 -57 0 -1 -70 -27 21 66 98 22 91 -53 -45 -41 -18 49 -16 91 -127 76 49 85 -38 -10 -58 -74 -12 -19 15 -19 -51 -80 101 110 -27 -100 -12 -34 -14 -93 -9 4 79 13 -6 -2 120 -51 -25 -56 46 -25 1 -19 -125 58 -7 35 32 -29 14 52 -91 21 116 -12 -59 41 -32 -14 -120 -57 26 85 5 127 19 -20 22 -22 24 -7 99 -4 -74 -22 -60 -91 63 -127 112 -20 118 -61 62 -20 23 -111 118 -34 68 -7 34 -9 -74 23 62 43 51 30 8 -47 127 90 16 -77 -124 60 -63 7 0 32 -17 41 -38 -85 -2 55 78 13 91 -56 10 39 -59 -27 -7 -68 -12 -42 -29 19 -46 8 0 -67 36 -10 58 -32 1 -63 9 25 -51 10 -128 7 -15 10 20 2 11 127 64 23 45 -71 -1 -3 -37 33 64 18 -5 91 12 78 22 52 -54 46 118 28 -17 22 -6 -1 -13 -14 -79 39 -73 -64 -78 13 49 -110 -19 81 -4 -114 -30 -106 -77 -128 -42 -68 -84 67 83 -112 38 18 -76 -13 -65 26 -46 41 -34 117 -84 -25 69 -35 -80 15 6 -111 74 -116 -44 54 15 -55 -16 7 -112 -48 6 60 -4 -47 13 -9 -16 -35 52 -79 -26 -45 -10 -23 -109 51 93 -13 -13 46 -21 -37 65 -72 -71 120 -57 71 -18 -69 -31 -61 -12 13 -12 -55 -37 79 -5 18 30 70 -36 33 -9 -72 56 90 73 -52 -35 -125 -66 -84 -24 -7 -61 -55 45 -41 -104 -24 -25 58 24 -119 127 79 -88 -79 -66 40 23 -90 93 71 3 64 -43 35 -62 -58 -35 126 14 -50 -82 -41 -31 -11 -125 70 -5 56 14 125 -22 -42 89 -88 -33 -49 94 -22 3 23 72 -86 32 -88 -10 -36 82 37 61 31 -92 -13 -14 -8 -8 -126 22 127 -43 -10 -4 -69 7 16 -69 93 -128 77 19 63 19 119 6 -31 67 35 -8 -18 15 -73 93 57 -13 124 3 33 3 6 -24 -87 -9 -8 -77 17 36 26 -14 -11 20 10 -43 14 75 -28 10 -119 -61 7 -22 -63 -115 7 84 -40 -70 -118 -105 -39 -34 74 18 103 13 24 23 2 12 73 -14 -64 -10 -35 -122 -112 -32 -10 -18 -121 -116 1 -16 -85 9 -103 -45 -96 101 -39 48 -71 22 -81 -46 -58 -56 0 -65 83 -46 90 58 -128 48 -127 -20 -126 -64 -120 -110 89 53 -128 -125 -3 -13 -128 -75 80 4 -96 25 -61 66 -1 -128 26 -37 127 120 0 -17 -128 -26 40 30 -46 42 93 -71 17 127 -126 68 -16 -34 36 -125 -29 111 -60 9 -55 118 -69 108 -46 17 85 125 32 -58 31 -122 29 17 71 -61 -51 24 -60 -63 -6 9 80 73 -127 -45 80 126 -127 -12 -17 125 -123 80 -93 47 94 82 33 -79 -91 -99 -55 -54 -126 -67 -113 27 -44 11 13 -14 125 6 -106 52 113 1 54 126 36 120 0 32 36 13 24 -126 -122 -27 45 -65 -86 -91 -117 13 -94 -60 -110 35 -34 55 65 27 127 -1 -68 -9 -128 -122 76 30 -108 2 -102 -82 59 -123 -19 10 -56 10 -10 -5 -31 47 40 79 127 3 46 2 25 4 34 -128 24 -89 -43 -1 37 -74 46 80 -1 -4 -42 100 109 10 122 -51 3 -58 74 -127 61 75 -37 -77 -19 -78 19 21 27 127 127 -52 -89 -77 -127 8 -125 -116 114 -112 94 -115 59 -18 18 27 -68 -11 105 125 -52 -93 -128 -44 -57 15 127 -8 43 16 -97 46 22 3 -29 31 4 -115 -17 -76 -53 -71 -24 -21 -108 18 -103 -18 127 98 115 68 34 50 -68 7 61 -126 -53 56 19 -75 75 -91 -83 55 -56 53 67 75 14 -14 64 -96 -126 125 60 125 81 57 -9 4 49 27 2 -126 2 -125 71 -11 119 -17 81 64 111 -64 -126 -59 -126 -120 1 -1 14 -56 69 24 -126 -100 55 127 127 -17 -81 -55 -116 68 -65 -54 127 76 58 0 -128 45 96 107 75 -3 77 39 -97 92 -127 -21 -113 -5 43 -97 8 -20 -74 -59 -19 -77 -67 83 -24 96 6 122 124 -56 68 -128 29 -3 68 -51 41 -43 -126 -9 109 55 -64 -33 -128 -87 -101 125 -11 -90 -88 122 -99 -112 -87 28 35 -19 43 103 -55 -15 115 6 -49 10 -25 14 -128 -7 24 -64 23 -52 -120 -21 -75 51 85 126 125 -61 -31 24 13 89 -33 31 -124 -48 38 -119 -12 37 -28 23 -126 60 -6 107 -59 -45 126 -70 -58 -124 -88 -122 -12 -64 -97 -58 -24 -64 -77 -54 90 -22 -107 -7 -124 3 52 111 -26 59 -7 114 56 -108 15 34 -116 18 -99 -128 -58 -43 -73 55 76 -117 -127 16 -81 55 114 16 25 -48 78 17 29 -63 -127 -128 8 30 -14 -13 -18 -50 -60 -1 -111 99 74 -42 -126 40 -67 82 -19 -122 -64 -19 127 -127 58 48 61 36 -32 -24 121 -9 -12 -73 -127 -17 -5 24 127 -62 37 82 24 65 10 -47 -45 -37 -36 -52 68 49 79 -66 11 -59 -88 20 96 -39 20 -15 110 -48 -10 -47 36 -62 -60 -97 35 103 2 -42 21 -16 -45 -42 28 44 29 20 -126 76 125 -104 52 64 71 -47 121 74 34 19 -73 127 -42 -126 -43 124 123 -8 11 -60 116 126 -125 -38 44 44 -126 -33 21 107 127 116 44 99 -83 -123 67 127 127 55 6 -39 -8 127 -76 96 124 54 -53 -1 -10 113 -69 45 95 -47 -59 108 73 -102 127 16 -128 84 50 106 121 114 -26 -4 5 -89 120 -21 66 -38 -20 -125 127 -127 120 -128 -6 27 25 65 123 -40 2 81 62 15 -113 10 -127 -105 -52 53 85 124 -13 -15 107 33 -80 124 -4 -21 0 82 60 72 119 94 127 41 -122 21 -127 -48 4 124 -87 -10 68 -89 -90 37 -9 -66 16 -127 62 74 -25 115 2 -5 -68 121 120 -120 110 114 53 -49 -124 56 126 -89 -35 -10 127 -122 -60 -8 -64 -17 68 118 -57 -70 -33 -66 114 76 -3 9 -47 -21 50 -43 34 24 53 59 -119 -48 -111 -127 74 -125 -89 -110 -128 -119 -12 -13 -91 -127 70 41 -121 -5 101 -48 127 -60 -90 24 -113 91 -127 82 111 -90 -15 -127 -44 8 -8 29 -71 -62 87 -30 -53 -18 -128 -16 77 125 82 93 30 -39 127 -127 -14 -33 127 -38 -18 -121 62 -128 115 68 -15 91 127 5 124 15 22 -76 -71 -3 0 -26 -7 34 -59 42 126 -38 -8 127 17 -70 39 -67 108 -40 -127 -1 -127 -54 -44 2 -33 -82 -101 -8 68 70 14 -17 -127 36 73 -64 -91 -66 -67 -32 -126 72 -119 126 116 -5 -65 -13 102 123 -9 -43 -36 -73 -47 127 94 127 -15 27 -71 36 2 125 -89 -20 -61 -65 -44 48 -64 37 -79 67 124 -1 -117 -37 2 124 -21 115 24 -58 101 -39 70 96 123 58 8 41 95 68 -123 27 -127 -14 -30 26 119 -125 123 118 -29 -16 3 -39 -45 127 48 -33 35 56 20 28 121 -36 110 -15 -71 8 104 26 5 -78 111 60 27 70 -85 -42 64 -30 126 70 -12 31 116 -69 -128 120 25 -59 37 126 -16 -126 -7 103 3 -128 -28 -125 27 -7 -121 -30 -62 26 -75 -94 59 15 80 68 94 -26 65 -55 1 0 -36 77 88 127 11 16 28 7 27 43 -13 -31 28 126 -22 36 -128 -95 48 23 -124 -9 -87 85 73 125 51 -7 81 -4 5 59 -46 -9 125 -41 -35 126 74 11 97 25 -94 -114 -27 -16 -46 -26 32 -126 127 100 59 -59 -126 10 21 -39 18 -96 -110 93 127 -45 77 -17 -77 -65 -24 17 -37 -45 -43 23 51 43 -5 -125 -127 1 -35 23 -37 -76 52 -3 -14 -8 -63 -84 -30 -127 -26 -51 72 6 127 -12 -73 92 77 49 -23 -118 -22 127 106 79 7 55 -78 -2 -125 -29 19 30 -122 -46 5 25 -15 6 70 38 66 -97 -39 -69 -124 -87 -19 56 -1 -126 -4 -35 11 59 16 66 -27 -36 119 -44 41 64 1 -38 14 -25 -112 83 -127 -7 61 -39 45 94 -2 126 -57 88 3 -51 32 -7 -18 -3 76 -37 -32 124 -83 26 -40 33 -20 86 118 97 -127 33 -106 -34 -10 116 7 61 -21 124 24 42 -114 25 -17 75 41 -3 -5 119 70 -115 126 -9 19 -7 -80 127 43 32 -12 73 -30 15 18 -8 -55 15 -64 -20 -30 -125 -62 -126 110 0 -48 -92 10 35 -45 72 99 49 44 -34 89 45 -38 5 -56 -34 -82 -77 -84 -33 -51 8 16 22 -49 -27 80 0 -10 -3 -100 -32 56 -34 9 69 22 -29 10 -41 -127 6 108 -67 48 -13 -42 -69 30 45 -62 56 -18 -92 118 125 12 -117 2 30 -67 3 40 -21 52 4 35 -51 94 42 32 -99 -74 -22 -40 127 68 123 -128 -44 88 -70 14 -126 67 78 106 2 70 -126 90 -82 -113 -32 -13 -22 113 -32 26 -69 -18 -46 14 61 -35 41 86 -46 -14 -40 69 -9 125 -32 -66 28 -97 27 1 -13 81 -87 -84 -20 95 -87 30 -4 -126 -50 13 3 2 -12 -4 0 -111 64 34 82 9 -47 24 -12 49 -117 76 -39 90 9 -19 108 72 -125 42 22 -45 98 127 7 56 -109 48 39 7 21 -67 71 52 -1 8 4 124 -103 -128 -24 41 105 -38 14 -10 0 42 -19 -30 97 16 -109 53 -128 127 57 -91 59 16 -63 54 -19 -30 3 -80 65 11 29 51 26 39 42 11 24 104 -1 -128 58 -70 11 70 -6 43 51 -55 22 31 -40 19 -115 -49 -6 -128 -123 -117 3 56 49 17 48 -87 -17 -62 -23 127 77 -63 105 38 44 -29 34 -18 36 34 124 -61 -76 -5 -7 -128 -35 -15 -45 56 -75 -40 48 58 -3 115 -126 21 126 75 6 -46 -50 -14 -48 52 -13 40 75 -18 87 10 37 8 86 -57 -68 13 14 51 -101 -107 -79 11 57 24 -9 -22 -18 -68 -4 -119 39 35 -11 -67 -103 54 103 99 -31 -37 3 121 -93 -40 -15 -86 93 90 23 -56 40 -43 -125 -108 67 -10 11 99 100 126 9 95 -7 -47 47 -113 -79 -18 -18 127 27 -7 6 -25 -126 -46 -62 59 112 -4 -30 -127 -53 -128 107 34 29 18 75 -37 122 83 2 15 -76 -12 -40 -78 -18 -83 126 109 7 125 -35 24 82 70 13 88 -10 124 24 -23 96 116 51 121 26 -41 -76 -66 -27 -37 -113 -95 -54 -59 -18 -34 74 -84 92 -62 -79 -8 -52 -128 126 3 -71 48 7 -125 18 -48 47 78 -33 -52 -23 -128 -19 -25 -23 34 17 14 74 2 84 -126 -50 -28 111 -4 -74 25 -47 91 101 9 -17 59 52 -35 70 10 -71 27 -32 2 -73 -38 -26 28 39 72 -127 -128 5 46 -94 80 -32 50 -70 7 8 -33 65 9 -127 -4 96 -24 79 -98 13 -21 59 93 100 -127 -14 -46 -72 10 -37 27 -6 -114 -70 23 -121 -30 30 63 -56 -33 15 -40 -74 88 110 74 32 24 0 -22 43 -30 -17 -85 -13 -9 -53 28 -51 20 47 21 0 -13 10 -12 84 40 98 24 18 9 33 28 56 55 46 -12 -19 27 12 -21 -7 127 15 3 -25 89 -26 61 43 7 -37 13 5 -15 34 23 -34 39 9 2 16 29 -13 -51 5 18 25 18 14 54 40 -24 15 64 -56 -25 -10 2 3 -29 25 14 -8 -13 18 -3 8 -26 -24 38 -71 -27 53 119 11 -8 -46 -10 -32 -29 -27 54 27 -11 -61 9 -7 -16 -66 -15 48 -3 35 -3 52 -19 1 24 57 -9 -72 -12 -38 19 -1 5 74 -33 -47 -2 -10 -37 -18 -59 49 -25 56 -59 4 -4 4 -50 -27 -29 -43 -59 121 74 -31 127 12 -46 -2 -33 1 -8 11 -2 18 -9 -9 13 52 39 -3 81 50 -11 -8 -26 -13 31 -27 -18 59 24 -36 0 8 -47 -33 -47 -4 -57 -15 -21 -7 -39 43 17 7 -6 25 -16 5 -9 75 -4 1 -12 -39 -1 29 -33 -15 -14 24 -21 -45 -22 9 19 -8 4 0 -33 26 4 50 -7 8 -51 -110 -3 53 16 -23 29 -28 -1 10 6 -6 117 -6 -1 -13 -20 -29 -12 66 18 -9 21 -7 -4 5 2 -50 39 -10 -18 -9 8 -16 30 52 81 -80 3 12 -6 40 0 17 1 14 -58 17 -10 -11 -18 -22 16 -4 -34 39 -19 -49 0 -30 -1 9 34 -47 -20 -24 -22 34 -8 8 29 2 60 10 -81 -18 -69 -7 -41 -10 -6 -48 38 -8 -8 -6 3 29 -1 -10 -34 36 5 20 117 11 -37 25 -10 40 14 67 3 10 -18 -31 -15 32 -18 45 -5 11 -16 -118 7 -17 24 -42 -17 -6 -34 -13 -27 9 -9 -11 -31 -8 -2 -50 20 -115 -75 14 -8 12 -69 -2 1 6 -41 -19 -8 -24 -51 20 -1 -43 -89 16 -2 -33 18 -7 12 65 5 -49 14 17 24 -26 -18 29 10 52 -55 -4 3 -20 -57 13 43 -52 57 32 11 -26 56 -64 -38 -21 0 -3 50 -47 -29 -14 10 35 -51 3 -30 -1 -47 48 -6 -4 112 -29 -15 -12 56 67 1 -49 -25 -15 -4 34 6 80 59 8 -119 55 -1 -19 -25 -41 51 -5 -14 -4 75 -16 16 -47 36 120 -17 -11 -5 -12 -22 -21 34 -121 1 -32 -128 -59 -19 -7 15 8 -9 70 14 20 40 14 31 25 -43 2 -36 -5 -35 -37 96 89 -23 -63 97 0 -32 8 -4 3 13 13 7 -25 -47 28 -5 14 -10 10 13 -3 9 -77 -2 7 -20 -1 -16 -10 0 83 -7 46 1 -12 -10 12 -10 -34 26 119 7 35 13 -9 65 -21 25 102 -11 -34 -9 8 -13 -93 10 -4 -3 -1 1 -1 -14 -12 -11 18 3 -19 11 -1 -12 -56 0 2 5 41 -33 -4 5 -8 14 2 -6 3 -26 -6 2 -10 14 -9 -6 74 -56 5 -12 50 4 127 36 100 58 -32 -52 -33 116 12 -102 57 13 48 82 23 -3 106 13 50 27 127 -14 40 -85 14 124 97 -27 68 -45 -17 6 10 -65 22 39 24 57 -25 113 -68 39 -39 17 -120 -75 6 2 -110 -92 73 53 -34 2 127 -28 -6 83 -57 42 84 74 108 -1 26 6 98 115 -109 -1 -66 -69 79 61 -14 -128 -128 -58 -3 -86 83 -84 -58 115 1 72 60 65 -2 -4 6 -60 -128 -6 20 -30 22 -16 20 105 48 81 -42 16 49 71 110 -8 16 -96 6 66 -22 7 -45 127 127 84 30 -73 -41 64 -92 -20 38 66 7 -41 35 -124 -104 34 51 -83 -97 -60 -40 9 45 -56 -53 29 -56 86 -42 -39 80 -26 -14 16 -52 -1 -115 12 -27 48 23 104 58 55 123 -39 13 75 -71 108 -39 13 -22 -77 -36 21 56 -30 -13 43 -56 -20 -125 79 -20 -27 59 103 57 39 6 96 -124 -111 38 0 109 57 -23 -65 -8 -44 30 66 91 -2 -120 -95 -52 -60 17 -69 -2 -62 -37 -23 10 21 -118 17 -65 -2 -92 -28 -68 -9 31 -37 40 -127 29 -15 -14 -8 -23 37 47 80 0 -84 -107 6 29 23 -67 -2 -7 -40 6 -26 -126 -25 17 -84 0 103 36 -6 -47 -62 -17 -101 81 3 -19 -80 -127 -69 -38 -2 55 19 -12 -58 -8 32 -20 -35 -25 -35 -41 22 -59 4 -79 35 73 -64 -46 -19 28 48 51 74 -122 6 33 -6 79 -41 45 -113 -124 17 22 -127 35 -56 22 120 -68 121 -126 34 -54 -68 -105 -105 55 18 -74 90 -26 16 -22 -91 -44 -20 76 0 -85 55 85 -127 35 46 11 -30 -110 -62 -30 112 33 -10 33 -42 29 110 124 -124 -6 -6 57 32 54 11 -127 47 -105 -80 -41 56 43 -124 119 -18 -81 -31 -72 -72 0 -36 12 -9 -53 90 -89 -21 50 -3 -59 -63 -125 66 75 -68 -39 14 108 1 40 -42 76 -123 51 -42 113 -36 -50 -5 -32 -16 -112 -20 -48 45 -57 -120 67 -20 -16 -23 82 -66 -24 13 37 -81 -31 -55 -128 111 28 -32 124 27 105 114 11 19 61 17 -9 -31 -54 -35 -18 18 6 -1 -27 10 -18 -75 -32 26 -33 -69 -98 10 66 -125 -20 78 -124 15 -23 99 -47 -100 62 34 10 73 -88 -51 -48 119 88 17 -90 -76 4 -119 -9 120 17 55 57 88 -49 -39 61 -31 -67 -15 88 41 11 27 -5 -4 -67 45 6 17 30 11 -39 29 3 11 40 -17 -33 60 15 -12 -45 94 -4 -17 -48 29 -34 -53 39 12 -24 71 -69 38 -29 -37 60 -13 28 41 79 32 -42 31 -5 -57 -20 80 -32 -22 46 -57 24 26 -86 -103 11 -26 -1 61 -63 -20 -43 -2 44 -90 62 -2 7 103 123 33 80 -45 -92 26 -41 -38 1 -32 0 -31 -40 -4 31 36 27 37 -34 47 42 -16 69 -9 -69 -58 25 112 -20 -76 91 -13 -25 70 -60 12 -115 17 -8 10 73 -22 -36 -1 81 -68 10 47 -69 -42 -2 72 40 -57 76 62 -34 70 2 12 15 121 -29 -121 30 -26 -30 6 69 -53 0 -31 79 -123 -3 47 -6 32 -128 -51 -15 -61 -31 -44 -15 30 45 3 9 71 69 -76 47 -46 -25 81 45 56 -90 127 -37 49 -81 6 37 -121 -16 -11 -56 -50 -30 25 96 -44 106 -91 60 -38 -44 -7 -27 53 -53 63 -73 -110 -57 11 97 -50 115 71 94 6 74 -14 34 -34 48 72 16 0 17 -123 117 -71 -49 -82 83 -5 89 117 48 -120 -49 40 -25 64 5 -7 -76 -45 -33 0 27 -36 -13 11 27 116 -79 -46 121 -18 30 -7 -52 -125 -42 -111 -31 -97 66 -12 -8 -39 43 -69 -14 57 -44 -4 2 31 -12 113 123 -19 87 -28 76 -95 60 -105 1 -77 1 -37 -5 3 64 18 -16 26 -32 6 126 -43 -52 60 -87 28 -36 75 -64 -33 -33 -53 -108 35 31 92 -29 -8 -96 -11 -5 76 127 89 -127 -28 -10 -115 -4 16 -25 -95 -29 37 -59 -11 30 43 35 -106 -40 26 28 -68 -22 -68 -4 108 51 41 -86 7 8 -54 -19 78 -106 46 17 -93 2 4 -42 -34 -93 -66 9 -82 10 81 18 30 61 24 47 11 64 7 -10 -51 -35 41 127 97 -15 20 121 96 -7 17 21 43 105 -98 -55 -104 44 30 -84 -50 -22 13 26 53 -107 127 66 -66 -18 35 84 126 34 40 6 36 118 70 -27 -34 60 -88 -96 110 45 24 3 13 -126 -60 19 -53 -21 -62 -99 13 -62 -20 -10 18 -36 -56 -30 13 34 -36 -6 -36 103 -75 -9 -125 11 -128 -118 -58 -45 65 18 22 -71 47 92 1 -69 -16 15 60 -13 -13 15 -30 -84 42 -82 -30 -12 -42 -118 1 10 -56 122 -107 -43 27 91 -48 20 -123 97 26 -32 26 -69 -25 8 48 28 91 -125 51 -47 -37 -21 -23 2 -40 81 -3 -54 63 -22 -30 -44 -52 76 -32 101 79 43 24 -3 34 -31 11 -39 113 -48 26 -76 -35 -49 -50 12 -119 1 27 50 16 12 2 -103 16 50 -5 32 38 86 -107 15 -110 -22 -12 12 -12 -1 0 -27 25 -10 -23 2 66 -62 -38 -95 -6 -20 -54 123 116 -29 4 -34 63 28 -119 -17 -17 59 -16 -17 58 4 87 -23 -29 11 94 -13 -100 80 127 -45 9 122 83 2 125 -11 109 -13 -7 11 -2 -1 -34 -127 2 -54 -92 -20 59 -36 65 0 91 24 -30 -58 -19 22 21 -99 -124 50 -114 -41 71 85 35 -13 55 112 80 25 -21 12 -96 -10 -93 -50 -1 -92 -95 41 -36 47 20 -77 -30 71 29 -61 -94 127 31 122 10 45 58 7 -37 -8 125 77 -109 -55 28 44 2 83 -32 69 -122 -104 -126 6 -60 30 84 67 -72 -40 48 -127 -112 -60 26 -66 59 43 -128 -40 -13 -28 29 -4 -7 -65 9 -36 -20 -20 -36 -75 -48 14 -68 30 -73 33 -116 43 -30 126 -21 -83 -96 -15 -3 37 80 -103 -28 78 -89 -20 -7 -39 -21 -53 -49 -69 -121 -63 67 -62 -1 -47 90 -108 50 -22 -106 -15 -122 -19 8 -66 69 -114 0 20 -18 -7 1 -68 30 17 123 -27 -61 -120 24 12 -38 -51 -50 -50 -96 -64 -46 -84 -88 22 -23 -39 -9 63 -85 5 -19 31 49 -2 -25 66 -80 38 -17 7 -44 -7 -49 15 29 25 -40 -9 -14 8 49 -54 62 -56 -40 -90 -9 36 -35 20 -14 32 55 -16 -8 -23 43 -51 -2 -49 66 -35 -55 -38 21 -47 -36 -7 4 4 -18 62 -50 13 34 -3 49 -51 -90 23 -95 48 20 7 16 -56 -29 -19 -98 -20 34 9 33 6 13 -78 -80 29 4 -10 -3 -105 -2 27 27 48 -41 88 -7 64 -50 1 7 11 -46 -5 3 20 0 -64 8 -128 15 -2 -76 -62 28 24 -31 -117 -100 -13 58 19 9 8 0 15 -41 21 20 -31 -31 17 -11 -27 70 38 37 -11 13 81 78 -14 3 -89 -26 -46 -40 -31 -64 50 29 -13 3 27 72 7 10 -11 54 -13 43 23 2 115 54 0 72 27 24 31 -39 44 13 -30 -33 -2 -51 -26 -4 -26 -13 31 66 92 95 43 -58 58 18 19 13 8 27 41 3 -47 -8 -43 -19 38 -127 22 -23 -102 43 -4 -85 17 19 53 -56 -32 -67 -34 20 -29 1 -30 65 -12 -24 -115 -95 -27 -48 -45 28 -44 -79 -35 -17 -34 -14 5 4 -34 -39 -17 -60 24 -61 6 -40 -59 -56 -57 -15 -7 -22 -35 17 -51 -9 -51 -13 -32 68 18 -69 -90 2 -27 -25 -85 101 -55 -60 -39 -56 -82 19 9 -68 -21 -25 7 -7 -8 -17 -65 -29 -88 62 -42 -74 -7 -92 -31 10 -39 -24 1 2 49 -21 23 -4 63 24 -48 -15 33 57 -42 1 21 -41 5 51 32 60 14 -13 -34 61 13 24 -14 -14 -12 2 -10 -22 61 16 -16 -41 16 13 9 -3 5 31 -3 37 45 56 -121 -14 -56 41 -23 7 45 36 2 -22 13 15 -42 23 -65 -5 -1 34 5 -45 35 3 9 -29 -41 1 39 -36 6 -52 -19 12 39 19 -30 -28 32 9 6 -12 1 12 11 12 8 -6 127 -9 -34 -8 14 -5 1 -79 13 -37 14 -39 -70 -35 -20 64 -4 4 0 -75 -45 -57 -46 -11 65 -42 2 -69 30 -5 18 26 -6 34 30 23 7 26 -9 -8 -40 31 38 -20 44 43 -18 43 -46 -6 14 -42 25 -61 46 53 31 -77 -19 37 -3 34 2 -40 -7 8 0 99 -44 37 -6 -3 -13 -9 1 56 -59 -17 -36 -30 -82 -37 -46 -37 26 1 56 41 -1 -40 28 -99 -52 22 -66 -4 17 52 -76 40 -73 19 3 -29 23 -1 -128 42 -89 -28 21 -38 24 24 75 -87 48 -46 20 3 -26 0 -68 4 -84 74 -13 -58 5 -11 -118 56 -20 -36 -11 -11 -31 -36 -22 -8 -35 -26 -67 -15 52 -30 23 -1 -49 -104 -46 43 -27 -89 -24 -39 37 -21 -40 7 42 60 -31 -98 -44 -30 2 16 -78 -54 -26 -10 26 -32 5 -5 -31 -92 -29 -73 13 0 -33 -36 57 -2 -33 24 -29 -106 -8 -120 -113 -67 59 -14 -66 -16 -5 -44 33 -8 8 62 1 -13 -14 46 -51 -52 0 12 64 12 -38 86 -6 -19 -21 -11 -46 16 -70 59 -36 7 -36 -16 -33 3 15 54 8 48 -118 -25 -59 26 25 44 20 -17 4 26 18 -51 -6 -14 39 -22 -51 7 25 -40 27 -11 -8 29 -11 -33 27 -18 -9 -45 -16 -13 -11 -60 29 -65 70 -22 -47 20 -33 30 12 9 22 -31 -16 33 -33 -8 41 -41 75 -3 45 -29 11 -7 50 49 -70 103 54 -13 93 -58 37 -36 43 -37 -2 3 58 -20 -128 45 -44 -77 20 71 -40 -21 -124 35 93 127 -14 86 -40 16 13 103 48 -57 -16 19 87 75 11 127 40 -123 -91 -28 -3 74 15 34 -68 -47 79 -33 58 5 -98 42 121 -28 -74 23 42 -15 16 7 36 63 -121 -31 -59 106 -41 9 -12 0 -13 -75 -7 -1 3 34 98 -13 -89 -30 -18 28 -5 23 35 -96 -107 -24 -34 95 108 115 80 -31 -67 49 5 -57 74 56 119 127 37 49 127 127 46 50 74 64 56 120 44 73 84 -45 125 91 42 101 -16 -27 109 116 78 32 58 69 50 127 92 -54 27 118 103 113 -56 51 127 -2 125 27 28 -29 78 99 -32 21 114 112 38 -99 62 83 -9 -9 42 -77 56 10 15 96 109 32 21 10 100 113 102 24 35 -19 41 84 98 54 -75 -1 123 2 91 64 22 80 122 117 -8 26 113 -39 55 35 11 31 76 77 113 31 -17 15 87 -41 26 -112 72 -90 89 -57 65 -77 96 18 -46 62 -42 -12 16 -31 53 -38 9 -68 56 -15 32 67 -43 -60 -17 -95 -127 -21 114 87 -87 -36 -39 105 121 16 58 -60 -110 -38 -103 5 -114 115 56 -48 -44 7 -62 -38 8 12 20 10 53 41 23 -34 -49 16 116 -44 17 -10 -34 -47 21 -84 -34 64 82 22 6 -27 68 41 -6 -50 105 -8 -48 -91 -10 -63 26 101 -70 56 -68 39 78 -27 -47 -36 -46 -93 -49 -46 -1 -7 -89 32 -16 -6 -86 1 -65 -102 117 36 60 -123 53 7 -31 126 78 105 -49 53 18 -50 -33 119 38 -46 -90 -7 59 -33 112 -62 -26 20 -19 1 99 -81 -80 26 78 -29 -30 -13 75 -51 -46 17 15 51 5 36 25 46 20 7 65 -110 73 32 -22 44 -128 106 -34 -36 -60 -75 -35 -3 -29 -20 24 73 62 -7 -7 44 51 109 -96 -8 12 -8 9 11 -44 12 63 -73 44 -7 29 21 -128 83 47 29 65 15 -34 41 9 -18 -47 -19 -67 63 2 -34 78 -79 34 11 110 -38 11 5 80 -38 -26 5 48 27 24 -40 -86 40 64 -21 11 -54 -24 34 32 -60 11 10 -124 24 -71 -41 116 -89 87 -38 60 7 26 -36 60 61 -25 83 47 82 -32 -44 -9 49 -44 33 -7 33 -25 123 -4 -42 37 -18 50 84 -66 2 -20 -3 -21 54 37 -17 12 59 55 29 -70 -39 30 51 27 4 -84 2 -2 -22 16 -128 114 -18 23 30 43 11 -66 59 1 6 -47 0 -75 13 -54 19 127 6 10 -25 61 76 -21 41 37 32 29 88 1 -53 6 -65 114 41 -4 19 38 20 40 38 33 -21 22 27 44 18 -7 27 124 14 -35 108 18 15 -23 60 -37 -77 -10 37 72 34 -1 40 29 6 -73 29 23 43 -42 23 87 30 67 15 35 42 49 24 12 -12 -7 66 -46 60 65 -58 -1 46 -2 -23 33 43 85 60 -23 47 7 87 -25 -22 -90 -23 -82 10 6 -29 -104 -33 -82 15 10 6 34 -6 -45 14 2 -51 39 -1 -9 -28 -7 -45 8 -83 -65 -43 24 -7 44 54 -48 -20 16 -67 -73 1 29 -40 18 102 127 0 35 56 80 45 22 36 37 34 -19 7 -7 -39 -19 1 28 -81 -10 56 92 13 15 11 16 -45 33 87 -126 100 20 -127 -43 -42 83 21 -28 -8 -4 -119 -20 -42 10 50 -75 -6 9 43 -9 20 -69 -70 -127 30 -86 56 16 91 36 -67 -49 1 -37 35 -45 17 -88 -91 -5 -40 -34 31 -17 -6 -36 -15 -54 66 45 3 -92 -8 87 5 -13 -16 40 -61 38 42 -34 -76 12 -22 -30 -27 -10 -79 -6 -23 -21 -65 42 -40 -47 -48 -3 -24 -98 -59 -90 -68 -2 -37 -64 -94 -19 127 -10 6 9 -16 17 -9 -3 77 -26 -42 -36 0 -26 10 62 103 37 -9 -45 26 34 21 -78 -18 -42 50 -5 3 17 40 0 116 74 -25 15 -127 -1 11 25 -30 -35 -112 -17 21 34 37 13 115 -8 -16 127 -16 70 12 9 -11 35 -57 32 -70 40 42 22 30 38 -3 67 121 -44 -2 89 -12 90 10 97 30 9 -43 -10 17 36 20 -27 -52 -12 -47 -32 112 -1 -81 -2 -46 -91 -61 19 -126 55 23 13 -51 55 35 41 -29 -25 67 -30 17 -5 -18 -16 -42 -33 -21 -13 -10 13 21 -34 6 37 -37 115 -80 -93 34 -41 -54 -6 0 34 47 -43 4 33 -45 -68 30 -8 -45 30 -46 -90 7 -66 -40 -37 32 20 0 9 38 -6 36 -39 18 56 66 28 -29 -40 19 -9 -13 -13 -63 71 11 8 38 -57 -14 43 -15 14 2 -21 13 -59 -37 -82 -6 -118 13 -20 24 19 -13 -10 -55 4 36 -111 47 78 35 11 -42 34 17 -11 86 32 126 10 14 -71 -28 44 125 -29 50 -7 90 37 10 -65 40 -77 92 1 77 38 80 16 -98 -117 63 -28 -84 -48 53 45 -40 -47 -59 -112 127 80 26 35 -101 97 -41 47 -9 -2 -18 -51 -124 123 -77 -12 23 42 51 51 124 -35 -67 115 -81 25 31 -30 -6 -43 53 35 50 -59 30 48 45 -35 -123 -5 -29 -69 -107 74 4 -25 53 127 -51 -43 11 -26 -55 -61 73 -41 20 44 46 18 65 28 -8 -21 5 -27 -62 80 18 -1 -38 7 83 71 -16 -6 -8 93 13 0 7 79 12 41 107 100 3 -45 88 -19 9 -114 -11 28 -19 -79 -35 41 74 -8 -37 127 43 -66 2 -61 -72 -46 120 -47 -100 -98 -6 30 -37 -4 57 17 -26 14 -30 21 -56 -1 59 9 24 29 37 123 16 19 50 -77 -78 -12 46 -61 27 21 -46 29 -19 -28 75 71 65 -34 -46 20 -103 84 -10 30 -61 -18 -20 12 82 51 66 64 11 -40 -86 -115 -110 -7 1 100 83 -57 -89 -78 -4 -51 -95 28 51 84 -38 -120 102 126 -63 -16 99 -85 67 125 -71 -35 -120 18 -36 44 -4 -37 -20 53 -73 33 105 -101 -3 89 2 -20 100 -28 77 -108 -15 71 0 0 -18 125 62 -91 23 35 26 27 59 36 87 18 -57 91 -32 71 -52 -60 -37 -60 -81 -22 -27 6 21 -41 -69 -37 -10 49 -37 -127 -115 -54 69 -96 -93 20 89 103 -14 32 123 61 54 52 121 -4 -26 -54 -116 -45 23 30 -57 19 66 11 -42 88 -88 -26 -16 -2 50 -86 12 -85 55 1 -5 -23 -50 13 16 -8 81 -12 22 61 47 -22 15 -8 -1 94 90 -7 67 4 121 33 -124 -23 9 -101 15 -108 19 -126 -36 -30 -5 -84 -17 39 -44 2 -14 -46 125 10 -51 -21 -22 36 -29 75 -84 74 -58 -59 -43 -48 104 -21 44 -69 6 -31 16 -79 -27 -21 -128 41 -128 24 79 -9 -125 -65 -123 -52 -10 8 -64 -53 64 12 40 -94 -126 16 88 32 30 -46 -29 -12 33 -14 18 -33 -52 -74 -128 -34 1 52 116 42 10 -70 51 -48 6 -55 18 -44 38 49 23 68 55 -21 -122 -66 -41 14 -84 -50 -8 -126 -9 111 8 -127 60 22 -63 -51 -25 -25 -87 -27 6 52 -43 -30 20 20 5 -17 -18 -31 93 1 -33 37 12 -35 -54 127 20 53 22 -16 24 -128 104 47 -126 -43 -78 -61 102 -127 -128 1 -52 23 24 -82 57 -17 -73 47 -127 -116 86 5 96 127 -12 21 106 62 85 25 127 27 53 -50 -27 -3 -20 -63 -126 65 45 94 -28 -30 125 73 -9 81 125 -28 62 72 71 126 123 -79 119 51 -18 56 -15 -28 33 -110 9 -106 -73 11 -102 25 78 93 114 -126 106 4 53 77 -23 -33 -57 69 52 54 112 95 72 109 58 94 61 -49 123 67 -49 -9 -68 -27 13 -45 66 49 -44 14 23 -44 -51 -11 -25 30 59 -54 -22 -3 8 50 -64 73 48 52 39 92 -33 -72 35 -46 53 -59 127 -3 68 91 -61 -85 -43 -94 71 -45 38 -77 4 118 126 -91 81 -23 121 121 8 37 -121 12 15 60 77 -3 64 2 -12 8 -100 -117 -51 14 33 -121 33 40 -64 -18 24 37 122 -4 -2 12 1 -55 40 -27 30 -15 48 60 -20 4 40 21 24 13 -43 -47 17 -51 27 -83 14 104 48 -42 59 47 -17 -2 -21 -58 38 -44 -37 7 -5 -28 -31 -7 -90 -52 -110 -26 98 -5 -17 -37 81 -60 54 48 -34 23 -29 50 35 -58 -7 76 45 13 -64 13 9 19 -23 -2 33 55 -75 -39 -9 -37 48 -39 31 48 60 -16 -60 -25 -26 21 -51 3 49 -22 32 67 -15 -20 -17 -82 -20 -72 33 43 -11 32 0 12 3 -12 25 -43 27 -31 -27 -70 -5 46 -24 -48 10 75 -8 60 -62 -36 -28 -10 -27 -56 -49 -28 -5 38 37 108 26 -55 -3 -34 -28 -43 61 53 59 77 127 24 -10 -49 65 20 -72 -22 30 -22 -109 -96 12 127 -13 64 -56 43 -102 27 3 78 -29 -19 85 4 -56 13 -12 -17 -10 -30 16 45 -44 -92 -95 8 -43 -51 88 -46 -22 -33 16 90 81 -110 -14 33 23 -43 19 14 -29 81 38 12 -21 -16 39 -32 -19 21 49 71 35 -70 -19 -81 -49 11 103 -17 -79 -45 -27 -55 -80 -19 -65 -58 27 5 -3 -28 25 -5 -61 -65 -85 46 -8 10 40 -14 25 -26 45 -116 -127 38 -46 -83 -43 51 94 -18 13 20 -36 73 -34 -37 -21 37 53 -66 -18 -49 -3 -72 49 -34 39 -25 33 47 -71 15 -118 -33 0 -15 105 30 -5 -25 -15 43 72 106 57 -17 -31 -56 94 -52 25 41 -111 3 50 -44 13 -51 -48 14 -97 17 9 8 -5 -46 -8 9 -11 -17 -34 -20 39 30 52 -52 -6 -1 45 37 78 -24 -23 28 -49 -76 0 32 -73 52 23 -52 -12 22 85 -18 -68 91 52 5 10 92 -2 3 -41 75 -53 17 28 41 -33 -19 -3 -49 86 32 -81 -15 -35 67 25 28 -60 14 12 -12 -22 64 15 -38 32 -100 -13 39 54 36 12 -50 21 2 103 5 -38 -6 -16 -38 10 75 -11 -54 -128 -7 -12 7 25 -44 37 -98 -22 4 -25 14 4 -47 -127 -6 71 16 -9 8 -47 -26 -48 77 45 -11 54 -3 -42 112 32 -31 -67 -31 -64 5 45 -116 11 5 10 60 -3 24 29 -59 -39 -23 42 -68 16 -42 -48 -121 -3 94 12 -40 -18 -1 40 17 73 -12 -23 -16 23 16 -75 -27 -45 3 63 -72 53 -48 30 59 5 27 -49 -20 -29 5 24 22 -86 -10 -92 26 46 8 -40 3 -67 -23 46 -31 44 53 -17 56 58 83 -7 53 34 -11 -79 -29 58 22 -89 -76 -19 49 14 24 45 20 -35 19 -26 -59 49 50 -38 122 69 64 91 9 28 -89 2 49 -14 2 28 -37 -30 3 41 7 19 11 -25 -66 -7 11 39 14 93 43 -39 65 -34 4 -106 -15 8 1 77 -34 31 2 23 19 1 3 -9 50 -16 -82 -100 1 -58 -41 6 5 -48 27 16 -126 65 -33 -43 72 37 8 45 13 -31 37 71 -27 52 -96 58 -63 13 8 20 47 32 -34 -34 -53 -19 -34 4 -11 -25 96 42 -24 -48 19 105 5 -42 19 -9 24 51 -39 -98 10 40 -17 39 15 11 30 0 82 77 0 55 -18 -60 -17 -44 20 -44 8 -53 8 20 30 104 54 43 -47 30 -15 -81 -7 60 -20 -33 -34 27 -41 -22 54 32 21 -21 -78 -102 34 -33 -26 -26 -5 99 25 6 19 88 -36 -96 -24 70 -27 19 4 11 -36 64 -84 -21 -98 83 -38 -57 -3 -124 4 -127 3 8 -13 -37 89 -17 -113 99 23 -7 27 -13 -73 47 -121 -24 23 76 122 64 -27 -51 18 10 63 32 11 57 -46 22 36 70 -6 46 23 77 17 46 -2 89 3 -88 42 34 50 -18 -51 40 127 46 -21 18 -12 -110 1 47 -32 65 -96 40 63 11 61 30 -65 -70 -40 15 -20 23 -2 -61 -39 6 22 -128 -18 42 12 -84 -34 64 -25 32 -41 35 13 9 -117 24 28 -23 26 -83 52 -20 83 60 24 -36 50 -9 -37 76 65 111 -85 93 7 53 -15 -127 -25 -74 48 84 120 -11 58 -97 -33 -82 -125 40 -11 10 72 -8 13 -122 52 12 -74 93 34 6 60 -6 3 34 29 -120 -6 -21 -10 31 -46 -107 -61 -1 -15 8 -123 26 5 -50 -101 -104 -46 -18 -63 -49 16 25 -24 17 69 46 18 97 51 72 -17 -41 17 36 -10 39 -22 43 -81 -44 -9 72 -21 -56 -4 34 44 -3 31 67 -49 -31 127 33 -45 -12 -25 53 -27 -40 -25 89 15 -61 73 -52 4 26 -19 19 -30 -37 15 54 25 22 -3 8 -70 82 11 -19 -37 -36 44 19 27 18 53 6 37 41 64 59 23 72 -36 -53 -17 -49 16 -3 -30 -2 -119 29 -64 -27 11 7 -24 14 39 -6 27 76 -2 -93 -52 -21 94 51 -21 -27 68 -22 27 9 34 8 -63 55 -81 80 -23 17 54 -127 78 -73 -98 26 111 36 -18 0 31 104 -39 17 69 -37 -6 16 10 11 -15 25 -43 28 21 -25 -78 -106 7 -14 -46 46 38 -22 -18 103 9 -51 -64 -79 -96 -115 71 38 30 15 -15 107 -16 40 29 5 11 72 -106 29 57 0 -60 -128 17 -125 -73 102 2 59 -48 -116 16 32 13 6 37 72 -1 22 21 8 20 42 -26 -39 -21 -21 56 -43 38 89 21 -56 89 125 4 -48 -13 -106 -75 -125 -123 68 -103 -47 -22 11 -45 -37 -97 -17 24 -16 28 -54 14 58 -18 -17 -62 60 34 12 80 -125 -70 -78 -35 -43 -23 33 -115 -72 -62 -103 -128 58 2 -8 -5 -63 -1 -117 -82 -7 -37 -44 -70 107 62 37 -1 -59 39 -114 16 -20 17 15 -92 -121 -94 123 -56 -112 -60 -52 -65 -78 -36 -96 -59 9 16 -33 56 -1 -47 -7 127 75 -44 23 58 -32 -69 25 33 0 -35 -1 -23 49 -53 -92 -1 1 -68 2 33 10 -32 18 -59 -13 -48 -22 -26 -29 44 -69 40 -41 -43 17 -9 12 -47 -53 -23 -22 -18 -10 -1 -18 13 -1 13 46 -22 55 19 12 25 2 -9 -21 29 -31 -39 -64 -3 -11 -53 1 -14 28 0 -44 -76 10 -39 11 -85 -23 -25 -41 -19 -6 -13 -18 -44 9 3 -4 -9 -16 -59 -24 49 -34 -24 92 48 -46 20 -36 40 10 25 55 24 -19 67 33 73 -8 -33 -14 15 -1 127 -82 -9 -16 -14 -35 20 70 -58 111 -67 29 -86 -62 -43 72 60 56 23 -16 -26 127 50 -33 9 62 -58 -84 -23 -85 27 -14 -119 -17 -30 16 -74 -9 34 -39 -43 -79 -21 81 21 2 -73 1 -47 -101 -109 3 50 127 -39 107 71 -46 -42 51 -6 -87 51 -70 -29 16 -103 -65 84 -45 16 81 42 25 2 95 -3 -69 100 -7 49 100 -5 20 17 79 51 92 -113 -12 88 32 116 -27 -73 -14 -23 127 127 12 17 39 -69 -106 -14 -59 -73 121 -29 -29 12 127 -99 -103 13 -9 28 30 31 6 108 39 83 50 43 -5 92 83 25 -41 -119 26 26 -64 24 -40 57 -2 -48 -96 -10 100 27 39 -23 -22 -58 -52 28 50 50 26 -48 -124 36 -101 43 -117 11 38 22 -88 85 -55 10 -39 101 127 -95 34 57 90 91 12 -42 14 69 118 57 -57 94 -95 13 -73 29 -49 -24 112 121 -43 -34 100 26 -42 -30 -5 -106 79 -41 -25 61 -20 -81 29 114 50 27 -17 110 89 -49 -65 -79 -7 -28 -84 -25 36 127 -5 61 28 52 48 -37 -19 117 -35 22 69 94 -102 -33 29 -38 -1 111 -61 8 -50 -41 -46 65 86 -74 50 73 -70 87 62 -37 -109 -27 -4 113 -128 -47 42 37 53 42 9 -2 -6 -56 9 -8 16 -10 74 31 17 94 95 -14 -121 37 -37 41 83 24 -126 -29 6 -29 -33 23 -20 -103 -22 -59 12 -94 -18 -31 1 -44 23 127 -25 44 105 56 59 33 -42 120 21 69 66 8 -38 -27 34 94 8 121 -90 1 15 2 -21 -59 -35 -22 65 -6 19 -66 -70 56 -51 96 35 47 30 -11 -19 -110 -30 33 79 125 -120 -15 -87 26 -127 70 -34 -21 53 -25 -20 -71 80 20 77 108 5 46 22 -38 -60 18 119 -22 58 71 -117 11 -126 -122 -6 -3 32 -48 14 23 55 34 -12 -126 29 -19 48 -82 74 12 78 52 -18 5 -28 12 127 83 -114 -96 6 44 127 -7 61 13 28 -45 -44 17 -57 -96 6 11 127 109 127 -38 -11 -46 10 -119 127 -121 41 14 -82 8 -96 -54 33 -18 33 61 16 -22 10 127 102 -37 -86 -16 -94 118 -13 42 -70 12 39 105 105 29 -31 97 -63 -20 -15 -38 119 -111 33 -74 36 -87 21 7 18 118 -28 3 -25 -7 -124 -94 -54 76 67 91 -24 -22 -119 75 -60 -19 127 14 99 113 -127 83 63 28 83 -68 114 -63 -77 -123 32 -94 -57 99 116 87 70 -3 -23 127 2 51 77 20 -33 27 116 82 74 -119 -35 70 116 54 76 61 -116 -2 -57 -27 15 25 -43 -18 -18 95 5 84 -14 -127 127 -119 -66 -97 36 109 57 -21 28 -120 -41 -8 45 44 52 -28 18 26 46 31 -123 -25 29 69 120 -4 -105 97 121 -23 14 -14 -7 3 56 -58 115 -36 18 -9 -126 44 -90 58 53 2 14 -18 29 -120 26 127 -8 1 -1 -128 -124 -128 -128 -44 34 27 5 -26 -17 -2 -64 -34 -125 24 125 98 -11 -44 -43 121 79 30 55 -93 99 127 -85 -72 -60 23 -78 -95 -54 -86 -37 127 -76 28 126 -126 127 127 11 -105 -76 47 -60 58 -25 19 32 6 74 -50 -12 -123 -112 -13 -43 -42 -20 -42 -69 3 -35 127 87 -90 -74 -2 -107 16 49 -70 122 46 29 3 -94 16 27 -81 -1 -26 -120 99 8 99 100 14 120 52 -94 -24 -64 14 121 5 -26 -113 61 3 48 -89 -120 -36 -41 17 7 50 110 32 -68 -117 -16 -79 63 43 -49 61 -33 93 -80 -61 30 26 -55 78 114 126 -112 75 87 -20 -50 -46 -119 -34 -127 19 -99 63 -52 36 122 -47 -47 26 -64 104 -39 -84 116 -67 16 -31 32 -52 3 126 4 15 -116 31 -20 -24 -12 4 -30 -23 90 127 5 37 -92 32 -56 -29 127 -10 24 -77 -36 50 91 -25 121 88 59 41 55 -53 -68 43 46 105 92 2 25 88 -86 35 14 12 56 -122 -84 58 57 -16 -52 -35 26 23 -2 -6 -71 -81 8 -81 -16 -82 127 -26 -13 18 95 -115 1 117 -13 -50 8 -55 -126 2 -69 15 79 18 36 -85 -113 -81 -75 81 85 -39 15 77 70 24 -77 -11 113 127 -74 -66 -40 -74 -11 -76 34 -104 -11 66 59 14 -3 39 20 87 -71 0 41 -39 124 28 34 -124 53 98 107 -27 -31 -23 69 0 -42 11 -36 24 -15 -55 11 23 -116 -51 -29 28 12 31 90 53 -53 18 -73 -40 19 -64 -35 -85 -77 40 -47 -7 52 -26 -4 31 -22 29 -37 67 19 -6 -38 2 -2 -45 -49 -28 -125 63 38 91 94 -52 26 71 1 121 29 18 8 -23 -33 -44 -8 104 -76 119 -28 -22 -36 -3 -49 -68 74 85 -59 -27 116 -75 -21 16 -3 -41 -73 7 -15 -39 -27 36 -12 -75 -43 -60 -66 34 127 32 -22 -37 -70 30 49 15 -17 -104 -27 -41 -94 -24 64 -50 -75 -126 -100 -19 -22 -20 41 30 4 10 -6 42 -2 2 -32 65 -41 -81 -65 -16 55 -115 78 -69 -16 -40 -16 62 9 26 113 70 -73 40 63 38 -71 -59 15 85 12 -24 -86 -24 -128 -15 10 -6 -75 -36 -38 -29 6 -4 -25 -13 -59 -49 -33 -68 -40 -64 -47 -43 27 -23 -18 39 9 43 -9 58 -49 -2 119 -75 -90 -76 -50 3 -37 -15 -4 -65 -17 -64 4 32 -113 -55 58 -127 35 -53 -57 -12 45 30 31 13 39 39 -39 48 -27 -34 -5 6 -48 21 13 32 -53 37 0 10 -43 28 -49 34 -22 -127 16 -16 -83 52 95 39 95 -21 27 -39 -1 3 -8 28 48 -16 -54 115 -43 58 -45 -94 8 -61 49 -105 -48 28 67 -49 28 -24 25 0 25 -21 -109 -85 -52 -86 -37 -13 7 -22 -65 97 -78 9 17 -70 -11 -15 -43 -1 60 7 -73 12 -82 -12 -30 66 69 22 -52 2 -33 41 12 57 -52 -31 -6 39 27 -45 -27 -15 -15 29 54 9 11 -24 0 26 43 -86 -38 20 -87 -1 -11 70 100 -10 30 -28 1 11 -11 -41 50 25 -17 61 17 12 -70 29 21 -47 -23 -47 9 -39 -34 -14 -19 -117 -15 -41 49 72 -61 45 48 12 -6 28 -43 -28 40 39 -14 14 34 -46 -10 20 -6 14 32 -29 54 -68 -55 31 -127 115 -58 -2 13 71 -80 -53 -28 -45 -121 -119 -126 81 -101 112 17 51 61 -93 -27 73 -90 20 102 -10 -30 -63 119 -105 17 -73 11 -31 -94 17 19 -66 -127 -117 96 105 -29 -62 0 -58 119 36 52 81 -72 1 -19 -30 -72 -28 125 -109 86 -21 -16 53 55 49 -126 -69 -59 -67 14 18 -127 -128 52 -38 94 -5 -117 -89 -16 -26 -60 -121 -127 62 -81 48 -61 31 -3 -15 29 -3 50 7 -31 -91 53 19 56 -6 71 -27 -62 -81 -37 -1 7 -15 20 36 19 -35 -40 44 21 16 61 -15 44 54 42 -19 -2 -27 -6 13 -119 -65 41 101 16 12 42 25 -20 60 105 -50 8 57 33 75 -116 -4 11 105 22 13 -22 63 -10 67 -20 62 56 5 -16 -28 9 43 40 5 -43 -104 83 28 -1 -58 -32 -42 -44 20 54 -16 60 -6 -30 -37 0 48 -62 107 46 16 9 54 34 0 31 48 23 73 -61 -66 53 -6 -25 -40 119 97 -25 64 124 8 102 53 51 -119 67 31 44 -70 -4 -52 18 -51 106 42 -112 -30 1 52 60 -9 21 123 -28 54 21 26 41 -118 16 -128 30 -67 -18 31 -82 4 -59 29 75 -47 -89 -102 8 16 -110 -86 -72 21 -26 48 103 -46 -29 56 112 47 86 -127 -58 -124 -77 27 17 -33 -33 -30 93 59 -60 -128 -69 78 40 127 25 -32 -17 93 -11 47 -123 -77 -8 -76 7 10 -123 -33 -71 -4 5 -42 55 31 -7 -124 87 36 8 10 12 17 -11 -87 -2 -126 15 -1 -10 -60 -72 -106 17 49 -13 -92 -56 -8 -73 -4 8 72 87 42 -69 -46 -14 13 87 -50 -90 -24 -89 -39 -123 52 81 77 -36 -106 11 121 -122 -63 -17 -45 -73 13 -95 -65 122 -31 105 -14 68 -52 -56 -29 35 -5 -47 -4 -16 -127 -124 126 1 59 -49 41 -3 -3 2 34 4 9 0 -31 51 -74 -96 89 -11 -73 -49 81 43 6 -48 -90 9 17 -54 79 -56 108 -69 1 -50 12 19 -32 31 -37 -52 -9 -35 -54 -31 -128 -36 85 -7 31 36 -2 28 -10 39 -12 18 107 31 127 -109 89 -85 29 -62 -33 -47 70 -48 6 5 -99 -14 31 27 -71 62 29 12 7 43 -51 20 -52 -14 13 43 16 -113 -75 13 -58 -37 48 96 -97 -21 19 -12 21 -6 -24 47 102 39 95 85 -41 -8 -28 97 18 8 -21 127 -100 46 117 55 19 23 -79 21 52 -21 53 37 -26 41 -9 70 -15 39 -53 -5 11 -19 -31 -30 -14 -83 -70 -127 12 98 73 -8 -60 73 -71 59 15 40 -5 -3 19 -66 -51 -33 -23 -32 20 8 4 -36 -66 46 26 -70 35 -4 -8 -36 82 -23 82 -21 -57 62 45 54 3 15 25 88 54 -42 -3 -43 -17 68 25 -32 47 69 3 -42 -76 13 -17 77 -123 6 -34 -84 -74 53 28 -13 101 70 60 15 124 -11 23 34 25 1 -2 96 -45 -58 30 -20 -43 -12 17 -36 -45 75 95 -56 61 -122 7 33 -34 -20 -124 -47 97 -87 -45 8 -87 -33 -15 -33 13 7 -25 -120 26 -24 -12 33 40 -22 -11 -17 77 5 107 124 -33 -12 -111 -121 24 59 13 40 -40 -80 -14 -16 -29 -71 29 -100 14 -23 29 -116 -8 -96 64 11 -105 12 -18 -33 59 -23 11 -49 -73 96 16 15 53 25 -18 -100 -45 57 16 -47 -19 11 -31 48 48 79 -54 -6 21 58 -19 -66 43 -56 16 7 93 -75 61 7 6 25 -53 18 -1 -98 -107 103 62 76 -78 36 49 15 75 39 -30 88 59 69 -11 -19 23 -61 46 -9 -21 2 66 8 -18 -83 20 33 -92 105 -67 -27 -24 2 66 4 13 39 51 40 -10 112 50 34 -79 -12 -52 55 78 40 -54 -48 -2 -61 -11 -41 90 37 87 58 18 -18 -36 4 26 -60 78 79 22 62 -41 21 21 45 -71 127 -27 106 -28 127 -78 -125 -34 -47 -52 -26 19 -6 -35 123 73 -43 -122 1 65 -28 0 -26 19 27 69 -85 -25 87 -6 -74 -3 31 -118 35 -45 -18 37 4 -17 -22 -27 75 -90 -44 -30 27 -77 102 -76 -30 -28 69 99 41 54 22 77 -4 -35 51 -43 -73 31 24 17 52 -27 39 62 -57 11 -87 69 0 -32 60 -40 -102 79 -120 -100 -28 -66 -7 -25 -12 8 -3 -24 5 -19 -65 7 -20 -51 5 -107 74 43 -18 52 -103 -15 -114 -46 125 61 -1 -69 -39 -24 -88 42 -110 -28 -34 55 -125 -121 107 -45 -41 127 5 3 22 -38 103 -86 -38 -68 57 -121 1 48 -105 -35 38 -16 -114 -63 20 -13 -123 -14 48 -65 50 -53 -3 1 -22 -24 -66 10 22 -16 -16 -38 35 -15 -5 -59 126 -20 -120 -40 -13 13 -28 -13 -14 20 120 55 120 -19 105 -17 15 74 -16 -114 16 72 -22 -19 -1 -47 -88 -74 30 -61 -19 -66 116 74 -46 -30 -45 57 26 41 25 -30 -102 -64 -7 -12 -5 -46 33 -81 -41 -70 -51 -19 -19 -35 45 -6 26 14 -1 31 -60 -17 -63 16 -48 -31 31 16 5 -6 19 -27 -27 -11 -51 64 19 -54 16 -46 27 53 49 58 -98 6 -27 65 37 -33 -15 -19 -45 78 -19 -57 12 -33 -63 119 56 -6 0 63 4 51 93 15 29 -41 104 -53 -54 91 28 -83 -77 5 -53 -69 -11 -65 -45 62 -51 11 72 -32 -23 28 -23 13 -23 -72 41 -41 -22 -27 49 56 -12 -31 69 -31 -20 -2 -67 -72 -114 -48 -58 51 -13 16 -46 -17 -74 -5 -11 13 68 -17 13 127 -22 15 2 45 42 67 -108 16 49 -21 -7 5 12 -52 -18 -32 -31 44 57 80 58 -38 -14 -8 -55 -108 -25 -127 13 19 -17 -25 -16 126 20 73 -19 98 22 47 16 34 49 57 -53 126 64 -118 -1 105 39 -5 88 -94 -1 118 83 123 -60 -125 -56 38 109 -4 103 -77 22 112 -87 -127 -9 22 -10 34 -23 79 -50 10 -6 46 47 59 3 80 -108 46 0 31 -121 -6 -109 4 36 39 -12 34 29 76 -32 -3 -118 43 -35 3 31 -35 11 71 78 -9 64 -88 80 -79 14 79 -59 -62 -125 -4 -88 99 -92 -84 35 25 -4 79 -91 -5 -27 -33 -63 -59 7 -74 -21 32 53 59 18 -8 90 -42 -26 90 -17 -13 -20 -59 43 -68 -7 127 -35 91 -49 3 -127 69 126 -27 110 -5 58 33 127 -27 -19 -30 76 36 30 65 -52 -11 -65 -70 59 -19 29 -46 -75 46 -40 3 47 -16 -43 -18 -68 -109 -127 12 30 35 -71 -39 -27 -22 42 -54 -13 -50 125 60 33 -25 -103 -54 61 42 -18 -82 6 31 -86 29 23 32 107 102 102 10 79 -43 17 67 22 -69 -49 -45 39 -21 87 127 26 3 54 -19 82 -29 126 94 109 -102 22 11 27 127 -8 -76 -23 -16 55 -24 38 -57 39 -46 58 -51 -18 -93 -81 28 -117 -26 5 46 -27 -54 -47 45 127 99 11 -81 -10 -28 -107 -34 -3 44 -127 -9 -70 -67 74 -65 -5 -25 -8 -50 -94 23 -34 -29 49 -39 11 -13 77 40 77 -85 -81 -86 30 17 -89 -40 -22 -9 10 86 -57 -77 -99 11 -128 35 -25 -93 37 35 -41 -116 -17 15 -117 -3 13 11 -23 34 4 -27 99 -24 34 -126 -30 -31 56 -63 33 0 -100 -43 -65 32 103 -76 -14 -82 28 -47 29 10 -16 23 8 -21 -61 -1 -59 -34 27 -90 2 40 119 -65 19 12 8 7 -62 -57 -66 -17 -80 -61 6 -23 55 -74 -111 -32 51 -71 -121 57 -23 -128 -12 30 -31 -40 -67 91 -40 14 -37 -121 -13 -98 4 -117 12 -39 -85 30 -78 -36 22 32 -4 -36 45 -7 -54 -26 31 24 -62 -127 -36 75 -28 -61 -5 -61 -11 -82 -119 -8 -104 5 127 -20 -61 -19 -10 -34 118 -9 -9 -19 35 42 -46 -22 -85 43 -9 108 14 -40 126 -13 32 -58 77 -2 -128 38 -19 -80 -4 -57 127 5 -43 25 123 104 -21 57 3 -19 39 -4 43 35 113 32 -24 99 127 29 22 -22 -124 -128 10 -17 2 -68 -76 -12 65 7 42 -75 11 41 -7 -38 -48 -43 -84 98 6 -28 -11 -24 -55 -27 -3 80 -45 2 -17 -54 15 126 26 4 -10 54 12 14 -93 -95 49 15 63 -2 -1 -33 18 1 31 7 72 82 -33 -61 10 52 49 -17 -19 15 74 -32 63 -44 104 69 4 108 -2 -77 -66 -25 -121 15 22 -124 -38 40 -71 11 -38 -48 12 -27 -58 -54 -55 -15 -14 127 -87 14 -90 -110 -125 -112 123 50 -128 -76 -44 48 15 -111 53 62 -11 34 -100 21 -16 12 -52 -39 92 50 96 -52 97 26 126 28 41 29 38 57 -45 76 -81 -30 61 15 54 59 -35 43 -62 -94 -32 121 29 -78 52 73 45 -28 -44 -44 105 45 126 116 -38 -18 -1 -65 69 3 -55 63 66 2 31 54 61 95 -126 51 33 -36 116 50 77 -120 84 23 -7 -39 40 42 7 -4 33 53 103 34 11 -30 -51 -41 41 -13 2 4 -47 -42 93 40 83 9 -47 -46 -73 112 8 48 100 33 -36 -15 -2 -23 26 -37 39 126 32 47 7 -60 65 1 -82 -125 36 -26 -27 38 -36 -113 -18 5 95 17 -12 51 -11 -121 68 35 -86 -54 38 -32 60 107 -69 -16 34 57 71 -58 -101 -89 -42 42 -28 -26 -79 -67 -109 9 35 7 7 32 75 -58 28 127 -7 103 35 127 -64 -40 -68 -20 -9 51 -65 57 33 36 -75 -84 -15 -43 114 -71 31 -19 10 122 93 16 26 54 96 11 -20 -93 19 -113 -63 -34 -13 -49 29 10 26 100 -57 -10 -92 22 -35 34 48 127 -69 59 -40 14 -91 29 10 -12 -46 -127 8 127 125 74 24 -40 43 -53 84 -35 -125 -54 127 127 53 111 123 -22 -6 -127 59 -23 -74 4 -81 -52 -115 121 80 12 -27 37 14 125 20 19 -24 -34 -24 127 -27 41 71 -62 18 -61 11 19 1 -49 -59 -40 -127 -60 -127 127 2 122 57 -128 -128 75 -65 -85 -86 -24 0 42 -124 -32 87 -33 31 45 87 18 -34 100 -127 27 90 -109 -128 -73 -83 -69 119 -115 39 -1 93 -128 -80 -8 -33 -52 -58 -120 11 17 -49 -7 7 -36 -6 127 -58 -125 -27 51 8 -44 94 -20 -9 -77 17 77 32 -38 27 -25 -70 57 -44 29 -38 36 -33 -46 -16 -116 59 -83 -73 55 -75 -93 21 51 1 46 -3 -53 23 -84 63 -57 -52 60 88 -77 -31 -35 2 2 -36 29 -12 98 16 -96 -6 106 31 -78 -23 -11 46 -43 48 44 4 50 11 -38 22 -26 -96 79 -11 -29 -122 -19 -3 -9 27 -60 -60 -49 117 -102 7 -50 -71 8 -16 -47 14 99 -5 68 127 55 74 52 -28 41 -72 -65 28 -5 -101 41 12 -10 -93 -54 -90 49 9 12 -10 83 79 -125 -61 26 -54 -11 -29 -36 -57 -49 -36 -2 18 -32 98 4 -78 -10 -53 -51 -32 11 52 -88 42 127 23 62 30 -42 -84 111 -36 31 -42 126 54 -44 39 -29 8 -55 30 110 -49 -95 20 21 -112 -16 6 -7 2 75 44 -78 18 34 -8 41 54 21 -30 -96 33 61 34 76 7 -6 33 73 7 -26 -97 91 55 49 -27 25 45 69 3 55 -53 -45 62 52 -7 -34 -58 30 -59 17 40 3 12 23 11 39 -33 32 -58 125 71 -30 25 -52 68 10 28 34 10 -97 -14 -51 6 24 -37 -13 -41 -32 -4 -50 18 -3 9 10 -87 -16 69 -25 -82 -32 -25 -127 -73 -28 -13 -87 -49 93 -104 -64 -56 85 25 -9 -23 -79 -112 99 11 52 -7 -16 46 -42 34 -1 -9 -73 -98 -12 48 56 -60 -8 38 -120 -8 47 109 4 -18 -122 -17 -3 -43 -106 -58 -99 52 -39 -43 23 -44 -76 -82 15 -29 -98 -120 19 -56 -111 -23 -29 -48 -55 93 -12 -74 9 -93 -45 -31 -102 -91 0 -24 85 -12 60 -17 119 115 60 -85 -64 5 -74 -97 -32 71 -106 38 19 -67 -106 55 -67 -30 -66 39 -67 -65 15 -7 8 60 -10 -43 -53 -56 -56 6 -33 21 -14 14 -100 62 -46 11 55 -42 108 44 42 15 -11 3 28 87 48 77 -24 76 45 7 -18 18 -15 -12 -20 -11 -14 58 -31 70 50 -39 24 98 -13 -36 109 59 -50 -51 1 -27 -40 -33 39 -30 11 16 -21 -13 -19 -9 -44 -44 -61 -52 -60 109 12 -30 13 -27 7 18 -18 49 17 -52 14 -45 39 -83 22 35 -45 38 14 -24 7 -26 -39 79 -50 -68 -26 -5 35 -4 0 -23 -16 22 119 -30 36 -33 -8 44 0 -65 -5 -46 -68 24 48 42 -35 -53 -12 -24 62 8 15 -26 -38 -79 -29 -93 26 35 51 -12 -57 54 39 -17 -43 17 -38 40 95 63 13 10 -126 -21 1 -25 -15 23 11 30 -7 56 -80 53 24 48 69 50 66 6 13 1 46 55 70 -26 11 23 97 -39 35 21 -72 -88 28 -34 -24 55 17 -15 -23 -32 -9 16 -4 -10 41 122 125 76 121 -27 89 69 17 -18 102 -73 -30 51 103 -21 127 -102 49 33 41 -80 67 9 125 -97 -3 52 20 -74 -35 44 -66 63 -53 126 46 -48 -67 84 23 -29 -59 -54 62 47 31 26 20 -24 -5 125 62 39 39 96 11 12 122 62 -19 60 -113 4 79 1 100 62 21 -93 -112 12 39 -126 4 100 -103 29 98 -30 65 5 103 71 26 120 -128 -68 101 10 -69 -57 62 -51 -34 -45 -128 5 -18 -70 50 87 1 3 84 29 90 -126 55 100 21 -22 4 -124 -52 -17 -46 84 18 10 -44 -1 61 -81 -15 40 -35 95 -13 107 33 102 67 -92 -58 18 -99 32 -48 84 -52 10 12 -43 -57 47 -30 -79 48 -42 -115 -54 24 -55 -46 52 -76 -78 -96 -86 6 36 -80 -72 -32 -68 30 -39 76 -59 11 -10 21 79 -22 -30 -21 -33 -49 -45 -50 88 36 -43 97 108 66 -9 -44 55 41 -76 -5 19 -44 -56 -55 -82 90 -93 49 -31 -21 -127 -49 -72 -54 -126 -125 45 -27 -11 -26 -82 -28 -86 123 6 19 -5 -54 -21 59 127 -5 86 58 91 -127 -106 -70 43 32 -120 -32 -16 105 -75 127 -78 -21 127 -32 -63 102 49 10 4 -45 77 77 -58 124 97 14 56 20 44 8 -57 4 60 -32 -19 -8 -102 32 38 106 46 -14 29 24 49 -78 -30 -47 -42 38 64 -22 -26 -80 79 -11 32 21 24 -116 -77 67 46 67 -91 -76 -5 41 -36 -44 -121 116 20 73 81 -3 26 -68 38 42 52 118 -27 -47 -31 -30 49 76 45 58 39 49 -65 -36 -62 -23 106 -12 55 3 34 -41 -50 -123 -41 50 -10 -102 84 -41 107 93 18 -22 121 64 58 22 -96 13 114 -39 87 -19 113 124 -39 53 -41 -28 24 -4 -59 126 45 -25 -40 48 45 -81 70 53 -8 127 88 -64 51 14 76 -67 9 -93 8 24 -20 32 -38 68 -88 -16 -21 -75 -120 6 63 60 13 69 126 34 -64 -5 -18 37 -50 -117 1 -4 11 -84 -34 52 -24 8 -14 21 -11 -64 -46 -90 -79 -3 34 -33 -38 23 -1 -3 -57 -119 -20 48 -14 58 -79 52 -84 -40 47 88 103 -61 7 -36 -8 31 -27 -52 -18 -53 20 54 -68 -8 -32 -9 34 -57 -4 -118 -32 -49 11 42 -70 -64 -11 57 -12 -37 24 46 -56 -56 -101 54 121 -47 111 12 -49 -31 -44 56 -43 15 -45 62 -51 -17 -25 67 -46 -65 -8 37 -84 -15 -67 3 -61 83 9 18 59 -13 35 38 94 2 104 75 78 90 44 29 97 62 -93 -125 -19 -33 1 -113 -23 126 -26 31 -58 -27 56 -76 41 119 13 -88 52 66 -86 27 -64 21 7 -41 17 -23 92 -100 -94 26 -69 15 -49 -41 -78 -17 53 84 44 17 -36 24 -34 11 72 -24 -5 70 14 22 22 -31 8 -123 60 -88 -18 -33 -108 -65 -107 121 -69 43 -122 80 -115 -44 -120 82 5 -80 -46 -64 -30 -68 -54 123 -98 -124 -12 -90 -87 -74 122 -41 -92 -66 22 49 -86 -72 43 24 60 84 -73 -88 -2 -66 -22 -36 -40 -45 -86 56 -12 15 40 35 42 66 89 7 -54 -59 -23 -42 -125 -41 38 21 -71 -10 -15 -91 -127 -47 -79 7 -19 43 10 -95 34 57 59 -79 -51 -7 -36 -66 42 54 40 6 -3 39 57 -42 -123 23 -20 9 35 111 -34 29 -40 -83 -126 5 17 63 48 -43 46 65 -84 -77 80 1 57 -119 -31 -27 -58 -73 -14 41 -37 16 7 45 -60 96 4 28 6 -38 46 -53 2 20 -26 -2 -3 -41 -42 65 27 20 -112 -43 -48 -10 87 -104 67 45 -39 2 -39 5 -44 -9 77 -22 -2 52 -58 -87 25 -24 20 -12 -103 -28 -77 -54 -52 20 58 -34 4 16 -21 97 -4 17 93 5 7 -39 -20 -126 -88 46 -61 121 -18 -35 13 -51 54 2 -31 -32 -45 25 -101 -120 -58 43 -128 -118 23 -67 -83 79 -59 -47 41 30 108 60 17 3 -48 82 2 31 -124 -8 119 -87 40 -60 -2 -1 -71 -64 -77 37 9 113 -1 -6 69 -11 -86 35 28 -1 28 56 116 30 41 101 56 20 53 125 112 9 2 20 6 45 7 -32 -120 62 120 124 -108 60 67 -86 -59 -1 103 -47 -108 22 -10 29 105 60 -26 62 33 -48 -86 59 84 -54 -121 -46 -127 -31 28 -34 -81 16 -51 4 127 -66 -47 60 -46 -26 108 73 -118 -127 -87 -31 66 -19 46 42 40 -27 -71 -25 62 -77 52 -118 -1 82 -60 -69 61 -41 -80 -126 54 -40 32 -32 2 -5 -37 -33 -26 -35 77 76 -13 0 -11 -39 -3 -92 72 -127 13 17 -41 -27 20 -66 6 20 39 -21 -119 41 -41 -23 -3 10 3 -127 -23 25 -67 1 -15 -22 -7 15 24 4 -32 -34 10 44 70 40 -62 -58 -51 -86 -25 -118 70 5 9 -21 -93 -45 -70 5 -49 -56 49 -67 -27 -38 -123 22 -5 -59 35 45 -88 -10 20 33 9 -17 43 -38 19 59 -16 20 23 -13 9 30 -19 -74 -62 20 21 15 -66 80 29 -14 39 67 -8 -2 26 13 10 -13 -17 -26 -38 10 10 -9 -34 -57 -33 -59 40 -34 61 -63 52 -11 77 -17 37 34 60 -13 69 -35 -20 70 -109 -22 9 62 -31 -57 111 68 -38 23 -104 -59 -26 -3 41 -25 -42 -39 -86 -71 -8 -71 -87 -122 -65 9 127 -74 -16 -3 -25 59 15 -103 -17 5 11 -106 58 39 1 54 32 -29 102 -52 127 -20 8 -6 -14 44 52 14 -37 -73 -68 -1 -8 -44 17 -13 -43 -47 -12 -10 -66 -55 -66 -13 -10 39 -28 70 -7 21 -37 -115 -22 -5 -88 -72 -6 5 106 -14 46 6 -57 -128 -50 6 -17 40 81 -1 -65 -2 37 90 91 64 64 65 30 92 39 -49 61 -14 -39 14 127 49 -30 17 123 124 107 73 -24 -89 60 124 63 114 50 -17 81 28 39 -120 55 75 82 -30 64 -12 1 65 -32 51 38 82 -24 2 43 16 85 -1 26 -19 127 2 35 -35 50 58 -66 75 107 66 -9 38 -42 20 56 43 41 77 26 -20 10 -67 -3 15 -30 -22 7 97 51 39 -21 78 58 -52 -55 -9 5 110 4 54 93 119 -40 26 104 22 19 -50 18 14 -13 -78 41 -42 -27 -10 -56 1 -31 -14 -117 82 55 -62 -57 -60 -53 -14 0 116 68 -33 73 -89 -122 1 -24 21 -61 103 23 -109 45 29 -1 -47 -36 15 -17 -12 -40 18 -6 -70 -20 40 106 -22 28 -45 -20 35 -67 -15 -83 53 43 -2 -25 2 -39 15 0 45 51 52 -46 65 -99 -9 -82 15 -69 -19 -16 32 52 -36 64 -51 -37 16 22 23 6 16 17 -23 1 -24 34 127 1 57 22 -39 44 -49 120 -33 -70 -34 25 59 52 -23 -128 2 -4 17 -6 56 24 40 -16 20 -68 -20 -13 12 -69 126 60 4 85 1 -54 -49 -74 90 -28 17 4 -53 -81 -90 -123 26 33 53 26 -78 -12 84 36 8 -29 3 24 26 19 12 109 11 -14 68 1 127 -14 -28 21 -33 -34 -35 23 36 -70 52 97 21 20 -22 127 -60 -8 -35 -21 51 51 -4 123 -32 31 -127 73 -23 -90 72 116 -96 -111 28 73 20 41 127 33 -58 53 34 -30 -11 -12 -20 -47 -39 -38 74 -90 -128 -20 48 -6 26 47 37 27 -37 -89 -105 14 -22 -9 -52 -19 -5 -43 85 -72 -80 69 90 21 -26 57 -1 71 68 46 -41 -60 46 -125 91 -66 -40 -17 59 19 80 32 -12 -124 -7 21 -79 -117 -56 -3 123 -12 -45 -82 -59 15 -54 -109 104 -3 -78 -26 -35 127 -60 6 -20 -28 -66 46 -23 1 43 1 -86 -2 -25 -31 -45 -27 99 -20 -25 96 6 -7 22 35 54 -51 65 126 -39 -119 102 -38 -17 -10 -29 -83 94 34 23 -9 60 -23 -104 99 56 35 -89 18 44 -70 7 11 -5 107 0 68 106 10 -5 53 122 71 -1 4 -39 -119 -43 -29 -32 -12 14 6 -50 -60 -39 29 20 6 -51 26 -23 84 68 20 106 -127 127 58 -14 -126 -50 -52 49 34 -15 -43 -72 17 25 59 -61 -61 -110 19 -4 -21 6 -101 -39 -81 -12 125 100 43 -3 14 -128 44 -102 41 25 14 -21 48 60 44 -9 -2 -11 -121 21 56 0 -51 77 -2 -10 0 10 -36 -39 -15 -3 16 97 -83 102 -89 124 0 -25 24 -127 5 -60 -40 45 -20 13 -1 -90 -10 33 100 122 34 -128 -37 32 -56 -35 127 83 -19 40 28 -8 26 101 56 -6 2 -81 -22 -47 -26 47 -30 16 -43 27 28 16 45 -20 -74 -60 -40 -34 -25 -33 -40 -24 -49 49 75 -76 50 -34 15 -88 -120 48 -18 -21 -50 -23 -29 18 14 -31 6 -81 -100 124 -52 -125 -57 -87 -54 -81 -19 -124 106 28 83 30 -119 -46 76 -115 23 -45 -91 -18 73 16 -48 76 -32 10 7 39 -17 -126 61 103 66 14 -114 54 -18 33 20 -33 38 -125 -28 55 -74 74 -3 0 -30 -45 -88 59 62 127 -127 -17 -72 40 107 -72 10 -109 -117 -87 -123 -36 7 5 -43 -21 -125 -41 -57 54 -44 10 -19 18 -97 -121 -33 38 -37 -18 99 8 -48 -120 -72 46 -69 -44 -51 -124 18 -99 24 3 109 -87 -24 31 -125 -62 -9 61 -10 -28 -48 -78 -48 -15 10 -47 20 62 -122 83 -73 -34 77 -66 92 -100 61 18 16 37 122 -109 127 35 49 -12 -6 11 40 -8 77 0 -32 79 52 120 20 -89 -119 -73 69 -78 -69 12 1 -32 37 -109 61 -64 -27 16 -77 -7 -126 -36 -31 31 -83 -6 -16 61 18 -56 9 -33 -43 -70 88 48 11 81 13 27 -29 -95 -22 50 15 -68 -9 -65 -20 109 13 -6 -56 4 57 -44 20 39 15 97 29 30 -3 -58 30 -67 85 -45 -18 113 -31 -8 -25 27 -22 -10 17 -2 49 2 -50 82 -8 -29 109 72 -60 45 34 42 44 102 -68 0 41 -35 -70 -51 -26 36 -12 13 14 -27 66 87 -30 -18 48 1 -20 -10 0 60 89 -50 -41 14 -1 33 -44 46 27 47 127 -99 125 -17 -91 37 -41 127 120 73 64 30 2 16 -31 125 -105 -67 51 89 -33 23 61 8 -77 -122 37 39 -18 -20 27 56 14 118 44 8 39 -45 127 100 -84 30 97 -17 50 -39 127 118 -5 36 103 127 -9 -100 103 42 -5 -52 -36 38 -20 41 1 -70 28 51 25 127 17 -15 -88 -66 23 95 16 -105 -23 -54 47 -23 86 -7 124 -56 33 23 -64 -23 20 -47 1 42 -25 9 14 72 -69 -58 75 -53 -128 -37 -4 -23 -46 53 50 45 -65 -22 -67 29 -86 74 24 -56 57 5 7 -99 -32 -2 -27 -28 -25 7 -45 26 -25 -10 -31 -44 24 -50 1 -2 16 22 -98 -35 -47 1 20 -97 3 -31 -14 42 31 -18 -12 34 15 28 -82 -18 34 38 70 -4 3 -38 10 29 -28 73 16 -25 12 -18 92 -47 18 -3 41 22 -6 -60 -22 -25 -59 43 -1 -103 -82 -39 -17 40 3 48 13 0 -41 13 -77 48 -45 46 -25 19 -13 -16 -89 1 -32 -7 -25 -47 -43 -6 -51 32 12 80 52 -48 -9 -47 9 1 18 29 11 -45 -30 15 70 105 72 -28 -39 7 -13 -69 13 42 -6 -12 7 -14 -74 23 -73 -13 7 -22 10 8 -5 -5 -26 -26 -2 0 37 -125 -55 -30 35 67 43 -29 -25 -2 -46 -124 -4 22 -110 -11 79 -31 -15 -38 9 69 -27 -53 -34 5 95 11 -52 -25 -28 -4 -35 47 2 -29 39 -61 -98 -67 -122 -59 -8 65 -110 45 -63 -9 41 76 -48 26 -50 -47 13 112 -88 -26 -76 -32 -43 -2 64 2 -21 31 -20 -62 -42 -70 127 -98 48 -66 -77 7 13 -49 -31 -104 82 -58 -7 -56 65 86 7 -80 88 43 -9 41 -24 -64 -104 -34 24 -5 22 -67 -9 38 -126 -2 -64 -76 45 -24 -4 -72 -111 -29 53 -37 127 -36 54 -44 -12 1 -68 -14 -31 -74 -16 -39 -15 -12 127 46 -48 30 15 -46 -27 -76 -19 11 -44 92 66 99 22 -98 13 32 -96 22 7 -41 34 -56 -53 -42 8 -13 -12 25 -63 34 -21 86 -89 -43 -18 -31 6 97 53 18 28 21 8 17 -67 -61 9 56 -34 -37 73 -7 -38 9 32 19 36 0 39 4 25 -14 110 48 13 -4 10 121 32 54 -3 -38 -18 -12 33 -15 34 -1 27 6 -24 -88 27 67 -70 -15 -15 9 21 -84 -128 25 1 -5 -8 -14 -82 22 -26 37 -6 23 18 47 -21 -15 -31 -16 11 -34 -42 16 -77 47 -41 -27 -27 56 68 -99 14 -7 25 -66 5 8 -40 25 26 -89 11 62 55 123 15 -56 12 -69 -58 13 -61 28 -14 23 -12 42 -24 -50 -6 22 0 2 108 -6 -85 101 13 36 22 7 -20 -53 -26 -33 -66 -47 -7 -18 -44 -43 -20 1 -51 39 3 -73 4 -32 9 -26 63 -16 -75 1 3 35 82 -22 53 41 -69 85 -76 -47 -20 124 85 120 78 77 104 -58 29 -10 -58 -16 -127 -6 42 95 65 20 68 -30 57 -15 72 124 82 68 72 -22 -82 74 -54 13 -33 44 18 121 -15 88 108 45 84 -5 -46 71 29 -13 72 -69 -26 -4 -82 86 19 127 42 9 6 19 -9 24 -34 32 106 28 43 44 37 65 55 81 26 39 -81 28 81 -15 -4 31 -59 53 122 82 97 2 6 -47 -46 31 71 -26 -27 -19 -5 52 32 40 9 24 35 -8 -16 -14 -47 -35 49 66 -39 -92 127 38 16 -1 -97 -60 -39 -99 -69 -35 -49 3 24 70 3 3 -19 -60 -17 88 51 -58 45 -10 33 41 1 -50 86 32 -35 72 2 16 7 14 2 38 65 28 105 54 9 22 33 12 48 -21 -46 23 27 -18 10 -1 5 -9 22 -25 -56 -86 23 -18 43 -77 9 -54 23 -6 -39 37 -90 -78 -7 -27 -13 31 42 53 -124 3 -49 -28 68 93 25 -13 0 13 -5 -33 -55 18 -54 -2 13 -71 73 -79 2 -6 33 33 60 -77 -114 5 -42 60 34 38 5 -50 54 -29 -39 -109 54 -32 -19 -45 13 55 17 88 -60 70 74 57 -51 -42 -15 -84 24 -17 5 3 35 -34 -15 26 58 -94 23 -4 -56 2 -2 -122 1 -12 -37 -2 11 -24 112 15 67 -54 1 2 -49 89 4 4 -17 -39 -29 29 -27 -19 -38 -6 -35 -96 40 -2 49 -72 46 16 44 -106 1 -39 -65 96 0 -73 3 -59 -66 -73 26 -124 37 -30 84 -102 15 91 7 -61 -28 -13 29 101 -123 8 63 88 3 29 -21 72 -64 -118 -42 -16 -67 24 -24 -22 0 69 -70 100 -79 51 106 -76 101 107 56 60 -58 -44 -23 -2 90 -51 23 -116 -116 -125 60 -10 -100 -17 23 -3 -39 8 -13 26 -127 -23 -6 -42 2 -77 27 -81 -78 -14 -97 -9 -111 7 20 60 44 -106 69 125 3 46 81 61 -2 5 92 0 91 -32 -58 -6 56 -51 -39 -34 14 57 33 -23 6 99 -65 35 -31 23 -11 -128 -38 30 -33 52 -16 -55 -21 -13 49 -28 5 71 -2 -30 92 2 -78 24 -2 30 -7 -21 -33 -6 -61 13 77 22 123 -27 30 85 20 61 -8 23 42 65 -41 38 -25 1 80 -77 15 -47 34 59 125 -40 -105 2 21 9 38 -10 1 -2 -23 5 122 -3 -65 30 55 -20 96 46 -46 127 106 -16 -13 127 38 -31 49 33 83 -2 -65 59 56 -55 -48 -28 -36 -26 -3 -81 44 64 65 22 -67 -6 40 -125 1 -48 -56 -87 -87 26 -31 -57 23 21 48 -13 -45 59 -66 65 -63 -24 -15 30 -50 39 -127 32 -128 101 79 29 13 -68 -95 -32 -93 64 71 32 -44 111 40 71 -16 -32 117 53 -89 -13 12 -108 76 -80 -21 15 10 -116 -10 -72 92 40 15 -11 20 52 5 82 -68 -15 -19 -79 58 -32 -43 -120 -127 62 33 -9 -115 -93 -127 9 -101 112 -106 29 30 2 126 29 49 126 -125 -115 -62 -2 -7 28 -4 127 -126 3 29 8 -18 -128 116 -24 -110 66 8 -126 -64 -122 54 -65 -109 -33 106 32 48 -122 -10 -31 124 -62 -52 -106 -127 84 103 -127 127 -81 10 -3 -53 42 -62 -16 -41 -119 -80 18 -41 -14 28 -71 -10 79 98 -75 84 -31 -53 -128 -62 -19 33 108 62 -27 -51 24 -57 -16 81 5 -73 -12 19 -102 -118 -112 32 62 0 -82 118 17 10 18 119 -127 61 -125 22 62 -5 14 82 95 -70 -61 22 -10 -22 -86 -127 31 -19 -78 51 125 -33 1 -58 47 -26 74 -124 -82 -1 -102 3 44 -28 86 111 4 26 22 2 91 75 5 6 62 5 19 -89 21 14 -29 -62 50 -35 -72 -4 -79 -9 8 43 43 70 -1 -25 -85 25 72 24 17 6 -58 29 78 95 -101 24 17 18 -85 -102 116 -127 -26 -26 23 -3 61 33 -51 63 22 54 53 -121 29 78 -29 -67 71 106 -41 93 -94 -65 83 3 127 -63 107 -125 8 112 11 29 127 -116 -12 -124 -68 100 126 -34 80 -61 -108 -22 93 -33 -1 69 -68 44 -19 127 -11 -58 -117 -66 127 0 -118 -79 -125 -53 -72 -105 -18 -24 36 -11 -76 112 -65 -122 -31 51 10 27 -47 -127 49 127 57 -82 -13 34 -27 -3 91 62 9 -26 13 20 -34 40 35 -11 -20 57 -56 -88 73 -19 36 -52 -18 22 -39 56 47 23 82 57 38 26 69 -17 54 -48 15 68 -22 1 -10 39 113 -10 92 7 127 -57 16 -15 39 63 55 -33 9 44 -108 -14 101 108 -41 -51 -47 11 -30 -62 47 86 -36 -15 -41 -22 88 -32 -12 -70 -13 -8 -42 33 6 -12 -16 103 127 6 25 -103 7 65 -50 -18 -82 9 -60 26 127 22 69 73 42 83 23 55 -34 3 35 32 57 53 15 -108 95 -93 -85 12 -10 -13 -36 -35 19 6 4 22 40 33 73 89 -66 -1 28 15 99 16 43 -8 44 13 -113 13 -127 -110 -60 21 -17 31 94 42 6 -111 -37 76 76 29 29 -80 -42 -65 27 83 -5 69 38 37 62 -52 13 -34 29 71 -49 -4 44 -4 -53 65 -44 44 -46 98 48 108 1 -42 -45 -4 8 4 37 35 32 -41 -13 94 -59 -8 -83 -15 -26 11 -43 30 12 86 -3 106 12 62 -44 7 -68 -22 111 -27 -33 -9 -65 -95 91 -31 -23 21 -84 20 -14 65 22 15 2 -17 -23 19 0 -71 -66 -4 -72 -39 74 90 8 -17 5 32 -52 -80 91 35 15 -22 111 13 47 -73 -79 -33 4 28 -36 56 38 -2 -7 -70 76 56 63 11 47 -5 72 -72 -50 -5 -19 27 -7 -39 53 47 77 36 -38 67 -67 51 -30 -44 114 23 -2 -23 -37 -4 -81 20 -28 5 115 -83 -12 79 -4 6 50 26 67 61 70 76 23 61 -19 37 8 -92 42 -16 -20 -79 -63 105 32 -89 -29 -51 48 -63 -114 85 118 -53 -5 19 -68 -7 -38 27 82 29 42 78 22 -29 5 -9 -8 83 -45 19 54 51 -22 13 -50 -87 -51 44 -88 -37 -8 -34 53 -34 36 47 -1 20 49 -14 -93 56 52 28 15 15 43 65 15 -21 -3 14 -11 -50 64 34 -44 -10 -121 7 -82 37 24 7 -67 -96 -7 42 38 40 122 4 -5 -27 -33 35 29 -64 -59 38 -35 7 -19 -42 62 -49 -53 63 61 8 4 -33 -15 122 7 50 -40 26 27 40 -9 -43 76 24 -37 -61 20 101 74 -48 7 23 -31 82 40 22 28 -16 44 -51 -76 -73 40 -52 70 -2 67 -69 -19 -29 27 25 43 -1 7 33 -62 -50 -6 -12 9 -38 9 -14 24 -73 27 -47 49 -12 53 40 -7 100 -123 -50 10 -25 1 26 -37 -12 73 28 39 -20 -74 15 -18 -1 49 -25 -53 -24 -48 45 103 -18 36 20 19 -59 27 12 -3 -56 -22 -42 -108 101 -23 -48 44 -110 29 -30 34 120 95 -79 -33 44 81 46 -68 22 -73 69 18 -21 -40 -2 -2 -72 -8 -79 -21 18 -43 -28 -101 9 6 -20 37 13 39 61 46 60 -4 -2 50 15 -18 19 8 36 100 -27 2 -74 127 -36 57 -61 28 33 18 7 -87 -126 -79 -126 -95 35 36 -80 -85 25 -66 49 9 -113 44 -42 -17 84 -54 23 -15 72 -14 -14 -13 -61 -4 30 4 -23 68 14 -86 -91 17 -52 5 12 -5 -40 -15 14 -37 -42 -13 10 -28 -27 28 26 37 0 94 -127 1 34 -59 -78 55 -82 -60 -50 -86 -27 -91 -97 45 -6 -58 -1 -75 -80 -74 68 -27 37 29 65 -50 -6 26 12 -8 -11 17 -27 -12 -73 16 -58 -23 -76 21 -20 31 -71 30 -10 27 -10 -73 11 -32 -35 -27 19 5 38 2 -11 -10 -20 6 -27 26 -56 -20 61 -35 30 -8 -35 26 46 31 -16 -18 14 48 27 20 34 -9 79 -36 -22 -10 83 -6 -4 -11 17 -4 55 -18 -1 52 -26 60 -7 -11 1 -30 74 -6 -27 -4 -19 36 16 -10 13 4 -75 -4 -27 45 -37 -16 55 28 52 30 -30 -62 -50 45 -27 0 37 24 -13 -32 18 50 5 22 -12 -9 13 -3 23 -82 -33 11 62 33 -17 -84 19 -22 95 89 12 -15 -24 -25 75 118 -32 65 30 51 73 22 22 15 17 -74 -5 57 11 -50 -60 -33 -85 -32 -10 -28 -51 -51 -100 10 -21 43 37 63 -96 38 -14 30 48 -78 -17 -74 35 77 -51 11 -23 18 -61 24 -123 -49 66 -8 -15 -38 -18 -14 -16 125 -55 -12 33 -71 43 34 46 -12 -53 50 13 -7 33 -18 -6 14 35 42 -108 -35 72 -41 -21 -48 18 -5 71 24 66 4 125 -107 82 69 111 -56 16 127 95 -8 -69 2 -52 78 61 109 -6 123 -84 63 35 117 -24 46 -39 126 120 39 4 -31 -3 36 71 98 -33 92 50 -6 11 91 127 51 -76 -67 -48 -24 125 25 -19 36 35 103 105 30 72 92 4 -126 -48 -42 4 71 -125 -123 56 -25 14 84 -26 25 88 43 -8 86 -95 1 -39 -36 43 68 -45 6 -20 -41 -89 21 83 -15 70 56 22 10 9 -38 38 125 112 34 -5 126 -25 -37 82 -79 24 -36 6 76 127 -69 49 -3 -50 34 8 -88 -20 -114 -51 35 -10 24 -82 -33 13 42 10 72 -95 -21 46 -16 39 46 -51 31 -127 5 -32 -14 -3 72 -75 -20 40 -94 -37 -78 -65 -7 39 -43 2 -19 87 60 -57 -7 43 -124 25 24 -4 -26 54 -47 33 14 -8 11 41 -37 116 -34 -46 120 53 -61 -1 38 34 -72 -15 -112 107 -23 -26 30 0 -106 104 -28 -80 103 -96 11 -68 97 7 54 41 101 0 -84 -24 -92 -35 28 -115 -85 23 -125 -9 127 80 -34 -74 -27 -33 38 103 -16 -48 41 81 -29 127 -60 127 -45 -77 4 13 41 -20 -28 -22 -8 -52 22 17 -12 -21 -92 -31 127 -113 -45 100 29 71 7 -31 50 121 0 3 13 89 -124 39 -4 9 35 -118 -86 -123 -7 -11 109 -126 -90 -29 38 10 -120 -66 -34 22 -39 3 -68 124 13 -24 -64 11 -29 -121 -58 59 5 -42 116 76 -61 -128 -23 -104 19 8 62 -87 7 -54 -21 124 -8 54 40 -15 -7 68 110 84 -23 120 -110 59 18 81 49 50 13 105 4 67 84 10 -62 60 3 52 -53 49 53 -87 28 79 63 52 31 -33 9 111 -59 -66 -32 49 47 -99 34 -38 -29 84 4 19 28 -81 75 -61 -56 -9 43 -15 -9 2 61 23 114 39 65 76 51 16 -2 61 3 -31 127 55 24 -53 23 -126 -29 21 11 -15 -39 -26 -115 19 -67 -33 17 -40 49 -5 -22 -67 58 8 -91 -23 -72 124 47 17 -68 -50 -45 -43 -87 123 18 0 -57 112 -36 -12 121 -111 -30 41 -47 -10 103 27 -35 -94 -70 -15 -102 -18 -51 -50 58 -20 72 101 -42 2 7 -7 87 82 17 99 -94 -114 -32 4 9 -87 -11 -113 17 -28 20 -69 -28 -10 -51 88 66 -16 -47 -45 -78 -62 -34 -14 -100 -7 -27 27 -82 -4 -47 -93 -21 -86 -85 -27 5 95 20 -103 9 -84 -69 -14 24 -97 -4 -25 -14 -15 -111 -17 -30 6 13 -23 26 5 3 25 57 -42 44 -20 43 15 6 80 51 -36 11 76 115 -52 61 -41 -62 -45 -2 79 122 13 -37 -35 -3 -15 -1 22 65 -77 25 65 44 72 41 -32 22 25 -9 -64 -25 -20 -66 -37 -37 -47 65 -50 23 -3 -99 20 44 -8 -49 -61 -30 17 27 -5 17 23 35 -83 52 52 10 55 34 94 59 25 -17 69 -85 29 -19 7 20 25 20 12 -21 -14 30 -75 -77 -69 -88 38 -31 9 31 64 -10 -37 12 -18 -8 -33 -55 42 24 101 25 32 7 101 -27 -109 -42 96 64 -86 -117 76 -80 -77 14 49 81 -79 -54 -24 23 76 1 60 32 12 81 -41 20 -81 -118 9 -6 -113 -80 72 -6 18 15 5 -91 -114 -120 -118 14 -119 84 -20 16 -60 121 -112 -120 37 -48 -2 -120 -13 -102 93 -6 -55 -18 114 -74 -34 103 -23 -54 73 -19 17 64 1 67 118 -49 -26 -47 -23 26 24 43 118 17 103 120 46 12 106 -47 19 -47 9 -42 -20 13 22 111 15 19 -27 107 79 71 46 -77 90 7 34 86 72 18 -107 -15 -91 14 10 -20 -28 -56 33 123 40 55 -87 37 127 35 92 -122 4 -26 62 63 -75 -122 -113 -8 -9 -22 -16 -25 -94 19 -44 -60 45 -117 34 -54 -25 -13 58 -126 -15 -68 126 36 -15 6 -74 -65 3 -68 57 21 81 58 115 43 123 81 -9 -58 17 -64 58 21 -30 -108 -65 16 -128 -45 75 -119 -117 -97 -65 -40 -123 125 127 127 17 68 -16 10 126 30 120 -121 -18 127 80 14 -125 -45 40 -30 -128 -37 -57 -20 59 -117 -70 12 -58 63 -59 -11 -17 27 64 25 -38 9 123 -32 -125 14 -71 127 116 -25 44 124 -47 47 -22 31 -127 113 -112 -117 21 -33 -53 57 47 -95 -39 4 26 32 43 -21 -16 -99 -64 -7 18 -49 -110 -13 68 70 -16 48 -54 14 48 36 121 93 -78 -24 3 9 -37 -19 54 110 -72 -42 -65 6 -90 -56 41 -1 102 40 13 -10 -62 -17 44 -66 -98 79 -51 -16 41 -28 -107 27 77 -1 -128 -120 -6 58 -119 30 -2 25 -68 3 -78 123 -51 54 -70 17 90 -17 -1 -74 39 -106 -42 23 76 -37 31 9 47 -95 -41 34 4 11 -127 9 28 12 20 -48 97 -5 4 5 -10 -71 38 -65 -77 -64 -50 -21 -16 44 6 -21 0 -15 -1 22 -15 107 109 1 114 62 89 61 29 -28 28 -67 -116 -70 -41 22 -51 40 121 42 -7 56 -26 -11 -50 43 -73 85 -110 47 13 67 42 71 -65 32 14 24 -111 55 -7 1 -16 54 127 -20 7 -16 -62 -13 -19 4 56 -20 -8 -12 117 28 9 -49 -38 5 -36 16 39 -65 -27 60 -51 30 -61 31 -24 -22 110 -6 64 -50 4 -33 -5 0 32 -18 -60 -12 14 -60 -33 74 -31 22 44 -29 -49 55 -38 -11 27 -77 4 -41 17 -68 12 27 -51 -126 -20 -3 103 61 -117 -48 28 -49 1 -6 68 23 -30 95 52 -11 -26 -20 -9 -9 -8 12 65 -57 -5 -66 -53 -3 -39 37 -47 120 53 44 20 26 -47 -50 26 -15 -3 26 2 1 -6 -80 98 26 -82 32 17 -24 38 8 -50 81 -45 16 26 8 -9 63 -43 53 -8 19 104 49 114 -4 123 -19 29 -7 6 17 39 111 -47 102 -56 16 67 19 -35 59 -16 62 117 -69 -45 31 -9 -39 27 116 -24 119 -65 -83 121 10 112 31 -69 22 -66 -48 66 3 -118 -122 -104 95 -105 -17 13 22 25 -60 55 29 -50 -17 -2 109 -19 59 106 12 -43 -17 34 -89 46 36 -43 28 42 21 30 -8 25 103 103 3 37 114 53 -33 1 -7 -28 -38 11 -22 71 -57 -98 90 83 -63 67 87 -21 -40 -12 -34 23 61 10 17 44 -13 2 78 -61 7 -43 74 -35 -51 30 -13 41 -17 -73 -27 -13 3 38 -115 -19 4 -55 -68 -47 -4 -29 83 41 -5 23 -3 -20 127 -58 17 88 13 -37 -10 -32 66 26 -8 -19 -42 -3 -50 82 45 31 -93 63 -66 16 82 31 30 -29 78 36 -55 -24 12 -40 -35 -3 -8 -1 -51 -1 60 -1 -38 49 -8 -40 65 -74 45 -14 34 15 -8 -49 31 122 -24 15 -36 -84 -20 -22 -91 -11 41 -22 -74 -43 -33 30 -71 40 -29 -20 -18 97 -114 -58 -76 -25 61 47 15 52 18 -17 37 -39 -63 13 85 -105 23 -13 -71 50 16 -25 0 -2 6 33 -28 3 -1 -23 -64 39 -10 109 78 -26 65 -7 115 24 -99 8 -87 -19 50 -75 -43 -37 126 94 75 58 -6 9 -63 31 -19 39 2 -38 55 -36 -17 -6 51 35 21 18 -41 22 74 -6 124 120 45 79 72 76 43 -10 25 112 51 -59 6 106 117 86 9 44 -26 40 26 -57 39 19 -38 49 -8 31 -53 58 94 7 85 19 121 30 56 85 -10 -33 22 115 127 8 -89 46 68 -23 -5 -29 62 -5 1 17 26 49 -2 6 84 -56 111 -9 125 -27 -25 113 -46 84 102 41 -7 45 -8 126 127 -13 29 -68 -58 53 66 100 42 116 58 109 -52 125 -73 -11 46 3 27 -43 -27 -13 -8 38 114 1 -54 -23 19 -15 3 60 6 -4 56 -61 83 20 7 -37 -7 8 7 41 32 -70 1 -21 -3 -27 -13 -20 38 7 -23 110 36 -19 -77 15 -67 -63 -38 59 -46 -75 37 42 -6 114 -106 111 -43 9 -58 -42 -46 50 -42 14 -81 37 43 -56 46 4 33 -58 -13 -104 -33 33 79 -32 -28 -61 119 25 -10 91 -5 -26 1 -25 22 67 53 -12 -50 68 29 -36 -37 -41 -11 52 58 -32 -40 -48 -124 127 18 -104 62 94 39 -74 -18 -15 -16 -128 -78 33 -64 60 75 -17 -32 -115 33 35 64 -64 20 -71 -38 10 15 49 -45 23 -31 -122 -126 32 -5 -40 -29 -31 117 -22 123 31 52 46 -13 27 11 82 -55 -50 6 93 126 16 39 127 36 7 -20 4 -42 -20 -95 61 -80 -3 119 -14 87 47 -69 95 25 48 13 101 -65 -17 -25 -38 106 53 -86 62 42 -56 -85 -73 31 -92 84 -47 5 -19 35 -52 83 58 51 63 -76 8 65 37 -2 0 17 -56 98 -52 -75 -36 -83 16 110 -80 13 -85 -4 -82 -84 -13 -33 -19 92 5 0 -84 84 35 12 25 7 14 35 -126 9 -27 -42 -53 -80 -21 28 36 17 11 1 -4 12 1 -60 -83 36 -50 -6 -18 -92 11 3 60 -48 34 -23 53 -56 90 82 29 96 -23 -101 -17 85 -58 -38 -6 94 23 -36 -4 -26 42 11 32 51 15 -2 -50 -68 -33 50 21 27 -13 53 -37 14 1 37 -42 -3 22 18 -9 29 -12 5 35 -90 -55 40 46 107 35 72 44 41 -68 4 19 6 -41 29 -84 -5 15 15 -16 5 -28 -16 48 -2 -40 -54 -121 -8 22 -13 -37 -21 13 -36 -5 -99 11 20 -64 24 -112 -13 -43 32 28 36 58 -28 63 32 -10 37 -11 -7 -51 39 -53 0 87 24 -21 -16 -5 -38 10 -4 21 -23 45 25 26 11 120 -3 76 44 61 27 -28 -30 -40 -102 51 29 35 16 5 -29 31 61 -4 23 -28 -31 -27 -14 -35 -3 -20 -49 -101 5 23 3 -54 14 35 -10 -90 60 91 20 -123 -127 73 33 -9 -64 61 -15 -5 17 45 34 10 -81 1 27 -43 -47 35 -32 -34 6 -68 11 -21 -36 63 -25 66 -96 74 15 5 64 36 -5 -1 -86 52 60 8 6 -73 34 30 3 38 -5 -21 27 -8 86 51 47 78 6 64 -100 120 86 -23 47 3 -3 -21 15 -22 36 -93 -12 28 70 -45 42 -54 24 13 -67 127 65 8 -123 -58 -65 7 1 118 66 115 -6 52 -14 109 46 127 127 17 4 4 -77 25 -52 127 -93 -34 116 81 15 127 -42 109 120 33 -81 -46 123 29 85 58 14 103 -14 26 82 -25 51 -114 -79 50 -1 69 91 31 24 -4 17 -45 64 -65 26 49 -56 -26 -67 -16 -121 123 -25 -28 -28 -69 -21 -65 -37 119 -17 -21 -19 -86 11 22 42 36 113 15 -52 24 -26 -95 37 89 24 -62 -67 -42 -45 8 -9 -58 -19 8 -52 27 -49 -40 37 -19 -57 0 4 83 10 -33 13 -8 12 -125 -59 17 13 -48 -55 46 82 -72 72 64 1 5 -17 5 -48 -89 -10 0 44 -10 -72 20 -30 -104 -25 -56 -46 114 -99 16 -63 -21 44 55 -11 111 11 -99 -29 51 -28 6 4 -3 16 65 86 54 28 -21 -14 -30 -77 113 -7 -46 -56 -69 -70 -100 -47 -69 -64 53 9 114 1 15 -4 -71 -10 -28 -43 40 -27 -1 -19 -54 124 44 -78 69 -113 -80 -69 18 -62 97 -97 56 4 49 4 81 -123 -23 122 59 -79 -34 24 -57 106 -6 91 -98 -10 81 -91 -30 2 14 58 -126 -86 2 -104 -3 44 -39 74 32 -48 -73 -113 6 -27 -81 51 81 60 -27 -73 -12 17 102 -60 76 32 3 -51 -23 87 -15 32 27 -68 -52 -126 -93 46 43 59 51 -3 -5 -40 53 -6 106 17 35 127 68 -80 -39 36 115 71 70 125 23 103 6 -1 41 -50 24 -24 12 59 0 23 -59 -16 29 -28 48 70 65 -47 33 -42 46 53 -50 121 32 51 -7 47 -70 -10 35 -68 97 20 34 62 77 -6 -122 1 33 33 26 84 -74 57 -36 63 -6 -37 31 101 29 -31 16 -87 28 4 26 80 42 38 -42 2 -42 9 19 -103 33 -64 -14 36 -71 -31 64 -31 -33 -34 38 3 -20 41 -77 -20 24 7 -25 -15 56 -88 19 -14 -56 -22 53 21 -83 52 -43 -27 14 72 -67 80 -1 74 63 65 4 58 -65 16 -46 -55 -30 85 -92 -25 28 -60 20 -6 97 -94 -11 9 51 -3 -13 -21 -71 4 69 -25 31 -21 58 41 -128 -30 -18 -93 57 45 -88 27 -77 6 75 51 93 -22 -84 25 -40 8 -44 -52 76 -50 19 79 40 -49 4 50 -103 -43 -31 -12 -57 70 46 23 29 125 1 -13 6 -11 39 35 -88 64 -71 -49 -97 9 53 -20 -11 11 121 51 46 -24 -33 10 16 76 80 -21 42 8 -81 -60 39 -3 -53 -112 53 12 -9 73 27 85 57 43 46 118 2 29 -58 -55 -11 -51 99 98 6 -54 12 -63 127 1 8 -121 -14 -114 26 31 5 -42 -11 -20 -79 -6 -16 21 3 42 -23 -1 14 21 -43 -107 -80 44 104 -49 16 -91 -7 22 -55 45 0 -90 125 67 -50 42 16 -76 93 -92 -44 30 121 15 122 117 26 25 33 -11 -52 122 -45 -34 113 16 -7 56 -62 21 3 80 40 40 -76 110 74 -7 7 104 81 116 68 -7 13 -61 -80 -68 -124 -43 -126 -18 12 -70 51 39 -40 -39 -44 37 -106 -32 65 -64 17 58 13 -5 -37 -13 35 44 75 77 -64 8 40 49 -123 -89 100 -44 31 115 7 14 -2 34 -1 71 75 32 -34 25 19 -10 43 -43 -128 -83 -40 -14 68 49 76 -78 -10 -83 -65 -39 -37 47 76 107 120 82 19 -55 -49 21 2 3 56 57 3 75 42 -23 -4 -5 21 -3 -17 3 24 -35 -32 -10 -125 37 75 6 -75 -2 15 -75 45 -85 125 98 25 68 30 -9 55 74 47 18 35 42 23 -4 48 -113 -115 38 78 88 -36 75 -71 37 24 -8 6 119 66 -92 57 97 23 -22 -18 -9 33 -9 -10 -20 -53 88 48 -72 -14 53 -3 -22 -9 -30 -75 33 -93 -76 -26 -27 -120 71 -124 59 -27 -33 73 76 16 -15 -10 -27 -53 43 -35 12 -58 -10 46 -82 29 -23 32 24 -33 -7 -28 35 -118 75 11 71 -17 18 -29 -37 -25 -32 -76 -4 66 3 -25 -7 -36 -12 5 39 -28 46 117 70 -21 -14 -58 -126 -106 -49 -91 -28 60 112 -7 4 11 -43 -22 -39 -54 -2 -34 97 69 -61 123 -34 -73 -73 53 -39 -122 -109 -82 -78 2 1 -127 -125 51 -33 22 -38 -112 84 -26 -57 -35 -86 79 -54 29 -56 29 48 -60 -93 -101 25 33 24 40 -86 -105 43 -53 -49 31 -55 -47 58 -64 -43 -40 -112 -27 -10 -100 24 -124 126 24 -113 41 -42 127 2 -117 -48 -53 49 -124 -54 -59 -24 11 -119 57 -52 -127 -86 6 -1 -16 -41 -12 7 -38 29 -92 42 -42 -1 9 -102 -8 -73 -121 -116 -102 -76 -3 -23 25 33 -17 69 -41 -16 96 -79 -33 66 -71 88 -50 1 -16 -5 -120 33 86 -42 33 -44 -79 -26 80 -11 -5 -75 -41 -48 89 32 -51 -23 -24 -25 0 -14 -28 -50 -102 66 49 -2 108 20 -33 -34 -10 -31 15 71 -46 5 -5 46 -123 -13 114 15 67 -93 60 -65 76 12 34 18 -46 -69 32 -88 -63 -3 -73 -89 -17 90 -50 -54 -73 78 -26 -20 -67 19 22 -32 -14 -48 -111 57 -112 58 -128 80 -61 4 -15 37 7 -21 -20 35 47 -19 31 -76 -19 -34 91 13 -16 73 126 93 -35 -41 -1 16 -61 61 -94 1 47 -76 -69 -67 -28 36 64 88 -35 -110 23 -35 -105 -43 13 99 14 -31 11 -36 -76 -57 26 -17 -33 -76 9 24 43 -42 25 49 94 -4 -105 -103 10 -38 39 -51 104 -76 55 -13 -58 23 12 -30 61 4 45 -9 21 -53 2 -32 13 -15 22 -7 18 25 71 -30 14 99 48 -63 -35 -18 112 -128 -39 96 20 -32 51 26 30 -53 -87 -54 -55 103 25 103 86 -4 66 -78 -44 46 16 -122 -38 2 103 53 21 -1 12 15 47 9 25 21 -43 -50 -41 -19 99 14 31 -80 54 56 -11 32 43 122 -60 70 -82 32 -14 119 16 21 -103 1 -123 -13 48 -14 -72 92 -57 2 -43 -61 38 -54 50 45 -61 82 -99 56 -75 41 59 51 63 13 -123 -99 -29 81 66 25 13 -37 -56 20 -93 -19 -48 -24 -58 -19 -44 -12 21 15 12 63 -34 53 -5 -87 -82 -42 -127 -43 54 56 77 12 -77 -28 82 -23 125 63 -52 -1 30 31 73 -19 -127 17 -54 -15 -31 6 -125 55 127 46 24 -37 -2 62 73 23 -2 83 -69 -4 -45 -15 12 -4 -47 -19 92 50 66 19 -51 12 -8 -114 16 3 -108 38 0 24 36 -1 33 -35 -5 23 7 46 -2 9 -93 -19 -21 21 -38 4 -1 -55 60 -104 -127 48 -36 -24 1 -18 36 -116 81 85 47 -69 50 -34 54 122 -12 127 27 35 -2 -61 -35 -1 106 -103 -121 16 -33 57 -24 10 -110 -22 30 -27 16 -33 -41 20 -125 -80 108 127 -3 37 -11 90 -7 -46 59 -34 4 -29 49 17 46 -121 -18 102 -123 -37 4 -47 -12 -120 119 104 -20 -60 -2 17 33 34 45 30 101 6 -39 77 12 -85 63 116 12 -51 127 126 -10 12 66 21 1 20 -26 78 -11 8 -11 -50 -127 -38 92 -74 -65 -108 -57 -19 66 41 -100 -24 -60 82 -23 95 2 -68 22 54 68 -10 12 9 -90 36 33 -103 72 -60 -52 -43 -103 -60 -83 -82 -72 -51 6 -53 -30 -34 -100 -119 -125 -123 113 -15 69 -96 -95 125 76 24 -66 57 126 96 -104 -33 8 73 103 -56 72 40 -48 -24 -12 -60 -4 -69 -56 -51 -70 -36 -56 -45 -80 29 -43 -22 43 -62 -31 10 -20 -70 18 -36 18 75 30 37 -84 39 6 106 -76 -27 14 46 84 -89 -24 -10 44 110 58 -1 51 71 -25 1 -26 -60 47 19 31 2 -116 -11 -42 84 -39 -14 -44 79 -14 2 -121 39 80 -62 33 -1 55 -13 -76 -90 -81 -21 -17 77 44 15 -25 -15 22 69 -59 -127 -45 84 116 -66 -87 51 123 21 13 5 16 43 7 41 21 19 -45 -12 -31 -108 -54 34 9 70 17 -81 65 28 21 50 56 -55 -127 22 -87 15 101 24 49 29 -42 -10 -44 57 17 -66 -36 87 -11 -5 -85 -128 115 -96 -41 126 -21 -1 36 15 1 20 60 4 -6 -88 -5 24 73 109 -54 77 125 13 60 88 127 68 34 -110 6 -3 27 -26 -62 -80 -23 19 -71 28 67 -54 116 114 73 -28 108 -23 -32 9 -8 82 -23 -81 56 -44 18 -45 -57 -1 -106 37 -54 -44 -43 -31 -73 21 -33 -24 -24 -114 -39 -8 66 16 -118 27 -6 56 -2 13 9 121 -31 64 48 4 75 -17 -20 -78 -36 11 23 84 85 -81 -78 40 -25 71 -54 -90 37 41 -16 109 127 65 -45 -59 -2 28 11 78 51 74 3 -12 84 91 51 -34 127 -52 -41 31 -57 -17 -68 -76 53 114 -97 120 87 118 37 24 43 89 120 109 -40 1 41 80 110 -124 125 -89 107 49 -61 112 0 36 17 35 -7 8 -57 49 84 111 58 43 46 10 -7 90 -101 -77 -80 127 109 29 -89 30 -77 -46 -28 -11 -35 12 -77 0 1 -18 -4 -56 82 7 -32 -48 22 -37 -18 44 33 10 -34 19 -90 -15 -54 -94 -94 56 -75 -43 36 46 27 -8 -73 -57 36 -43 90 -36 -70 51 -88 -38 -83 -39 -16 -29 -87 5 32 -14 48 13 45 42 106 80 18 -75 -57 -1 43 15 44 -29 12 -44 -114 44 -20 -48 -15 -36 127 -26 54 -52 90 7 104 -10 77 -18 46 75 48 35 -83 -43 -9 58 121 18 -12 84 1 -40 -47 17 -120 -77 -22 74 10 52 4 -30 -43 -19 -4 11 -86 68 16 31 -1 -6 127 -4 31 -38 -38 21 5 88 -112 63 11 -29 117 -39 108 79 -113 -65 3 48 -24 -15 -15 52 39 -22 -32 34 -27 -32 8 62 22 -27 68 -44 26 10 5 124 25 -74 -4 15 77 -126 -127 -63 -27 -76 -5 -35 37 -50 52 -10 63 7 -78 30 -42 13 -75 18 -63 -31 89 -2 32 73 -17 104 -34 35 -103 13 87 19 -14 -104 -36 -76 -50 30 35 -72 10 -8 -91 104 -96 5 52 -34 24 90 -13 27 -123 72 -27 114 -20 123 -12 -34 -26 -54 -127 -24 70 -6 -75 -50 0 13 -21 5 103 -57 -71 -74 32 68 -73 -18 67 117 -80 -42 111 50 57 -74 -127 -10 -34 127 112 -121 -63 -107 25 61 91 -16 -35 9 -25 1 -34 87 59 56 -105 108 90 -92 37 15 18 -111 29 31 74 -22 -20 85 -76 -42 55 -41 -23 -35 -55 -92 46 -3 -81 -40 17 -84 -54 1 127 26 -120 -15 79 -72 -1 -126 60 -29 -70 3 67 36 -45 15 41 100 -72 14 -36 24 -30 -61 -28 127 82 -58 -6 -51 7 -41 23 -5 -42 -10 -24 79 -70 88 40 113 0 22 -55 -46 0 9 -75 31 -67 -37 -15 4 17 27 24 -113 28 -125 -117 -8 -124 -1 74 -3 -74 50 -20 16 -50 -63 -43 -20 -90 -49 -93 -30 11 -97 83 -121 1 -57 -43 27 -11 28 -62 -84 126 -15 -64 45 50 -32 74 31 -125 95 -46 -79 -3 18 16 79 15 -26 -38 -49 127 74 -32 -25 85 41 23 -17 1 -66 -29 53 5 -33 36 32 0 55 -62 50 -25 36 -119 -47 -3 16 11 46 71 8 -52 77 -37 -25 105 89 36 -37 -3 -19 -49 68 -29 3 -59 34 -127 40 2 56 -127 -121 -53 17 34 -53 -29 25 -19 1 56 -40 75 14 26 -55 67 -126 56 9 -26 22 17 -13 59 70 1 -39 -33 42 61 -5 -51 -3 23 -90 -32 57 -97 -45 15 -65 43 118 43 17 -121 4 20 31 19 -90 44 -62 42 98 -60 -105 -39 24 68 38 -71 64 -75 113 0 -103 -39 34 -39 72 -34 -46 -123 -58 15 55 11 -39 -110 82 -28 -53 -49 -91 76 -21 53 60 -32 -60 50 13 52 11 39 46 37 -85 -124 -20 -7 76 5 76 44 -16 -73 -69 -54 15 19 -47 26 84 -65 -30 50 -24 31 61 47 -12 4 -34 66 -99 -16 -60 78 -1 72 -19 -52 9 48 -7 94 73 37 -11 110 32 98 -62 -45 -124 63 7 -47 54 -49 -18 44 62 46 68 -39 102 -16 -57 22 -36 59 -47 48 39 -27 42 -40 0 31 -1 -6 2 -68 66 -5 33 -41 -46 59 -19 8 1 106 -46 5 48 90 -23 -52 51 10 -7 56 91 -7 51 83 -7 36 -68 47 -17 -87 120 -43 40 -53 -10 -15 -35 85 122 7 -78 30 30 85 102 -26 92 -25 40 24 -11 2 56 46 10 22 121 29 27 -30 -84 -98 -15 -11 12 -35 -85 -123 29 -86 -27 -23 122 76 12 17 29 -27 -42 84 0 23 -5 -22 80 -64 -89 -38 76 -128 -32 -10 -47 2 -97 67 104 -41 36 10 127 123 10 16 21 39 41 19 64 -53 -118 -49 -65 -10 -3 8 -37 -68 -45 89 10 53 -16 -9 -38 -13 -75 -106 -27 -73 94 95 72 -35 -19 -28 6 -76 -57 34 4 -45 18 75 -52 -4 -59 -34 -91 -12 45 -9 6 114 -43 -3 5 -73 -5 -24 -81 66 24 -83 -127 -52 -121 7 40 2 -33 -3 5 3 65 1 55 -34 22 -9 9 125 40 22 126 -105 74 24 -21 126 -39 1 -52 22 -10 -20 -43 -51 -60 -36 3 25 124 45 -12 -120 -32 85 -98 -21 -120 35 -2 -5 9 -38 -84 -1 8 22 -122 2 104 -17 93 -65 127 61 -101 -32 -44 1 -74 -23 -37 60 -27 -125 10 73 79 -48 43 -29 -109 39 -126 15 -121 -125 -41 44 52 -114 -64 -33 69 -55 76 -26 -113 -42 -65 38 -87 -1 47 -14 -14 -27 -43 40 -52 -11 -16 115 -57 59 -90 -20 -64 14 25 2 4 59 3 25 -4 7 32 13 9 77 121 6 -64 -26 25 125 -21 -3 -128 25 -25 72 102 90 -23 10 14 -34 -37 35 -17 -90 -28 -46 -43 -13 11 25 25 -9 -125 -21 -68 30 2 -24 36 21 -128 -26 -11 36 76 -20 -24 -41 -120 -59 32 40 -44 -127 -22 -3 15 -64 53 -22 124 19 -28 59 41 -22 -18 -5 -56 31 31 -41 -53 -93 -39 -13 43 54 -127 97 7 82 89 36 -70 95 0 24 33 -20 -13 60 33 17 -32 -48 -68 -36 -127 21 19 -62 -105 -30 -21 -49 -27 113 -9 84 73 3 -36 -49 -111 104 -65 -122 -45 -20 -29 -9 19 41 17 -108 -64 20 -26 24 -85 -22 -30 -89 -57 -49 -51 -67 82 26 23 -82 -95 -111 -48 4 -6 50 -32 -33 -117 4 49 -117 -24 -105 24 42 -27 -80 66 73 -100 106 -123 -66 -23 -24 3 3 -68 -57 -7 -47 -70 98 34 65 32 -40 -89 124 27 -37 -4 11 42 65 -127 -1 -82 127 -6 -103 -5 -67 -82 -58 11 43 14 -14 -57 26 -92 -6 47 -62 -19 -7 75 -16 -55 -108 23 -55 48 75 -26 69 63 -37 -18 -21 15 -43 49 42 -2 -110 -23 29 45 -1 -70 37 49 -33 123 -22 51 0 -97 -39 -41 -115 -49 0 55 -57 10 -26 -77 82 5 -58 -94 49 44 8 -33 -41 -72 -93 17 87 -50 -37 -40 11 -35 -13 2 -21 0 -36 48 86 80 38 20 70 -31 35 9 32 20 -64 -51 -67 -4 29 -75 -36 -73 60 1 16 -49 -74 -19 54 -11 8 4 2 50 -4 -40 25 -12 -55 -40 45 42 32 107 -108 -27 -64 -23 -54 -3 39 71 -21 77 -52 24 -12 -5 6 75 -9 -63 -41 -125 0 127 -109 57 13 7 73 94 98 -36 8 20 16 64 -9 5 -72 -116 26 -57 -51 31 8 -75 65 -73 -33 21 -35 -22 75 -4 3 39 18 32 -2 -5 46 -53 106 -23 29 21 38 10 10 -75 -97 -54 -48 -63 -15 -66 11 48 108 8 -37 -103 -23 29 -116 93 -7 8 -64 -48 74 -99 111 -65 -87 -74 -34 -71 -64 -3 -38 -79 -5 43 -93 5 -41 2 -87 5 -61 9 54 -51 -77 -101 -45 -29 -5 -41 -89 -61 -13 -76 -1 -1 -41 -51 -64 -7 -49 10 -30 -48 11 -74 -14 -30 -93 -52 -7 -73 -74 -55 15 -5 -56 -48 -88 -52 -11 -12 -53 -30 -15 -21 4 -45 -24 6 -64 -127 11 -99 7 -8 -79 9 -51 -38 -49 -35 -45 6 -127 -48 -18 -25 3 -66 -44 -15 -78 -11 -26 5 -27 -17 -1 -41 -21 -35 -1 9 -40 4 25 -22 -3 -35 7 -1 -25 13 1 51 20 9 -3 27 11 -36 30 -35 -9 -21 -12 -26 -4 52 23 33 7 -19 -63 -22 50 -74 -10 -32 3 -18 -25 25 -13 -5 -34 -12 31 16 31 27 -33 -25 -17 14 14 -6 -22 5 28 -1 -46 28 18 58 -5 -11 -36 -29 -26 -7 2 -5 -10 -14 -18 -38 28 -3 47 6 6 -2 24 2 5 -60 -42 2 -14 1 -2 20 -21 -56 20 -28 28 52 61 12 -126 14 63 -117 34 124 27 -47 -125 -85 9 -60 -128 100 -25 -31 80 -3 53 53 -27 67 36 39 127 -77 68 28 103 61 -31 127 23 86 125 -11 -17 -128 -82 11 -101 -13 -69 5 -1 -18 -65 -16 111 -58 -124 -5 122 -79 76 110 48 73 9 -72 117 -128 -38 17 53 -104 -53 -17 23 88 -87 -82 58 -111 42 77 127 -31 80 25 -97 13 51 3 -50 51 46 -38 93 108 61 37 -38 -8 28 8 19 70 35 65 16 33 -2 -60 8 -73 18 61 -23 -103 -27 -3 -14 87 73 60 -74 -16 1 -122 48 42 19 86 118 84 -44 9 34 36 47 73 -6 71 -12 78 -44 -19 -31 -56 -25 21 -15 96 67 -16 -14 104 38 36 20 127 -24 -29 17 -26 -90 28 116 -26 63 17 82 -14 -2 -48 41 -9 74 -47 44 44 45 30 -126 26 5 -78 -54 53 42 -2 -42 60 -9 43 -3 126 31 -38 -43 92 109 -8 -43 28 -72 30 27 -20 -69 11 14 40 -45 -71 -105 -6 0 30 21 22 12 -75 -19 6 18 25 -26 -20 -43 27 -74 -72 93 -27 57 -14 35 -30 53 52 -85 -94 18 -31 -63 44 32 -10 -77 1 -15 -24 -21 -11 -11 -9 1 -38 -34 -13 -7 -22 -80 -6 62 -6 -88 34 -80 -48 40 23 32 -106 1 53 -40 15 8 -6 -16 23 91 1 -13 21 71 2 -36 -124 -3 -69 53 40 50 52 34 52 -42 17 37 -37 -6 15 79 21 2 43 13 -65 -53 27 -50 -76 61 22 37 51 70 20 -4 -1 32 68 -113 54 -32 -26 -1 8 -11 60 -54 -82 3 48 -5 75 -6 89 5 20 -44 53 -9 59 -22 -24 -15 50 -49 -36 -101 40 -20 101 23 12 -31 -2 -10 24 -8 -21 -12 -15 47 22 -5 14 -17 -24 126 35 34 16 15 -53 85 47 64 1 38 -9 89 -17 -36 53 127 -10 -90 0 32 9 21 92 -128 22 5 -30 103 56 21 20 22 -88 -77 2 6 -31 3 52 -7 8 -10 53 -126 119 83 123 -20 -37 -16 -104 14 -18 127 11 -42 -4 -94 3 93 -66 51 -106 -33 47 -75 -45 100 1 31 -4 126 -60 19 -48 18 -2 -68 -9 80 6 -123 -84 38 -2 -51 13 -22 -54 -62 120 39 59 57 47 56 -37 67 -13 9 6 -21 70 -7 -73 -62 39 38 -63 -46 34 56 97 -20 7 -72 -52 -63 39 -80 -73 -63 42 -1 -31 -54 -33 18 -95 -13 -18 -2 -45 42 -83 95 -85 -76 -101 -58 49 -7 29 -18 109 -17 -14 -55 5 46 -4 -78 7 87 -17 -44 33 -111 -72 -31 -29 -29 -5 81 -30 11 -82 87 -23 101 -35 5 -74 -25 47 47 46 -66 40 -48 -26 -87 -27 64 13 -106 -14 -38 -6 -8 -43 -2 7 38 -122 -18 101 -107 -13 -46 1 -34 1 -14 -3 75 -34 -85 -2 26 42 9 40 22 -125 23 49 -28 -4 -125 -45 52 -104 -128 8 -52 -14 -17 42 -10 -33 -13 -34 -26 -8 48 -25 114 127 -57 -86 45 97 -73 -9 87 -5 -27 -125 43 1 -43 -103 -43 45 27 -4 13 28 76 -21 -20 -4 124 3 8 117 -125 -7 -20 5 13 41 10 19 2 -94 -18 -33 -24 -29 -55 6 -58 -26 12 25 8 -71 1 -23 -49 54 100 -74 0 87 51 -8 46 29 53 91 -53 -99 -40 -61 111 22 -2 67 -3 -8 90 54 -28 -22 -51 -33 -24 47 -24 48 -18 34 97 123 -27 -72 22 -50 36 24 41 -17 83 126 93 5 22 69 99 102 58 7 -10 41 27 -11 -29 -83 7 16 -50 71 22 -128 126 -19 107 31 107 97 -73 -39 81 51 -118 -35 123 29 46 65 -75 31 -55 -102 -3 35 -2 11 -100 -37 127 71 97 16 47 8 17 -55 43 -126 -25 87 4 36 -20 55 -124 86 11 -30 104 53 -67 18 -11 -34 -31 1 92 -77 -19 -116 11 61 -126 36 44 23 90 -63 57 50 -18 -94 -39 -20 -103 30 -34 -5 -64 -19 -48 72 55 -36 0 -19 35 -16 19 13 24 -127 -48 24 0 43 -5 2 10 41 127 6 29 40 20 30 63 34 -49 18 85 -5 28 90 -9 -51 -1 -55 -45 -85 4 19 -1 -84 83 -23 64 -29 -50 16 62 -37 -14 14 31 -88 15 24 -32 -36 -44 55 9 2 -30 55 -36 -90 -28 -30 -12 13 -99 29 -51 -56 -28 -23 -52 8 -38 -18 -55 52 79 15 -45 50 -65 -59 -35 -16 -125 -22 45 42 -29 46 61 21 -82 -5 -13 9 -53 23 -25 8 -22 48 -25 -51 -7 39 -34 61 69 -19 32 44 41 -22 -2 70 -3 -76 -24 -88 -27 -93 -46 -17 -33 41 -15 -59 -87 -31 30 49 41 -33 41 53 -62 -12 119 56 -38 16 1 56 80 8 104 -15 -10 -44 35 13 -8 -8 -48 -85 -5 76 -22 -110 31 44 77 18 -2 57 1 110 25 41 7 83 -17 -33 -74 75 -54 -51 116 99 15 11 -60 -7 7 31 24 26 -5 40 46 17 5 10 73 9 3 -49 102 -2 -107 54 -54 -52 -70 -91 86 -77 -38 76 -41 -15 -7 8 -16 -92 -26 -27 60 -11 24 -69 -69 92 87 21 106 65 47 8 -7 -22 45 48 35 -49 24 -10 30 41 39 23 -3 102 -114 -65 -86 10 -57 -40 -24 3 -18 -36 -12 -13 -35 8 -17 17 48 7 -58 4 16 -17 17 -52 36 22 -53 -28 -62 89 3 36 26 98 -17 125 5 118 64 50 -70 -42 87 29 -125 6 50 1 -9 -21 71 -75 -25 -27 55 -20 -33 -41 0 -73 -101 -1 -71 27 26 -61 42 -92 54 -9 -92 -58 -93 -52 -9 4 -22 -56 -5 94 38 31 0 31 -77 -9 58 -36 22 -5 -10 39 46 -9 3 -94 31 -1 -15 -105 -7 -1 -97 95 38 36 -25 22 -3 56 0 66 -1 69 -93 -18 -91 -44 -39 99 -8 -65 21 12 -77 -53 -26 -33 -63 32 17 101 76 -14 -19 -10 -35 -36 29 36 87 71 76 15 -71 -38 35 -38 33 -49 36 -50 17 54 17 -28 -76 30 -40 -112 0 -62 -28 -5 52 -50 -44 -11 10 8 15 -70 72 -53 -82 -35 -41 13 -95 11 32 22 1 -12 -110 7 -82 -91 17 92 78 105 98 -44 -32 -22 23 -8 -26 63 -81 25 -49 16 -31 82 -87 38 62 -3 -113 -85 -4 -6 36 51 17 -21 21 -92 -6 -14 -82 -38 15 -16 16 -116 36 -78 48 2 94 43 -75 46 70 -32 -25 -116 10 21 28 21 126 20 52 -46 15 127 64 7 105 69 -28 8 46 -103 -6 -40 49 54 39 -37 -33 -97 -43 60 127 -2 -47 14 15 2 -53 49 28 -29 -27 43 -49 -14 54 -36 -3 58 -45 -28 -37 20 42 -61 -1 -18 43 -60 -69 -32 74 65 -21 87 84 45 30 29 -53 -6 -122 30 17 -56 14 37 58 -1 29 -56 26 -15 -29 -27 39 80 -37 26 13 42 13 50 -24 -22 -6 -13 -3 -42 -20 -43 16 55 28 4 24 -14 -17 -38 -78 63 -50 -33 -55 -49 -2 -91 -57 41 -15 -57 -64 -81 -15 2 -2 73 45 -101 -34 72 2 -2 -1 -102 -13 -36 -2 34 21 1 -13 65 1 -50 -11 3 -54 -17 48 -87 -120 -8 -61 -48 5 126 41 3 13 -80 91 -19 -61 67 16 8 7 3 -28 27 -98 -63 -9 -64 -9 -13 13 19 24 57 9 62 29 -34 57 91 -26 -46 8 -37 3 12 9 17 -14 -13 26 -8 2 -60 126 109 -46 -86 40 -24 -31 -14 -59 -20 38 21 8 39 -99 -40 11 -40 66 40 40 -102 50 -21 -8 -42 16 -66 65 -18 64 5 26 -88 14 2 4 -80 -28 -92 -83 -21 47 -52 -27 -46 73 -4 40 -17 -50 -62 -81 -54 -15 -105 -14 -34 46 -10 -125 -99 -25 27 -32 -53 115 21 10 60 48 35 5 -22 61 40 87 -48 -125 -71 56 8 97 -17 -51 -68 1 -12 -2 37 41 -70 46 48 97 17 10 24 23 21 -125 41 -52 23 -61 -91 -11 -101 103 18 1 -44 -90 49 -49 -43 -26 47 -2 81 -17 -38 75 -104 77 -14 -3 -46 -58 -18 68 -5 -97 -21 112 -92 -57 92 80 -40 -75 83 -87 -45 -34 -23 4 -70 -128 -82 121 -51 -58 -82 89 36 -102 -35 -23 -59 15 -120 -36 -47 -20 -115 -70 -83 -96 -46 -45 18 111 2 -43 41 -68 -25 24 -65 -46 -16 77 -35 -109 -38 5 -12 -52 -127 32 -66 89 57 86 -21 5 60 8 -65 -84 4 8 -32 46 -19 9 119 -25 -13 -56 -94 -39 -28 89 9 -9 -27 119 -39 55 -64 -28 -36 -60 -69 -100 2 -17 -32 -94 -9 0 -58 -74 -63 3 -67 -11 52 -67 61 21 -2 -90 110 -72 -127 -56 -62 -7 71 -37 5 -50 -94 -98 50 10 12 6 47 53 -5 -79 -35 -43 -5 47 -64 127 -40 53 100 -10 29 58 44 -35 18 -126 -17 -41 18 -26 -19 122 -16 -45 66 89 -18 81 53 8 35 30 -19 40 41 -15 40 0 -23 -4 -57 -30 -23 25 31 -34 17 69 -59 -128 8 -29 118 -5 -1 56 -25 61 69 67 -62 21 -128 24 -78 60 -105 90 11 106 -126 -13 83 -78 -20 -57 -7 10 42 73 2 113 -30 -72 -112 45 -74 -36 -31 -66 -35 -3 -15 10 37 31 19 -27 5 -28 -46 37 -50 -9 -39 -22 -56 -76 -19 62 -45 53 -65 7 -7 41 -73 106 -1 -51 -15 -22 -60 -10 -44 105 -5 46 24 18 -81 -27 -128 3 -74 -12 13 17 33 -4 6 -7 -18 21 45 40 -20 42 37 -107 54 60 -37 -121 127 -31 -77 8 -42 -16 -54 -6 -66 -14 -15 -74 -19 4 -12 -89 36 -21 18 -1 -39 -17 -43 -49 -101 25 -32 17 -7 -12 4 44 -42 -4 -11 21 50 38 127 55 38 81 1 -37 48 -58 -31 -56 -20 -20 -53 -45 52 -60 -40 -7 -23 52 4 52 -8 46 -86 11 -14 -24 -15 -22 -2 -24 72 48 34 12 -56 -23 -10 74 -12 27 83 -127 -40 -2 9 49 4 23 -13 -37 -58 14 -45 -26 38 -2 107 -81 97 -27 -40 47 26 -49 89 83 75 6 -101 22 -127 -46 46 -95 -11 -84 -46 34 -93 -118 -36 15 -65 16 23 0 126 -12 58 -82 30 11 16 94 20 88 -38 -8 127 72 127 50 -23 -3 -96 35 -37 -31 -48 -72 -79 2 54 42 -94 88 -42 54 -31 96 -101 23 107 -85 -74 94 0 114 -41 1 82 17 22 -29 -18 33 1 -72 -42 1 84 -51 -8 46 28 93 -8 -66 69 25 25 -32 -7 -53 15 65 -36 -24 45 55 -54 -46 -13 -42 12 -98 4 6 -88 -120 -19 -32 -44 -57 71 24 24 -77 -30 -24 -87 16 95 -66 19 -47 -49 43 75 91 10 15 20 -62 85 27 97 126 -97 32 50 -35 -70 -12 -1 -33 -72 79 -23 -54 -126 -28 25 -6 51 -18 13 -18 44 29 -45 -33 37 18 8 -32 -34 -11 -3 -90 -83 -39 -80 74 25 -89 32 -39 -75 -69 -24 18 -29 -61 -15 -2 -47 7 20 -11 13 34 19 -8 14 12 56 30 -56 58 5 -15 -73 -27 -5 -94 16 -23 7 3 21 38 55 -10 9 -40 -38 34 23 41 -4 -15 -51 25 -13 -21 68 -40 0 21 -36 77 -78 -20 64 15 -78 -68 50 55 90 -33 -35 -24 30 40 -38 -58 -40 -14 8 -20 -50 68 47 11 -47 51 3 45 -29 -53 43 27 69 -47 127 8 -10 -18 22 22 102 -10 63 -84 -21 9 -12 -52 -25 -24 -5 -4 54 74 -33 15 -1 -23 -29 -17 62 7 66 26 -43 -40 -12 69 24 4 26 -37 -27 20 -44 -18 -20 -44 -100 -38 -50 -21 -15 8 -23 85 -7 46 -3 -10 -8 -38 -9 -22 -19 -6 -49 59 -44 -42 -25 3 1 -34 -8 -46 59 -31 52 -46 -21 27 42 -14 -44 -25 14 76 33 -52 -18 15 60 0 51 10 60 -7 -2 -25 10 -24 -80 32 -12 31 45 -27 16 48 -66 57 26 -78 -75 12 49 14 33 -18 -42 74 21 80 -22 82 28 17 43 -29 -70 32 42 -62 -19 1 -114 60 119 50 -28 -15 -62 66 -23 -78 -39 -37 -60 60 -25 72 -22 21 -44 116 -15 32 25 -21 4 101 1 -24 -46 33 32 65 -62 -21 58 -71 70 -65 19 -15 59 -40 -2 11 45 -128 -96 -72 6 30 -40 112 69 -119 69 -127 0 8 119 50 3 -42 39 85 -8 73 39 -59 -94 -7 -108 -24 -20 -11 68 -34 15 -83 31 8 -63 -26 -66 16 -120 7 -53 -78 -27 -43 0 103 -61 11 122 127 52 2 109 40 1 -40 -29 79 30 15 4 -20 84 -18 -113 82 82 79 -37 64 -52 62 -17 -38 6 123 60 10 -98 -56 -21 -63 123 -31 30 39 13 10 -12 4 85 -46 121 -51 69 -124 -65 34 -25 -111 15 9 51 92 -43 -26 89 -83 -4 24 -18 -29 -17 38 12 -39 -94 -46 58 -103 9 -116 89 4 -55 10 -9 -51 56 -48 -7 120 -11 -8 87 49 -49 -29 12 -6 -5 106 57 -1 12 56 25 80 -53 13 51 77 -76 57 -48 3 -51 18 -50 -40 -9 -76 92 16 -32 17 -14 -33 65 14 -75 -73 -13 -125 -50 62 39 6 -31 126 18 101 46 -22 20 44 -6 -102 -6 -48 102 -98 51 -108 -23 -4 -74 -16 -70 -46 124 -110 78 -43 63 18 120 29 -12 110 36 88 -48 -123 -72 26 -68 -8 -53 -20 -93 -32 -13 61 -84 20 16 -3 56 60 -92 121 -117 69 1 32 64 -60 -121 -126 123 80 56 22 64 -16 -35 21 -38 108 -50 -44 108 -98 6 -43 -58 -91 -32 2 -49 17 68 54 -49 17 -88 42 36 -20 -7 -90 -82 -100 60 69 -58 28 -38 124 24 55 2 -28 39 -3 16 99 -10 16 57 16 41 -53 84 100 -44 -91 58 -15 -11 -45 35 12 -115 -33 -54 -66 21 -109 50 72 127 58 47 20 -29 -2 -60 86 -22 78 -30 37 43 -52 -76 -3 19 52 12 -18 6 -17 -102 11 36 4 60 -12 17 43 -39 -59 -43 4 -48 -21 -8 -7 9 -3 65 124 85 6 104 97 29 35 0 -13 -92 -53 59 -112 -99 71 28 46 28 102 6 -79 110 -1 15 23 -22 -12 20 -93 80 -10 96 48 40 -7 57 6 117 6 30 4 115 9 23 46 69 9 39 -43 -22 4 2 17 40 -20 68 -25 19 93 53 45 4 -5 -73 -44 98 -13 50 104 9 -35 47 -43 -31 70 37 22 -14 -16 -4 69 -9 28 -38 -47 19 15 -11 20 -5 -15 78 9 106 -25 99 24 -60 -58 -26 3 -53 48 -52 8 -9 -28 -26 41 -61 35 40 59 -88 64 -44 -3 22 33 -55 -17 18 -33 -71 -22 -12 -1 26 -105 22 -27 -41 31 -86 -112 -33 8 -43 6 -26 56 52 -20 7 -34 -95 42 -33 -35 -37 -89 -62 49 -66 19 -72 -40 14 -43 41 -46 48 15 0 -61 -113 79 10 56 75 -15 -22 -40 13 6 -58 -74 23 -60 -22 -3 8 -94 -21 41 -66 50 35 -19 -41 -123 -120 -26 -56 75 -41 -37 -124 -75 -37 -85 -66 -48 -46 -101 19 -69 29 -96 -31 99 8 -26 7 -47 63 -1 -8 -5 41 18 57 0 -22 34 -78 36 -66 5 -53 -14 -23 -123 -42 -126 -48 15 -19 84 7 -36 8 12 56 37 -31 25 98 -5 -37 -29 -4 -49 117 -43 -59 14 4 81 26 -31 -37 -120 -71 50 -88 -128 81 0 -15 10 123 1 -13 57 -19 -14 48 84 -23 2 -40 -35 95 -36 -10 23 41 17 -23 -121 15 -10 -16 10 -61 21 -87 13 127 -95 24 17 46 101 -14 -77 43 127 39 -32 4 57 -73 -75 -6 13 104 11 4 -114 -28 63 72 33 27 -10 -63 99 -14 -45 -91 23 24 25 77 -79 -42 -28 121 57 60 107 -3 -66 11 -36 -88 37 15 -9 -58 -86 -13 43 -36 18 15 -1 -86 61 -107 -87 88 43 28 10 9 88 4 69 43 -26 115 41 -9 -5 65 10 102 42 -22 -100 -68 -57 -28 -113 -34 13 -36 123 0 66 4 -98 52 -84 -5 54 58 -12 41 44 -33 116 -58 25 -127 6 13 -124 -49 54 -68 24 30 -111 -48 -12 -86 -35 -44 -44 -68 -31 23 -3 -63 -1 29 32 76 84 90 41 -32 14 -103 17 53 -28 -10 98 18 27 20 -26 21 -73 31 -42 58 95 -18 -7 -46 120 6 86 2 2 -26 2 -22 -53 -13 112 40 -66 109 31 13 108 -117 77 74 -52 13 73 98 91 -7 -121 -50 39 -66 41 121 94 73 -71 -88 126 -20 91 -13 26 23 80 12 51 90 87 -55 -38 68 12 -54 47 110 28 63 -98 36 -2 23 -21 -26 -72 44 -28 -126 -43 6 89 -5 70 -30 -15 -53 -125 50 -34 -10 85 77 26 -39 39 9 36 -31 23 -57 102 2 78 -43 -45 -20 -2 -3 34 -17 5 -9 19 84 42 69 118 125 -29 -52 61 3 -16 12 68 21 -5 96 6 -12 -35 115 -16 108 -42 -49 83 23 -91 -63 -93 88 -19 90 -94 22 47 102 91 42 94 35 -28 113 52 -27 -52 -22 19 33 24 -27 39 51 -61 -45 23 69 -13 -47 -32 -12 8 45 -6 13 16 78 -9 52 -63 39 -44 15 -26 -22 81 -39 -17 27 49 4 98 27 20 -3 36 22 -30 18 40 -10 119 6 63 -2 117 35 121 105 30 -40 -15 -76 2 10 -39 29 86 -114 20 -21 31 34 -7 89 -115 -74 -44 -1 -66 54 -100 0 37 34 -58 -23 -121 -23 -41 60 17 46 -25 -17 124 10 13 79 81 12 40 50 -108 123 20 -81 -125 32 -11 -32 6 -20 -26 80 -61 6 -82 15 13 3 57 90 103 5 20 -14 22 96 -42 36 -128 -16 18 -108 76 44 85 20 -37 2 -68 36 56 44 61 -67 -19 -1 125 -9 122 -49 -78 21 -5 116 -15 2 -79 20 -35 -60 24 -122 -98 -123 -118 -93 -127 29 -5 -96 -60 -21 -105 -76 -29 -3 -37 50 -56 -124 21 -38 20 -67 28 -27 -41 -67 20 -10 -41 88 14 36 -25 34 -67 -36 83 53 55 -37 -44 -24 -69 86 -32 -126 -18 -57 41 56 -104 -35 -29 -107 -125 -99 -45 -103 -25 23 -64 -123 36 13 66 -91 -33 -62 14 -75 21 -49 -13 -88 30 8 20 34 7 -27 96 -30 47 15 -29 14 -30 55 56 -8 0 16 49 -40 -101 13 39 -29 -56 48 14 35 -65 10 32 5 70 9 -36 8 9 16 60 27 -56 28 -57 -53 3 43 54 61 90 52 -28 23 -16 -38 25 55 20 -82 -40 124 117 84 20 56 30 31 -53 -35 2 -30 24 18 11 -18 -9 11 30 34 -38 17 0 40 -47 -79 54 30 20 -60 45 -37 65 -16 -43 -56 -38 -53 -87 72 -1 23 31 10 -17 20 15 13 59 36 -1 39 76 17 5 -18 -40 -24 6 29 4 -24 74 5 11 62 -65 -87 -53 30 -20 8 -30 -24 74 32 3 46 -54 0 -51 -7 63 74 -34 -11 20 38 -47 19 -13 -28 48 -72 -22 -37 26 -23 0 -36 -1 62 120 -123 19 48 -62 -7 -21 14 -7 -2 90 62 -24 54 -31 32 -46 -42 -17 -1 -87 24 79 -7 0 -50 14 24 -68 20 -44 87 -1 114 106 -27 60 26 6 -30 -21 -41 86 58 -13 21 18 -6 90 28 -91 -43 -91 -67 -6 90 33 45 114 -62 5 -26 -13 -24 -16 -52 -114 51 19 -44 -72 -46 -6 16 -3 -61 -71 120 120 36 81 -54 -19 57 -51 -24 -68 -31 -27 50 -35 -43 7 48 -13 36 12 121 -52 -19 25 1 72 9 45 -14 -64 78 40 118 16 -5 23 -58 -3 -12 -127 27 9 5 -70 80 -47 -57 -1 83 -96 -79 121 -30 38 -12 26 -6 98 14 -2 112 23 104 53 -50 101 -90 4 0 -27 -30 105 -27 4 -120 -16 -1 79 100 22 -95 66 -25 127 40 7 52 -39 -18 53 -119 -4 15 -73 64 23 38 -89 68 -7 26 70 -67 12 66 -18 103 -83 22 -66 13 9 -42 -11 -4 -1 36 71 1 -53 -4 3 119 63 -37 26 -36 66 16 -31 64 49 26 11 25 24 -42 -17 -17 56 28 -113 -7 -105 26 16 -33 38 -47 -23 23 -58 43 23 -55 83 35 45 -27 -7 127 18 -32 -67 -1 -24 -65 -11 29 -2 32 52 70 43 50 -15 82 -20 15 45 21 26 -61 -9 94 75 -47 9 -76 65 -11 -56 -24 -2 -1 -107 39 -106 27 -28 63 11 41 -48 -84 -76 102 -51 -127 16 -30 -3 65 32 58 50 21 25 33 -24 51 -14 102 16 7 -102 -5 -43 50 29 29 27 -41 54 63 -3 -10 -21 -34 24 33 94 -57 123 -8 7 -70 82 -6 9 -128 -128 -8 102 63 84 108 -73 37 96 123 12 35 -10 54 67 13 -98 -19 -58 38 40 72 126 97 -31 -66 37 37 74 64 70 6 -52 4 33 -45 104 0 44 84 -32 19 -10 44 81 -52 -83 66 -93 -46 127 116 9 -8 -12 -51 -63 3 57 52 39 41 -79 112 1 23 115 -32 -36 84 80 89 -52 -14 118 46 -2 125 -66 52 -82 45 -37 5 10 -38 108 -48 -71 -20 43 -27 31 80 118 46 20 89 61 44 -78 -49 110 -21 4 5 52 -53 51 29 12 -8 41 40 0 51 27 17 69 0 -44 8 16 -22 60 -20 -46 10 17 -63 -104 -41 -27 -84 84 17 75 26 -100 6 10 114 28 62 -14 -35 15 -53 16 -24 19 16 103 107 -16 -91 -79 -8 28 25 58 -6 -62 16 48 91 -29 -33 -70 24 22 16 5 124 22 -126 21 5 57 14 34 -1 42 -116 -41 -49 42 -22 -59 35 -42 -87 -87 73 109 -41 60 108 -5 1 -64 -106 -66 -46 -96 13 -103 103 -84 -92 -94 31 -9 -57 -31 -22 107 120 -4 -13 30 69 107 45 -19 -98 85 34 -116 -128 -104 51 47 -104 -37 -55 -38 126 12 -23 83 3 18 108 -33 25 52 43 12 31 59 66 32 58 123 -9 -3 3 -103 58 104 24 -52 46 -101 22 -11 27 -26 -41 -31 39 16 -4 12 47 57 111 -21 -52 44 43 -80 -98 42 -30 -34 116 -63 12 -63 41 15 -110 -76 -20 98 -81 -21 42 30 0 118 113 -7 -64 -128 -125 -18 -12 -61 84 -90 -56 -3 -70 76 -125 34 126 -100 -68 -24 -24 -124 -64 77 -13 -11 56 94 36 -117 -1 17 57 -53 -102 -48 64 43 34 -99 75 10 -46 -49 -15 -51 113 90 65 -33 -122 -17 63 112 86 -5 -58 71 -68 81 78 -54 35 -85 -59 6 25 -19 -40 57 96 119 33 -124 11 37 -8 -20 86 26 58 -122 27 42 -31 6 121 -12 -7 -53 -105 -59 14 -20 30 120 -5 82 29 -79 66 11 80 -45 43 27 -43 23 55 26 -18 -30 -39 42 73 27 58 -8 28 33 38 86 56 68 119 47 -52 37 40 -80 41 99 -38 -51 109 -109 -47 9 -85 86 3 -57 42 -4 62 37 -7 109 -14 43 -12 36 9 10 81 -1 56 -67 13 -51 105 33 -57 18 33 13 -30 14 39 72 58 73 20 71 -45 66 58 58 21 -47 83 -87 17 70 20 37 51 -62 41 14 -62 -18 -52 35 3 -71 -11 37 -70 -75 53 16 -127 65 -23 -30 -43 -51 -83 49 14 -48 26 101 119 81 1 -14 -20 93 11 -31 -31 -28 -50 -39 -8 50 -25 -59 6 -22 59 10 -33 0 -4 -124 3 -16 -27 -127 31 37 53 -76 -33 -51 38 -30 60 -2 54 -2 40 -83 25 8 -43 -6 62 -71 49 -10 -9 -24 -13 -7 -25 -3 122 -76 14 -24 17 43 20 2 -82 47 108 -12 -1 63 -74 -79 4 12 -96 -12 -86 65 65 55 -3 -36 -65 -80 -5 26 -40 43 112 -78 10 41 82 60 -21 62 15 -51 -11 96 -18 45 -84 76 -69 -83 -34 34 38 -21 -86 35 5 4 -20 42 -18 -102 -18 -26 -77 33 -4 38 64 -16 41 51 30 -65 46 27 -55 -27 -6 -44 -79 -24 41 115 29 -56 -36 -55 -13 -31 -49 73 -6 -48 52 34 -47 -32 8 4 38 3 -36 82 -8 -96 71 -13 60 49 -73 -27 -35 -117 -29 -98 45 101 -59 -1 -56 -7 23 -57 87 8 -15 -71 75 34 -25 -31 -70 27 25 31 -55 -30 -70 -36 -16 -51 -81 29 80 24 -11 -14 31 -5 -57 -39 31 93 -41 80 12 35 85 -10 -37 -51 13 -40 -40 -4 -79 9 -57 -29 -57 -87 -12 20 -62 16 -19 24 15 -14 6 -31 78 6 -5 -40 -48 -103 5 21 -74 6 40 -95 12 21 7 -55 -70 -2 -10 47 35 48 -27 -30 -61 34 98 6 73 -58 -70 37 68 46 97 -31 -3 -41 -71 41 -105 -68 -85 19 -12 42 118 119 0 11 -55 -39 -5 -18 16 48 13 -30 50 -18 53 -23 -10 -25 90 -30 -18 14 -11 15 23 -3 46 8 -39 104 -32 -75 -48 47 10 41 31 47 -76 -28 -96 -12 8 -2 -13 -81 56 3 -21 3 5 14 -46 38 29 39 -26 -51 -11 90 99 23 -41 47 13 48 -49 9 -67 -24 0 61 39 -102 41 -1 -59 -25 -65 -62 75 74 4 19 -22 -8 -128 -63 -76 -79 -9 67 26 11 -74 68 -4 82 56 -105 -34 -83 2 9 -47 33 -26 -52 70 -16 44 -114 54 127 97 29 64 94 -18 118 19 -17 16 -71 25 10 11 -83 126 -57 61 -25 -116 -127 16 -43 -49 -25 41 8 79 37 49 64 -122 40 -90 -22 -127 -53 -4 22 -57 -72 -49 23 75 26 7 15 -15 -60 26 103 -40 -3 116 9 10 39 6 3 -57 -44 -56 44 -17 -32 -91 -1 50 47 -36 -34 -38 -96 -61 -127 -68 -4 -11 -94 100 54 69 58 92 3 -41 -110 -70 7 30 -13 42 2 -119 -1 50 7 14 100 30 -100 8 55 118 -21 1 -5 17 -70 118 -43 4 -69 8 -26 45 -11 -29 -60 -92 -128 -44 116 69 -39 -11 9 -1 96 -17 -58 -49 -34 -15 24 51 1 -98 0 43 26 -44 -11 19 -41 -75 -23 28 -4 55 -37 -23 77 -56 -57 98 36 -35 17 -52 -5 117 78 36 -12 -39 -1 75 -65 -53 -10 48 13 66 86 122 57 31 -45 -52 38 -38 -22 -128 -34 -89 -16 45 68 6 26 72 30 2 105 -27 21 -17 -77 65 10 40 55 -3 42 11 15 4 -13 -5 82 43 50 -41 -32 20 -25 -30 4 -38 62 4 29 99 -83 83 -65 -121 28 43 -65 24 26 27 12 37 -66 -42 36 -84 -38 63 -95 -24 91 -50 -126 -91 -88 -77 -86 18 -112 48 -12 -21 61 78 -3 17 -39 -26 -88 70 29 33 -8 75 -53 12 -32 -80 -36 0 16 -114 -91 6 28 12 -8 -46 -76 34 27 -71 18 10 -25 -124 -24 -72 125 30 39 69 -69 20 108 -95 5 -10 103 -13 -31 97 -109 -46 33 46 45 0 -29 -117 -106 -27 71 30 -48 -115 5 18 25 -77 -123 -2 18 40 -26 4 -61 -13 -26 -92 89 -40 -101 -48 -14 -78 -127 -65 91 127 -8 -127 31 83 -68 -73 10 -82 50 -111 -29 -71 20 -31 112 55 -41 49 3 -70 -25 -56 -34 -72 -3 -7 24 -22 -66 -16 -45 -38 -1 -18 -45 29 -41 -30 60 74 -126 94 38 -46 62 -25 -108 -27 86 40 27 -14 -1 -17 -65 6 -43 74 37 -5 8 -75 23 -80 -14 -39 -28 5 60 -34 -47 23 -16 -4 28 25 -32 -28 -17 19 8 -44 48 -30 -40 49 -1 29 -76 -17 -31 -2 13 15 5 118 28 83 80 29 105 -43 31 -4 48 68 59 35 58 10 -77 -128 -21 28 4 -55 -107 -3 47 42 -43 -43 33 127 35 -14 92 60 122 -57 16 -97 127 -7 -77 26 -5 -17 39 -3 -1 -100 14 -50 -13 -79 4 -14 -67 -22 42 6 52 -24 -24 -3 -47 -7 116 -52 -2 -106 58 125 6 -41 -20 -67 21 50 -94 -111 -57 23 -48 -72 -21 1 -117 -21 -27 9 75 -125 -54 33 -6 -5 0 -35 3 -27 -6 62 -16 -5 -39 -33 -3 -41 45 -13 -84 -20 9 10 -39 -42 -43 31 -30 -59 92 -51 -49 -17 103 -22 -69 9 -57 -12 -32 -19 73 -37 -126 47 19 -15 71 -53 43 25 -17 -61 18 -11 -16 45 -61 -42 -55 25 18 -57 118 -80 -12 -2 42 -45 17 -23 73 -50 46 47 -43 -21 10 -63 30 -69 -33 -64 -93 -24 -19 55 -27 -123 1 65 -2 27 -87 97 37 -97 -7 3 -114 -22 -51 -16 50 -17 5 -95 30 -68 14 35 -45 -47 -8 -23 -36 -68 -98 58 47 55 -7 38 59 -46 66 -15 25 -47 -11 -12 -58 -12 87 11 63 -20 -38 -51 5 -6 -89 -2 -44 -44 -3 -29 88 -18 -11 -60 -41 -123 4 8 -4 -8 -56 -64 -28 18 -87 4 2 -43 55 50 127 14 62 70 -4 -14 65 -24 -15 56 -17 -79 -36 80 -6 -18 59 -11 7 106 85 -20 108 -71 -33 -64 44 124 19 -63 -99 -51 -13 116 103 127 38 -24 -36 41 -2 86 94 -59 -72 26 -12 1 -10 -111 56 -13 127 -50 -96 38 -15 71 -120 55 -18 127 -55 -72 38 126 92 -12 38 -128 -13 15 -1 -78 -56 -76 -127 83 57 -47 -49 -69 24 -101 -87 -58 26 96 -68 13 -47 -14 23 -65 60 -44 26 -15 -54 -29 67 111 -65 19 -127 48 -1 -118 46 -20 -35 59 -37 -107 -23 -116 -68 -28 -115 18 -127 26 99 -9 11 -108 -90 -125 -128 -73 -5 4 -45 -72 67 22 -27 -122 -72 -123 -78 -118 62 116 107 53 -19 -118 -126 -127 -41 59 -72 63 -99 31 -126 18 19 -19 -112 91 -85 -28 -5 -59 31 -60 -125 -118 -8 -47 -74 -52 -98 -86 20 -40 -37 -18 -62 -10 -127 31 -33 -114 15 -92 31 127 -40 -32 -18 -54 127 -42 -36 -30 -22 -38 -108 15 -30 -59 -16 -3 104 -29 -88 11 -15 6 26 -65 30 58 -77 22 -12 63 -32 -59 -100 -38 -79 -70 -13 16 0 2 66 14 -51 61 -12 5 -50 7 -43 81 33 99 26 19 127 -36 -10 113 26 29 -62 0 -107 -65 52 -90 127 16 49 15 -22 62 12 50 -7 -65 18 -63 12 -85 16 -39 -20 -31 -63 -55 -90 -10 -96 -4 20 -38 -65 -122 -14 -3 0 125 -21 17 7 95 -10 -8 10 1 -49 11 -57 -2 21 122 81 46 9 -98 26 -35 18 9 -95 124 -70 30 7 -17 19 42 15 9 -128 -124 39 -112 58 2 -87 14 -123 -44 -128 3 8 85 97 -14 84 -12 80 -60 -17 17 -60 39 127 111 127 23 -16 -106 -16 18 -84 -61 -29 35 9 12 47 103 -40 -126 -14 86 -24 -108 100 21 -67 76 25 96 12 -128 125 -9 70 -68 -35 -63 -45 -7 -124 -97 -100 112 101 123 30 -45 -109 45 -114 -5 -44 33 13 20 -13 19 116 -26 16 -27 -60 -109 -38 59 -63 95 73 -20 -4 99 52 82 126 31 -59 54 -1 -16 59 12 28 -93 -5 5 -5 -121 -63 -47 -82 -72 -38 22 -72 29 121 -64 6 16 -24 66 -66 11 8 57 -110 67 -28 15 19 124 89 110 31 -38 44 123 124 58 61 10 -35 87 -98 55 36 60 49 91 23 66 -24 -51 35 127 32 -22 47 4 -24 23 113 127 58 83 -73 -37 -29 121 54 27 46 78 -78 86 107 18 -44 84 50 -30 51 -32 -21 71 -108 18 39 98 -4 -23 -55 -39 44 60 13 38 -109 -81 98 -116 -89 38 36 -81 -10 33 -47 26 -12 4 35 56 35 -42 -18 -51 -29 -17 11 -56 99 -48 62 -54 30 -98 52 35 -44 -95 -8 107 47 -24 37 34 -35 45 -64 -13 -95 25 48 -28 47 90 16 -34 -24 65 -32 25 88 -19 40 93 12 63 -21 12 84 83 32 103 -56 62 29 125 -3 -55 70 -5 37 22 -36 27 -17 -110 19 -87 -78 -102 55 13 -67 -14 103 -83 -57 9 -4 21 9 -116 49 84 -10 124 -7 -12 10 26 55 -31 -85 -53 0 127 75 127 127 31 -92 -51 51 -83 22 -67 5 69 -13 19 65 35 -40 -42 59 13 127 -30 21 37 -7 41 5 10 -24 19 63 45 25 -79 82 -22 -60 13 -57 8 -114 -15 56 10 30 43 -4 44 -51 -83 -54 -17 48 -10 6 -15 127 -49 -24 -45 -43 63 -49 49 24 -48 44 83 88 -11 43 -40 44 20 90 41 7 52 -101 49 121 49 -14 -79 75 17 -7 8 77 14 40 110 -38 51 29 67 -23 -32 -30 -5 101 111 -9 -29 -16 -39 -48 -58 14 14 25 -64 113 -68 -36 -57 25 -31 65 -53 29 22 23 -10 -59 -2 59 -64 108 10 -1 111 40 121 76 87 104 -77 83 90 124 -107 -63 17 38 15 97 125 105 -63 65 27 -8 37 28 -1 -80 51 -37 119 3 -62 4 61 -12 -58 -7 -105 56 -74 -9 59 -77 -6 2 110 -34 -116 31 20 11 -39 -91 -2 -55 24 -48 -21 -21 -22 77 -125 31 14 101 47 32 -20 20 39 43 -61 -35 -126 -29 55 -33 21 1 -9 32 -28 -43 18 87 -21 -77 -10 -66 -29 -68 -77 -2 76 -57 5 -21 -65 58 8 -40 26 -16 -3 19 93 -16 -8 127 -23 0 1 11 -111 -48 102 -22 -101 -18 -33 -19 -1 -13 -56 2 56 26 -10 -75 -35 11 -27 -4 -1 -60 -59 7 -21 -107 -21 -112 9 -82 -43 4 -22 55 57 -33 48 84 -50 41 25 -24 3 -58 17 36 -21 20 -19 21 -50 102 1 -106 -2 -74 34 32 -7 87 45 -35 39 -2 -9 40 -54 -19 39 40 -48 6 -25 -54 65 39 -34 31 -53 -14 -25 -50 -76 -32 -89 -78 -79 29 51 53 -71 38 -21 -91 -59 -39 -52 92 125 -19 -89 60 76 106 52 75 -67 121 22 69 100 -60 -88 80 29 127 76 51 40 -3 32 33 16 121 28 38 101 83 42 82 -4 -65 36 29 -19 33 18 26 32 -31 39 119 103 43 126 0 79 6 -26 -25 34 114 74 23 19 125 53 -16 54 -111 60 63 84 14 6 111 -69 71 32 -56 79 33 120 -13 19 96 104 71 34 -81 11 14 10 46 -40 10 43 4 51 47 63 62 75 79 61 75 -16 -83 61 98 -112 -28 18 47 -24 -5 37 -7 -19 35 73 -47 3 -53 -98 76 49 -74 -75 62 16 -30 124 -54 120 25 117 126 3 16 -55 45 3 -3 -23 -107 25 29 50 -72 36 43 52 -47 -45 26 44 59 98 37 44 44 101 -49 -31 -1 23 37 -16 -48 -14 -23 3 -14 22 17 49 68 56 67 -44 91 22 38 45 38 15 -21 37 4 15 73 50 -32 125 -7 -107 66 -1 32 -15 -12 -33 63 15 -8 5 -2 -65 -41 -126 31 112 63 109 -100 -93 48 -7 126 -7 -2 78 36 -23 36 79 15 82 55 32 -24 -24 124 -50 -83 -76 -26 -39 61 1 -3 -36 -93 -39 -50 -30 38 113 7 3 22 -6 74 36 47 -61 11 47 -68 104 0 -49 -81 75 -48 -109 -21 -100 -79 -12 -116 -17 -40 -41 -25 38 49 8 29 50 22 86 51 -87 3 -126 -128 -12 43 -83 82 127 69 43 -31 72 26 -10 -102 -2 22 31 31 -32 44 69 -31 127 63 -17 106 -36 37 11 74 -69 113 47 18 28 58 124 17 12 -49 2 110 27 9 56 -38 -15 -23 22 42 -17 14 -3 44 79 -8 77 -7 -92 50 37 -8 111 76 52 0 23 68 -21 2 82 12 46 45 -62 48 27 3 53 82 -44 -27 124 -10 46 -11 51 71 46 104 21 42 -31 37 37 105 56 -18 -17 -1 45 -2 53 49 41 124 68 20 8 33 44 40 -1 -9 -42 6 -7 -61 -21 3 24 -36 66 43 16 -15 -36 3 25 -49 -4 -24 29 10 64 30 30 -51 -3 46 -34 -40 -5 -14 7 27 35 -30 1 7 -16 44 33 8 -7 0 -17 -69 -36 3 1 1 8 4 28 45 -4 -31 -38 20 38 -28 44 -1 4 21 1 28 30 75 12 97 -3 -13 -43 -13 -33 7 47 -16 -10 -2 23 0 38 -58 56 -78 -31 48 -7 -8 -1 -10 -44 21 -7 39 99 86 -80 -41 -21 20 -27 59 -28 -63 -7 59 -20 42 -2 60 -3 -6 -75 -66 -10 -57 31 49 -58 26 -34 41 21 -64 4 3 -8 -9 -26 -11 -111 -36 51 -52 -59 53 85 18 -10 24 -13 88 52 -57 -86 3 -4 -59 16 -49 -39 -5 -33 -104 -27 62 11 -20 9 -8 -10 -120 8 -77 51 -63 -28 -3 37 28 22 49 -65 -18 -74 -23 13 17 0 15 127 -35 78 -78 14 -17 -2 -36 -14 45 127 29 37 37 73 14 69 -55 64 40 -96 -19 34 -11 -52 65 8 18 10 4 60 9 26 -99 63 51 -98 8 57 -89 -20 -71 -47 63 -5 -45 120 -17 -63 20 127 -62 -46 57 -27 -82 76 58 21 -111 8 -90 86 9 -91 20 47 59 -69 -13 58 -30 -15 7 -48 -29 120 118 -8 -31 66 0 -24 44 -119 10 -39 36 66 50 -25 -5 -20 -7 -63 101 123 -86 -58 79 -1 125 -39 94 33 17 65 65 -47 21 -7 -60 -35 -58 3 23 87 -36 59 -50 36 36 68 -7 -76 83 -2 -34 -69 -32 -40 41 5 -29 21 57 -53 -42 -51 -26 15 -82 42 30 -39 1 -5 -12 27 105 -12 -36 -26 15 -8 58 -83 0 47 -50 127 -112 5 -1 35 -111 -5 9 -40 10 43 -37 56 30 39 13 -10 -18 16 59 -37 105 -22 -40 19 -89 10 26 -8 -54 -34 72 -51 -53 68 -12 4 -70 55 40 -41 -41 -19 55 20 50 53 40 -18 24 -20 -61 2 -31 -89 -20 53 33 63 24 -88 100 51 72 49 37 -109 -15 -67 35 3 -18 -42 -93 63 4 2 -65 -12 -80 17 -96 26 21 69 -105 -61 106 -23 1 -74 68 -73 -16 -6 27 66 35 -54 23 3 -89 -71 -59 -71 -11 -17 27 0 -50 4 -18 8 -40 10 32 40 18 -5 53 -42 -45 -91 59 -6 -4 22 1 62 77 -12 24 -6 -125 126 -20 89 -45 67 -13 89 -25 -10 -30 36 108 -97 51 -10 -13 -20 41 -64 32 -28 -66 -2 3 2 -83 -42 -21 -41 -3 -6 -90 65 115 -84 -11 -109 22 -69 -56 34 101 -68 -8 -31 -65 -15 121 104 -87 12 -9 -4 -13 -97 93 3 -40 5 6 37 -59 -9 -126 35 -25 68 -30 92 47 5 -44 -25 -110 -98 46 76 -119 -22 -29 37 44 -35 -21 78 70 40 5 108 -13 55 14 72 -25 99 29 -28 10 11 12 -63 -19 -17 112 41 33 58 10 -37 99 13 -9 -15 12 -10 14 18 -9 -59 70 -92 0 4 27 69 -41 75 48 13 62 39 -49 60 -33 -5 24 13 -21 -49 -8 -70 34 126 25 -9 -29 -19 -39 2 75 -93 -56 34 -26 75 -65 -42 -45 102 -96 23 -14 -16 -41 -80 -66 -91 40 4 20 40 6 30 13 97 -34 -2 -40 8 -43 34 -29 66 -63 -26 4 -16 -66 -59 -44 73 -3 -39 -9 -12 -27 32 -22 -47 -56 -2 13 -26 91 30 -94 -69 -45 100 69 35 34 101 92 -36 59 4 -27 -17 21 -100 122 80 -48 28 127 8 60 37 32 -124 -17 -10 -41 5 -124 33 101 32 22 -7 45 -36 28 -11 -39 108 118 -4 2 52 41 -45 -53 34 -121 -78 18 -81 23 3 -44 -30 -29 -43 -80 69 50 26 -25 21 -5 117 -12 -79 -39 43 -91 -22 0 -44 61 -70 30 63 -63 40 -77 -7 -45 -29 6 -28 -19 -14 18 -32 -43 -51 106 6 -120 6 35 -22 12 -28 -4 -16 -101 -27 -125 -98 -44 -41 31 -61 38 -7 20 -16 -18 47 -6 -33 76 -40 -32 12 -5 -63 41 21 70 15 -12 -67 20 -19 125 -98 81 -47 -59 -39 -1 35 106 28 -9 67 0 1 46 -22 -94 2 17 -14 3 75 96 37 38 -23 82 -106 -37 7 -5 -73 -5 2 56 9 34 -6 -17 41 54 -24 -70 -87 23 -25 -42 -84 -92 -3 -57 12 -43 44 51 -70 -17 -18 -71 -58 42 52 -9 -14 -100 -11 -1 -67 -33 91 99 1 41 -35 -101 -123 2 8 31 125 23 28 35 -55 -5 15 -27 126 -46 16 54 74 50 -18 24 -37 14 -13 -39 -46 9 -54 60 55 -13 -90 -24 27 2 -6 27 -44 -23 5 9 9 -101 -4 44 108 10 55 -52 -10 -68 -8 -126 -61 -12 5 39 -17 -9 -21 26 46 -30 99 -3 78 -6 33 -8 -12 -61 -62 -23 0 -49 17 10 -7 -63 -51 5 -12 -59 22 45 -14 50 -2 -16 22 -35 9 -31 -54 -8 10 7 13 -11 55 1 45 -34 -20 20 43 0 127 39 47 -5 71 36 -18 46 37 47 -27 -68 -11 -2 5 103 53 90 0 39 -9 34 -48 -11 -10 42 59 30 61 39 27 -23 -7 54 -41 -58 -70 -24 -46 -15 -34 -36 0 -4 51 20 -10 40 50 -32 24 19 -37 125 -24 14 -89 -36 5 61 101 -45 32 70 -122 9 39 -4 65 -110 -39 -52 27 38 65 -9 81 -121 6 -83 9 123 38 116 -14 16 -15 14 -120 -13 -13 56 127 -43 57 103 61 18 26 26 -35 127 72 -80 35 -78 -10 -55 -85 116 6 9 -69 -44 -79 -44 -8 -38 67 124 -11 -7 -51 31 105 4 -6 119 49 112 91 62 -75 47 72 76 -68 79 -80 -16 8 77 48 29 -24 -7 30 -61 5 66 -59 30 -14 45 -49 -6 61 -113 -10 -116 -113 57 -2 -74 19 48 -108 -6 70 -112 102 -116 78 37 -30 -69 44 -101 28 31 44 103 -63 2 11 -58 -17 9 -67 -6 -51 22 70 -35 39 66 73 26 -26 96 14 6 57 0 -7 -50 34 53 -49 -47 -61 26 112 6 -38 9 -19 20 -93 97 69 -1 33 -33 -58 -14 64 -76 72 -20 -24 57 1 -123 -126 -45 98 52 -60 65 -10 -115 -61 34 20 12 46 -67 74 97 79 20 12 36 -47 -93 5 -44 38 -15 112 -70 -52 21 2 -18 39 91 18 74 -62 -88 -69 -36 46 -58 -27 -80 -45 70 56 -127 -108 -47 -5 22 2 -32 -90 -8 34 34 -48 -68 -45 36 -4 16 48 124 -37 64 -62 13 -83 -32 72 127 -70 21 21 -4 -99 -93 -38 -123 39 -32 34 63 -83 17 -54 12 29 -34 -2 -21 -67 4 46 11 -38 11 59 -25 48 28 -36 -10 26 -16 -125 -87 -37 18 -26 79 -25 -34 6 -44 65 44 -30 -8 -22 -6 -6 -33 12 40 9 -66 21 27 10 -45 -49 53 -82 -6 -56 -47 -39 -28 -45 -35 -110 -5 57 -10 -19 -125 -69 31 -13 -55 -58 -40 71 11 -83 45 -33 32 -30 -45 -44 -128 101 -6 126 -55 -58 71 66 28 -11 12 -88 -70 4 -26 -61 -53 4 26 20 -70 11 22 -75 -110 6 35 17 50 -83 -7 -44 -35 -73 -12 41 64 -40 10 -102 -25 37 49 -15 -97 -64 -58 53 -51 -5 120 62 26 22 -28 15 -19 -20 -33 57 51 -7 109 -50 -66 6 -99 40 66 5 56 -113 13 -42 51 -67 38 -32 104 26 36 66 -23 -76 -13 -28 -40 28 5 -57 -18 29 66 -76 -34 -16 48 -71 -27 -2 -43 67 30 23 28 -16 39 31 6 -55 39 25 -83 -4 -12 -55 -51 13 -38 -24 21 -30 20 -57 -22 19 -7 -18 20 24 3 15 -55 59 10 5 -10 58 -49 67 105 -47 8 -5 10 50 -95 -67 -68 -61 -114 16 -58 2 41 39 107 -34 -30 -87 -40 -12 10 18 -9 27 -127 -25 115 -30 -46 38 63 2 6 -85 -50 -17 -13 80 35 -27 18 -47 37 -47 -23 -89 -37 2 -5 -21 -3 -31 -10 -47 -2 -1 69 -97 -31 1 -29 49 -36 -81 35 16 3 -29 -13 -56 62 80 -29 -46 14 -38 -14 -110 51 -56 45 50 7 -79 44 0 19 56 -84 -23 -39 -59 -31 27 -34 -49 -8 111 -9 -16 66 15 -15 -59 -23 -16 13 20 -94 -17 18 -27 32 -78 60 40 53 29 -98 33 96 -52 -89 -46 0 11 11 -52 21 6 -50 19 24 121 -40 -40 -22 -2 56 65 -11 117 78 -7 -88 5 -15 -11 -84 71 12 -40 -43 -28 -127 24 15 -65 15 -42 -73 31 -112 10 -98 -67 -52 -40 34 4 94 15 -44 -49 -4 42 43 121 -21 -8 75 30 29 -7 48 -45 31 35 8 57 63 -64 26 15 33 -68 60 9 -15 -47 -4 77 61 31 68 -13 68 -59 8 46 92 -28 16 90 -1 35 -73 126 -43 39 -56 22 12 -3 -33 -113 -3 22 3 17 -28 -95 48 42 25 -49 15 34 122 123 122 23 38 63 74 48 40 59 20 70 -85 14 84 52 24 -91 -34 18 -34 -41 29 0 -17 37 -37 72 34 23 27 50 90 -2 69 60 -128 20 -82 54 -5 1 -48 -3 1 41 35 -15 -15 78 -33 27 75 -19 23 0 52 74 -19 -7 46 7 24 40 -35 2 -14 -39 108 13 66 49 -19 -80 -13 48 -65 41 -12 -91 -7 -12 -51 -78 57 20 -17 76 -96 -20 37 -17 -60 28 14 -44 -28 -102 7 -113 29 -109 -45 -37 -49 -9 -54 37 -21 7 55 44 1 -52 32 -12 -103 -45 -19 23 40 9 36 80 8 86 50 -48 -20 -24 -20 1 36 -26 35 -55 3 8 -74 5 -37 122 -23 -37 1 75 -47 -1 30 -38 -2 -48 -66 3 17 -23 24 122 -103 -39 -120 -23 40 -3 26 55 -50 -75 -2 118 -47 -24 2 -50 55 -35 -48 -105 75 8 89 32 19 -7 39 -78 40 -7 -26 6 -123 -123 -5 -31 120 21 -76 -16 -77 11 45 -3 16 34 127 36 -34 10 1 -47 -9 -121 -13 -52 84 -17 -15 -70 -35 -124 -67 -8 -78 -22 -118 -80 72 -37 49 -34 3 -124 -75 -59 -54 -58 -78 35 -122 69 -52 27 -39 53 -62 -5 80 -20 -96 -116 49 -31 -126 25 22 54 -18 1 19 -17 -97 -6 53 -80 56 -117 67 -40 32 -50 12 3 -43 11 2 86 38 22 -90 -22 23 -65 87 -9 -40 118 86 -83 -18 -28 -47 44 2 -97 9 14 -68 69 54 99 62 8 65 22 55 66 13 -39 -30 -28 2 127 -13 51 -15 4 -53 -121 78 -45 -43 -56 -29 -17 -11 -41 50 24 43 15 -66 -39 -25 -55 -20 50 86 31 -10 15 -40 -17 47 64 -70 12 14 -22 -15 20 -45 -44 -26 -6 -2 -7 3 39 -25 -90 26 -54 96 33 83 11 -7 -77 24 47 -3 -18 -11 -40 68 1 38 33 -15 61 -17 -91 36 118 -61 3 -64 -75 -37 39 -41 6 -115 22 -56 2 87 -54 -73 -57 23 -51 -88 -84 -48 -62 -52 10 -21 24 2 10 -54 -10 61 -6 -6 -73 126 22 78 -102 -38 -57 68 119 -26 -69 0 55 14 62 59 -30 -12 -24 -55 36 -13 30 46 -48 102 -71 -12 17 54 -18 39 25 -29 25 87 68 -17 10 -45 -7 86 36 21 108 -69 15 -61 50 13 -5 36 -25 25 25 -37 29 0 -105 74 47 -11 90 42 54 5 -28 -10 4 28 -95 98 40 80 -55 -19 23 -38 58 68 12 12 118 -58 46 -11 24 64 61 44 38 58 -42 58 -4 89 53 31 -19 5 47 58 -10 43 -11 47 56 49 -29 48 -16 16 -6 -27 -1 35 13 -33 27 13 37 -38 31 44 -15 13 -46 4 32 -34 8 -12 22 -24 46 -23 19 -2 22 20 5 -32 -46 2 7 8 3 -26 52 37 33 33 40 22 9 6 -19 -45 4 22 -12 -17 33 31 46 10 33 -6 -25 20 -15 -35 29 30 -1 -11 -52 7 17 -5 15 31 -9 -4 -19 -8 -3 33 22 -3 18 -18 17 -2 15 -3 28 -11 5 24 -15 4 -32 12 -18 8 -1 1 6 -15 -83 -46 -44 28 -2 -7 -87 -14 -14 23 9 22 19 25 -42 22 -24 -23 10 -21 -13 4 -12 8 -14 -51 25 -5 -21 -16 -5 7 -14 39 -37 23 -33 -39 -29 23 -54 13 3 8 -7 7 37 2 56 21 10 -27 14 -19 -4 25 -23 0 -5 -3 29 0 -3 -26 33 0 -40 -15 49 -9 2 2 -30 2 -6 32 -8 -3 6 -16 8 0 15 7 37 -1 20 -5 22 -1 16 -59 96 22 1 39 16 10 11 19 15 15 10 7 6 5 4 2 4 -3 -1 13 34 49 44 43 84 -34 -24 -15 -10 -22 -26 -37 -29 -7 7 22 15 9 17 27 29 8 0 -5 7 4 -53 21 25 37 44 38 46 55 63 49 41 46 28 30 37 43 49 46 28 3 3 2 3 10 -11 -12 -8 7 20 17 10 5 13 17 27 38 48 61 67 58 46 36 40 30 28 -23 -23 -20 -16 -7 -7 -13 -22 -25 -33 -45 -46 -56 -67 -78 -101 -123 -124 -107 -112 -99 -58 -61 -28 3 20 29 30 17 -18 -65 -86 -77 -67 -39 -29 -30 -18 -18 -21 -22 -41 -75 -90 26 8 -28 -62 -81 -84 -70 -60 -57 -61 -54 -64 -63 -60 -41 -20 -6 -5 -2 -2 19 21 -14 7 25 37 43 36 28 22 23 18 16 14 20 13 2 -3 -9 -23 -4 4 15 16 1 13 15 5 4 9 5 0 4 18 19 18 20 17 9 11 20 45 73 89 104 68 92 53 31 24 16 10 14 15 22 22 26 19 5 3 4 15 14 6 -22 -16 7 7 7 2 21 30 38 51 70 81 87 94 96 99 102 109 108 110 116 101 62 72 67 22 10 11 8 2 6 11 11 10 12 12 10 14 18 11 2 -35 -80 -128 -128 -128 -77 -7 -17 -34 -46 -27 -33 -41 -41 -40 -48 -53 -61 -62 -58 -57 -51 -41 -36 -37 -32 -35 -37 -24 -10 -11 4 13 10 5 2 -1 7 10 0 14 26 34 42 55 52 67 45 45 59 107 -47 -85 -100 -65 -25 -13 1 1 -5 -7 -10 5 9 14 27 35 35 8 0 12 25 20 17 23 25 21 16 15 18 17 21 25 36 43 50 54 49 45 42 33 24 29 30 -1 -62 -36 -28 7 28 35 40 54 64 62 50 50 43 32 7 -3 -2 3 18 16 24 31 13 10 5 16 26 25 25 27 32 32 38 39 41 35 28 17 15 23 25 6 -6 -46 38 38 43 44 59 85 104 119 111 112 113 115 104 96 92 71 60 58 52 50 48 18 18 27 4 27 42 48 34 47 64 75 71 69 69 85 102 122 125 112 127 127 112 81 -77 -68 -47 -30 -19 -20 -16 -17 -15 -9 -12 -10 -10 -7 -13 -26 -29 -22 -25 -15 -11 -16 12 14 29 39 46 50 47 35 37 52 47 48 48 52 47 15 20 66 83 79 71 69 -19 0 12 10 5 12 11 15 18 17 20 25 22 17 12 3 0 -1 4 15 16 -1 127 105 62 44 39 37 26 19 32 38 27 39 38 40 35 31 17 11 30 59 92 56 1 9 16 14 19 16 18 11 9 3 -2 1 6 10 8 8 16 22 19 17 19 29 39 30 -4 -2 22 30 17 2 9 24 -1 18 24 31 12 2 -5 -4 10 15 11 -12 -58 -75 -81 -92 -62 -47 -44 -32 -24 -21 -19 -17 -8 0 11 18 16 5 -2 0 -16 24 -61 -32 1 4 4 4 13 13 20 15 6 4 -2 -7 -11 -4 -2 -11 -14 -21 -29 -23 -13 -13 5 7 4 10 10 10 15 13 4 10 0 2 3 12 7 -30 -31 -28 -35 -66 -11 -2 22 29 40 46 39 39 46 42 41 52 49 39 39 39 33 31 16 14 11 3 37 32 -9 -18 -30 -43 -42 -40 -41 -42 -34 -40 -42 -36 -33 -39 -30 20 24 -2 -42 -68 14 5 -5 -26 -32 -37 -40 -37 -42 -53 -63 -75 -80 -79 -70 -67 -63 -62 -80 -69 -52 -27 32 20 -2 -30 -39 -24 -20 -27 -31 -18 -19 -12 -17 -23 -33 -26 -14 -3 -3 -8 -4 39 -8 -31 -55 -41 -34 -30 -29 -28 -21 -4 7 7 17 32 30 24 28 52 51 42 29 21 18 -1 -20 -16 -10 -11 -19 -17 -13 -13 -13 -8 -4 2 19 20 -2 -89 -128 -108 -42 -6 127 127 75 25 13 15 9 0 5 17 27 32 35 39 45 47 37 14 29 29 15 -5 -18 -55 -67 -47 -21 -12 -16 -24 -21 -28 -33 -16 -19 -22 -14 -7 -13 2 24 32 32 13 -62 -79 -80 -88 -95 -89 -85 -67 -52 -38 -31 -28 -31 -23 -12 -6 -15 -26 -31 -20 -7 -11 15 -22 -29 -15 -15 -23 -37 -39 -36 -33 -32 -23 -28 -25 -20 -16 -16 -17 -3 7 16 20 87 70 31 -5 -4 -7 -33 -65 -73 -69 -72 -30 -19 -36 -72 -82 -54 -5 10 7 23 5 -18 -9 18 32 42 39 36 35 34 38 37 41 47 51 60 59 57 27 3 13 -8 -126 -64 -35 -17 -32 -42 -31 -31 -20 -30 -39 -37 -43 -42 -43 -48 -63 -62 -58 -65 -46 -24 -44 28 18 18 23 29 33 35 31 21 10 2 2 6 12 15 15 18 -20 -87 -79 -56 -33 30 27 22 29 39 48 63 60 34 17 20 20 21 21 24 31 26 13 1 10 14 23 47 62 72 97 81 73 42 48 85 127 127 127 127 127 118 74 61 43 24 38 31 16 1 -34 -55 -46 -44 -37 -28 -15 -8 -10 -12 -15 -10 -7 -7 -3 1 -3 6 25 47 124 -31 -52 -56 -52 -43 -41 -40 -35 -24 -27 -29 -29 -16 -10 -8 9 33 25 10 2 -19 -115 40 48 44 53 31 17 38 40 33 18 16 21 33 43 40 36 37 24 25 24 25 20 3 24 38 26 16 7 3 6 15 15 20 19 10 -1 1 -1 1 5 9 18 9 16 44 62 46 41 43 58 71 72 68 73 81 86 100 102 87 78 66 60 97 120 127 118 -27 -40 -41 -43 -53 -51 -53 -60 -53 -43 -45 -36 -40 -50 -71 -93 -93 -78 -82 -65 -53 -85 -27 14 52 95 117 115 96 67 36 12 -3 2 12 8 -4 -17 -17 -16 -21 -7 -1 -26 -46 -60 -78 -96 -96 -86 -80 -68 -64 -63 -58 -64 -62 -51 -29 -15 -19 -4 0 -23 -49 -55 -25 -26 -17 -6 -1 0 2 1 -2 4 15 29 36 36 25 20 25 32 30 28 20 -3 3 16 14 16 7 -7 -9 -12 1 8 19 26 26 19 5 -7 -26 -40 -60 -106 -127 -128 4 12 16 21 16 11 15 12 -5 -22 -34 -48 -57 -72 -82 -79 -68 -59 -44 -25 -13 -4 30 15 24 41 49 54 56 56 54 51 40 42 41 35 28 23 21 19 14 15 3 2 -4 -29 -55 -67 -70 -77 -74 -80 -90 -89 -91 -88 -84 -74 -45 -34 -21 -11 12 12 25 27 -54 -36 -46 -45 -39 -38 -48 -59 -56 -41 -25 -7 -5 -1 1 0 -5 0 9 9 -6 -19 3 19 22 15 18 10 13 6 -13 -38 -62 -75 -91 -107 -128 -128 -128 -128 -116 -127 -119 -76 12 26 51 74 81 76 65 62 57 65 68 65 70 64 51 45 46 54 45 39 32 20 -74 -60 -49 -49 -59 -63 -61 -55 -56 -56 -54 -48 -48 -48 -50 -50 -51 -58 -46 -33 -39 -42 22 11 -17 -43 -48 -50 -37 -27 -18 -18 -18 -19 -20 -22 -22 -25 -21 -19 -10 -9 1 7 2 -28 -57 -60 -44 -40 -35 -28 -41 -57 -52 -66 -52 -49 -63 -60 -31 -4 -16 -41 -45 -81 -104 -76 -45 -36 -32 -30 -28 -28 -34 -35 -43 -33 -38 -35 -32 -31 -38 -67 -81 -49 -15 46 8 -8 -20 -15 -2 -5 -11 -7 7 13 9 2 -13 -32 -60 -76 -91 -107 -124 -104 -66 -25 -4 -28 -30 -26 -7 7 5 -13 -40 -64 -89 -81 -65 -56 -40 -31 -28 -21 -10 -11 3 -14 -25 -57 -79 -68 -69 -63 -62 -56 -32 -23 -29 -23 -26 -22 -28 -35 -40 -41 -47 -53 -62 -71 -23 -21 -12 -35 -50 -61 -67 -79 -80 -57 -28 -21 -3 14 25 23 18 -4 -60 -53 -29 -25 -40 -37 -48 -45 -44 -39 -35 -36 -47 -49 -26 -25 -18 -13 3 6 7 14 33 27 31 43 0 -3 7 -3 -7 -3 3 12 16 20 27 27 33 34 43 60 62 -22 -124 -128 -128 -127 -13 -19 -17 -10 -9 -16 -11 -2 3 -1 2 -2 0 3 13 20 19 9 1 -8 -31 -18 -8 -18 0 13 37 51 58 73 72 54 30 16 17 12 4 0 4 8 20 0 -17 -31 48 23 11 10 27 46 55 43 33 33 34 40 39 39 43 47 43 3 -20 12 61 80 59 33 0 -6 -6 -6 -14 -8 10 20 21 30 34 27 19 17 25 41 53 72 82 56 33 36 31 32 54 65 58 60 54 42 41 31 16 1 8 19 27 39 47 45 35 33 110 127 49 36 43 45 44 49 45 53 49 67 59 62 71 74 73 68 62 76 80 90 57 88 98 80 53 26 19 14 12 15 19 18 23 33 36 35 35 37 27 6 3 3 28 34 31 41 41 43 36 27 34 41 26 37 34 33 41 42 42 39 29 30 33 37 -5 38 76 105 107 87 75 66 62 62 55 32 19 -1 -35 -55 -58 -61 -37 -19 -9 -17 -44 -50 -58 -42 -39 -37 -34 -36 -47 -37 -33 -41 -38 -34 -40 -46 -46 -51 -49 -53 -84 -128 -16 -75 -79 -36 -5 -2 -4 -6 -13 -31 -43 -46 -46 -44 -26 -12 -11 -10 10 38 59 71 -77 -82 -101 -119 -128 -128 -128 -128 -125 -113 -106 -88 -89 -88 -82 -77 -74 -64 -44 -32 -13 -13 -15 15 13 0 -21 -31 -34 -41 -47 -44 -40 -40 -48 -52 -50 -53 -59 -66 -68 -79 -97 -42 69 104 90 59 25 13 8 21 13 15 28 22 25 32 27 19 8 3 0 1 1 -16 78 76 -9 -11 3 10 12 1 -13 -11 -16 -23 -28 -30 -36 -40 -40 -48 -56 -63 -60 -25 -65 -51 -43 -33 -31 -25 -24 -22 -13 0 -2 -6 -11 -3 -7 -9 -16 -23 -19 -31 -28 3 44 33 25 32 33 34 35 40 47 49 52 52 46 40 36 35 26 16 30 40 59 57 29 37 29 46 43 38 40 45 45 48 44 33 19 8 4 0 4 13 7 19 3 -38 12 19 19 3 14 27 34 29 21 17 2 1 1 -4 -16 -19 -9 14 14 10 -13 -12 40 42 56 41 27 31 38 35 28 27 18 22 33 36 35 35 32 26 19 20 19 12 -84 -34 -22 -14 -7 -8 -16 -12 -8 -4 2 -1 -5 -6 -4 -17 -34 -53 -40 -18 3 10 10 -19 -66 -66 -57 -64 -83 -93 -91 -98 -108 -101 -104 -107 -112 -120 -104 -36 43 33 -8 -128 30 10 -34 -40 -50 -51 -47 -34 -29 -29 -30 -29 -38 -38 -39 -41 -40 -51 -46 -24 -26 -29 43 38 27 22 17 17 15 17 12 11 15 16 13 12 14 19 22 36 33 24 11 -20 -108 -128 -127 -122 -100 -87 -79 -74 -83 -78 -65 -62 -57 -40 -25 -19 -18 -18 -15 -5 6 -8 -3 22 24 47 33 34 8 3 -7 -8 4 4 18 20 11 -16 -26 -12 -34 -23 -19 -13 24 1 1 -128 -35 127 127 -99 -128 127 -128 -125 123 -103 127 127 -128 127 -128 -128 -128 93 -114 -128 -128 127 -128 127 boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/lq.rnnn000066400000000000000000011041211516712004000272720ustar00rootroot00000000000000rnnoise-nu model file version 1 42 24 0 2 -7 5 -3 -2 -18 0 6 -3 1 5 1 -18 -2 -2 8 -8 12 19 -10 -43 8 5 3 -13 9 23 -8 16 29 -9 -10 1 -13 -20 39 0 18 -22 -15 -46 -1 1 8 10 -25 18 23 -30 -1 42 -8 6 -18 -13 31 3 2 -32 9 -2 -28 -44 -29 -41 23 14 7 -37 -35 -11 11 1 -18 19 15 -7 19 3 10 -7 34 4 -20 16 53 -37 -62 27 48 2 3 29 -31 19 -26 5 -37 1 14 2 -68 -9 -63 -8 -17 24 48 22 -23 -13 -62 -9 9 -12 -22 -56 9 -53 -25 -9 -5 18 11 -9 41 -16 -48 16 -48 -2 -5 -19 73 -19 -36 -18 -25 8 -23 80 -45 38 1 -65 -40 -59 -27 -90 -122 29 -66 -2 -56 -28 -124 -10 10 -17 123 67 97 34 -86 -78 -20 -110 -110 -1 -6 -72 98 89 -21 -37 0 -6 15 127 -17 11 121 -128 127 65 30 -102 -86 50 -20 15 -69 -88 -72 -86 69 -58 -100 -43 -2 57 -99 106 -102 120 -125 -101 126 74 100 -50 -73 -61 -99 -111 -126 -53 -87 -18 71 -125 -26 31 -101 -7 4 56 -95 0 76 -55 -52 79 18 51 -99 3 -74 2 -87 -10 -26 -127 -10 33 -90 75 126 1 64 -22 -20 28 23 19 106 127 -76 70 -41 80 9 -125 89 -63 83 -48 4 -41 51 126 -30 -68 72 -126 65 30 -18 -13 126 114 -82 19 -124 107 28 32 14 -4 35 127 18 -38 55 -12 -122 119 -79 127 -53 59 31 120 -76 -117 17 105 13 -128 127 -100 80 -49 68 -12 34 59 -61 2 55 23 11 4 118 125 86 72 -127 -60 -72 33 -67 19 -63 92 114 47 12 -125 32 40 -82 -127 93 54 122 112 -24 -112 31 120 18 -57 -54 -20 -122 61 -11 -97 94 40 -126 -22 -6 40 -87 -126 28 25 127 44 -46 -17 122 -13 -33 -40 115 15 -61 127 -32 49 84 27 -68 -50 12 95 -93 -100 126 75 24 65 -55 32 -92 126 15 -122 126 -83 -67 -122 -128 -7 -12 75 95 -41 127 -55 48 -126 8 123 80 -3 -31 -126 95 -72 -123 -48 127 58 -35 91 -128 36 95 26 -79 -85 127 17 -102 -109 23 86 -19 85 -33 -112 98 114 -10 -124 -61 77 85 84 -121 -125 48 -25 -99 -126 -36 -69 -86 113 99 -7 127 -127 -12 127 -82 -70 79 -128 125 -87 -121 -125 -128 46 -94 78 -47 46 28 71 -127 54 83 127 120 -127 124 126 26 103 -106 -54 89 -38 105 -88 -75 -80 4 -71 -38 -63 25 52 104 -10 69 102 -50 126 127 -70 72 49 127 -123 34 -76 14 -93 -117 81 -67 127 5 76 100 -98 -68 -116 127 -45 -128 -77 18 12 125 -87 -20 21 102 -29 -53 10 48 -8 101 22 -4 22 -12 127 -87 -126 51 -128 -119 -122 66 78 3 32 60 -28 40 30 4 56 56 18 82 -104 58 -47 -56 -41 -47 -113 127 12 -19 -95 56 16 51 -127 -51 -118 29 9 -16 66 -33 11 121 56 21 -70 10 -20 -21 -11 76 -29 6 71 -35 -62 55 -52 -2 -108 31 -34 -33 73 121 41 -123 -67 -80 -18 -44 -2 -35 -105 -59 -69 81 -86 55 74 61 -57 -117 17 -1 37 20 -84 -7 -77 -10 35 15 3 70 -39 4 26 -12 58 23 35 -80 -14 -7 -85 32 -127 -21 -113 -98 69 96 -47 -67 124 9 -1 120 12 -71 -9 44 -31 113 6 13 9 -44 -13 31 -21 65 2 -45 15 51 15 92 26 34 10 32 92 98 7 108 -15 56 -19 51 -45 79 -8 11 -28 -31 -11 -9 40 38 -57 21 18 34 -125 -46 57 -7 -23 -50 45 70 38 12 -28 -51 -4 61 -123 49 -59 -12 -80 59 19 78 45 -31 -52 33 -38 127 -115 49 -19 -32 85 -10 77 26 -77 -69 104 -112 -91 26 -78 44 -65 -23 26 -15 -118 -127 79 -126 -4 -37 33 -11 14 52 -15 18 -69 -55 -76 93 -12 -69 -44 15 -18 -63 -15 94 -99 77 -46 111 -13 -77 14 -43 0 68 -37 93 106 -16 -91 127 -37 13 -27 -39 -50 17 27 115 125 111 -117 22 -128 16 127 127 47 -18 -54 -24 -115 -99 -47 -15 66 127 32 91 46 125 86 66 127 86 -101 -52 -127 122 126 93 100 17 -126 98 -99 -81 62 -15 69 90 -17 75 -6 127 121 -61 -41 -24 10 115 99 44 -73 -41 121 17 38 33 -40 -8 56 50 -64 -60 98 -10 -56 -62 80 123 -13 15 23 80 -127 81 127 69 -67 -16 -85 -14 -38 59 -61 -56 32 127 -40 4 40 33 33 6 117 -35 -4 71 -6 92 126 66 83 17 -87 -31 7 17 -8 -103 0 121 -34 -54 38 50 66 -98 -25 -17 49 -49 121 -58 -92 -87 -1 -29 127 63 13 91 0 111 -59 26 -28 127 -19 -118 -11 36 124 29 16 26 50 26 9 -40 82 -25 39 -78 -23 1 -25 -26 -13 -113 17 -10 -19 -18 67 -24 -28 127 4 56 17 23 13 83 -5 -27 48 -15 10 -65 -46 -22 47 28 127 25 12 18 -11 127 -60 4 127 125 20 -58 -127 22 -74 41 103 41 25 -125 93 -59 -127 -26 -1 -128 41 -1 24 24 0 -10 -117 52 91 -127 -32 -128 -96 50 -114 24 25 54 28 -122 -127 -97 -125 -27 -20 -70 21 -10 17 123 50 126 7 -121 32 88 2 9 -116 37 -84 17 32 -26 -120 -31 21 33 -54 -50 -47 127 -36 -109 -100 -16 47 -114 -120 -65 86 26 121 -77 -22 43 14 4 40 -122 122 6 -43 -128 50 -14 -5 -126 -97 23 -121 -58 68 -10 -111 -122 -39 127 -25 -103 34 -55 -50 37 4 -126 96 -37 127 -26 127 41 -57 -25 127 14 98 5 22 6 -83 71 -77 96 -18 -126 -100 26 -11 45 12 23 127 -51 126 3 99 49 14 26 -27 16 -50 34 34 73 -82 -10 7 48 -90 41 -2 19 40 -16 13 -19 57 -65 60 -37 -126 74 -56 -25 96 -115 -39 -79 -47 73 71 125 22 41 51 -124 -123 -127 50 127 -39 23 92 -69 126 108 -125 -128 -95 -88 -86 -85 47 -72 -45 -100 -127 126 -112 127 14 127 66 -127 14 -34 32 21 -90 -56 -43 -5 123 -85 26 -13 -94 15 -23 -110 59 -12 41 16 40 -59 -20 -14 27 65 -117 -126 35 -42 -84 -23 -125 -90 -118 -128 -127 32 126 -127 -66 -126 -126 -82 -53 -110 -69 -128 -50 -44 -35 -38 -110 54 93 13 -16 -71 -128 124 -118 -13 125 -84 -56 53 -16 -93 -43 -113 10 87 68 -123 -34 43 83 35 -20 -39 63 -54 122 -45 -114 59 -120 2 -35 -78 127 97 54 -78 -48 48 50 -123 40 127 124 25 127 58 -63 94 -63 -46 -58 -37 126 96 121 -64 1 84 106 14 127 102 -57 31 27 -21 126 51 -69 -127 -31 16 20 -121 57 -32 -50 6 41 101 -125 79 -9 42 61 -60 54 33 47 -90 35 108 35 80 -49 50 11 77 28 -9 9 -34 -13 72 -98 -17 -51 -31 -15 87 -12 -71 -30 22 87 -81 -24 -68 22 -36 -69 -42 -123 -41 127 -59 -19 -24 31 -52 51 31 127 -97 88 99 -21 91 39 46 -53 60 -4 -87 -20 -27 47 4 47 -40 -41 4 127 -3 125 77 124 71 98 -12 -49 -44 -9 -46 34 -20 35 42 -36 0 -55 58 -12 33 -6 -49 37 13 2 5 20 -59 85 -81 92 47 127 30 -59 -31 -66 -3 -124 -112 -7 -23 -94 126 74 9 -120 72 47 24 67 -68 -6 19 127 -76 52 -17 -11 -116 -113 -73 -35 14 75 -32 17 20 117 -9 127 113 69 -6 -39 -16 24 91 -54 -37 100 88 25 -39 -50 73 -90 67 88 -39 -58 118 -17 45 -71 -80 -35 120 -20 -59 -45 -11 -109 74 -15 -17 99 43 123 1 13 43 19 -15 -1 -109 -46 -13 -2 -53 40 -37 -120 31 -124 121 4 96 53 -84 20 19 -127 -6 -27 58 60 9 46 127 -8 -26 56 -3 12 -39 66 99 -128 -53 -6 -20 -36 31 -106 -21 -24 -64 -1 -78 -37 -20 10 -38 22 -31 16 -43 -59 -51 -3 -20 4 123 127 -127 -127 97 -53 -6 -80 -128 73 -37 -12 -14 -126 -18 21 122 -8 8 -125 -73 -128 -101 -22 -26 61 -126 9 -21 -54 32 -120 17 -93 -76 17 -74 59 -45 -49 -40 14 -127 -59 53 -16 -79 -32 6 -22 40 -37 93 90 0 6 92 -3 -10 -25 33 52 10 45 39 -5 97 66 -43 50 108 -45 25 112 -127 11 127 4 72 -24 -21 127 -12 -82 52 -88 -2 -56 -33 -34 28 -19 113 -31 -125 3 -82 -12 -28 -98 -90 26 126 -98 -46 -74 -89 -103 73 99 41 -38 -67 53 -128 72 -60 -69 -29 -7 -72 -116 15 44 -14 27 -65 15 -63 74 41 -82 16 110 -96 95 -15 -57 51 29 -29 0 -52 103 77 -49 -74 82 -21 -47 123 -126 -57 -103 -114 124 4 -51 59 -51 108 51 55 10 36 -27 -72 -88 127 127 -51 -40 -80 -126 94 21 4 -35 104 111 -31 61 29 -4 -95 122 -125 79 -10 61 -20 -20 -65 -82 43 45 -31 -34 -48 -16 36 37 -18 -25 -15 51 -53 4 23 61 -21 -80 57 -81 -52 -34 127 35 -7 109 -66 -34 102 28 127 43 -20 110 39 -53 86 -42 111 -7 -88 -42 -125 53 91 -12 -51 -126 -40 -46 23 97 -125 -123 48 -7 50 -41 23 118 52 -1 127 102 -85 -14 125 68 -118 -72 -127 -103 46 -78 -118 48 -125 84 -120 82 -100 -128 47 36 -73 13 -125 -11 70 -18 48 -40 -32 43 4 37 125 -16 19 -43 -79 46 -39 -4 13 -46 -71 -15 -127 12 4 -21 10 125 -80 31 -67 123 -30 46 36 20 31 -49 37 29 -8 -50 -43 -104 2 -66 -33 39 32 -81 -2 27 -11 13 -82 7 39 48 -17 -23 5 24 16 26 44 -4 8 -32 58 1 -60 10 65 -4 -66 -9 -40 47 0 -28 -125 -126 11 -93 37 45 -115 34 -75 -22 14 -51 64 -4 -84 25 -116 117 -126 -124 9 127 -69 45 -67 -118 2 -21 87 -127 -6 62 -116 -54 -57 -29 100 88 -34 -27 -6 -8 -120 72 13 9 -126 34 -114 15 39 -15 -99 -80 -93 76 -62 103 -106 -111 -6 -37 -101 35 -82 67 13 71 -4 -47 -52 44 -120 85 49 38 23 105 -29 -120 7 -127 -7 125 33 -123 -52 -7 -17 -117 110 31 14 -67 -52 -100 -46 -86 -61 -17 -4 76 64 -68 96 64 78 -4 -47 -9 112 -26 -30 54 -79 22 -80 66 126 96 82 -15 -37 127 100 15 119 -30 80 -126 -40 67 -71 108 48 -27 82 -36 22 -5 55 -25 29 -23 127 -11 -33 127 48 90 127 67 127 86 -64 123 23 -120 97 2 127 -23 27 -90 10 -34 70 -31 87 11 -15 -20 12 -125 -124 123 -78 -76 -126 121 7 -50 95 35 -127 124 2 30 -4 -127 -13 87 -107 -6 -34 -78 62 -92 31 77 -44 19 -20 -122 -27 -6 -87 61 -9 -7 22 9 43 -18 -73 67 -124 -68 -12 67 46 117 -127 -14 -16 -127 0 -107 -8 36 -57 -9 -107 -93 -92 53 -25 127 35 127 -14 52 77 -55 58 -108 -51 45 -17 37 2 -65 121 21 14 5 4 -115 120 125 -58 68 7 127 62 47 18 43 17 -42 18 0 -5 7 17 0 -75 55 42 -42 23 28 -6 49 12 47 64 5 43 82 64 -79 36 10 -30 127 -99 55 74 91 -83 -57 70 20 -51 108 -7 -32 29 -81 82 -128 83 73 65 -46 -40 -29 17 5 -30 42 -121 33 -44 11 116 -55 50 64 16 -2 51 -70 33 -126 -85 -55 4 -17 12 -1 -55 -26 -63 14 23 48 -6 -64 -11 27 -16 -2 -37 -7 -86 -46 -49 37 28 59 -62 22 19 17 121 -105 -17 -30 -79 -105 93 33 126 -43 -36 -27 -37 -92 48 -128 -90 -127 -115 -74 -69 -34 8 64 -70 -63 -28 -11 6 99 -98 5 46 49 9 3 1 -82 -13 -127 37 14 -30 -21 -12 -51 -49 32 -41 75 40 80 -46 -73 26 -6 -2 49 -25 39 69 -55 -9 39 49 -58 -16 127 -66 -1 -87 46 -29 -26 -63 24 13 -64 -66 -111 -70 -15 10 79 -43 -101 -2 -62 -119 72 -128 -128 20 -29 62 57 -122 -126 86 -28 -127 -114 3 -94 -128 2 93 -110 48 12 10 82 -103 25 -51 -44 82 -7 -40 22 73 75 3 -20 58 -127 -55 -11 -128 -82 -27 -57 -5 7 10 -43 120 -19 -22 13 70 -35 -103 -2 -35 15 -74 -65 -37 5 -62 60 -128 -24 -27 -29 -65 83 -83 127 -125 115 18 84 122 -44 60 -15 -1 4 -123 -123 -26 1 -89 -5 -80 20 44 8 -20 31 -78 103 -55 -39 -37 -26 45 -13 43 0 34 42 -32 -10 -34 10 54 6 -100 -18 -47 -33 46 -25 -27 -12 -27 15 109 -43 -36 13 -76 -63 -59 -122 127 127 -61 -14 49 67 -16 -125 5 -17 -65 84 81 -128 -127 -63 -25 11 -27 -94 -13 -124 -5 75 -29 -84 -29 -104 44 33 -62 40 -106 7 -100 30 -71 -128 80 63 -44 -64 47 -78 -12 38 -55 110 9 61 30 -76 16 15 -26 -26 -124 88 61 0 -58 33 -8 65 -126 39 -55 43 114 -15 45 43 -113 -128 -109 60 76 81 99 93 112 29 3 -63 71 -22 -32 -83 -125 -78 18 46 103 56 -100 -49 -37 -20 33 65 -128 5 56 49 52 127 -8 -50 71 -62 -8 -52 -114 -60 9 -102 -105 -2 -32 37 -69 79 32 -95 42 100 -30 -1 -91 31 70 -24 -33 -53 -61 45 -74 -122 -124 -81 12 13 -51 -118 10 -125 92 76 63 57 -37 -124 89 -114 -127 -40 -98 -91 -108 56 69 -127 -122 54 -56 47 -61 117 -1 -38 -47 38 -3 127 -11 -43 -31 16 -16 -13 30 2 53 66 -64 -6 64 -49 -22 4 0 40 -45 69 -89 -63 60 88 -101 53 -54 87 110 71 -72 10 -29 6 -111 64 -6 5 37 9 -89 -68 22 -3 -40 -112 -95 7 -26 -53 -22 23 -60 -9 -46 -10 32 37 -50 35 9 -53 15 -6 -22 -20 9 27 -9 19 -32 -14 -13 9 -50 -9 19 73 -59 -38 -9 34 127 -81 -24 -23 84 -50 16 -74 80 -128 48 72 29 -128 107 -7 127 -91 -20 8 21 32 -14 -16 -126 -128 -34 -18 91 46 -128 -127 -105 -128 -48 -127 -20 112 -98 -31 -79 -127 -64 -12 -114 13 70 97 1 -45 14 -61 26 6 -19 61 25 6 28 -62 -7 14 -5 -11 -8 -110 81 -59 100 56 -12 -45 127 127 -49 46 98 -5 127 -127 98 -128 -22 127 -103 -50 126 -73 127 -88 -33 -34 -79 74 122 -44 48 -79 35 -126 -116 -119 -83 -126 -74 20 23 127 78 -103 -57 93 -37 60 96 127 125 9 -85 114 16 -50 -36 85 69 2 20 -102 66 -103 -34 68 -39 57 123 0 20 -41 -28 -67 -47 -29 83 -34 -127 -128 60 -9 -48 -47 -97 95 -60 126 -61 23 89 21 117 -124 -112 82 121 124 -77 91 -87 -29 -128 -69 -20 -41 -19 -18 -127 -117 -26 -127 1 -69 11 17 80 127 -124 -119 -122 -92 -41 111 -2 1 6 -83 -53 -16 -11 103 33 -74 -76 -48 58 -31 -58 0 -37 -21 76 -127 -64 -3 -71 61 17 108 127 127 -14 83 121 -3 127 -76 125 -127 18 119 -90 -120 0 -67 126 -110 7 55 -26 85 126 -55 66 -59 19 6 26 -14 29 -116 36 66 -11 -48 -110 -68 -89 -62 -39 -80 -39 -74 -74 -5 16 -65 114 37 -51 53 59 -87 -66 6 -24 -15 -58 -27 -48 67 -48 -50 22 -75 4 -108 -14 -25 -45 -14 -18 52 25 -34 37 -18 -41 15 13 -21 -120 92 15 15 21 41 52 -72 83 81 -3 -69 -2 -29 127 127 27 -88 123 -73 78 76 76 127 127 16 109 -102 -122 -77 126 43 24 32 41 -70 -127 -55 122 81 30 111 2 -67 127 105 -116 -25 60 -25 -65 -36 -56 39 41 92 -32 98 -87 48 69 107 111 16 -64 48 64 126 53 -123 53 -111 117 26 -76 -128 19 67 119 -110 -107 -41 79 -50 -19 -14 -47 57 -21 54 109 35 28 -33 12 20 49 -14 -11 -77 -23 -73 -11 -32 17 -79 -49 -17 124 43 117 17 -14 63 37 22 -41 21 -42 -7 -1 -54 -44 -13 -89 -26 -26 -76 -22 33 -98 6 84 -6 127 82 -29 21 120 61 72 -91 56 -128 95 127 -88 16 60 -29 127 -80 26 34 -68 23 -10 58 36 -80 -126 -83 -125 -57 54 124 4 -58 -31 124 -34 53 -17 16 -19 -47 32 -21 41 3 -47 41 -47 -89 -13 -38 -88 7 -19 -9 18 -92 -26 36 18 38 -34 29 -88 -13 50 103 38 -18 -44 61 -128 12 125 -79 -105 -49 -125 125 -124 127 9 -104 76 29 -99 -24 -127 43 51 11 -28 -36 -45 -57 -24 87 7 -119 100 -13 -90 -123 3 11 -42 -124 -15 6 -24 -98 -121 -20 -46 -108 21 -36 22 57 9 11 -45 -71 13 -24 -16 13 -26 -9 -79 25 -50 -18 -46 -65 59 -102 -25 5 -88 -30 48 74 116 126 -62 34 6 32 73 -63 67 -12 34 78 -37 32 -13 65 97 -40 -19 -8 -12 -3 127 67 102 24 60 -32 -72 62 118 -21 92 120 50 96 95 43 39 9 -74 83 50 68 52 3 8 -23 98 2 -11 30 -49 4 4 2 72 -27 -33 43 4 -23 -17 -15 -13 -77 -69 -54 -75 -6 -3 87 -53 -17 127 -50 47 -11 41 52 -48 79 9 12 -12 2 -16 59 -36 10 21 25 36 87 21 39 6 73 63 -114 87 60 -127 -126 -124 -16 55 -114 9 50 64 -9 -79 -128 63 -61 -8 45 -4 12 54 122 40 100 56 43 42 95 -60 35 -12 -5 9 -108 -67 66 127 -127 113 37 -64 -12 3 -2 127 95 -36 127 126 52 82 -96 126 -125 96 106 -128 -38 123 -67 125 -115 -78 -35 6 -28 30 -6 -126 11 116 -8 103 -1 -24 -125 13 -34 -48 -91 -128 -34 -3 5 -125 30 -127 -8 -5 124 30 29 -42 4 4 -43 20 -78 -2 -3 -10 -17 -15 -76 -31 -19 86 7 -3 -110 -59 -118 -114 -115 5 -40 81 -8 53 63 127 -63 127 -127 16 52 -35 17 6 1 -38 -10 127 10 82 78 -10 56 111 -64 117 26 -62 42 -85 -5 58 118 55 -47 47 112 -10 76 -77 82 102 38 127 18 67 -57 69 70 -27 40 -6 -14 9 -46 16 28 50 24 1 27 -16 6 -44 27 -9 -41 -21 45 3 45 -41 -67 -126 -20 47 -12 -31 -63 -9 -48 -61 70 -56 -71 27 -64 2 27 -127 124 -53 29 -8 123 -43 -47 125 126 -28 -11 64 -9 126 -25 127 127 127 89 88 -109 11 -3 127 110 -54 36 -128 -48 23 25 108 15 -122 -51 -76 -50 -50 -8 -32 -37 -20 -15 0 -42 -26 -16 -65 16 24 -63 -54 -43 -107 -14 13 120 -32 96 84 127 60 -61 19 28 61 44 -90 49 11 37 35 -35 -87 -34 65 127 95 -32 -118 -107 125 -123 -93 -2 -122 -125 -6 -121 -40 -82 -28 124 118 127 -128 -104 -125 95 127 127 115 88 -70 98 5 88 -2 127 53 -56 -40 -10 56 23 68 26 41 -11 3 21 79 10 -4 70 61 126 -127 -25 16 68 -80 -94 -17 127 -42 111 -60 112 70 -17 126 5 -128 36 115 -3 -99 -34 -94 14 90 37 -126 49 103 -70 3 16 -106 44 -28 -69 -82 9 127 27 73 -96 -68 -127 -58 -128 -41 -90 -30 78 -80 -78 -13 -81 -77 -35 -35 -31 1 67 -85 38 75 -47 90 -96 -46 -16 -53 0 -34 -13 127 46 -56 90 -19 -2 80 51 28 -61 69 -30 17 95 -27 10 31 -57 -94 36 10 -51 111 75 -23 33 75 67 119 15 51 2 -20 -16 8 28 -46 -20 -50 -51 -15 34 3 48 2 -1 30 -67 4 -78 15 -50 68 -79 -23 28 -20 32 4 -49 6 46 52 -21 9 -8 56 -14 28 11 35 -14 -49 -66 50 -72 -30 -19 -87 -4 7 50 -33 -53 -111 14 33 58 7 -47 -10 -36 -69 -42 5 -59 126 114 46 126 -41 -61 88 122 71 126 -6 123 37 9 20 10 13 117 63 126 44 -74 -40 10 84 59 -26 69 -18 -27 36 0 18 -13 4 60 -25 17 -20 29 -41 34 -11 49 -100 -39 -1 61 -127 -68 7 -127 -127 20 -21 126 -57 127 -99 -82 33 47 54 -38 -128 24 -17 -81 -39 -87 -120 -4 35 -32 -123 -63 -126 -31 111 -74 90 78 28 46 127 -53 -104 -7 -18 -20 10 19 119 -3 -54 13 -36 -116 -108 48 -41 75 46 13 127 -60 -93 32 23 103 -5 23 -39 25 -20 -9 -39 52 -7 115 -128 -79 123 -51 -53 30 -40 45 -116 127 -34 -127 126 51 48 -12 -128 127 86 59 -59 41 -35 11 117 16 -96 87 -126 -17 124 33 85 106 -49 80 34 98 -78 -33 50 66 108 -99 -3 -125 -42 56 -56 -125 -44 -21 69 -23 57 126 113 -13 -23 -35 23 102 70 0 3 -72 37 -61 32 -57 -124 76 -128 -128 124 -127 -90 -103 -127 55 -125 124 -7 -79 119 24 -72 29 -96 127 87 41 -26 65 -43 7 127 -12 15 117 102 -3 64 111 22 47 -11 114 -100 -112 43 -127 127 112 25 -30 -116 -97 -14 -122 89 12 -41 -64 99 -67 -122 -69 -20 53 -58 72 -82 -90 7 -23 108 21 49 -126 -49 -119 -98 49 38 127 -121 71 66 75 84 -57 127 -126 26 29 -50 -57 -2 21 -5 -86 -83 19 127 38 15 -75 127 76 -111 52 -8 -124 119 84 13 -39 -122 40 -117 -117 -120 -127 127 124 10 -128 -78 28 -113 -77 -45 -126 -100 -101 55 -86 -13 -106 18 -60 -127 -3 -126 112 -9 18 -50 -92 -126 -36 42 -11 -124 33 -126 -114 3 -118 -114 -79 -127 122 -120 101 -108 -105 68 112 -126 20 -127 75 70 127 -6 39 -83 -59 -73 85 -107 -30 117 35 -6 66 -60 85 30 -104 -70 -79 38 -126 -59 -100 12 -94 -113 -97 -97 -15 74 -55 3 65 94 -35 37 26 -8 -34 -14 -20 10 -21 -93 -35 12 -123 6 -29 -63 12 -35 47 127 16 14 24 117 127 122 -126 50 -128 70 72 -67 -17 3 43 127 -85 -126 47 53 34 84 -77 -41 6 6 32 21 -23 -16 -93 -13 -102 114 -12 114 -37 21 21 -126 -74 5 127 38 127 -127 126 107 127 6 118 46 19 55 -84 33 -33 15 -63 61 -121 31 -54 81 -81 -101 -4 -63 -47 82 70 123 125 -14 123 36 60 127 -128 94 -45 127 94 -128 47 126 -97 97 -28 -97 -127 112 -75 72 51 -128 -128 106 -108 -128 -56 -127 -124 -123 -127 -78 -116 -17 118 71 127 -128 -128 -101 127 54 127 -33 116 -85 -30 123 85 -39 69 19 -25 -28 18 32 -4 41 20 36 49 -20 109 95 124 56 80 90 5 -109 -28 5 -35 -75 -41 -44 58 -24 14 -21 -20 -1 -28 36 2 -59 22 4 -17 -23 -51 -64 68 90 48 2 -94 20 -36 46 32 38 10 -14 -6 56 -60 12 -64 15 33 -59 -56 -25 -29 42 -41 35 -37 29 -10 121 -44 15 0 19 -6 83 30 -28 49 19 21 36 -49 19 -41 -53 -21 -113 -128 -53 -11 -17 33 -35 -2 -39 -22 65 0 55 -1 -40 -75 38 23 40 -49 -26 25 -49 -56 13 35 34 1 -82 -32 21 35 -19 -12 14 1 58 -11 -82 -76 77 -23 36 -28 -17 90 -13 -36 -35 -48 -96 42 -4 85 82 13 -17 -35 -58 -38 92 -44 73 33 -9 24 -20 72 -27 -48 -6 -24 -7 -54 39 -10 -33 -3 -44 -6 -6 96 29 65 -31 -89 11 -30 -10 13 -17 55 51 -78 46 -12 -79 126 15 7 -31 -22 46 22 -20 1 0 25 52 -10 -73 -2 60 77 -5 -17 -44 -10 34 -70 -6 19 28 -16 56 -29 -1 13 -59 -22 -18 2 5 -14 -27 14 40 -6 -15 46 40 -21 25 12 -35 -39 0 10 5 35 24 14 -8 -3 47 47 -11 -40 -52 124 -48 38 16 10 25 39 2 12 10 -17 55 9 13 -20 -28 8 -27 22 13 44 49 -53 2 -76 42 -33 -13 -45 -34 40 20 -71 66 21 -9 16 -21 18 -23 -17 -26 -22 -46 3 12 51 -49 17 -37 42 12 41 -19 -16 11 -25 -3 -34 -23 -2 29 -27 -45 55 -9 -24 -31 -31 73 25 3 1 -62 -15 36 -34 30 27 -59 -38 0 65 0 111 -32 46 8 18 27 78 47 -5 20 12 -58 -27 54 18 -20 49 16 -49 -47 -95 10 26 -42 -20 -16 31 -47 24 -123 4 -28 21 33 67 10 -19 -45 -75 -32 -7 -53 -14 -2 -25 -16 6 18 21 -58 33 -9 46 39 6 -23 -6 91 -5 7 17 -31 67 -46 -33 32 22 -69 -82 1 8 6 -20 -13 -55 -54 8 -71 -23 -45 40 -23 -12 -9 64 -8 -25 35 -43 8 19 -19 -51 -30 -17 40 -7 57 -30 -30 -20 -20 18 14 -47 -29 -32 -28 26 -37 -48 -20 -35 7 7 -6 -44 8 -23 -4 -46 21 -86 -36 -31 -36 68 -49 -24 6 -3 -65 24 52 -20 -6 -30 32 -3 -63 -41 -27 66 -33 -21 19 -93 -1 -56 -37 -59 33 -25 -34 -4 37 -114 14 -4 53 -31 66 83 5 -87 -12 -65 -48 35 -30 -11 37 -53 44 14 -46 63 58 32 20 -43 -16 117 -5 -123 11 -47 119 31 -90 -51 -30 14 -43 39 -30 48 -47 -9 22 -40 7 71 -22 -36 95 -120 27 -7 -88 16 -47 -26 47 11 124 -63 -31 -47 10 -110 -4 -36 26 77 -17 -34 -114 20 35 -91 -54 26 -13 -12 35 -2 -25 -38 -51 0 -35 68 -38 7 -26 13 -65 46 79 14 -5 -127 32 25 18 115 1 -62 69 27 47 13 79 -52 34 97 -1 46 8 62 -5 -9 -3 -42 40 29 14 -77 57 -3 25 25 -42 -13 -59 78 -25 -54 -74 44 58 48 -77 -4 6 72 41 49 17 85 -43 44 18 80 85 -28 51 114 -29 41 87 43 124 45 -54 59 20 59 -23 -12 -22 10 3 -44 39 48 82 11 30 65 -16 -6 71 9 2 0 -29 -1 -17 -48 -63 -49 -48 49 52 67 -77 -37 -53 44 7 17 -38 28 -99 82 27 66 -29 43 60 13 -14 125 30 5 -17 -115 24 -8 -11 -77 -27 11 -89 80 32 -124 -3 63 -3 -73 32 19 -57 -64 52 -10 -14 -18 2 15 -75 -33 10 -2 52 -10 -18 -20 -13 52 51 9 20 16 20 7 -74 36 9 -109 -9 -42 -18 -30 50 6 -8 -78 -5 -21 -72 20 -18 -21 -46 68 112 -17 18 -58 26 57 28 51 -43 2 0 -5 -3 18 -21 34 -45 40 41 -46 -7 42 4 31 12 -21 -24 33 -49 -50 -23 20 -34 -55 13 -20 -34 -27 33 37 49 46 -7 75 14 2 8 -25 2 48 27 29 28 48 -71 -3 -61 -1 43 32 11 -32 -24 18 -54 -12 -31 19 -43 -9 4 -30 12 11 -40 -15 12 -100 24 -73 -95 -73 38 -16 1 40 -18 -3 -31 -47 49 29 -69 4 -20 -29 -26 27 18 -60 -15 34 36 15 -13 -22 18 -4 67 15 -40 -6 -8 -2 8 8 -11 20 55 -5 1 -49 -46 23 5 -44 -6 -28 -46 -29 -20 34 13 -27 0 31 -21 -16 -8 -24 -16 -13 6 -37 0 22 -5 3 9 23 -11 -16 56 -39 65 -14 0 -79 -71 14 14 0 -1 -32 40 28 30 10 -39 84 15 -35 82 -33 17 43 122 -11 116 -62 -7 61 10 54 34 5 59 78 -80 35 28 -11 62 -97 71 34 72 31 13 41 -30 -29 62 -25 15 13 102 -84 -56 38 2 33 31 -10 62 23 -12 -76 41 18 -53 67 34 -15 -54 24 14 -34 112 16 -61 10 -37 -37 3 -30 -4 13 47 81 78 61 -20 33 -17 -11 -30 27 32 51 5 -27 -10 12 23 -23 -19 41 1 -11 -46 117 -4 -53 -24 4 41 -75 -7 6 12 -3 6 15 -71 -24 -4 -41 25 -85 -36 17 -95 104 -56 16 -11 28 -14 22 -39 33 -9 58 -37 27 -52 -98 59 65 -48 56 26 12 52 -33 -27 43 -24 -18 25 -19 -48 -32 44 -1 36 -37 -67 -45 -17 51 9 12 11 109 0 16 -22 -101 -27 -41 54 -26 -37 50 -74 45 -88 57 -38 41 63 -13 -11 11 18 -5 30 12 59 4 50 -31 21 6 -70 -52 -44 -125 -14 -54 -3 -38 -66 -27 16 27 11 29 26 52 -121 -36 5 41 27 -7 -35 -40 -41 14 63 -14 -2 -27 38 -55 5 9 -48 -19 -13 63 9 -50 -22 -25 37 -5 -37 10 21 -23 -55 77 23 -23 16 -24 -8 2 22 -72 25 15 33 -34 -37 -26 -3 46 18 9 25 34 37 19 -12 -44 35 -20 17 -2 -35 48 34 14 -11 -1 13 -41 -26 -28 71 38 -16 45 -106 -38 17 -13 4 -38 11 37 -47 -18 -16 12 -30 26 -10 -41 -76 -4 -55 -25 -41 15 -24 10 -46 8 1 -78 -79 39 23 -73 12 -53 46 20 -38 -78 16 -31 19 -21 -32 46 -44 -40 79 65 22 -48 -8 -47 -34 8 28 -49 -8 -61 -21 8 23 -42 -12 -36 -48 28 -32 33 -39 -3 20 33 -1 -35 57 -67 5 0 17 28 2 15 45 41 28 -7 33 14 -15 54 -24 48 -23 -46 36 -18 55 -2 13 26 26 -3 12 -1 51 -44 -23 38 -14 16 17 40 9 33 7 10 -47 2 -19 117 47 72 10 -30 -9 21 33 13 -31 -3 23 -13 14 -25 -58 -62 10 -24 10 -42 -12 22 7 11 20 -12 -15 5 35 -66 -7 45 49 -5 -11 -60 21 -90 36 -58 -5 -1 -30 -54 -47 -90 -27 -59 -9 -5 -39 37 -60 53 43 33 37 -13 -65 -80 -45 0 -3 30 -16 -56 -4 0 -13 32 -24 6 29 2 36 -53 -63 -14 34 -78 -9 -61 2 -34 -77 -28 -12 -72 -55 114 30 10 -15 -12 30 31 7 46 -50 -1 16 81 40 -39 67 21 118 39 -53 -47 -23 -28 -51 12 -58 -35 -92 24 57 29 16 -2 -61 17 7 19 52 -31 18 -27 54 43 7 6 52 -16 30 -26 65 -90 67 21 28 85 12 27 12 12 -41 17 54 -14 -1 -13 -20 55 30 -38 -12 -71 93 -31 -43 -20 70 30 42 -14 -15 -65 -12 9 11 34 54 102 12 22 -58 -54 18 -96 72 -27 -51 38 -29 -9 -32 -22 -10 -39 -18 -36 -44 -40 -107 -18 7 -26 -59 -31 85 -10 -54 -2 -53 -2 67 -40 40 54 -113 27 124 -74 -48 -32 4 -68 73 13 -37 -4 10 6 60 -100 -74 22 -5 -62 4 46 13 54 24 17 -2 33 -16 -22 50 -48 46 12 9 -66 -14 -2 23 24 106 -16 50 4 -14 0 35 -30 -73 20 37 90 5 1 32 -19 -33 1 22 -31 28 13 69 -48 20 56 66 21 -33 2 46 -1 -72 1 9 94 -11 -22 6 4 -39 -4 -3 -45 19 -54 -47 -7 37 69 3 43 -58 -14 47 -34 86 34 -48 23 -53 36 6 0 32 -63 -13 43 -23 -46 48 -66 -15 8 -88 -33 -81 2 -38 75 61 -2 20 -33 49 -75 9 -17 95 -83 -31 -25 62 -38 -53 37 -19 100 9 -78 -91 -15 -86 -3 62 -33 22 127 11 -27 3 -7 -96 -1 -43 -50 28 51 -32 -26 124 -38 53 18 1 -2 -62 9 5 -6 43 -1 40 54 -38 -14 16 -47 -35 5 -63 -41 -10 -23 -37 4 -67 -17 42 18 -38 8 72 27 -27 -16 10 -66 -39 3 24 -36 -87 11 12 4 3 -52 36 -90 -25 -51 20 -17 16 -16 44 12 -12 14 31 -59 31 30 24 2 72 -53 -38 -25 25 30 12 4 13 -1 -22 -34 -48 -62 -54 -64 -17 8 85 54 58 45 30 80 88 6 -31 -4 -25 50 -10 -11 -22 55 72 -18 28 -10 15 63 10 65 23 44 48 -13 91 41 6 -23 -17 33 -38 18 17 19 20 -37 -5 24 36 -21 29 32 -47 -12 -11 -47 23 -42 -11 -7 -33 -16 22 11 -56 -29 44 10 34 17 64 -98 -15 19 -17 28 -30 -37 22 -48 -38 0 -11 -45 -80 10 9 1 -9 39 -44 24 22 -25 24 -50 -17 -1 12 52 4 -10 25 31 -48 -13 25 26 -30 -34 2 33 -21 33 26 -40 18 -15 -23 0 7 29 8 54 6 -48 -24 -4 31 -13 -15 -9 -15 20 -16 -7 -61 -41 -6 45 82 -107 -2 -22 -29 52 -55 36 -9 15 98 18 -45 42 -34 14 -73 -25 -12 70 91 -22 -37 -87 -32 67 16 19 24 31 -54 6 -16 -20 -45 -12 2 -10 78 -48 31 -29 -9 -104 -61 60 -27 -7 -53 35 -2 32 122 44 27 113 -19 83 -10 39 -4 -33 -47 -18 -27 -42 -1 51 25 -4 -32 23 -13 32 -14 -62 37 -7 38 2 -4 -2 37 53 41 9 -13 69 -62 57 -45 46 -65 17 0 59 -17 -48 -29 46 -21 -43 -34 10 -54 56 1 14 -55 23 -38 27 41 -44 -7 66 21 -13 45 -10 3 30 -5 41 -43 -5 -30 -25 -86 -26 19 -16 23 50 -28 -53 -22 -33 -14 40 33 -21 -51 -27 -20 40 121 34 -61 31 -1 -22 127 3 -85 -56 33 -62 -21 6 12 74 65 75 -12 8 11 -35 48 33 62 -2 48 -19 -61 -3 -28 55 86 103 -7 122 -68 -23 -48 -43 46 97 29 -7 -25 -10 -32 -61 -74 7 26 -38 55 -4 5 43 -24 34 16 44 42 44 120 74 0 -25 10 10 -60 23 -30 41 -22 -44 24 -35 102 41 -32 5 -81 -25 5 103 -69 -39 -38 23 15 35 21 74 -78 -24 12 24 23 9 59 35 52 23 28 0 1 12 -6 -22 -56 38 41 -1 -73 -91 44 61 -4 -16 45 -16 21 19 -28 -27 -48 46 92 -94 -58 11 -71 -11 11 -9 118 -25 20 31 71 27 -126 -4 58 -52 28 -61 -3 -6 -4 26 -5 -41 7 -35 -52 -25 115 19 -66 -41 -40 -5 -75 -2 45 43 -90 0 -2 58 -12 8 -46 -30 -34 47 -42 -57 71 15 -17 -14 37 60 21 -49 9 -16 -84 -33 -3 26 3 -57 79 -25 -28 -48 -5 -3 -56 -52 37 40 -60 7 -17 10 39 47 31 -42 44 25 22 42 -27 15 11 -52 50 7 -75 -125 -44 -38 22 -23 40 -19 79 42 -28 -21 1 11 72 77 -15 -63 23 18 26 34 -41 -7 20 17 20 -34 53 -2 7 20 -44 39 25 61 23 22 79 71 -4 17 9 27 27 -23 42 -23 3 -3 47 7 6 -37 49 -33 37 1 -18 -22 -49 19 38 97 54 85 -1 51 63 1 0 53 3 11 10 112 -44 13 -11 -44 -1 3 -33 65 103 -32 22 3 70 -1 46 -55 -3 -37 106 -4 -9 -9 30 -32 -108 27 -25 112 -48 55 -2 26 -10 71 56 -28 -55 47 -21 42 -10 -42 -57 -13 -21 -5 44 12 -35 -3 -4 -63 11 -18 -62 68 1 -27 34 68 -16 -57 13 45 61 -30 -45 41 -21 -39 95 12 -10 11 -47 -21 64 9 -41 73 -10 -21 -7 112 28 34 13 -4 -1 15 -26 -33 20 6 -37 21 -4 -44 34 5 5 -20 27 -33 21 49 79 24 5 -4 53 -7 -43 -30 13 5 38 -60 -64 5 54 4 -58 20 6 40 17 -42 65 9 6 -5 -38 2 27 30 -3 25 42 -52 -28 11 62 -61 -16 -44 14 38 -63 -5 -32 39 -57 19 8 -37 -72 -10 55 42 59 -3 66 43 65 -4 -3 -47 -56 -127 44 -28 -14 -82 -18 1 -96 -25 6 -6 -39 -43 12 66 25 78 -42 22 22 -68 15 -29 -50 -6 29 18 12 -105 16 -7 -28 21 -80 -71 -8 43 35 -7 3 -32 -23 10 57 -16 -51 31 5 -24 60 -8 10 10 25 1 -39 12 34 28 -7 -39 -20 16 43 -69 -15 -9 5 -31 31 -64 11 -12 -17 -14 -17 -21 42 10 -5 -24 21 -8 -20 -2 -25 40 63 -49 -9 -50 -53 9 61 2 -24 -30 -11 12 -31 -21 -4 32 -7 -24 6 38 -25 -62 -15 18 31 64 -64 -17 -25 5 -12 -38 -78 57 -52 -18 -69 28 22 13 48 -36 40 32 -49 -38 58 34 -4 -44 -81 -77 -34 6 -101 -9 -68 -49 -47 -98 -8 -28 -58 27 -50 -5 18 38 -3 -22 -50 -19 20 -4 -65 106 15 -25 1 -5 14 -66 -11 -4 -27 22 -26 -21 46 -1 29 18 -30 34 -4 15 -53 -3 -14 20 12 -55 -62 58 4 -31 46 32 -15 28 23 18 34 -15 29 26 34 -23 -41 20 18 -59 -21 -28 29 -3 -6 -26 16 22 -24 -12 -21 18 28 -5 27 15 27 26 -35 -1 -49 57 2 -35 -2 -3 -1 57 15 63 11 -27 11 -51 20 -7 -21 -21 -24 -14 -5 18 -8 23 -31 24 85 -61 98 -60 -44 12 35 78 38 -14 27 -82 64 50 -43 -44 8 -44 -114 -11 -51 67 -51 -74 -11 -2 -28 50 3 -37 47 38 -20 95 44 -48 15 7 -26 0 -11 69 -33 -28 -8 -9 38 9 -2 -5 117 30 7 8 60 45 -65 65 4 10 22 14 12 -8 44 -18 64 35 31 -87 -14 54 -53 67 -43 -25 -43 31 -59 75 -44 127 -6 -48 87 78 25 75 94 -62 -4 -5 -20 5 31 55 -29 123 -29 31 -23 32 -55 -32 16 -25 12 18 26 12 8 -32 -35 -23 23 -36 59 -49 15 12 2 23 8 76 -41 21 -18 -4 25 55 50 10 5 -23 0 24 35 -4 -3 -68 5 9 32 10 -5 -73 -86 -95 24 -15 117 16 102 46 82 74 -6 1 22 -36 -17 -34 6 -76 -58 18 -22 5 -17 -57 61 35 55 60 74 25 -18 46 25 -9 -29 4 16 62 -31 -9 -55 36 -66 -54 -55 47 62 -3 -4 -101 -27 29 -69 -46 29 12 -101 23 5 -92 -8 32 -7 0 51 -21 25 -91 11 16 -5 -14 2 19 -24 30 64 -45 39 42 -66 -23 -48 17 23 -58 58 1 17 -35 -20 -14 -43 12 31 -11 28 -16 -9 -28 10 6 -24 20 -17 -57 -65 48 21 -12 16 39 41 -87 -2 1 15 -13 -27 2 53 1 6 -17 -12 -43 -17 4 4 12 -23 37 27 -4 -14 30 -12 64 120 -83 -7 -30 45 20 40 73 29 -76 8 23 38 19 43 3 -50 -64 -19 -24 -1 -55 -62 20 -66 -26 -120 1 -21 49 3 20 36 -2 -11 -54 -57 34 -86 4 13 27 4 -50 -55 57 36 -13 -66 10 -6 29 19 -90 -79 -69 -30 36 -46 -73 18 28 -85 54 2 -26 43 -29 -9 2 18 62 54 12 -85 14 30 6 -36 -56 -87 -14 19 32 50 -67 6 45 28 -10 -74 33 -28 -76 53 -40 -24 -54 46 18 38 -34 -48 -8 22 -46 22 2 53 34 31 -34 1 -33 -11 -21 17 18 10 14 16 35 -50 49 -6 -14 -61 34 14 71 49 19 -1 -24 0 -29 -8 68 -29 -78 -55 6 -18 73 -40 -3 7 -23 -93 -8 7 27 74 73 -14 -26 -58 33 -39 -58 -61 0 -38 16 -59 -101 -85 -70 -11 15 -14 7 -5 26 -65 -5 9 -59 -33 -5 22 9 36 -44 76 26 45 23 -61 28 -76 40 -34 -20 -5 22 24 74 -1 25 16 29 -57 34 -10 -12 -30 15 -63 6 8 -3 18 14 81 25 -4 -66 0 50 5 37 4 -9 13 8 10 56 16 -3 65 4 30 4 -14 45 36 -35 97 -31 -62 -2 48 -26 10 -12 -79 -13 3 2 42 -4 18 35 -17 -12 71 -40 -36 14 39 48 39 -10 -29 -47 -25 1 -19 -3 -38 -40 -40 44 42 43 10 19 2 -23 10 10 8 36 17 -51 -11 -51 -19 -21 -63 44 -8 4 42 90 -73 -70 56 -7 -38 -2 4 -55 -44 -44 9 -56 2 -54 36 -10 -115 -48 -72 -20 4 17 34 -26 -75 37 -36 -101 -18 -88 54 44 -110 -8 -73 -22 37 -50 -37 24 -16 -9 -36 16 -41 -90 41 -18 -99 56 -26 53 50 -37 -31 -38 24 -125 -54 33 22 -67 46 -37 -44 -16 -7 4 1 114 -45 -65 29 29 -25 -13 13 -60 -28 20 57 -23 -7 -110 17 -4 3 42 -64 4 46 46 -17 -24 -27 -45 -22 -37 -14 -51 17 56 -20 15 -58 41 46 10 9 23 59 7 3 -11 -44 77 22 38 -19 -59 24 26 30 -32 8 -53 15 -12 31 -37 -56 -34 12 -79 33 18 20 33 22 -18 12 -20 32 18 10 19 24 20 5 -27 6 -21 -28 -48 52 14 35 -7 -24 -46 16 16 -52 -51 21 -8 9 -27 23 30 17 0 -34 46 1 -47 25 -47 -32 4 12 4 -1 32 -1 -43 9 4 50 -21 -29 -5 -34 23 -8 22 -41 35 48 -53 28 18 -35 16 38 25 25 1 27 -7 9 -12 15 -11 37 -46 31 -38 -12 -2 -10 5 -30 5 -44 -22 -19 25 30 59 34 30 4 19 -18 -3 21 -35 28 -4 18 9 18 -38 -23 18 -32 19 31 11 23 -7 3 -46 -1 -31 18 24 11 8 42 31 8 -42 32 -29 11 -32 -28 -19 -31 31 -22 -22 2 40 9 28 -47 4 47 15 0 61 28 -23 -43 -47 47 -16 78 12 46 -21 8 5 -10 20 -5 73 14 46 -40 -24 32 -35 66 -27 -51 -37 24 -30 -4 11 -1 -38 -63 2 45 10 -83 -53 -63 20 -47 32 -57 59 4 33 22 -39 11 49 13 1 -43 -37 77 30 -11 -17 47 35 -30 -12 -39 7 20 -11 23 39 32 -25 12 -66 -15 -20 -35 -19 42 -17 -30 31 27 -55 -10 60 14 -46 -44 27 -6 -45 -7 24 12 -8 -33 -17 -46 15 2 -32 -8 -7 -26 17 21 16 27 18 -25 -40 -34 -14 26 -42 -22 -17 -22 24 -26 29 -8 6 -29 -10 -10 11 40 -12 -5 -18 -20 -16 6 23 -3 22 -48 -56 -9 -28 7 -40 83 9 111 44 82 -33 21 -36 -15 37 64 -1 -10 118 24 -109 22 22 -4 6 4 24 64 16 10 64 42 -53 80 -9 -20 33 14 -29 29 9 35 -20 7 75 91 -24 -48 11 45 -57 -45 31 -3 23 40 -21 -1 -58 -45 14 -6 -30 6 22 -95 31 -4 -19 -65 21 -21 -2 50 29 -25 -22 -16 31 -26 51 14 -64 -41 15 16 -2 28 -56 5 -29 42 -6 -54 -57 15 52 -5 -3 -34 2 13 -10 14 0 18 5 -50 -10 22 -8 -38 -13 37 3 17 29 23 9 -17 18 26 29 17 -10 30 4 -14 6 15 37 3 3 32 14 -34 25 -35 28 22 32 -6 40 9 -9 42 -35 -20 -3 8 61 -34 -3 -1 5 -33 -59 0 14 -19 -6 4 1 -4 20 5 5 17 -29 21 25 67 -28 -5 -17 33 -24 2 46 5 32 9 -66 -66 -8 26 58 -56 -12 47 3 28 15 -40 -31 -20 -10 16 -16 65 45 -12 33 45 -19 5 4 5 -45 -9 18 52 15 -39 9 22 6 -67 4 -13 10 19 -8 16 6 -54 37 27 -38 19 9 -15 30 -24 10 -60 -26 -51 -36 39 36 -43 33 -15 -16 19 30 -28 -31 -11 8 -20 -9 36 -14 9 -6 -30 -22 43 -15 -14 23 -3 49 -6 -7 39 7 -18 -26 -10 -16 -32 46 -30 -34 -5 -26 -9 -15 -49 39 26 10 -11 18 33 -37 19 -29 -51 12 -53 -21 26 -10 -15 -28 4 -43 27 -22 -47 2 66 76 -3 -14 -19 -4 -57 57 25 27 19 24 16 0 -59 -10 -9 21 -23 0 -1 -19 -24 14 -68 9 -23 -44 25 -11 -25 -55 -42 -21 -22 32 24 31 13 76 20 -42 7 -40 -26 1 1 21 18 -29 33 16 -26 -4 21 16 -49 -22 -36 6 -6 -16 -10 5 -57 3 36 10 43 6 27 -9 -4 34 -13 -39 19 42 21 -9 -7 24 -9 13 31 -8 -15 38 -11 28 -36 -14 -44 -19 69 -29 12 30 -37 6 -5 -21 38 20 30 -15 41 16 32 20 -14 34 -10 -40 18 36 54 -31 -11 -37 17 -21 -15 40 -7 58 -22 19 1 -22 -22 66 -43 -20 -87 -9 -11 16 1 22 -70 47 -23 -56 123 28 56 40 -34 -42 -61 3 18 79 -52 -17 -127 20 50 29 -110 15 -43 -42 14 -22 -31 -55 -120 53 112 -6 125 -10 -14 4 28 29 -70 -9 -83 14 -71 -43 52 27 99 -13 13 24 -15 22 -10 13 73 -22 37 -20 51 70 7 -27 -16 -34 -18 -12 32 3 -30 -26 11 22 11 -7 -24 -28 -20 51 15 19 -84 -45 -1 10 -93 -22 -3 -5 33 46 32 -6 47 -43 -67 -49 5 2 28 32 37 -41 -10 14 -38 39 20 -33 24 -54 -16 -65 -64 -14 -20 -34 -39 -30 -9 -30 22 41 17 -3 3 -22 0 49 -47 -51 0 13 30 31 -27 -13 -24 43 7 -27 -34 3 10 43 36 -27 31 13 -46 0 36 5 8 3 -50 18 26 30 -19 -54 -6 -70 -44 1 -54 -41 -24 21 5 49 -7 83 8 -64 24 29 32 13 55 -3 20 -11 -9 -18 23 5 28 32 40 -23 -50 16 -40 33 36 48 44 -6 41 50 4 -22 -11 -22 -22 -22 -15 31 -11 -50 18 2 40 -14 16 -2 19 -5 -7 0 14 -25 17 -48 -16 29 61 -24 -10 -11 36 -21 -45 4 -15 -24 -23 34 36 -22 21 -40 -30 36 -27 -9 -5 4 -32 26 -3 25 31 -10 -26 33 15 -27 3 -1 -28 40 -15 -15 -18 17 9 -28 35 -23 47 48 -1 8 14 -12 23 -61 34 -41 20 41 25 -9 -1 6 -37 18 -60 11 22 56 13 -87 -7 -37 -26 -36 -26 -11 -62 12 -27 47 -50 16 53 24 6 21 26 -40 14 28 4 -70 46 43 -52 16 -37 -59 20 88 11 -6 20 39 -40 -11 4 -8 -48 5 92 6 -21 -7 -35 -15 17 -17 -26 1 17 -5 18 4 -21 -22 -2 -31 -40 -53 8 -12 20 48 -35 5 -26 -47 22 -8 18 -66 -23 28 -31 -7 12 -56 6 -20 -57 24 28 -1 -17 -34 -15 -26 -46 33 -13 -14 -25 7 -5 15 -18 15 22 -47 -42 -29 0 7 21 -29 -7 31 -8 -45 9 -27 35 0 -50 10 10 -34 -41 25 43 -19 -3 42 6 -14 0 -5 -12 42 11 -18 -73 -3 5 10 -55 -40 -11 52 -14 7 15 57 2 -11 -7 -8 -17 -18 32 -13 8 7 -64 -66 42 15 -45 -24 -2 -25 12 6 -1 -26 -30 -39 15 -78 -32 -12 10 -76 29 26 0 -23 17 57 70 32 -45 -15 6 -5 -44 7 2 37 -6 -51 -9 52 -10 20 27 28 27 -3 -25 37 22 -23 -23 59 -14 -53 10 -49 16 7 22 -23 -34 -42 -23 34 -18 37 27 38 13 40 -46 17 -45 1 23 -8 7 6 -1 -59 -19 -1 18 29 29 17 -18 -31 -11 -18 -2 -2 -16 18 5 32 4 20 25 -33 24 -18 8 6 0 15 27 37 41 -9 28 13 17 -31 -18 -23 -28 42 27 -10 -3 11 -10 21 44 24 33 -6 -43 -52 -53 -13 -7 -52 -11 16 -19 33 57 3 1 48 -14 -1 44 -7 1 -38 59 -8 -21 -10 -38 14 -2 -5 34 -10 -28 -21 -31 -14 -42 20 31 16 -4 10 -9 -37 -36 2 7 -3 20 43 -5 -44 40 5 -15 52 -12 -25 13 39 21 4 -47 -17 12 -8 26 -12 -17 -26 29 11 12 -3 26 -31 -16 16 -22 14 -33 29 1 -12 -28 -2 -6 7 -7 -33 -56 -1 -11 -6 1 0 29 -15 0 -28 36 -11 40 5 9 -28 20 -6 -21 31 -31 -29 14 53 16 -7 14 28 -1 -6 -35 1 -15 30 -38 -26 13 17 24 15 18 -25 14 -12 42 62 15 89 -71 44 -32 -6 -13 -18 14 40 -32 73 4 -103 9 -57 76 -39 -5 47 -50 24 52 49 -8 -33 2 -37 2 31 15 62 -12 -25 14 -15 7 -20 -126 -2 -5 -9 15 -1 -8 4 -17 49 -86 -37 17 -17 -31 55 48 72 -27 -55 17 63 6 9 -28 -7 36 -12 18 -8 56 4 -6 1 -22 -87 4 -45 44 20 30 -26 -28 -4 0 29 -43 -4 -40 -3 89 17 -17 -24 2 -38 -78 -13 16 17 14 -28 9 43 -24 61 18 -46 4 23 -29 19 -6 40 -13 -52 -15 26 -15 8 9 -25 30 -45 -46 34 57 -22 50 8 30 -13 40 32 12 15 19 11 55 74 34 -21 12 51 -23 -4 -43 -27 -2 47 16 -7 9 -28 48 -14 -24 20 4 -29 -13 13 8 1 38 55 -26 -27 -4 10 72 57 -1 -20 -31 3 65 10 -31 64 9 13 -10 70 -51 21 -1 16 -28 -13 -38 -71 26 -22 -8 -20 15 75 35 20 -39 -26 16 -74 -18 -1 38 21 -18 21 -33 47 25 13 -25 9 14 -7 13 49 32 40 28 48 -9 -29 11 -36 -24 3 41 -6 -41 14 -53 -28 16 -9 -4 9 -7 6 -10 19 4 -46 6 -14 -4 -5 -8 8 25 12 -23 -11 4 -16 -48 20 -6 31 -33 14 4 12 28 -32 13 -3 -2 -15 29 8 22 6 -43 15 -41 -25 11 -37 -11 -39 12 -28 10 41 -46 -18 7 -35 -5 -5 -9 39 -24 -52 -28 -50 -36 18 43 -12 -27 -6 6 47 26 -36 14 -25 -2 -33 22 -22 21 -71 31 27 3 -34 -28 10 -2 2 -20 -52 24 86 -23 57 51 10 -29 76 -26 19 93 -7 -53 -31 -19 -68 27 -47 -45 5 -18 0 18 16 -5 -3 -18 -12 37 -36 -60 18 34 8 9 41 67 -3 -37 43 -68 12 -17 40 -39 -59 -16 15 15 -7 58 14 28 -43 48 1 10 4 20 55 22 -1 1 42 13 34 35 -44 0 60 16 42 -2 2 -21 49 -28 -10 -7 39 -18 47 19 18 -8 21 45 41 -24 -1 -34 4 5 -11 3 33 21 -35 24 -13 1 38 -33 9 17 -4 -94 7 -48 -26 -74 -47 10 7 -4 6 -91 23 -61 -11 12 -78 -94 32 -59 53 -8 -62 6 37 -31 -60 118 29 -36 47 9 -1 42 93 -50 65 21 -7 -31 5 57 39 62 0 -40 -6 -53 -19 -36 3 -25 57 40 -25 69 -28 44 94 33 26 22 -65 -77 70 -23 9 31 -4 4 -16 37 -45 46 -50 59 35 -29 -29 -66 -90 39 76 -35 28 15 -14 -23 -69 54 -13 45 31 -25 8 -9 -54 47 83 6 3 52 -23 25 27 -8 -59 8 27 17 -41 -21 -23 -5 -46 19 27 33 60 31 -3 -2 -25 -42 8 37 2 -43 -102 17 -28 7 16 -40 49 -14 -18 1 -48 -36 -11 -37 29 38 49 32 -19 -8 -68 -39 22 -102 38 23 16 71 77 -44 -46 5 49 31 57 19 63 -2 62 7 0 86 28 28 -26 50 -29 8 55 65 -8 36 77 35 64 -30 -25 38 3 30 15 -55 4 124 -7 42 16 -26 -18 50 -20 -61 26 -37 -46 6 -55 -24 -78 -3 -4 5 77 25 29 -26 107 -40 14 -83 -32 -30 -33 47 25 -39 47 9 9 -23 60 -11 6 -68 28 -2 25 23 23 -23 37 37 40 -74 -50 -35 -24 29 -39 39 48 46 27 -16 27 -39 -4 35 -26 -8 -36 -14 -21 43 41 -1 25 -43 -33 -23 -61 -11 2 -4 1 -20 12 23 8 -43 39 -6 5 24 12 0 -20 29 38 -4 -4 -107 -41 -14 63 -32 -63 58 47 -49 47 -66 8 22 -51 1 4 -9 65 -34 16 -45 -4 17 -6 -10 26 27 35 -44 72 -50 -6 -1 14 -9 -84 -7 -51 -25 -41 -32 -41 -32 -37 -99 -1 26 -39 68 -19 12 -28 -18 11 30 85 85 25 36 43 -8 15 41 -41 18 -14 1 -53 -54 61 -23 -11 22 -16 -20 47 -26 -31 90 88 66 -54 -69 10 -34 -18 8 -28 -83 38 25 -8 -15 -6 -9 -11 21 -12 -17 29 34 -67 -56 -64 4 37 16 -23 10 -50 -8 16 60 -50 3 -9 21 66 -18 42 -7 -41 -22 32 20 27 -33 36 15 48 -6 13 44 -35 14 -14 79 -14 0 -12 -26 -1 23 14 -2 37 10 32 7 10 21 18 37 14 1 -33 -23 -17 15 -21 -22 -15 4 29 -21 -34 -4 -16 -9 41 32 25 -6 15 -14 11 -40 -8 21 -52 15 8 -27 12 -3 -27 -11 19 -49 -27 -17 -12 -19 -35 51 22 49 -8 14 20 4 5 2 57 15 21 -4 11 31 -6 -14 7 9 -13 52 37 -10 37 40 39 -19 18 -9 3 -24 -14 35 -1 -14 -18 -15 2 -31 23 19 -7 5 -18 -17 -21 -1 6 -33 6 -3 15 18 7 -14 -2 -12 18 29 11 12 6 -10 -29 -13 -31 27 -25 -8 32 -7 -39 -43 -43 11 -15 -46 -10 -20 20 14 27 -7 -7 44 23 -14 -30 2 14 0 -20 -1 -42 36 14 60 -27 28 -18 -51 6 -13 15 4 46 7 7 -5 -41 -39 -31 -27 7 46 -27 -6 0 -39 75 -53 -9 -12 20 -36 20 12 58 -5 45 48 -20 -5 15 -28 35 -73 5 -31 -2 -2 -71 -1 2 -20 36 -43 8 -72 -10 48 23 -29 -6 26 -46 -50 6 0 -39 -19 -24 -21 -31 16 -33 26 19 14 -24 -3 -55 -11 -37 33 -14 -12 16 -12 3 52 11 -11 -9 31 -5 1 -11 -9 -35 27 -9 53 -30 13 -6 -10 13 10 -2 0 42 -5 -14 -24 -11 14 -9 -23 -17 -36 -18 15 -26 -17 0 18 -8 39 -49 6 -10 -38 -17 34 -6 -26 17 30 40 -4 -9 22 -28 28 20 -18 24 -8 -51 -35 -82 57 -29 61 39 17 -20 -14 -45 -8 53 -3 -40 19 -46 -23 -4 14 -46 53 18 -64 30 -12 14 -22 3 -36 -78 6 -37 15 17 -65 -42 57 30 -5 50 12 60 -58 -45 40 6 -10 32 15 19 26 15 -25 -36 -32 39 -42 -5 24 29 -69 -21 -12 -21 -25 -14 -19 26 -4 16 -66 -6 -2 30 -25 2 5 21 12 41 -52 10 16 9 -12 -10 58 2 -16 -41 16 -21 23 10 -25 -3 24 -13 -10 30 30 -7 21 -32 16 -22 52 6 27 -14 -6 8 -23 -4 -41 25 10 0 29 20 -38 -9 -37 15 -10 6 -52 70 -32 17 23 5 -11 -42 7 -27 10 -11 18 36 11 -51 -53 -90 23 -8 48 -13 55 24 -72 4 9 17 -32 -33 -99 7 -75 -19 -8 -1 43 -24 -11 -2 62 127 -16 63 -19 -60 40 -56 -17 -40 1 2 6 -43 52 39 36 1 20 -56 28 19 6 6 -22 -1 27 77 68 -70 -118 -42 -118 34 37 60 -88 1 -72 25 67 -33 -67 15 -46 -40 57 -43 -20 -3 20 54 -53 -69 4 49 -61 -7 -11 17 -15 -30 -71 0 60 15 19 -6 71 4 47 8 -53 -19 38 -37 -27 37 27 14 57 -61 18 9 24 -80 5 -27 0 50 -16 -28 32 31 17 46 50 35 13 8 -40 -5 -73 46 -7 -6 -16 -62 -8 19 -84 -14 -90 8 -35 -38 88 -35 -69 22 -35 -34 -2 44 -11 -14 93 9 14 56 -56 25 -60 0 1 4 81 53 -38 125 -27 -16 20 33 29 -43 46 -19 -46 -71 33 -35 -68 -9 -12 -8 22 127 0 13 19 -70 35 30 104 44 -30 23 7 13 15 -11 28 -6 2 -33 113 68 9 -11 -29 -17 31 16 18 35 39 1 -15 28 44 33 31 37 11 12 -28 15 12 19 19 -52 -51 38 8 16 -15 12 -35 117 5 18 -7 119 -7 6 -11 7 16 29 -7 9 -25 39 -71 41 -35 -36 -1 -43 15 47 -3 -56 38 37 39 16 23 54 32 2 -38 40 11 -8 14 -35 -24 -19 18 43 51 42 -43 36 -19 7 13 -8 17 7 42 -5 -13 -126 0 -6 96 11 77 -35 5 -74 -33 -59 -3 24 48 -26 -93 -50 -40 -48 36 -61 -51 54 42 -53 -32 27 0 -36 86 10 -21 71 12 -23 -87 46 -4 31 12 57 25 -101 8 100 -61 -27 -11 -13 -40 46 84 -25 -55 -18 -51 27 5 26 -85 -34 22 8 -4 5 10 22 -13 11 58 23 14 89 -19 69 -73 -32 -49 -23 -65 15 11 -2 24 -38 -23 -20 9 62 93 23 61 -25 2 16 22 16 16 -10 1 18 58 33 -2 -13 -6 -34 40 40 75 -12 15 47 5 32 68 30 20 15 10 53 39 46 -58 -10 -24 6 38 -21 -56 -15 5 16 40 -47 -30 17 3 37 -23 7 1 8 -35 -44 0 45 -21 -88 -25 27 38 -19 -24 2 26 14 32 62 -11 30 -3 34 1 -65 -11 45 51 16 -26 -13 -22 -11 -6 -17 -1 -23 -42 3 -19 -51 -27 -22 -56 -16 30 -50 -41 23 -67 -40 -67 -2 27 9 30 31 45 52 11 17 -39 0 -54 -26 49 -27 -3 34 -15 -18 51 24 55 -26 -35 4 33 -16 10 -14 -24 19 -29 -38 17 4 7 25 -66 40 -21 -19 -12 78 -23 75 -14 2 -17 -23 10 50 50 0 19 -20 -14 -4 -57 -46 50 -29 36 5 38 34 35 4 19 -6 -32 -27 13 13 -23 -23 13 9 -33 -57 -12 -8 28 43 -40 36 0 21 47 65 40 26 3 -34 -1 5 8 13 -88 93 -91 -23 48 -59 60 54 -26 -2 77 -15 -91 80 74 -62 7 -77 -6 -18 116 -31 -24 -60 74 17 99 55 24 70 45 29 -4 90 -20 51 15 -14 15 25 120 31 -106 20 30 -35 -66 19 14 -1 58 30 29 4 -83 33 -90 -20 24 1 -101 12 -1 29 38 67 78 -40 -28 -53 32 -127 3 -86 19 3 60 1 -28 64 -11 84 -8 -41 -19 -102 -53 -8 -102 -16 72 5 31 14 -21 -41 1 -27 -19 -13 0 9 -56 -73 -16 2 -4 65 -36 26 63 -28 30 5 17 -44 -15 -105 21 -8 -43 28 -16 -58 8 1 -1 7 40 -19 -8 89 26 -7 51 19 1 -19 -6 -85 52 3 -52 -15 -1 -4 34 49 5 7 -23 6 11 13 2 19 13 -7 -61 -12 -11 -12 4 -11 -2 -35 15 14 -1 24 14 -34 11 22 -15 14 13 6 14 6 18 24 -13 14 5 -5 28 15 15 10 -53 -21 0 -58 20 8 -30 -35 -29 22 -6 -19 -17 4 -2 2 -19 14 40 -17 21 -5 -20 14 -19 -8 -26 14 17 7 -26 15 -19 -26 25 -10 7 -14 -19 25 31 -33 9 11 1 -12 -7 8 20 5 10 -6 -8 31 11 45 -19 -4 13 1 -9 1 1 -5 -11 14 14 -21 -19 14 -6 0 12 2 8 -7 -26 19 7 20 -14 -13 -20 -23 0 -22 -16 6 -14 7 9 -9 6 14 -12 10 33 -18 -30 3 3 -4 -9 32 -28 -18 43 16 -3 65 -26 0 -47 26 -7 31 -24 22 43 -74 6 -1 -9 -20 -16 32 -11 23 -7 -16 15 13 27 2 3 32 -40 -6 -45 1 -9 -41 -7 94 54 9 61 46 -28 22 6 7 -1 36 -17 26 -14 62 66 25 -69 5 -1 -28 2 18 8 19 -26 -8 1 9 -18 2 -47 -31 -12 15 -59 -10 36 45 28 -28 10 9 29 -13 36 38 -52 -19 26 -18 39 -16 -8 -6 -2 24 32 -22 -9 -3 5 -17 7 8 -36 -10 15 9 20 24 17 6 -19 -5 33 -15 5 -28 -10 -5 12 16 -12 25 29 18 -20 -39 -7 10 -6 -31 -6 -63 -34 4 -50 51 -41 16 4 -21 -41 -5 30 -25 7 -5 -5 4 -43 -29 34 5 -14 -46 26 47 56 33 1 -15 29 1 -11 5 72 -23 -68 -15 -19 -13 19 -63 1 7 -33 -20 23 104 -26 -19 -18 -12 43 -57 4 33 -74 12 60 13 39 -43 60 -94 -8 -37 -34 -43 -2 -55 92 -19 -1 -27 25 -9 19 0 12 2 -9 40 -70 -36 8 59 12 44 26 -63 -42 -37 35 -34 15 -32 30 -51 29 12 31 -21 26 -23 -14 -34 -11 -3 6 -36 39 -17 16 -12 -16 23 -21 -15 -10 11 -17 -7 -9 -36 -37 -29 4 29 -18 -31 22 4 -28 25 -12 -8 46 -28 27 -36 -26 14 -6 -13 -33 -23 33 -39 70 81 -18 -26 -30 -22 30 0 -46 19 74 -65 2 44 11 -90 80 -16 35 -54 59 -15 -68 16 36 35 33 50 -50 -16 -41 -9 -1 -45 48 10 -27 -86 -67 -45 -53 -40 0 12 -16 -12 22 -23 -27 3 45 -8 25 29 -55 12 -53 18 -7 9 -38 -49 8 -33 -40 -59 22 38 27 0 -15 -68 33 19 25 23 -21 -56 -51 62 75 44 -8 14 40 -99 41 -12 -52 -3 -22 61 8 46 -4 17 7 3 -29 -26 -57 21 30 -29 12 47 20 -35 20 -33 13 19 -4 -11 -1 8 21 -29 -36 -22 25 -57 -31 19 -13 24 -41 35 20 -13 18 -28 26 -33 27 24 15 -26 -18 -22 -53 -21 -40 33 17 -24 45 39 23 51 -23 34 31 25 45 -48 -36 18 13 38 19 -4 33 18 -77 2 -53 18 26 42 -97 -6 32 -43 12 -21 4 -31 -22 100 -11 -60 -7 -74 42 -24 36 -12 10 -52 16 -4 34 31 24 -42 -44 -13 4 -19 64 -34 35 -5 5 47 55 104 -9 0 66 0 32 -4 -34 -56 74 17 -12 -40 -65 7 19 60 89 70 115 -122 -33 -63 2 21 -82 -50 -44 41 -60 102 -2 14 4 15 -52 -22 -55 38 70 21 -3 34 51 -24 -12 -8 -18 -20 10 18 -30 -25 30 8 -46 41 16 -24 42 -71 -10 5 -46 0 28 1 12 15 23 -14 0 -3 35 14 -7 -2 -17 -28 24 94 17 -4 -20 -41 -33 -11 -29 71 -30 -11 -26 -32 10 -8 -23 93 81 -1 9 17 69 -18 -1 76 36 35 -68 14 -2 51 8 44 38 45 -13 63 -17 -6 39 -56 5 -69 -45 26 70 -8 -7 8 -42 19 80 53 38 88 -23 23 11 0 17 84 -39 -36 -52 -16 -63 32 69 -19 53 51 -3 -5 -14 38 -39 -90 -45 27 -3 37 111 25 -54 -16 42 34 -62 1 5 12 -42 -18 -59 1 -49 -34 -7 20 3 79 42 14 20 33 19 -11 -33 1 -46 -28 -73 -9 11 6 -19 -6 12 -7 3 68 -88 -42 -32 -1 -23 -27 -6 -35 23 -19 27 -1 -15 -1 -40 -29 -36 -4 -21 12 -19 32 -29 -80 -39 48 -84 -91 -125 33 37 -97 -105 -24 123 -57 -21 -19 -36 70 5 -3 20 57 -37 -78 127 49 -14 -122 -24 1 56 -35 -25 33 -71 -23 -89 -124 93 -118 35 -117 -55 -43 66 -121 30 -75 -59 -49 -14 63 9 53 52 127 -14 -6 -14 -22 14 -22 -128 97 -10 -123 -35 99 6 3 -21 -34 39 127 12 -96 -110 59 -111 -50 -22 -2 -5 -1 -122 75 127 -26 -31 0 -128 68 88 91 -69 -36 -98 17 -61 17 -14 97 127 -95 -126 1 0 -83 11 -64 -58 -20 -35 -64 -8 -18 -24 -21 49 -47 40 115 51 64 54 82 -16 -24 45 -11 -6 -23 41 -5 26 41 -46 122 33 -87 49 76 -120 -46 126 -31 -32 24 -92 -49 100 36 -74 23 56 82 45 24 -50 26 111 121 -49 87 -62 97 24 -44 44 -54 -78 -64 90 68 6 8 -12 -44 -71 -26 39 -127 -77 -45 -115 -12 65 2 96 -128 24 127 -18 -25 12 -23 -1 -64 127 92 -21 28 27 -117 127 -121 89 -54 -30 -15 -125 76 44 -25 126 -128 -85 14 -78 6 -22 124 77 -78 59 -102 -53 -82 27 -27 44 -10 -111 42 42 -75 67 124 -32 -127 98 12 29 -55 -35 -25 -119 -106 -55 -57 6 -7 -39 90 4 -46 -29 -75 74 -21 -14 106 95 20 -5 34 74 31 -26 79 30 -79 38 68 -28 32 -69 -29 52 16 -32 119 -111 13 14 42 -78 -114 122 25 31 116 6 -79 -63 -94 41 -88 41 -1 -6 -80 -91 -34 122 30 -68 -128 -49 -95 14 -11 69 -127 -123 -64 -14 -85 70 -2 45 -13 29 -85 -89 -10 -126 -128 69 -16 22 -126 -121 127 113 -10 -16 -66 9 14 126 4 -68 14 -81 5 80 -25 114 -101 9 -40 26 -34 3 33 -73 -45 -35 83 -30 -117 63 -59 127 -104 3 -4 -102 5 97 -101 -18 9 16 -101 -48 -51 73 -89 126 -59 -62 104 62 -37 -51 -4 -1 44 -70 -32 -60 1 13 -50 -62 64 -26 -60 19 5 -13 25 18 67 -23 23 -46 66 55 57 37 -12 38 -47 -11 -82 -1 31 16 18 31 -75 28 96 72 -87 57 -20 26 -15 36 -1 -123 16 -62 -32 -84 -25 8 -67 35 -4 -127 59 9 -82 3 44 13 -78 89 14 -127 1 -80 -65 117 -89 -75 -18 -41 -75 37 -35 13 -75 -77 -17 44 33 -12 26 124 100 -15 104 127 -101 115 -83 46 124 -41 -23 -36 -82 -59 66 46 52 -40 41 33 -23 18 98 -18 -35 -29 -67 -7 97 34 127 88 46 108 77 32 70 -125 29 -52 -20 29 48 -3 -64 16 51 -14 2 -58 56 -79 -124 23 -63 78 24 30 10 -32 -8 -44 37 -8 40 102 -12 -106 -41 -13 51 33 -8 -52 69 32 15 -21 121 -115 1 22 -128 95 8 -128 14 -18 -41 55 50 8 -46 -123 84 11 -21 6 -127 -124 112 15 3 23 95 -126 -51 120 25 -120 -11 70 83 -7 37 94 100 127 -125 -60 40 48 40 -82 17 127 19 78 25 66 94 -122 -13 -89 14 -89 118 -11 -126 1 -36 -92 127 55 93 112 39 -39 21 54 -18 47 -84 3 -50 -125 -122 -89 127 -53 -17 -29 14 64 -71 -126 19 0 -121 3 -15 -121 107 28 -59 -36 11 -31 -120 -56 17 -123 83 -47 -74 -128 -93 -122 -123 -127 -31 19 125 2 -121 122 -123 -25 42 -49 0 5 67 -121 9 121 52 19 26 49 11 52 -124 -31 101 -2 -33 12 5 -124 -24 -90 95 50 -34 -8 -128 43 93 55 7 64 -92 -29 -34 -66 24 -127 80 43 127 -38 -125 11 -34 49 23 100 76 -89 -96 1 95 -45 15 -44 -88 -121 82 36 93 -35 -16 -123 18 -124 40 -117 -36 108 24 -38 88 102 36 -40 10 -97 -27 -49 35 63 -62 123 -91 34 50 127 104 -70 -40 -92 -33 -72 7 -122 -11 100 -127 -44 -21 86 30 -30 104 -75 -76 56 -127 -90 -27 -40 -92 -76 88 -82 -68 59 -106 -40 35 95 -39 22 102 43 -94 -48 -29 -32 -13 -18 47 -79 127 -19 -126 81 62 -18 65 -124 101 25 -98 5 98 127 -124 -68 47 92 -35 -93 -28 49 -65 127 100 -24 -116 -36 70 86 -128 125 103 -34 -104 -4 85 0 28 -78 -124 108 -106 -117 83 -43 -8 -87 43 57 -46 -37 119 -16 8 75 -100 -101 106 123 23 -36 127 -91 62 0 32 -125 24 21 -15 -17 50 -30 -65 -48 121 -1 -4 70 28 21 -15 100 -61 -53 -104 -4 2 74 -5 -13 -95 123 -92 -122 127 127 -127 66 63 79 -36 -104 -103 -75 -49 10 -7 120 26 -76 -29 110 -4 38 -51 -56 -48 11 -100 26 -76 -40 -10 -117 -60 0 -120 4 126 -97 -75 83 49 93 -1 92 50 -119 -107 -106 -114 -117 86 -64 -127 102 32 83 -13 58 0 -29 37 -72 51 127 -49 107 -57 21 98 -44 -23 -85 -43 -30 4 -59 -60 99 -111 83 21 48 100 9 -37 1 56 -22 10 -127 -12 75 -97 -14 54 -42 19 -57 -6 -125 -126 -37 65 -7 -35 -122 108 1 -36 122 -71 -126 43 -76 -43 -8 104 -39 71 -29 -105 0 123 61 65 -16 25 113 61 -30 -26 110 -92 58 126 -31 123 -4 -57 127 -56 -32 -118 52 -40 -127 -40 18 -103 -29 32 -82 -94 84 -122 -24 89 20 126 40 101 -63 91 -37 48 -77 50 -39 49 8 112 -3 114 49 76 -68 29 95 0 93 -2 30 28 -128 0 -34 -108 127 119 -127 -14 46 -127 -90 28 -16 80 37 103 66 -30 -80 -3 16 127 -69 47 120 76 24 110 -29 -74 67 -18 35 4 -24 -34 -1 116 4 127 -5 -91 27 10 84 37 58 67 -20 127 -60 -12 10 -40 -8 33 83 -30 -77 127 62 113 -16 54 79 48 26 -97 127 70 34 -77 -116 31 -30 127 107 -92 125 -1 12 -62 26 -32 122 5 -77 -126 55 50 -41 -11 60 -69 73 122 -127 -22 -110 -39 -61 113 -2 -67 -128 -120 -16 55 -63 127 -33 -54 -95 -14 127 -58 -32 -70 -27 26 -78 126 82 -67 -126 111 124 -18 126 9 50 89 -1 70 15 125 127 127 -124 12 -82 92 90 119 -55 42 114 24 22 -77 -36 -32 123 -128 -42 -10 -4 -29 -66 -62 -97 127 104 -45 -10 -64 -124 2 123 -49 11 41 -20 -52 18 -110 -82 19 13 20 127 -85 110 123 -25 -1 -94 -67 35 -6 -96 -102 110 93 127 2 -49 -78 74 57 55 -57 -24 125 126 127 -106 3 61 -12 68 14 -106 -10 53 -83 -91 -65 -120 4 59 -59 57 72 81 10 127 -38 -10 -53 -32 -127 37 9 127 109 97 68 -17 -83 -127 39 -44 112 84 53 -97 -81 -127 -128 -27 127 -109 108 87 127 -5 77 -69 -50 -65 -126 -124 119 -110 -47 -51 -15 24 42 -96 -119 127 9 -56 127 -35 -79 48 23 -56 -9 -58 24 -127 80 57 -38 -128 -7 10 72 -79 40 -41 -98 -105 -57 121 -46 26 -26 -128 -126 -125 93 124 -86 -52 -28 41 122 69 34 124 -32 112 -67 53 -121 127 -128 117 -2 -13 -83 46 83 15 66 -16 46 -25 -13 -104 -125 67 -25 127 24 -117 49 28 -24 -57 -75 -34 59 123 127 -92 -119 18 -126 9 90 -120 -115 -125 -125 115 -123 -75 -35 41 119 -68 7 82 -126 25 -126 27 105 95 -66 -122 -119 125 54 78 119 98 77 -127 -68 -122 -120 117 -29 97 100 69 43 26 -20 -118 -52 89 -37 -34 -120 63 -17 29 15 78 119 27 11 72 30 91 -57 58 127 105 -29 -15 108 -2 2 24 79 -54 83 -126 -126 28 123 1 -116 -47 -113 115 76 28 -22 -36 -38 18 111 44 27 -26 -18 21 -124 64 119 -60 -61 65 113 6 90 -58 -90 31 0 54 -55 -4 19 43 61 -41 -53 49 -46 -98 65 127 -7 -64 18 59 -37 -77 -122 -107 62 23 -17 -24 16 -93 -17 37 -37 12 127 102 30 -57 -80 126 73 -125 70 -116 66 -36 -36 -25 63 73 106 -76 113 -30 -20 -4 -127 -62 50 -53 -51 46 -35 127 -84 127 -51 122 116 54 27 -58 -127 -120 -14 104 125 -91 127 100 -21 -74 106 7 -88 44 -21 -124 84 -72 92 -16 21 -87 16 7 35 -61 -27 -25 31 -63 42 -26 72 44 -100 126 -77 -66 126 -47 -14 -49 -126 -113 124 17 115 -127 -40 20 43 124 -14 96 -100 84 110 50 65 -61 -86 -114 91 126 127 3 -125 -27 67 -106 20 127 -55 55 -126 21 17 94 116 -50 -1 17 -5 0 37 -124 66 115 -7 -72 -111 0 79 -8 94 -5 -11 -118 47 23 -17 85 2 49 38 -105 74 6 6 115 127 127 90 -122 37 114 67 8 -45 81 46 12 -6 -90 122 116 -39 -45 -96 -118 122 52 -76 -23 42 -116 67 -51 -128 -122 2 -70 -96 26 -39 -127 22 -39 89 -41 54 -86 5 -68 -7 -32 122 -36 127 77 -52 -112 -24 127 -60 -4 36 -49 26 -102 11 50 -18 36 -85 44 52 -54 -54 109 -79 -70 6 45 71 7 -17 -31 127 -84 111 4 -2 -113 -31 125 65 -4 -88 -86 -26 -29 127 -4 4 -49 -54 126 69 16 -17 -51 -5 -124 6 -21 98 -5 -50 -24 57 -52 82 84 -105 -115 1 1 -6 123 114 100 -58 -35 18 72 5 -29 52 -116 44 -101 -40 -78 7 -51 -23 2 -21 67 110 71 123 57 -29 -76 -43 32 -56 -125 61 -90 -126 119 -65 -70 -125 117 123 -18 53 -4 -101 -128 16 121 -102 45 -125 11 127 15 -41 43 -12 -122 -3 -115 122 74 2 8 124 -72 -74 -121 -128 110 19 -39 35 47 -125 33 -34 -113 -17 40 19 95 -17 -4 -20 42 -91 -6 80 62 48 68 85 8 -31 35 -1 -73 66 91 -87 -98 25 39 -22 -76 -123 52 -120 -26 4 -33 97 55 -60 -128 -110 107 44 -60 28 -123 -127 106 -4 27 16 41 -11 55 126 -108 124 -128 127 -39 -122 -7 59 -128 -97 42 127 -125 -16 115 120 35 17 -126 -14 43 125 71 -32 -15 -125 127 -127 -128 -58 110 83 -78 18 45 125 56 105 -99 -126 -29 23 -16 127 -20 25 23 -128 -39 -105 91 -124 -8 23 -123 0 -122 81 -52 -47 23 -120 -126 63 57 50 -94 50 56 125 -56 -42 -111 49 43 68 93 -47 -17 -73 -41 11 -49 44 17 82 -126 -94 127 25 35 -48 63 -63 -93 28 -58 8 74 56 -10 42 -128 -78 48 -87 12 -26 0 29 23 111 -7 -70 -127 -9 -118 -38 -53 51 -126 -57 1 105 -105 -29 20 89 9 121 82 -57 -92 126 -71 -128 -7 -29 6 95 96 -63 -125 127 -127 82 -62 68 -13 -100 -26 124 124 23 12 12 119 -102 91 62 124 -83 -7 21 -102 -118 5 -124 96 56 50 117 -104 92 -54 -105 -73 -17 -39 42 44 126 -23 -107 -29 -118 82 -30 79 81 -128 -128 -126 124 114 24 -12 -128 -29 -125 -127 -124 54 89 42 5 42 -94 -52 41 -41 76 -128 -41 12 -50 -109 -104 -21 37 25 -119 124 -79 -24 89 106 -127 18 -117 -65 -128 118 -128 127 126 94 -111 -83 -14 19 127 -122 12 127 -69 -23 -29 -128 111 21 -126 0 45 -92 -24 47 -27 24 -79 45 32 -46 105 -18 -21 -105 126 -13 -84 8 -1 -75 127 26 112 66 107 0 127 9 -9 -108 -15 -50 -34 -103 -42 -41 -125 123 9 -124 115 -81 -48 -47 77 -119 -35 41 7 -6 -101 34 2 117 -123 86 -27 -24 127 -90 58 -67 -116 101 -121 22 -104 -44 35 -4 -80 -5 -70 0 115 67 31 -126 -37 44 -9 16 50 7 13 26 7 -73 -68 45 20 -75 19 -44 8 21 -22 1 93 86 6 -11 -16 -18 20 75 -29 -12 -16 40 67 7 11 74 58 -50 -46 37 -8 -45 -5 -3 -50 -36 -12 36 65 29 -29 -92 12 10 -91 1 8 -2 96 -61 -44 -28 -24 -2 14 37 -19 25 76 47 9 -29 42 -21 -10 17 31 25 23 22 -52 20 -14 50 17 13 -91 -41 -4 12 -69 -91 -8 -125 14 -30 82 0 -26 -3 46 32 -28 24 -3 -90 -101 -79 -61 64 -45 31 6 5 67 7 49 34 -4 -19 -4 -13 12 5 28 -76 12 -46 -5 -5 3 -28 -25 -5 -19 -17 -85 -58 30 -44 56 -73 -29 -74 58 45 -24 -42 57 -57 -15 -50 -2 -1 68 -20 -5 -32 14 62 79 23 90 -44 -47 85 41 72 121 -28 -47 -17 33 -3 64 -57 -51 -21 2 42 -126 17 10 61 24 -128 -93 -32 73 -38 -25 78 -31 -39 -34 -97 34 -118 -125 6 -7 -43 11 7 48 1 96 -12 -48 -12 79 29 117 -57 57 116 -16 116 -81 -38 7 -35 -111 -125 -51 -67 -13 -21 14 -21 48 -12 -127 -45 55 -127 -121 42 -11 7 22 3 -61 12 -10 60 -25 20 0 18 9 -24 -79 -66 -11 22 -44 -52 7 -10 -42 32 -38 18 43 -44 7 35 19 105 86 -95 26 29 -23 18 1 116 -14 66 -128 -83 50 122 48 -55 -125 -84 78 74 -76 -61 -70 18 48 21 -6 -91 88 33 -115 42 -1 -73 -78 -10 -35 -21 -16 -70 31 79 -41 -8 -55 93 -38 -36 -63 -36 -69 -23 -68 -126 -78 19 -92 114 -79 97 127 25 127 -32 122 -44 125 106 -10 34 -17 -5 102 -55 62 -31 117 -7 -34 8 -118 74 -124 -3 -34 -47 -125 -112 -81 -66 -88 10 -52 93 4 -17 110 91 1 61 -65 4 -18 -78 -11 -5 -72 -27 -57 113 45 -45 -125 14 -56 3 -14 56 -58 -82 77 80 41 8 109 -22 -65 -82 -48 22 87 -32 -37 -4 45 -18 17 -23 -40 -108 57 -53 -4 21 -87 -17 56 -118 -4 -78 26 61 -50 118 0 -54 -13 87 -59 68 45 92 127 48 16 -56 -37 -63 32 74 -3 55 115 21 7 126 -17 3 -38 43 31 -4 46 58 -52 -91 -25 28 -126 89 -8 -98 124 67 -71 20 -52 -42 -68 -20 -51 33 -31 17 -21 -15 60 -60 -128 -56 127 -10 -21 -23 62 -23 95 -121 16 126 -60 117 20 -13 -72 -69 65 -61 -127 41 15 29 48 -123 -32 35 23 74 44 112 53 -118 -117 45 -68 127 -44 126 -66 3 22 -17 19 51 -93 83 -111 -21 -13 -13 -66 9 51 -79 -76 -2 64 -70 81 -68 -19 82 -26 95 101 76 -65 -53 32 127 75 -32 -98 123 51 -61 45 -61 37 19 -80 -103 -12 71 1 -8 -59 -15 106 -17 6 6 -46 -14 -1 -51 -19 -63 -45 -32 -15 47 -122 99 -2 43 68 -29 15 32 -26 120 51 -44 127 24 107 15 -76 44 73 -10 -31 -17 -68 -79 -53 28 -123 2 -122 122 44 58 -16 127 -76 -84 71 45 3 -63 -102 -59 -18 38 -84 18 11 -102 76 -52 -124 -15 -84 113 -114 56 63 2 81 0 31 -117 114 38 23 -40 34 -3 127 43 -42 -95 54 -68 -13 -91 41 127 16 -64 -37 5 -72 -20 77 75 -1 -26 53 86 10 30 -19 43 -27 -105 62 -29 18 -13 3 16 -42 69 22 47 26 2 12 58 31 71 -85 12 17 -82 -44 30 -68 123 97 -37 26 -64 -40 127 -76 -47 -65 -7 5 7 -71 95 -24 4 -124 -2 45 -19 74 -11 -46 119 -78 -37 -9 -33 -102 11 44 -52 49 -109 -103 -28 -20 104 90 -80 119 18 69 125 3 38 -27 111 -15 87 -82 -2 34 -24 60 39 19 105 17 18 -61 18 -42 123 -10 11 -44 12 51 38 -35 70 97 -127 -123 -29 126 -63 126 -79 -96 56 109 -14 68 56 -111 -13 46 -16 63 -128 125 -93 60 -86 71 124 49 -11 -6 44 -25 -72 -29 49 9 -90 68 58 -37 -112 117 10 -7 127 32 -31 103 30 111 32 54 -58 68 -3 9 -73 -47 4 120 83 1 35 -7 -17 -18 58 74 -127 -50 -68 -25 56 32 -21 -108 -45 -15 14 89 0 -104 7 36 -80 -66 60 -115 34 127 61 -19 98 -28 -19 -18 -7 46 1 2 16 -61 -33 -43 -39 -4 8 4 -63 57 15 69 -35 -76 28 -55 -45 -34 -37 72 57 -108 18 10 -85 17 61 67 -31 -28 -30 -8 -33 4 -13 1 -36 -29 14 69 49 -29 23 13 -29 -4 -32 -101 -17 -116 7 24 -2 -48 -68 -91 52 -66 32 78 -76 -58 47 -33 -66 6 53 -29 93 55 14 -21 30 -44 33 -31 -6 14 -68 65 82 -58 3 -21 -102 102 -37 -6 67 28 6 86 -19 -10 99 -31 68 31 -65 34 20 2 -119 71 -83 -66 95 21 -37 -98 -97 -15 -68 71 50 57 -9 -125 -88 1 53 -49 30 -22 -5 20 -16 -83 -20 -24 -85 6 -127 -7 93 -55 12 55 17 33 31 19 64 -25 16 -42 35 -108 -68 -1 92 122 58 37 -125 -78 22 53 109 -17 25 -31 57 -18 -2 53 103 13 -53 35 -25 -68 -15 6 -65 111 34 34 -47 -17 95 25 -15 37 -17 15 92 -125 -15 -27 -33 63 12 29 94 -53 -44 45 -90 -128 16 53 29 9 -28 125 60 45 89 87 -42 -9 65 60 20 -10 33 78 105 -2 2 -115 18 21 -118 45 76 -124 -68 -42 73 69 -15 7 -28 -76 39 32 10 36 -8 -33 -38 10 -24 2 -69 -28 34 8 54 -83 107 -47 -65 -6 6 33 78 76 -14 99 -40 12 85 -23 7 5 -16 20 30 12 -78 -97 51 13 61 41 68 38 27 -3 -40 18 -7 -62 44 71 13 56 -30 -18 -5 -6 5 20 -22 -21 37 122 -38 87 42 -15 -10 -56 -29 11 23 -36 -40 -39 -27 40 -42 -42 -10 -55 22 -13 -78 7 0 -66 65 -5 21 0 -69 -125 -58 33 45 -9 -126 75 19 -93 -43 -95 33 -62 -41 -38 58 0 35 -68 68 37 126 -3 -35 -56 90 -8 -102 110 -49 41 -38 -53 -111 -15 -12 -88 29 -113 23 28 5 -86 31 -1 112 27 23 8 64 -76 36 56 52 -44 -34 89 27 33 -5 -37 -21 2 28 72 32 -88 47 17 85 96 -21 -48 5 -60 110 60 -51 -32 -54 54 9 38 -26 -49 -21 10 50 22 67 -48 40 -20 -102 69 -52 -80 -125 -18 -88 -26 -95 -42 -87 -21 -5 115 -32 11 -68 -41 69 38 -35 35 -38 102 117 41 44 -42 114 22 -27 123 4 101 -116 71 -52 24 47 -23 -94 114 48 -119 -43 6 88 121 13 -51 -44 124 -12 -34 -32 -37 17 75 -66 5 48 12 4 49 10 32 -37 -110 -90 103 67 -8 -99 30 21 48 57 52 -17 -37 -82 -68 -10 -64 98 -2 -110 99 -123 121 -61 -68 -101 124 12 -37 18 -62 -69 32 11 101 39 7 -72 47 -77 18 -43 59 -30 22 8 -75 -62 -4 -106 -23 -87 -35 22 -57 -28 -7 -58 -87 100 -2 50 32 3 103 -46 1 -33 41 -39 -68 -61 82 17 -74 -80 -26 -27 -52 -14 23 -51 -36 -12 -40 -65 17 46 -5 76 55 123 53 26 -88 9 34 -32 -3 -9 -48 19 57 85 -17 53 29 -27 16 13 -124 -112 -86 -19 39 9 44 -125 74 -56 8 60 -23 34 -127 -5 -91 -89 -55 -117 -32 102 -8 2 93 -17 104 -90 -71 43 -39 -19 98 -52 -5 63 37 -62 21 -21 63 8 68 0 46 -65 -56 65 -53 -35 -23 -46 -52 45 -62 -26 -24 17 -51 6 -8 -92 -67 118 -8 -1 -60 27 11 46 -95 -26 -126 -89 -85 82 18 12 57 71 -26 42 -4 48 88 122 120 39 9 55 41 -6 21 -40 -21 87 -44 14 -29 11 -85 -46 -93 -54 11 62 -40 40 -128 -74 -12 115 62 -25 105 -128 -17 25 99 -18 117 4 31 -59 127 56 -98 -38 127 61 -23 11 49 -21 -68 -30 81 -65 -8 -126 42 -80 64 -38 -115 -37 59 -70 -125 67 -44 -40 66 -17 -16 -33 112 -18 54 -57 -3 -71 124 -88 64 38 -14 -124 42 -77 74 71 -105 -3 31 44 26 20 -18 -33 108 78 53 -116 -115 -106 41 127 0 30 -128 -78 -39 -81 -68 119 -80 -36 -55 -17 31 67 -35 42 33 34 38 4 -2 -19 -114 12 -1 -29 -15 -37 -124 -58 -37 8 31 -14 -78 97 80 -4 33 -123 47 113 91 -20 66 41 28 -70 -38 -25 -99 -61 -45 66 26 75 34 -38 21 71 18 -123 -9 -17 -20 -73 -7 -70 47 42 -126 -120 41 18 -49 118 27 -87 52 -7 127 -13 34 -52 -67 41 -43 -30 -75 -28 -65 -124 -15 -126 -43 -125 34 -124 13 -28 -116 -27 -122 10 -128 -126 91 -120 -20 -66 -48 -126 32 81 -80 -13 -40 17 -48 -33 17 8 -48 -99 79 40 52 18 -57 78 -126 -63 -13 -2 17 49 -61 82 -121 70 50 -46 -123 -126 -1 84 127 -122 -20 20 -38 53 -10 77 -20 23 64 -69 38 -27 19 103 53 126 101 -14 -82 -122 48 -37 17 -66 30 93 14 33 7 20 75 50 -105 14 -57 87 48 36 -29 124 -15 -38 15 -126 -53 100 42 -11 -35 -20 127 58 32 127 -77 -76 -34 -93 -29 -125 -56 62 -21 35 127 97 -108 12 39 116 -1 81 -28 -128 -91 35 127 110 123 15 -80 0 14 -110 -6 -26 -44 -120 31 -47 38 -125 -3 -125 -27 106 -115 -26 -57 1 -43 -76 37 -68 -79 8 17 -113 6 119 11 60 106 -15 -50 70 -28 -16 28 -58 36 63 10 -56 -59 87 -75 -11 -89 9 -99 5 7 16 -26 24 65 1 -121 -126 -63 94 116 -10 -14 -18 10 97 -15 127 19 13 5 -30 -29 23 70 -2 -16 118 88 81 -99 16 -61 -5 -119 67 65 122 126 29 64 -26 41 -128 -127 -40 -64 84 31 18 -40 126 -46 -46 53 -127 0 -11 14 -5 81 -22 127 15 -53 126 10 -14 -127 -93 -93 -68 18 35 33 -19 115 50 3 127 22 120 -98 4 11 -80 -127 -22 -89 30 78 97 123 -106 31 -82 126 -17 40 127 -6 -18 -42 120 100 69 -46 -36 33 58 -79 20 86 127 65 58 -126 -15 101 -16 -56 -43 24 -8 99 40 -7 117 13 19 120 6 -55 92 -105 -93 60 117 -62 109 -24 44 -128 -43 -66 -106 -4 -74 -35 11 -101 5 6 127 -35 104 -27 43 63 70 -34 127 -91 -42 126 -27 -6 78 -101 -19 -65 127 117 124 -8 97 -117 -9 -127 127 11 81 126 -127 -51 37 -39 -73 2 -115 4 120 -78 -8 -66 -33 -38 7 94 -4 74 -41 60 -38 94 -43 81 -87 123 -54 48 -101 -37 -18 -67 16 0 -106 -90 63 -52 -8 90 115 -126 -7 -128 -48 1 -127 122 -21 -72 27 29 95 -62 -61 59 -34 49 -13 26 29 -41 -117 44 82 36 -111 -50 -124 0 -35 -87 0 62 114 85 66 -101 -50 -43 63 53 -73 -125 64 -73 6 33 52 -49 -26 0 38 41 -24 -11 13 45 7 -120 58 109 -55 26 29 -9 -30 67 12 -27 -3 -128 125 83 -6 82 -43 -115 82 30 51 102 -47 -36 -41 126 -37 -57 2 -39 4 -74 40 63 31 74 -53 35 -104 6 -63 33 127 -85 -51 -97 -21 2 18 40 -86 127 120 -6 13 -114 -32 -15 46 -94 47 -51 41 8 -17 -3 -122 31 -92 126 25 30 121 49 70 87 -6 3 -28 50 -21 44 107 110 -41 -42 47 77 -13 69 -23 -4 -76 0 24 100 36 -50 42 -56 -8 120 18 -37 -118 96 48 -14 27 -109 -110 -86 -85 -103 -89 65 -41 4 104 -46 52 -122 -56 -6 23 35 49 31 100 1 -43 16 125 89 21 43 74 99 75 -46 69 14 -20 -96 9 73 -36 -10 -2 10 -48 16 69 39 24 -128 80 21 -11 4 -53 -90 51 -14 29 -15 -50 -15 11 34 -17 -127 -34 19 -123 117 -26 -26 27 3 52 72 38 14 -28 -74 63 -36 -91 -25 -51 -74 84 -96 11 -58 0 54 29 -81 8 7 -35 -109 -19 67 -58 -52 -40 -122 -111 -14 -44 127 -127 32 -24 -26 50 -5 74 30 53 11 51 -18 126 121 127 -22 86 -46 9 -23 18 127 13 -107 -108 52 23 -24 -50 -1 35 127 -18 15 -33 115 67 7 89 -15 58 -78 81 51 -9 -2 -31 82 85 -127 -24 -118 3 -29 37 119 -39 97 106 20 27 86 88 108 121 127 -13 -6 34 -49 50 125 -74 -36 -74 121 33 21 122 -54 67 38 -35 7 12 -96 -69 -2 36 24 -36 -21 -4 52 -18 35 123 -42 2 -122 -128 120 42 -44 -46 -70 87 119 -35 21 -81 35 -26 68 2 -63 15 -127 105 40 -40 -1 18 57 6 51 78 -93 29 -122 -3 -83 -119 -21 -52 58 -118 121 -9 -128 -17 32 -6 118 6 -21 48 32 -126 -28 -11 -24 -75 31 -10 -8 -52 53 -82 37 4 49 -13 -49 -19 49 76 27 -3 -38 -6 26 40 46 47 -25 13 9 -60 44 68 -41 20 -75 48 36 -90 31 32 -40 -18 21 -12 -8 -58 -24 -33 -82 74 11 56 93 54 35 75 40 -122 -58 -34 -3 25 -98 -67 -25 -36 77 -34 -17 69 49 -34 32 -14 14 8 -14 -118 8 29 -3 -46 -17 -38 -46 2 -38 -48 0 -17 -54 24 -81 -35 -48 32 2 67 15 -9 -11 -31 -18 25 43 -31 -107 -38 28 9 -86 -67 27 29 26 -17 -68 5 -13 -31 51 37 10 -22 -128 3 29 28 -24 30 38 -69 -12 -34 -68 38 43 1 -22 -99 19 -30 -54 -40 38 75 46 -61 1 -46 7 -34 -61 3 -33 -42 32 54 43 30 -128 9 -23 12 29 39 11 44 -4 21 -96 22 44 -17 -10 -43 -39 -35 58 -21 -23 39 6 56 81 -62 21 -90 90 39 33 -18 5 3 42 -6 -14 28 67 28 -47 14 34 -10 -36 -6 28 3 -117 -6 -33 -36 -26 -16 27 109 2 15 21 -100 -51 5 -6 36 -4 41 65 -53 -27 -27 -97 40 29 -27 97 -6 29 -25 65 58 62 25 6 65 6 -35 -17 -67 -23 31 0 -10 51 24 -24 47 -125 4 -71 -20 31 -8 19 24 69 27 -41 40 12 13 -64 36 12 -34 53 -10 -20 -20 -20 60 -47 -31 17 4 -33 0 15 39 -6 -5 2 -77 -15 -72 12 15 -79 27 0 -24 -53 4 65 -30 44 -28 113 53 7 -2 12 -22 15 -35 -66 91 14 -14 22 -13 95 -4 45 -3 16 -47 61 17 -38 124 11 -38 -78 -59 -26 -29 -38 -25 2 16 49 123 -23 -77 53 -15 0 -35 -15 48 126 -7 -2 -23 -25 -31 -2 53 -43 -37 12 -5 39 -28 -6 -8 97 36 -9 30 -52 -11 -18 58 55 44 -27 10 110 -51 -64 -7 30 -53 12 -23 25 -35 31 22 -12 -19 -43 19 -16 -1 14 34 16 26 -19 -29 6 -6 -50 18 -57 54 13 35 -21 -27 -4 45 70 30 15 31 65 -10 39 55 11 51 56 42 -97 60 19 -2 -5 -23 -29 10 77 -8 -76 -113 -14 40 -41 15 16 -37 24 -35 45 -26 -106 -39 34 51 48 103 -27 -30 80 117 -117 -17 -19 84 -18 -46 63 -40 -40 -24 54 -3 -17 -46 -51 -25 -27 33 -41 -125 -14 -37 19 -12 -122 -78 -51 -25 -22 0 44 19 85 47 -1 34 16 127 -19 61 -47 66 29 56 15 -1 5 63 -83 41 -63 21 20 42 108 12 -23 -7 -68 32 22 21 -4 -110 39 -112 -30 125 21 0 20 -14 16 -8 0 -87 -47 28 -31 -45 102 71 -49 -15 -111 38 12 -45 -19 58 83 -45 -21 100 -56 -44 8 52 9 -57 -38 -78 11 47 62 0 48 64 -33 -52 14 29 24 17 -111 -14 121 34 49 42 -26 -11 29 41 31 33 -49 -45 50 -72 -115 -12 52 9 -59 74 -70 -52 -40 -40 -7 62 53 17 -62 -7 77 68 -4 -79 16 -64 -27 105 43 110 -15 7 -89 -5 54 83 -49 48 -51 -48 36 -121 39 -5 -77 109 -37 -28 7 38 -37 -24 8 -7 -13 -60 64 -69 -25 -55 -34 38 59 41 -4 -24 27 -17 61 3 -57 82 26 -59 -77 -12 14 12 50 50 -50 -1 -13 12 -56 -14 -9 22 21 20 -48 -25 7 -34 43 27 12 -45 -8 20 16 -51 12 -48 -7 -22 -19 42 15 6 5 -58 -63 -116 8 -17 -18 -45 31 -20 12 44 1 40 -10 -18 -17 79 0 -4 11 29 -7 52 40 -30 -11 -16 -12 -13 37 -25 -11 78 68 -55 -38 52 32 2 36 21 -49 47 5 17 11 -17 48 -8 7 38 -33 5 -55 -31 18 0 -28 -79 28 31 59 34 2 -6 -14 34 -18 -27 11 15 63 -84 -59 -21 42 -43 7 48 -68 0 23 24 -85 -86 58 16 -1 11 -51 -5 -18 -1 -41 -54 6 -15 15 55 21 43 -127 15 -70 -34 -44 -13 -19 38 5 3 40 -5 -23 49 66 56 0 -33 36 18 23 0 -121 7 66 87 -15 44 2 28 -24 -85 54 -25 70 29 -50 12 90 24 -61 -14 -13 -33 10 22 7 37 -42 -38 -33 -21 22 -11 59 85 -59 34 -3 -21 33 48 -45 -60 34 -48 2 -16 0 -20 15 -58 -78 4 -30 2 8 30 -4 1 -13 -71 41 -4 -28 7 -40 -34 46 12 36 26 -10 -22 -27 -14 36 -31 5 -19 -16 -31 -28 -40 51 -9 15 -3 -29 51 -10 -32 2 -14 54 -3 -38 -35 -1 48 -16 15 69 21 -33 -17 13 14 -95 34 65 -11 15 16 33 19 -16 36 -20 -2 -56 33 -44 65 -12 -62 -13 18 13 -59 -8 -19 56 69 -50 -7 14 36 29 -95 -93 -40 13 -18 24 -43 -82 -7 16 -32 44 -39 32 -1 23 18 -24 26 119 39 0 -47 10 36 48 31 -11 15 36 23 4 -12 38 5 -5 -31 -10 -3 15 -8 -29 9 -128 -53 -51 67 -18 5 24 -31 -37 -102 33 -59 -81 34 12 -1 -31 34 -54 58 -8 17 -43 -87 75 125 -35 39 -31 21 30 20 65 19 -11 -31 27 4 25 78 62 55 -4 -31 -6 93 -39 -3 18 112 9 -20 -18 50 11 69 37 -50 35 -79 47 0 -54 41 -4 79 -47 35 47 5 1 -109 -87 -100 52 82 28 -40 19 -29 -1 71 25 13 96 -19 -16 21 5 39 1 -68 -24 9 17 90 6 57 21 -80 20 -16 21 27 -82 20 35 -63 -42 -33 -6 -36 22 40 24 44 -40 32 -29 -86 75 29 22 -33 1 -7 17 34 -28 29 -20 27 -46 -7 43 66 2 -30 35 2 31 35 55 31 -29 -34 31 -7 -7 -37 -70 -63 -14 -73 -68 -28 -21 10 -21 5 68 56 34 20 -33 -3 -9 -18 -33 42 -9 -23 -24 8 -24 -6 23 85 -4 14 125 -47 22 -6 -58 -115 -29 -64 -6 -32 -58 11 35 15 4 -31 -16 -112 -37 11 -75 7 42 110 -28 -23 -28 -34 -96 -40 -31 -1 -11 30 27 4 -26 36 -83 70 -15 -16 -76 27 -17 -67 -19 14 56 -4 8 28 13 14 -19 85 -71 11 29 -42 -13 -2 43 -4 18 -25 10 -76 -70 -22 -14 29 -117 -3 1 15 35 1 55 -12 17 7 -51 -48 7 -41 -49 46 -28 -10 -3 -28 19 -2 8 52 24 -19 -77 19 -35 30 -9 2 6 -52 -27 54 -28 -31 35 19 20 -13 -69 36 -6 -41 -10 12 -82 -106 -125 108 -28 -44 43 -20 -18 47 4 21 -17 46 -20 22 36 42 37 -60 -45 63 -54 91 48 15 36 -77 5 -35 68 -22 113 2 -21 9 -80 87 27 33 24 16 -7 -24 -18 -13 10 13 54 11 4 21 7 16 61 88 32 13 -14 -25 16 -1 56 -8 13 -32 -45 -23 -17 -45 -64 5 -56 1 -34 -58 -50 32 57 -27 -59 9 26 118 42 37 73 14 -4 -3 21 -51 28 -13 -107 -33 -23 32 -68 -35 -7 103 -39 38 -74 -49 -32 -23 1 -26 11 67 14 -73 50 -13 -20 115 -103 6 18 -33 33 64 -74 -19 15 19 15 -62 47 17 65 8 18 -15 -55 -31 2 -39 -52 50 -39 31 66 -58 45 -14 3 -35 -2 27 24 -15 -25 -6 -9 -3 34 -12 27 14 -33 6 -42 33 97 84 3 -63 34 -89 -23 -12 13 -33 127 -85 40 -24 -6 46 25 11 -108 29 42 27 -76 -30 -34 -43 18 -10 -34 6 -45 -26 -27 27 -43 -76 10 -104 -43 15 -33 43 -20 65 -9 -5 125 -10 -24 76 -60 72 59 6 -14 -9 46 30 41 -10 -9 9 -31 75 -24 -26 9 -69 65 92 35 -91 80 40 45 -59 55 -9 79 56 -79 -32 91 -30 -32 -33 71 20 120 -16 -35 -120 79 77 1 37 -43 -111 50 48 21 79 69 -67 99 -39 -126 123 -12 14 -66 -92 127 37 118 -53 -5 61 26 -3 -14 57 125 -19 59 34 42 37 16 -11 30 5 42 33 -15 -62 -33 -75 -34 73 49 59 -27 5 -26 -35 5 26 31 15 47 112 8 15 68 52 -34 106 31 73 -15 67 -32 -16 -19 -59 37 -84 63 9 62 -40 30 118 40 -25 -47 76 29 120 15 -80 109 -27 -7 92 -73 37 27 -51 8 -23 -30 -4 -45 -27 -102 -68 -1 40 -3 2 6 -43 -23 28 76 -13 6 -21 -5 -4 35 17 -34 -6 -21 40 -38 -8 -110 -33 89 -54 27 -33 28 -61 -26 33 -14 -68 8 -31 -11 53 -5 -14 46 18 -59 -31 -16 29 50 -26 33 3 -32 39 -33 18 -48 -39 11 -46 5 -23 32 12 -8 27 -6 28 -41 16 26 -16 -62 22 -10 6 86 53 -45 -18 -9 -34 43 -28 -128 47 -35 8 -52 -54 72 119 67 -44 50 -25 52 -9 -61 -51 39 -40 93 67 -18 -25 -60 37 -49 -55 53 57 53 53 -6 -72 -78 -6 56 -8 -40 -39 50 19 98 -7 -43 66 45 -35 -13 -18 3 5 33 25 3 -54 -36 56 -44 4 -45 18 54 4 23 53 8 22 14 21 37 -18 88 65 -43 -11 -96 -21 0 47 88 -25 -61 -77 -60 -24 34 10 -4 42 -42 30 -15 38 -39 6 15 32 2 39 -9 -64 -45 -46 57 39 -5 -60 10 -91 -6 14 -14 -67 0 11 -106 7 20 54 54 -28 49 -54 -17 -32 3 62 -32 -35 -11 -32 9 6 -39 0 -25 -31 65 -71 49 -10 28 2 80 63 -42 -24 36 29 -35 83 107 80 -89 61 124 -10 34 -39 -109 -28 -6 29 50 94 15 25 -103 -5 -95 34 17 -52 55 -31 -32 -24 63 -48 22 -120 -1 56 -18 -28 18 77 50 -92 -46 60 1 -13 -31 65 -65 64 -33 -59 52 -84 -46 -30 -27 -48 86 50 34 31 55 8 -30 14 56 -4 -71 -2 4 -27 74 4 90 -32 -40 26 -25 -63 -25 -119 24 52 -34 -10 75 -33 -36 -26 40 -28 -45 -28 -2 -19 43 -50 -27 50 -39 -2 -25 47 -48 -12 -15 -41 20 -33 14 -45 -40 -40 -22 3 -25 26 -58 11 -14 18 -43 -41 23 -1 -105 -99 56 -25 17 0 39 127 34 -69 5 5 -79 48 -26 -5 -51 11 -4 -32 10 57 97 78 -65 36 65 126 55 -20 4 68 1 -40 17 77 70 16 -39 62 77 33 -25 19 88 119 -21 42 76 64 -25 -55 56 -23 28 0 -23 51 -22 76 -3 -24 -10 30 -27 -56 28 33 46 -64 7 -13 58 38 -11 -17 -48 -99 27 19 30 -10 2 -23 29 29 -30 -14 8 -9 9 -10 -5 -22 -10 -62 -47 32 -24 -3 -7 -58 1 57 41 -13 9 -18 12 -62 15 49 -44 -2 6 -41 -17 -105 43 -2 -37 -3 -28 -1 -16 -35 9 52 24 10 -16 10 14 26 -41 50 -52 -23 -17 -12 -85 25 29 -82 -38 12 -33 49 18 -22 -54 -3 7 -24 -2 -40 125 33 -66 46 119 34 49 -30 -18 60 -30 -5 -8 10 -12 -9 49 -1 102 -36 12 -47 2 54 -12 -19 25 -10 14 107 32 -28 -35 23 46 -43 20 -32 -21 62 25 67 53 -32 -30 -13 -10 -9 -83 10 87 1 26 0 -8 22 13 52 -12 32 28 -8 61 5 -6 -12 38 -8 37 -30 30 42 -56 3 -37 -13 45 45 4 24 53 90 15 -66 -35 38 11 15 -20 21 32 -28 -3 -8 -41 4 -82 14 -15 -1 -23 -88 -7 8 -15 20 -37 -23 27 55 -18 -37 39 -16 -19 39 -37 -35 -30 -14 14 60 42 -59 42 -44 -10 41 -10 -45 -4 -25 -6 8 -3 0 -14 3 18 68 -58 -3 66 41 -49 40 8 -4 46 -14 27 13 -14 -32 40 41 -13 33 -20 27 -27 25 67 -62 -13 0 1 56 2 -32 1 40 24 -12 51 80 2 18 -13 -21 38 64 -43 -31 31 45 38 -4 -54 -30 -48 30 -9 9 37 -41 -24 30 -5 -22 22 -30 28 -5 79 42 33 -25 -51 -24 -82 -37 40 59 -36 30 -11 -23 -53 -20 73 43 37 1 0 30 -47 -51 -45 -20 -31 -21 3 -28 17 71 49 50 -23 53 41 -64 -47 23 -43 -13 35 -80 10 23 14 -57 39 11 16 36 3 -3 63 45 -5 44 24 -41 -2 -21 3 -58 -13 30 -36 -10 32 -49 52 16 -27 63 -89 -40 -54 -40 -22 68 -38 28 -51 -18 -37 60 -14 0 54 35 47 -3 90 -15 -123 -26 -28 -19 -71 14 81 3 71 1 -3 -10 -36 -3 56 51 69 -45 6 43 -63 -73 -40 9 8 51 -44 65 80 -10 24 1 -20 -128 -27 -18 -59 24 48 51 105 -106 80 -44 -6 -17 8 4 89 23 1 17 49 -63 62 65 40 -16 6 53 58 -19 -26 56 26 14 46 -12 13 -8 -43 18 -27 -15 -7 29 4 42 -98 70 -32 6 13 29 -23 -30 47 -5 -10 31 56 -9 6 -28 -16 12 8 51 45 18 -64 -10 -17 -13 -5 -10 -7 50 11 -12 -44 5 -58 -53 -32 -44 -39 6 -81 -20 -43 8 38 13 -95 14 17 33 27 -35 93 -49 6 -44 -12 -68 27 5 -63 19 -76 -6 -17 -20 -89 74 11 93 9 72 19 52 -31 -46 13 -13 60 98 -4 -21 85 12 -20 28 -15 -28 -17 -24 -40 -32 -52 -41 65 -39 48 -10 -28 -26 43 96 -55 -48 20 -1 97 2 -14 19 -34 -11 28 20 -10 76 -47 50 -53 69 9 19 -9 -12 -14 14 -15 -12 10 15 -39 31 116 32 24 49 3 49 54 -5 52 -50 -18 14 -77 13 34 20 79 -41 4 -9 -3 13 -69 11 -11 -41 -36 30 -61 40 -22 24 2 -16 -1 -47 -39 -57 -84 19 -73 -32 -65 8 -51 8 -55 -23 2 -9 20 38 -55 -27 -2 15 29 6 -70 66 -17 -38 -52 -29 -52 27 32 32 40 62 19 48 -1 2 -23 -78 -76 -28 7 64 -76 99 53 -70 101 71 -10 -70 48 -10 -43 36 4 41 -3 2 12 -75 77 18 44 -17 -38 20 21 -4 -11 -72 -89 110 9 -68 70 -91 -10 -114 -55 -5 -82 52 13 -7 -5 27 -30 81 -6 -53 -11 -2 69 112 -36 117 -94 -65 9 -11 -50 -78 57 106 16 43 -5 -7 29 22 56 -14 -88 17 -17 1 9 -27 43 -55 -19 5 5 20 -33 19 30 -55 24 -64 -70 34 39 -9 -6 -25 -3 -61 21 98 -36 -19 21 -8 -42 -65 12 0 -10 3 19 -26 52 -25 56 18 5 25 18 18 -36 2 -10 -36 -23 -21 -37 -49 -69 11 22 16 -50 8 24 80 58 49 56 50 -79 37 -21 -30 -122 -5 -52 -43 29 19 0 -16 68 -9 29 -30 -18 -6 -8 -32 20 -98 -61 37 19 -74 12 17 -58 16 44 5 31 13 8 75 -40 -20 61 26 -46 -19 -67 33 122 14 63 12 15 -17 11 0 106 38 -39 7 3 -77 -1 5 -32 60 23 -51 19 47 7 -20 8 3 37 -1 39 -26 7 3 -70 28 -23 -5 -6 3 -7 3 28 16 20 25 40 24 16 -2 -41 -24 -115 -73 45 20 21 5 -49 32 55 14 59 -8 13 -69 -19 -13 -37 32 35 4 22 -28 0 43 -40 37 -48 -41 -12 -27 20 -80 -16 74 -12 35 11 -2 -2 50 124 29 105 -63 29 -72 13 6 5 20 42 61 -41 -6 83 34 -60 77 0 20 26 48 -23 -68 33 76 -29 53 27 -51 40 12 11 -25 12 40 51 -26 -11 -80 2 27 -6 -53 -46 -24 4 -50 65 -35 87 18 59 36 4 60 61 -49 -21 82 28 -9 -25 59 -29 -33 84 -24 -7 66 -106 44 4 -54 -6 44 -7 66 -58 38 48 0 -9 34 -15 76 -60 15 68 -115 5 -38 22 -54 22 28 32 -45 -41 7 -77 4 20 0 27 14 -9 42 5 61 40 71 -3 -2 25 65 -9 56 -60 -9 -18 49 28 -14 -57 -3 44 6 47 42 -8 31 77 62 -18 -79 3 -33 -9 -38 -46 17 -44 10 37 7 -1 -13 -32 -27 -2 -20 -2 86 123 120 23 31 -4 95 -37 -1 -8 30 -7 50 9 8 62 42 60 64 19 64 77 -8 13 60 25 -2 -66 -11 57 -71 -4 -90 -29 54 61 62 13 -28 -33 -44 -30 -24 -4 -55 -29 -42 -8 -61 -36 35 21 106 20 -32 -1 -3 3 19 27 -37 35 -57 43 -30 -21 -13 -20 55 -118 -43 -32 -12 -16 34 -28 26 21 66 6 -17 4 -9 -109 -49 34 -123 -11 1 -25 17 33 29 -81 -2 47 27 3 15 10 41 -32 -12 10 -11 -40 9 71 -16 52 -1 29 -1 22 -85 0 43 57 -58 -41 -10 -68 10 15 -24 30 -33 37 35 -14 45 58 3 -39 -17 62 50 43 -90 17 -63 5 0 21 37 30 54 32 5 -3 60 -24 44 -100 -16 54 27 5 -20 -5 -89 69 78 -18 1 55 14 -46 26 -28 86 -68 -30 12 -3 22 -8 31 -8 -77 -12 6 -74 -34 76 -18 60 -22 -7 39 -7 -18 22 94 45 48 85 -11 -21 -33 -18 39 -83 -10 -10 -36 -16 44 -25 37 -4 37 1 27 -50 -25 23 7 3 28 98 8 22 29 22 -32 -54 -67 -15 -64 10 19 -12 16 54 21 -65 -34 -98 -14 -20 29 -21 63 -47 -29 51 72 -89 26 61 -113 13 -4 64 20 -30 7 -43 -3 -22 -104 5 94 51 -34 55 21 61 36 22 45 -15 -33 98 -6 -77 -18 -26 57 36 81 32 69 -45 23 65 -42 18 -8 -17 9 -41 -38 -14 -42 36 103 -37 64 -20 -31 -66 41 -14 15 17 71 -73 -59 48 -88 7 50 -37 12 -16 -64 -49 -91 58 113 -16 -55 -5 8 16 17 49 -15 -5 -12 -10 -4 22 61 -15 2 18 -69 19 85 13 39 -91 -34 17 -46 32 -103 12 25 -12 5 16 62 9 17 14 -12 -39 10 5 54 18 -6 -73 -3 7 19 5 57 48 24 -10 107 -6 51 17 20 -103 7 -34 68 6 22 21 53 -46 32 61 13 17 -44 -11 34 -46 122 -64 -48 4 -14 68 41 -25 -7 -39 -75 -9 40 -61 -2 3 23 9 7 -51 104 9 16 7 54 22 -29 14 60 -28 -103 3 -17 45 75 24 29 86 71 -55 -58 18 16 44 4 -43 -39 1 -49 -31 -10 45 5 120 -15 -85 8 27 -1 31 14 38 36 -32 10 14 -33 67 29 29 -32 91 20 71 -10 28 -17 -59 -54 14 -13 -72 14 14 18 -45 -6 45 -2 -31 -2 -63 -78 -6 -93 1 23 13 -4 -62 -19 66 50 35 -83 11 1 0 96 32 45 -73 80 -43 14 67 34 74 -11 -40 -48 -30 29 31 43 58 -59 56 65 -19 49 45 28 -18 12 -28 0 -18 -29 3 -73 -70 -11 26 20 -12 37 -23 37 -38 73 -37 6 -64 -2 -21 -53 40 -45 -3 12 -67 -44 12 -70 53 -21 -21 97 60 -113 104 37 126 -21 -3 -44 -46 55 -7 75 -58 13 35 18 93 47 -24 9 -122 17 50 -4 2 -22 67 70 68 -19 -65 5 45 -34 57 -43 39 -51 -79 -26 26 88 45 -24 60 32 33 28 57 6 25 70 -6 -67 -127 -12 -119 -11 63 2 14 -26 20 -59 52 -6 -56 -16 -30 36 12 16 -24 -18 41 44 72 -57 21 21 -41 -115 -43 -34 127 -40 1 51 -94 -7 -37 -21 -38 -1 -52 -29 -76 -30 35 77 -31 3 -34 11 -84 -27 17 6 66 16 -97 -70 28 -9 -18 -63 -102 10 58 88 -9 8 -49 -6 113 -31 -39 -7 92 99 37 -12 -2 -59 99 -21 -23 87 13 5 47 72 -18 -24 43 -45 23 -34 39 58 33 -19 62 46 -36 -34 58 -28 -29 -99 -20 -41 56 50 -50 66 26 24 -26 -6 34 53 14 49 -122 7 62 10 102 -22 31 77 -71 -26 -66 -32 26 72 14 62 116 -40 -55 17 54 28 20 -31 44 -92 13 -27 -6 58 38 45 -32 -11 24 12 -33 -72 -103 -13 10 52 59 0 26 51 60 -41 74 -29 18 39 31 -62 -1 -27 8 -25 48 19 17 -20 23 -41 32 -43 4 37 -45 11 -43 -2 19 -24 -40 8 -63 20 -105 23 -20 -13 43 27 -57 3 4 -15 -31 -127 -23 18 -55 -46 -72 18 -10 51 1 19 -61 -52 -19 -11 2 34 20 -45 -17 4 8 -4 -17 -43 30 16 -5 28 -1 -39 -77 83 37 43 -53 -32 1 -86 -3 -34 -43 -63 -22 21 -29 29 -24 -70 17 5 -53 -49 -53 -36 38 -26 29 13 -19 -50 -11 -109 13 16 3 5 13 -58 -41 -72 -63 29 10 -59 41 2 51 68 -11 -119 112 54 -34 -76 -50 -70 24 -15 9 -54 26 -28 -111 -24 -56 67 34 -12 40 -54 54 -36 -18 -41 59 -30 -7 0 30 -52 -17 -50 -6 17 -13 20 -25 -30 7 -78 10 6 35 -85 -12 16 -32 6 -58 -21 -43 -45 -23 -23 -21 -13 -14 -42 -42 -38 11 -60 -38 22 -49 20 32 -45 -10 -75 -22 -88 35 -13 33 11 -106 -40 -13 -29 -23 -44 9 -49 -26 6 -61 -44 -27 75 19 19 -56 29 -19 23 -19 -23 44 -22 42 -4 38 11 8 -61 39 -28 -19 14 20 22 53 42 -63 -12 39 2 75 42 32 -39 -26 40 -66 -47 -88 -61 42 -3 -60 -2 20 46 40 -61 78 7 -37 91 112 18 14 20 23 -15 -77 17 38 -11 42 127 74 27 36 -28 19 -55 17 5 17 27 40 -11 62 -35 18 -9 -13 -21 4 7 -15 -11 -48 -39 -4 -38 -1 26 9 -61 -9 16 1 -11 -36 63 -3 -35 -81 -54 21 -6 97 -36 -20 -14 -12 0 0 -7 14 -14 17 -12 -20 -26 -51 -37 -13 5 -10 -75 -1 41 52 -84 -20 42 -64 -58 -35 67 21 -17 28 -51 -45 -61 -47 101 63 -19 39 -64 -8 -70 -79 -5 50 20 -57 37 76 27 -51 35 -38 -15 54 -78 47 0 -25 93 9 13 -12 -34 100 -45 -87 84 42 -69 22 66 -22 7 41 -60 51 33 -10 -60 74 -5 81 40 -30 76 5 79 53 -37 -16 74 -5 -28 -55 21 -56 27 11 -93 38 2 59 3 -33 -8 55 111 -24 -23 6 8 28 4 -31 -127 -25 -7 23 3 25 46 48 -93 -93 -42 21 22 -27 4 -12 -51 42 -25 32 -39 70 1 -10 10 -8 77 -58 29 -44 27 -5 7 53 73 11 -46 -55 11 -34 19 44 -70 -45 40 82 47 17 -39 -79 -19 -29 7 44 26 -41 73 9 -104 7 -68 9 78 -52 -29 67 -36 45 3 43 32 37 66 4 26 -8 -10 -54 89 59 -4 54 75 22 -53 32 52 -59 -49 -47 14 67 71 15 32 4 124 -48 -4 59 40 53 20 64 -9 25 2 -4 16 22 -53 40 29 14 -44 25 -17 10 49 9 14 -43 -11 75 10 49 37 67 62 -6 8 -76 6 -18 -70 29 -4 -11 12 96 37 8 -27 -20 11 1 -15 -13 -44 35 12 -9 -20 63 32 54 -6 -2 22 -7 51 -69 6 62 3 -60 -25 40 -37 48 -6 -31 87 -6 15 -35 64 -5 21 5 1 -31 -18 48 22 12 53 -77 6 -24 21 -34 -119 31 60 -43 -44 16 47 -58 -35 -82 -68 -90 -44 6 70 -43 -9 5 16 27 -6 34 -10 24 -75 -25 -30 67 19 -10 0 -40 23 71 22 -6 47 22 76 3 40 -68 0 -30 102 12 17 114 -56 70 -18 49 30 3 62 -42 -21 -58 14 5 -102 3 -58 94 8 6 9 23 -41 -34 -10 -35 -57 -10 23 -23 11 23 1 8 -3 62 38 27 26 20 -4 7 -55 18 -20 -30 -69 3 -15 -14 -49 7 34 18 18 -29 -65 58 -49 11 75 -30 -16 25 -1 10 25 -44 -45 37 3 -12 16 22 57 54 46 -14 19 0 13 -62 -80 37 -24 -1 -17 22 -14 105 -21 -49 -46 7 -7 -1 -40 -33 -1 -14 1 73 7 19 -70 -71 -7 -9 57 -95 76 -8 -89 66 10 -15 33 -36 9 3 18 95 -22 19 35 38 38 21 -3 18 34 -6 87 11 -45 1 11 62 96 -80 -18 -11 49 4 -9 -51 -10 35 18 72 53 -68 35 90 28 32 -28 -71 -34 -10 -55 -35 2 -60 38 40 -42 -39 105 106 -114 -60 -19 50 6 45 11 -108 -13 13 -22 44 -28 -33 -128 -93 -42 -123 29 92 -99 81 31 68 -18 -7 2 86 15 15 8 3 62 91 14 42 -32 7 -58 50 -65 -64 71 69 -33 12 33 -11 37 122 28 -16 48 -23 33 -47 18 -20 -79 -55 -34 32 19 16 -23 -6 -9 15 -7 97 -22 47 -24 -15 11 -10 -50 -8 -4 12 23 62 20 -17 -50 35 27 -6 38 24 91 -32 77 -30 -27 -16 19 93 -8 7 38 35 39 7 17 48 109 73 53 -63 -42 -43 -121 -34 104 -19 13 39 -68 8 8 120 60 4 91 -48 34 -4 -21 -55 20 -14 60 -17 18 -4 -38 -56 -18 12 -6 60 -8 69 5 68 36 -4 -11 71 -44 -27 -18 47 37 -7 86 32 -59 -70 0 61 6 -33 8 -54 -29 6 -31 107 57 -65 -8 -75 -6 -53 -3 36 -26 -52 -53 -32 -15 51 -41 -6 -20 -25 5 -30 -8 26 -48 0 -24 32 77 53 42 -64 51 -51 -94 -5 -19 -35 -1 34 -57 -22 51 -4 -27 82 -63 28 17 18 70 16 -31 -1 -26 109 -19 2 4 -54 -29 -1 -18 -2 -18 90 29 -16 -103 52 -5 -27 91 104 -5 126 57 -16 64 -19 -16 85 42 4 69 16 -6 -46 -7 36 -4 -31 -4 36 33 -35 22 33 46 42 -17 25 -20 -38 18 -2 32 -14 -44 104 62 92 -27 -96 -28 -2 31 33 -2 -32 61 22 17 -2 -54 28 20 -14 -10 47 0 -12 -42 54 36 4 61 51 -31 6 -39 51 11 47 25 2 -115 -11 38 -44 -2 -20 34 0 25 14 40 -63 10 -13 -10 -85 73 -16 -19 -9 -12 0 11 -51 25 -71 33 -25 29 -83 4 -49 64 -66 -2 -44 6 -8 -27 37 19 32 -3 8 24 -16 -11 0 -9 11 -8 -18 0 -34 -1 -61 -31 -10 6 -64 58 -14 -28 13 -25 -5 -16 -22 40 -19 -32 10 11 21 38 -20 73 -7 22 25 -56 -15 -112 18 -24 14 8 27 -96 13 -22 53 -29 75 30 57 -5 -32 -11 -42 -32 16 10 36 71 80 85 -64 46 12 -26 79 31 -62 29 -55 14 90 0 37 14 92 8 8 -52 -13 26 17 -39 -23 1 -3 -123 -4 -65 68 -30 -18 -54 17 -16 -26 -19 41 -12 61 14 5 39 87 -36 -73 -44 50 -29 87 -48 15 37 -25 36 69 -27 -57 -23 28 -46 -9 -46 68 28 31 49 36 -58 -10 39 12 -14 -81 21 -4 -31 6 62 41 24 -6 49 -70 28 -69 4 -23 27 17 51 -12 20 -47 -1 13 -37 -60 -69 -15 14 19 3 12 -13 26 56 22 9 -44 29 62 79 10 38 -75 40 54 -40 38 9 6 38 57 34 -31 36 -88 53 17 -3 -108 -16 -14 16 6 -10 39 -27 0 76 -90 10 -8 -27 33 28 5 30 56 -7 -42 -89 24 -50 39 -61 -22 3 -51 19 -39 78 22 -12 -20 32 39 24 10 9 99 12 -68 8 23 -19 -14 -19 -30 -88 -25 48 28 -34 3 46 21 66 9 -39 -21 7 31 -98 28 35 -64 -69 26 -4 -51 8 48 58 8 -41 3 42 -15 54 67 16 -70 0 -5 20 8 76 7 -92 -32 -13 -5 81 -17 22 59 -12 -28 59 12 -14 57 18 -23 3 19 -13 -10 14 5 24 -52 -60 19 -35 31 -28 -87 -31 39 -2 41 -34 45 7 44 24 16 -41 124 -34 -24 -6 9 -43 -4 16 36 23 -16 50 -61 54 -38 84 15 -35 33 25 -30 37 1 -61 -82 -15 -24 46 70 -32 43 85 53 -11 -9 9 -23 7 28 65 21 -6 113 6 -55 11 60 21 -65 -21 -20 -35 -60 52 -40 28 -19 26 16 6 -4 -7 -47 13 -2 -7 9 -41 -21 7 36 49 23 -7 79 56 -59 -28 16 7 12 17 -5 18 -40 -51 8 97 -16 -58 -7 -58 20 8 4 -50 -32 39 -14 -25 -70 -16 -7 -24 -18 41 46 10 -1 -71 -60 -115 -67 5 -13 -29 -1 -60 -45 9 -24 16 32 -21 34 24 25 -7 60 13 41 -18 56 29 -54 -2 -28 -19 89 8 11 9 26 102 0 -50 78 -41 22 -4 -9 -38 -127 -14 -3 60 86 -20 -7 -53 -22 -126 -1 26 47 -1 8 67 8 -35 -37 -25 -28 -96 127 40 -22 3 -68 -6 -78 9 78 -31 -2 15 78 30 23 -32 -4 -30 -49 35 2 78 -25 -19 7 60 73 21 1 26 -47 6 41 -44 64 -17 -9 46 2 107 -36 36 -83 9 107 -63 37 37 -15 63 -11 -67 10 -65 101 -87 31 13 28 -8 10 61 -19 104 -37 -7 2 37 -22 -8 7 -23 22 -29 -50 35 -2 50 34 42 27 30 27 -1 -12 -55 24 8 -56 43 -73 -29 8 46 14 80 -36 -49 91 10 10 0 23 103 95 7 -13 23 4 73 11 -23 31 58 -3 -94 26 -17 76 38 -13 5 5 18 12 55 55 -22 -16 84 -30 17 46 20 55 -71 -18 60 12 43 -83 -39 65 77 56 27 76 77 -49 14 5 16 -113 -36 4 -31 24 8 14 -7 1 10 99 21 -50 29 -17 35 14 -76 80 15 -110 -47 -16 -7 -21 -11 50 -50 27 -11 -43 -8 36 83 -102 34 42 53 21 -26 23 -9 6 7 -28 -6 40 -66 16 -72 -25 38 -57 37 59 0 -4 7 -45 41 32 -49 -56 -75 73 -9 12 -3 30 4 -45 66 43 35 -51 -27 -32 11 11 -47 -40 33 -24 20 68 6 32 11 -32 -29 35 21 -35 20 -88 -64 3 -49 -2 -91 22 17 2 13 -37 -78 127 -12 11 -57 -2 73 -26 -17 -88 34 -24 24 -2 -31 -77 52 2 -14 -30 22 -25 2 -18 -3 -111 -45 -70 63 -5 -64 -16 -38 71 11 -17 8 -40 -128 18 -46 -7 21 50 39 -52 20 31 51 65 -7 54 16 27 -4 1 -35 72 0 44 -11 15 -3 16 97 29 28 22 17 -6 15 21 21 13 11 -8 -17 33 -12 -13 24 46 28 54 -37 -11 58 -13 -21 -26 -40 -54 -70 46 67 -3 -9 -78 58 26 8 44 -9 2 -24 -5 5 40 -39 -43 -96 -6 -70 -59 -43 24 36 4 -56 11 21 -46 6 19 -21 68 24 10 -31 -10 -1 -18 -30 9 1 -25 -76 81 -33 -3 -128 27 14 16 100 49 9 124 34 8 67 -27 14 25 7 -61 38 -6 6 -28 -16 -46 -2 40 -12 0 15 31 -108 48 -12 12 83 -29 45 35 -76 0 18 69 -28 -35 -6 42 0 17 -15 63 -18 55 -39 -45 -3 31 -14 -16 -61 -67 -49 -85 32 104 -6 43 60 4 -11 61 84 -6 -43 21 -23 -91 -25 -22 1 -56 28 -21 9 5 -10 -31 14 1 81 -23 50 47 41 27 -21 -25 -15 -45 52 -46 -22 -5 -25 -67 55 14 -39 -31 -27 -56 25 35 86 18 6 -26 9 -107 -27 -13 11 -56 42 -31 -67 16 28 31 13 8 -25 23 -22 24 -35 75 70 -8 9 -59 70 -28 84 -37 -83 81 13 -1 -71 33 8 -74 -7 64 39 -14 63 8 -17 -14 35 -95 21 70 -22 -52 49 83 94 10 9 25 65 -7 5 -90 15 50 30 15 26 1 -64 6 -75 14 -4 -13 -26 48 69 -24 54 -118 -33 -1 -20 -7 27 -96 -56 -7 -44 -43 56 17 44 -29 -39 20 24 -26 -67 33 124 -14 -35 31 -78 -96 -9 24 18 -2 6 -15 2 -17 52 -72 9 100 -16 46 48 85 91 -61 -21 27 -11 25 -75 34 -70 35 -7 -51 -48 18 70 -38 -45 16 23 -62 66 95 11 2 -36 -68 58 -61 -3 -106 -126 -49 -32 49 -11 71 -49 87 -36 -8 14 18 65 -17 79 24 -61 -20 42 11 35 42 4 116 10 54 68 -28 -31 77 -51 -14 11 -12 -20 -37 10 18 -14 -1 67 -1 -5 -63 20 23 75 59 -8 -40 6 -13 -10 42 25 31 -69 -123 0 66 42 -17 -69 -16 -35 -54 -5 20 12 8 14 -70 20 30 60 59 22 -96 -4 8 -82 -32 -43 13 -5 -7 31 -4 50 6 -63 103 -16 -15 -39 67 -25 -84 -76 -40 -14 27 12 25 -10 16 -33 11 31 53 -85 -19 79 -74 22 -3 43 -2 44 -4 47 45 30 12 118 127 45 -36 0 -12 1 -22 -48 -13 -11 -44 -73 26 14 79 30 21 -25 -10 -8 4 33 -35 -29 33 46 -8 -26 -19 25 -23 27 2 -56 -35 -50 -9 -67 -61 -40 5 48 81 -60 -35 5 19 -4 -8 38 67 73 15 -8 36 42 -24 -42 -32 -19 -28 15 77 -4 13 -43 46 -83 -3 -38 -2 -92 -73 -13 -68 1 -73 -37 11 -6 53 1 57 -30 -37 14 -40 5 -4 -83 23 -66 -63 18 -38 15 3 12 48 -5 -68 -3 33 36 38 -9 -9 5 1 24 11 -14 -31 -84 -18 21 -1 -56 -15 14 34 -29 -26 39 54 -44 26 -65 -22 39 -31 -38 67 10 -109 13 39 35 22 -54 -72 -1 -3 -11 -61 32 -32 -11 7 -12 -36 2 -27 -18 60 41 7 80 -5 -58 -21 12 -93 -6 -21 42 -31 6 12 -79 13 40 -41 5 -20 -53 11 27 -11 29 -71 -38 -70 84 -8 19 127 30 56 21 8 51 -23 17 2 -50 -2 51 -7 52 -24 -11 54 4 38 -29 -48 102 54 -43 -21 22 26 46 10 1 -99 -3 -88 -34 -66 -71 115 5 -54 43 50 38 13 -70 -65 123 -78 -1 -1 -8 -41 17 -22 -68 -12 -38 -46 27 -6 58 -24 5 19 9 7 -11 -9 48 90 -128 -19 -9 20 7 3 -20 7 -8 33 -77 -65 17 10 -3 -45 -74 1 61 -39 -14 23 -25 -60 -49 -45 113 10 -49 -46 -10 33 -2 24 77 -20 26 16 -67 75 -17 -41 15 56 93 34 45 -36 -39 -15 -16 78 8 1 88 -32 17 17 37 22 -20 22 78 -34 -30 38 53 66 -3 67 -19 14 23 3 0 49 -7 -15 -7 2 32 -53 4 -28 57 -27 4 -35 -20 -97 68 24 -31 -19 51 -29 27 65 67 9 -23 40 48 22 9 9 31 0 -70 -65 18 36 99 19 -56 22 42 -17 -27 39 -27 -4 59 65 47 -2 -118 18 76 67 2 57 -17 -16 45 -8 12 29 8 2 -60 3 -9 42 -106 1 -28 -21 45 5 -15 -26 -15 -10 6 -31 -54 8 -27 46 -45 -61 -36 31 -4 -24 -9 -15 -112 12 51 36 44 -61 37 -59 20 -61 38 -59 15 42 14 -11 -45 61 19 24 -63 -16 44 -63 59 -56 -13 -36 -43 30 -26 -29 97 1 -47 7 -30 29 -37 -12 35 89 55 28 -49 36 -24 53 -8 7 3 -45 -57 -1 47 -32 83 -2 71 90 -46 2 71 18 -4 -3 -59 22 121 1 10 -39 6 45 -20 29 -25 90 -41 -3 -18 34 7 -55 45 48 -68 -16 -73 -21 -21 66 -36 45 71 -11 64 59 -2 -73 44 -16 20 -88 -71 29 -29 75 -77 -2 -8 -78 -6 62 24 -48 -37 110 20 -36 68 -29 -36 -28 -53 21 25 -32 -31 13 -53 -5 -123 -39 17 -14 -101 -80 -31 -7 -24 40 9 46 0 65 46 -65 -7 -16 29 47 -17 -5 -56 13 -12 -12 6 44 1 -39 17 -85 59 -54 -26 4 4 -54 39 -52 -28 92 10 -32 -48 115 1 -113 68 127 -13 46 49 9 -39 0 30 126 49 -88 60 -36 1 20 32 -3 11 -10 -11 38 3 7 -11 -6 -9 -2 -6 32 93 4 27 -45 -7 25 21 -28 2 13 34 -31 -36 40 -7 47 -18 -78 -60 63 -100 -13 22 -24 -29 24 -39 17 -18 -6 11 24 -53 11 -53 -1 -3 -48 29 -11 -48 43 43 -126 69 16 43 16 27 14 44 5 66 -104 -120 0 -51 28 14 48 26 7 -78 -31 51 54 16 -16 -25 12 39 14 -15 8 -15 30 38 99 82 -6 23 -6 -29 -22 -1 -88 -58 31 -7 66 15 -1 90 39 -57 16 21 -53 -15 8 54 -18 47 -18 85 17 22 95 16 -9 84 -76 14 30 -74 -13 -80 -11 22 57 36 -20 0 -19 40 -68 49 12 8 36 47 36 18 -13 -27 44 13 77 9 35 33 -10 19 29 45 23 44 32 12 32 42 66 -44 68 63 5 42 28 10 -2 9 -26 25 -35 -73 56 13 6 -7 20 -5 0 4 13 49 -31 -4 18 -7 7 -13 -9 -10 9 -10 -2 9 -18 -12 25 14 5 14 10 -8 27 14 31 -3 0 -15 15 -23 -12 6 -37 20 0 -13 -13 -8 7 10 4 -18 23 2 -13 1 -5 4 10 4 -22 47 20 15 -39 -9 -14 -28 -6 -35 -19 4 -13 -2 13 -18 -35 -20 -16 -20 -13 -13 39 26 0 4 -46 -47 3 0 -26 12 -13 -1 -8 2 23 11 -23 114 96 0 -38 5 22 0 -22 54 -17 20 20 56 -13 41 30 -37 21 2 -20 -27 -31 17 3 -12 -23 25 -17 -31 55 4 -31 18 -64 -4 -11 -11 20 -32 -8 -1 22 -55 66 -3 -9 19 46 9 29 30 -13 15 -30 -33 7 22 -42 -12 29 -23 -30 27 -1 39 8 -26 -1 -8 -12 24 -39 32 -26 54 0 14 -20 37 -17 -24 1 -12 3 -30 -11 -10 25 -29 4 8 13 -6 -53 14 45 20 -29 -10 10 -17 -14 9 16 -16 46 -8 31 24 12 -5 6 13 -7 8 0 10 -18 -23 26 1 -18 -1 20 -14 32 8 -12 -5 -4 25 -12 -6 -46 -8 33 27 -16 -3 18 -26 22 -26 -6 5 25 -11 23 -14 20 -16 18 -18 -18 -26 -3 32 26 11 4 9 -25 27 -23 -29 -10 16 22 21 -13 -41 28 -24 -9 -6 -6 7 -14 4 -12 55 -9 28 4 -20 -6 1 -10 23 -18 26 -1 -16 17 -6 -13 -13 -47 -13 -11 30 -14 -28 26 16 -24 -8 6 13 -10 7 12 14 10 11 5 -26 -17 1 -6 -14 2 5 -14 -15 -25 -14 -7 1 39 18 14 0 -7 -19 21 13 12 0 -2 20 0 -4 7 -8 24 -5 40 -23 10 -4 24 -20 -8 1 13 -28 8 -29 4 -2 -15 -19 -17 -21 -16 19 11 -26 -22 1 24 15 29 24 14 23 -13 0 35 -8 24 8 18 3 -26 -5 7 -31 6 19 -13 -45 -7 6 20 32 7 74 59 -77 -5 51 11 -17 -2 -33 14 40 4 -24 -1 41 46 2 -13 -12 -35 42 19 -11 19 -47 -38 -13 20 -2 -1 -7 23 105 34 19 -11 -10 -33 -18 10 51 -9 42 -26 31 33 12 52 -18 0 4 -15 -47 -19 -35 5 -10 -19 -106 43 -21 39 -36 50 14 60 13 25 19 -15 -3 -26 11 25 -24 -29 -50 -28 3 -29 33 83 -25 50 41 -12 -14 33 -22 -21 16 3 -18 15 57 7 23 -5 53 -53 5 23 11 -7 -12 11 6 -23 -31 39 -15 24 -4 -29 -16 -56 18 -14 -5 22 14 7 -33 12 -23 21 -19 -8 0 32 32 7 -32 -13 46 -13 -8 51 19 50 -13 0 12 5 -13 0 33 30 2 33 3 -64 -17 -28 31 9 9 9 17 15 33 17 5 -5 8 -12 35 -7 27 35 -32 21 -60 26 -55 29 -16 51 -36 -23 13 -10 23 3 -20 -15 -14 -7 -3 0 -39 31 -21 -22 -32 -9 11 -30 4 -33 22 -9 -4 38 18 -11 34 -38 27 4 18 -2 17 -26 28 33 -35 30 -9 -33 11 -10 -1 14 1 -38 6 -7 26 4 -11 1 -12 -30 7 61 -11 -19 -12 14 7 44 25 46 14 40 31 -8 -10 -26 10 25 19 -51 11 15 9 -10 3 24 7 -23 -66 9 -9 -20 16 -14 6 -17 2 -4 -6 62 0 15 3 -16 7 25 38 -20 -41 19 -13 40 16 4 2 73 93 -24 -91 16 40 -30 54 -60 -48 3 -17 -59 -8 12 30 7 6 13 65 -5 25 4 18 37 4 -6 -27 32 -3 -24 -51 -38 30 -1 105 -40 -38 40 -19 41 40 -50 33 47 11 -32 53 -29 50 -20 -40 11 3 35 -11 4 -70 -32 -31 45 47 18 -6 7 -36 -71 10 68 -30 2 8 19 -33 -4 -45 14 2 -50 -15 -33 -23 -24 43 20 33 -29 -15 -8 4 21 -91 55 28 -1 -4 -5 -6 -36 60 6 45 19 -12 18 -38 1 -38 85 11 -35 43 59 -52 9 -62 69 28 58 97 -37 9 3 -61 69 -13 28 1 13 -18 -4 5 22 -4 -12 58 -18 16 16 38 -14 -60 -96 6 -28 -16 -32 -41 23 14 -15 44 -2 6 -16 6 22 64 -34 -11 57 -61 23 29 -51 -21 29 -60 -24 18 29 -26 41 43 -20 -45 -31 47 51 3 1 -3 28 6 5 24 14 4 -6 -15 -23 22 -30 -1 24 26 4 2 -47 54 34 -16 -11 12 20 25 -16 5 -9 -30 -17 43 6 11 7 -39 27 1 27 -12 -19 -28 16 18 -24 34 53 42 5 26 -19 25 -33 -20 4 -3 30 -49 -5 43 -41 43 84 22 -32 -17 10 29 23 -8 -33 -93 -25 12 -24 43 -29 17 10 27 16 -49 -10 -3 45 -29 57 31 -65 7 15 -21 -4 -27 25 17 1 -17 -20 28 -31 -22 -9 -27 -54 37 77 119 -2 -43 -2 28 -14 9 -8 -78 -20 -10 -66 1 29 -50 13 -17 -45 -7 17 64 23 37 21 -32 -16 45 12 -24 -9 -49 46 76 -23 0 -48 36 10 20 8 -44 -12 10 55 25 -29 -27 29 -22 16 18 -17 -49 22 -31 18 -6 -35 81 35 -53 55 -18 49 22 -3 67 2 -84 -6 -25 -4 6 30 -65 42 -83 -76 18 81 27 -13 12 48 43 -24 -21 21 2 52 78 -19 19 -42 -8 37 31 -6 -14 -46 10 49 -24 27 26 -1 -34 -17 50 -26 70 -68 18 -20 31 46 16 -2 42 10 -47 29 -29 25 46 31 -26 5 57 34 -1 -8 -11 -44 32 -7 -32 -56 -11 12 -12 4 4 43 24 53 -10 30 0 12 -1 -38 -8 -20 45 36 6 45 -25 -30 38 14 33 -27 14 9 29 -51 -39 56 -9 -35 32 13 38 -14 52 -7 -15 19 -60 -4 35 -39 46 32 12 11 18 -13 9 13 16 -26 35 29 -39 19 -25 -35 -42 -50 -57 -14 24 8 -2 21 -20 -14 -38 20 13 17 2 21 -8 -18 -26 2 -4 32 61 -23 26 -32 -20 11 -8 5 -18 42 -23 -24 12 1 -14 2 -6 17 -10 -26 13 -15 -10 20 0 8 -29 -6 -27 33 26 35 -21 27 -4 -18 -77 23 8 4 4 -15 -30 -6 24 1 34 8 -25 4 -10 -7 20 36 27 11 3 13 -12 -22 -28 -3 2 43 37 3 -32 14 -31 -7 -9 -40 9 27 -49 12 -7 -10 -47 43 -3 -55 -39 -40 54 -22 -25 54 -33 84 37 -42 3 1 17 -7 -45 -22 -17 -61 -25 10 -75 -66 16 -27 25 34 12 -12 -16 53 -15 -77 -62 -31 -28 -43 -41 -2 -81 -32 24 -13 -36 16 7 -12 44 19 16 -14 -20 3 -21 -12 -51 -4 -14 17 -47 -16 -29 8 13 -5 -4 -7 -49 23 28 2 -45 17 -57 35 -72 10 32 46 -12 32 18 -13 -1 22 -19 -3 -21 14 -2 39 30 -37 32 2 24 -31 31 3 -13 5 7 11 29 56 1 -44 -14 20 13 17 -22 25 56 -55 -31 44 -4 -24 -3 -31 25 -20 -11 -1 -22 -40 -19 -62 0 -30 40 -25 -31 6 -29 6 -3 8 3 15 -24 1 7 0 -82 40 -49 25 19 -2 32 -14 -47 0 -23 3 -31 35 -9 -17 -10 17 -18 2 36 2 1 14 1 15 -1 32 -4 -4 17 26 17 4 -21 18 -13 22 -15 28 44 4 3 25 -9 19 -19 -10 -17 7 -32 30 -18 6 -21 -49 -45 -3 28 -33 -7 4 -32 16 26 4 15 -16 1 -5 18 2 -15 -18 -7 -7 15 9 0 -28 -14 -7 -10 -13 -30 -17 -14 -3 17 -26 1 -29 7 -27 -34 -47 25 16 18 -42 6 -6 25 -13 -6 11 13 22 -18 10 21 -10 -17 -20 22 3 37 1 -23 14 21 11 -72 -1 48 30 -54 12 -83 -7 -31 -15 46 23 -26 -46 -52 29 -35 19 31 -6 23 2 -11 -47 37 60 -30 -36 -34 -36 30 16 42 -34 -24 -29 91 -22 35 13 -55 8 -12 21 -21 -12 -27 -37 -19 -77 -27 -23 28 -6 -10 42 -20 -25 41 45 -49 -38 32 -26 84 -49 1 -42 28 -7 -25 19 -36 3 -4 7 31 -12 -2 23 -21 -57 -39 43 -49 -16 61 -23 -34 15 -46 8 11 -27 54 36 24 26 77 -30 -66 -81 -9 53 18 23 33 -25 -93 -1 -22 39 -1 33 62 -4 68 -58 -19 4 56 15 33 -8 19 -13 -23 12 28 7 0 -81 17 29 7 77 -41 -17 19 -31 11 8 1 -6 -25 -51 -9 28 -4 -19 20 116 23 -25 9 3 -59 -51 -2 27 -2 72 50 -87 -2 18 -42 -7 -4 -6 -55 63 -44 24 12 32 -15 -101 28 -5 33 35 40 -14 -22 -2 -15 18 -39 -35 -63 -17 -15 23 -5 -47 44 25 17 -33 22 -1 -8 50 43 53 -9 -25 -3 -5 9 12 47 31 -12 -9 -19 15 19 -49 8 9 17 30 -2 38 32 25 15 -23 37 -31 12 20 -3 -9 -26 -51 20 5 34 -5 10 -44 -4 -13 -5 39 4 13 33 19 -5 -54 -20 -17 42 19 -48 -11 -12 17 -23 -37 37 43 -2 7 23 -7 16 6 -3 -7 -42 -8 -11 17 5 -8 -25 -14 -28 32 -5 -68 -21 -29 15 -8 -22 2 26 21 -17 29 15 34 44 10 -26 -29 18 -10 -25 -12 41 47 16 35 3 30 -12 -12 -4 50 0 -78 -11 -9 -21 3 34 7 56 13 -22 46 -3 -11 -11 -4 34 57 10 -34 3 -5 29 -27 -21 32 -13 0 -43 -20 -15 3 -10 22 21 -47 16 3 -27 -2 19 -32 40 -7 -29 -12 -41 -29 -23 24 6 -21 11 -44 0 -32 -29 -26 -30 49 3 -10 6 -31 33 -43 -27 26 -14 7 24 28 8 -1 -23 11 -7 -33 -28 -26 4 -37 -23 12 -15 -20 47 29 25 -31 22 -38 -27 -14 33 -10 -3 -4 15 -15 -23 -3 -2 7 -10 24 10 -13 -18 13 7 2 40 -37 -15 -22 -30 -15 48 9 12 26 -13 12 18 -29 2 21 -15 -68 12 26 -52 -3 4 21 58 -33 -21 -7 -13 -9 -10 -19 -17 -15 11 -34 -77 -50 -22 -18 -13 -8 30 38 -32 13 -51 -6 -4 29 32 -6 -28 -4 -13 -24 -30 17 29 44 16 -12 -17 -17 -3 16 -27 -46 -25 -6 0 -6 37 -44 -26 30 28 3 -3 -46 20 17 -37 20 -49 18 12 1 8 -32 -45 13 18 -29 20 -27 13 26 -14 20 19 24 27 -11 -25 2 -1 28 0 -7 -13 -12 26 25 -1 -29 13 37 -15 16 -1 -33 29 -6 13 10 -15 -29 -3 27 -8 22 -5 -5 1 24 4 34 25 -35 -24 -8 -30 -24 34 -24 -16 4 -31 36 -15 -32 -13 -22 8 -12 -81 23 21 -11 -13 -37 23 -2 -6 -8 -5 -13 45 -12 -30 1 9 -1 -12 36 5 -47 -20 28 -39 -7 52 7 -48 -11 -2 3 2 26 4 8 -38 20 64 -36 -14 -45 -45 16 36 20 -70 -18 -27 3 11 -9 -19 -14 -16 7 -27 6 -13 -29 -2 37 33 -23 -22 8 -28 -49 25 -21 10 48 5 26 -3 -38 26 11 4 0 -34 42 5 -6 -33 22 5 15 -10 -6 6 -8 13 -2 14 -35 15 -9 26 -43 -61 -32 -20 18 8 -12 -13 -62 15 15 -23 -30 -7 -5 -33 15 -3 -16 -36 22 51 5 -20 -41 -6 -10 2 -8 -3 -47 -36 -11 -1 -34 -16 2 -43 43 6 -1 -13 8 4 17 -32 8 17 14 -13 16 9 37 14 2 32 7 11 13 -2 -27 22 -39 -38 23 -5 -49 36 19 32 -34 8 -15 7 -20 -5 31 50 7 -10 -51 4 9 19 14 16 -3 -17 -23 -1 -11 -9 -24 2 -4 -34 36 -2 32 4 -2 -5 -17 -9 8 17 -41 -27 -9 -16 8 -7 -26 -17 13 -30 -20 -13 16 0 -14 3 -10 -12 -37 19 -6 -9 -23 10 -8 12 15 -18 8 1 -2 3 -10 -5 25 -9 2 24 -32 -27 24 -8 -14 -18 -40 2 -8 -24 -5 4 -13 3 -3 -3 -1 -13 34 -9 -13 12 -15 -10 1 -11 -3 34 26 14 -14 20 5 -8 16 28 6 -8 -21 12 -14 -22 0 29 57 8 15 -7 -12 18 1 -24 -35 -51 10 -11 -2 -47 16 38 18 47 -34 -45 4 16 -5 -14 12 30 16 -25 10 -15 -32 -35 69 25 -23 -1 -8 35 -27 -28 -5 44 30 -17 20 0 27 -3 -28 35 -69 4 32 2 -24 -5 -16 25 2 -41 -50 9 -18 57 -5 3 -52 -31 -22 17 17 4 13 11 68 2 -70 -4 24 -1 6 40 -7 -9 -12 56 -23 -40 -23 -18 -12 -6 47 9 22 36 12 12 23 8 -6 -23 -27 -13 -20 -38 3 17 20 17 -55 21 -32 -20 20 -13 11 35 -21 6 -3 18 -13 -17 8 17 8 -6 -1 -6 -10 32 11 -5 10 -31 2 -23 23 26 -45 2 -8 54 14 -12 -12 -6 26 -37 -17 30 2 -2 -19 3 28 -1 9 -37 70 -3 -6 12 -18 49 -19 -31 30 -6 -9 -14 -26 27 -47 21 -37 -30 4 -15 2 26 30 20 -13 32 0 -9 13 15 -20 -10 -37 -6 27 -22 -12 4 16 3 -11 -13 23 -17 17 -15 -43 -14 7 4 24 22 -2 10 -42 29 -18 7 38 28 6 -39 -13 -12 5 23 26 -13 -8 44 2 22 -32 -6 6 -27 24 -17 18 26 -34 20 -14 25 -12 0 -9 28 -28 16 -33 3 -8 23 -13 -16 -3 16 -19 12 28 7 8 -45 -19 -1 11 0 10 -16 -11 -17 2 36 3 -34 12 -3 -40 -22 21 7 26 -18 -15 27 -3 35 27 8 42 -29 18 27 -23 -37 -1 13 8 -22 -14 63 29 -2 18 2 1 -5 36 -14 43 -1 32 1 1 -7 -19 -40 8 -21 -17 -1 8 -15 -37 5 24 -35 27 9 45 -13 -33 -65 17 18 -14 21 -17 -14 -16 -30 51 1 -21 26 48 -26 -11 14 15 -68 26 25 -3 -9 14 8 -2 11 29 12 -16 17 27 25 35 10 22 -17 6 -13 -24 -5 19 20 -3 29 21 -6 16 -7 8 2 19 -20 9 -12 28 38 0 -6 -7 5 0 2 11 10 -15 -25 -28 2 -8 -13 4 5 -5 -37 -11 20 -26 3 -23 -34 -16 9 8 -4 -45 -1 -26 -18 16 -17 -22 8 -11 -17 29 11 -16 -5 34 8 -6 -30 -7 19 1 -17 -2 4 23 -16 9 0 -31 3 -1 -6 24 -34 -15 8 11 -9 13 -22 1 -7 19 -11 10 -18 5 8 20 22 -15 7 -4 19 -12 21 -5 14 23 29 -4 1 -2 -21 2 7 -1 -11 -2 22 -5 28 -6 -33 30 -40 6 -19 7 -8 -41 -15 2 -13 -24 12 -11 7 1 5 -16 3 -18 -8 27 31 23 39 11 -16 -1 -10 2 -30 -19 -22 7 -24 1 14 -5 -22 -7 18 21 27 8 2 -9 1 -2 5 8 -14 -18 5 -13 13 -11 3 -13 31 5 -12 31 -14 28 45 -14 23 -6 -22 9 9 38 -11 -3 -27 8 3 13 -9 -39 -4 -5 -14 6 -66 14 -17 8 26 19 -16 -18 -16 62 -12 15 39 26 7 -4 55 6 16 76 35 12 -24 81 0 59 30 -32 -17 14 55 -51 45 59 -20 -41 -28 0 2 -28 8 -36 19 -6 17 -25 -52 16 21 34 30 -7 -6 -2 0 -49 15 -40 76 -9 -89 18 -13 7 34 67 -19 22 -32 49 7 24 -2 -49 15 -39 -40 17 7 -9 34 -91 -37 -8 -51 -47 -62 -8 74 -41 -10 -8 9 -40 -19 -56 -52 22 11 -10 30 10 -4 37 -33 25 -23 22 67 63 -8 -11 31 17 -2 -42 34 -4 9 46 19 47 12 -12 68 -68 16 40 -35 11 -4 37 -53 32 20 -19 -33 39 23 -47 17 -35 14 4 -28 18 -27 32 -1 -27 -4 -55 -10 5 15 26 62 -81 1 -12 48 -22 14 -24 30 10 -8 18 1 -6 -122 5 -61 -26 -34 38 20 -36 -9 50 -33 -44 -30 -58 10 48 54 82 -14 31 -3 14 12 16 9 -26 -95 35 9 -7 -19 3 -24 18 11 22 36 3 -27 -47 33 36 -4 -14 27 -10 52 9 18 -43 1 35 -12 14 -9 -18 5 -26 -19 -23 12 -59 -12 -6 1 23 4 8 -21 -11 26 -24 -29 21 30 5 -9 -15 6 34 44 32 52 -4 54 -19 8 22 17 27 0 14 33 -31 -4 -2 -34 11 59 6 15 -37 24 -54 0 26 -31 -26 -13 9 -9 -6 34 4 -25 53 22 5 27 -2 10 -7 -4 41 -4 44 46 -15 -55 -32 -8 51 -17 -9 4 -21 29 6 17 26 -27 28 -23 -12 -28 -12 17 -6 40 -9 23 -44 36 21 21 22 24 12 25 -34 16 -4 4 33 60 -29 43 -11 3 -40 4 2 3 -38 -10 -38 19 3 59 12 18 2 56 23 61 -30 25 25 1 9 0 2 15 -26 60 25 17 -7 16 10 -9 -11 -22 -9 -10 -12 -11 -19 29 3 2 5 21 19 16 -31 -49 -24 7 24 73 -25 -40 2 -7 2 -29 -4 -49 -30 -14 -23 -2 -15 -12 22 -22 -6 3 -28 -34 -20 -33 -5 -40 -16 41 -23 -13 56 11 6 -22 -5 -6 -5 15 -3 -8 28 13 -16 32 -38 31 25 17 1 23 14 18 -12 30 28 -59 -52 28 -4 0 39 -17 45 -3 -16 1 29 -57 35 0 1 33 -17 -25 5 42 -7 -36 -8 13 -15 -28 -31 -43 34 -6 -21 -15 -11 -18 -6 9 10 -5 6 15 -16 -21 -12 22 -23 11 7 0 16 -25 -13 -5 -8 -7 -2 -23 29 45 13 -14 -20 21 -10 -18 19 5 -25 -35 -3 33 19 -3 21 -3 -6 4 -18 28 -12 -10 -14 -16 -18 -26 12 7 -7 4 -3 -5 47 -19 30 12 4 -14 -6 -2 9 -5 -17 -3 12 -23 -6 -1 -32 11 -15 2 19 21 -7 3 -15 -14 28 6 -21 22 16 -22 -15 25 -33 -37 -16 -9 -3 33 -24 66 -53 -9 -14 24 -11 -26 18 -34 -41 33 8 25 4 -20 -42 9 -9 -71 -7 -25 2 29 -28 -5 -28 -4 18 -46 -12 13 -41 32 -29 -43 -13 -75 -14 -29 79 -59 -30 11 -58 -30 17 3 14 25 42 44 13 -43 3 -21 -1 -17 -16 14 23 -31 -33 -32 -76 2 15 -45 -1 12 5 28 -46 -3 -19 -17 -23 3 39 0 34 20 -33 17 29 -3 55 -5 55 50 14 51 -21 -31 32 24 -40 -31 4 6 13 42 -6 14 32 15 12 -25 -18 -45 31 6 51 28 8 22 -6 -16 -13 7 33 -32 30 -31 -30 4 21 -17 43 2 0 -22 -45 -19 -3 0 -1 -42 3 -17 -13 26 -58 32 3 -18 3 4 21 0 27 -10 19 -11 -12 2 18 -6 -5 3 -26 8 19 9 -6 13 -7 -26 -17 -10 2 -37 10 -37 -10 13 -16 -12 -18 -15 -25 -2 0 8 -31 -9 10 19 -19 -2 -9 12 -23 8 3 14 15 16 18 -34 20 3 -27 2 36 16 14 23 2 5 15 21 21 -23 11 -30 -16 3 14 -8 14 -20 -25 5 3 -36 -25 12 16 27 -2 -38 -15 3 -17 14 -3 29 14 -22 11 -2 1 -40 7 6 12 9 -1 -2 -23 22 25 -1 -18 18 -14 -54 13 26 -13 17 -12 6 -32 9 21 0 3 -23 -1 19 2 -18 8 -27 5 15 -26 3 16 19 -49 -35 -67 -7 -75 6 13 -27 18 7 -24 14 41 -7 -98 41 -5 51 -7 -44 22 -35 -38 -43 65 21 -14 5 -89 9 -67 4 34 -10 42 -6 -45 12 -19 -60 6 -46 3 -13 -23 -92 10 -22 21 2 -55 19 -24 54 -51 -26 -57 38 -44 19 0 -55 -5 -48 -19 37 -89 7 -102 -36 -3 -7 -22 40 -29 47 56 -54 -12 9 -42 72 44 -57 14 -9 29 64 -45 98 -36 -9 59 12 19 0 -20 -10 7 37 -19 -32 -30 -41 90 27 23 -19 24 -6 20 -12 4 63 4 -26 21 -2 -47 42 -109 -12 -28 -8 -60 16 22 -48 21 11 -70 -43 -62 -28 35 40 -9 21 -4 -20 27 -20 -66 -51 -62 4 -2 13 11 -53 10 42 -62 20 -1 -51 -33 -11 41 -16 4 20 31 12 -22 23 20 14 -7 2 37 3 2 23 -33 -9 27 -3 -90 9 -15 29 15 -23 -2 -42 -26 -31 52 -74 -6 19 -33 10 45 24 -14 -6 -3 -27 8 77 6 -40 21 -33 1 -21 -26 3 2 18 13 -2 -31 -9 -5 9 8 2 16 33 9 -34 -14 -12 47 10 18 1 18 -2 -4 9 20 -12 15 -23 14 -4 -5 7 21 38 35 -2 7 8 3 -71 -27 13 10 -5 11 21 22 49 35 18 38 -25 14 20 -17 78 -14 -7 -8 6 -49 1 27 16 -37 -25 40 -13 21 -9 -16 7 10 -19 -9 17 -16 -2 28 -21 20 0 38 4 -6 36 73 100 1 -24 -2 -54 65 35 -2 -89 -3 19 66 13 30 37 22 23 12 42 13 60 -23 36 96 22 -17 -20 21 17 38 29 2 11 3 -26 -44 10 78 -77 23 -6 24 48 -1 -32 -104 51 -12 37 46 14 61 -13 14 56 23 -62 30 16 9 52 96 99 21 7 43 28 33 19 0 34 54 -25 -13 69 27 50 45 48 16 92 -17 124 53 10 -50 -30 4 42 34 29 -28 -9 -72 -49 24 1 12 19 3 -46 104 17 5 -16 -7 11 -9 21 -70 -15 -8 61 27 -27 36 -5 -17 -43 -51 -6 -5 33 42 18 -34 50 -4 -2 -5 -32 53 40 -12 51 29 48 -37 -17 9 -9 31 20 -24 33 -22 -19 9 11 -14 21 -8 94 -1 11 -39 29 14 -14 2 -18 3 42 -7 -61 72 13 37 -12 -38 28 5 -14 -45 19 84 -44 56 25 32 -41 -31 -18 27 7 -11 -22 8 5 34 1 -25 33 8 19 -5 4 48 -26 23 -12 47 15 -21 30 -4 -4 19 -38 40 -1 -32 22 -11 -22 -59 -30 4 30 9 28 29 6 40 -8 19 -14 -9 25 -2 38 4 4 0 7 34 -1 12 9 -4 -46 10 -17 14 -16 -21 1 3 12 8 27 -15 -1 25 -27 -4 31 24 5 -40 -14 27 -12 56 30 34 30 -2 11 -23 -21 -11 58 -32 51 1 -27 -6 -5 33 1 -48 2 -24 52 2 90 -65 -49 7 -18 -125 -59 38 -55 74 36 -3 -27 80 -6 -36 29 -38 -36 -51 26 7 21 0 65 -51 -2 -19 -36 7 1 3 -68 -1 -20 -7 120 -32 49 -128 -87 -60 -8 -34 -11 -13 -23 -9 31 31 3 -46 50 16 18 -48 4 36 -17 -15 -114 29 -24 106 -6 -65 -6 63 26 9 103 35 4 47 -8 17 -16 -123 -12 18 31 83 49 31 -48 17 -5 -69 13 49 20 -21 -67 -50 13 -32 13 15 11 -23 -41 52 7 -28 -3 10 44 38 48 -36 -72 -16 -1 28 10 -6 -3 -92 -25 -16 8 -70 -77 18 -3 -29 12 -47 -40 -28 -32 -7 24 -32 -20 6 53 16 22 -27 19 -24 28 38 -37 -6 -54 64 -25 -1 -50 -7 -20 -96 -21 48 30 34 -9 25 48 -6 33 0 -44 25 31 47 65 -50 -44 -17 -26 -26 31 44 -19 13 -4 -49 -23 -1 -33 -53 8 -4 -9 -4 21 -26 13 17 27 13 34 -38 -30 -27 32 -13 -7 46 2 20 -12 30 12 57 -40 23 53 -3 22 -39 23 15 -6 -9 37 -12 -21 2 34 14 -29 4 -1 -27 -42 56 5 15 -5 24 -15 31 31 -47 -10 -32 -10 10 2 -12 10 -8 33 -9 14 10 36 21 3 -20 15 -33 -17 -19 2 42 -7 11 16 6 42 -18 -34 -32 4 15 -11 12 7 43 5 23 11 -25 33 -13 -25 8 -15 -24 -3 17 -24 37 13 16 12 -4 -13 5 -35 -24 11 -29 1 7 32 1 20 20 26 6 -52 -5 -11 8 13 1 16 -18 27 -12 -23 -10 3 0 28 -2 16 -11 15 -26 23 9 -4 -19 -14 -5 11 42 34 -20 -19 -3 -26 -12 -10 -15 5 3 20 -15 -54 26 27 34 -44 7 37 8 -21 -7 8 -1 -3 -27 -23 29 16 -53 2 38 -23 -15 0 -15 -17 25 41 -21 -13 4 -12 -18 -14 21 20 15 -20 6 -21 19 40 23 18 16 -23 16 -33 6 -5 15 41 39 -41 -11 -12 -9 9 5 -10 -17 -10 -13 13 -26 -27 25 -18 17 -7 13 -8 17 5 25 -4 -35 -21 -11 14 10 18 -5 11 -44 6 -9 6 -35 38 -1 -2 42 -17 -17 4 -36 6 9 -33 4 15 33 -9 -30 4 13 17 -31 -7 16 12 13 -18 31 27 -28 -16 -17 27 -2 -5 -6 -16 -17 -1 6 -18 -3 -9 5 22 -32 -34 -31 16 0 -6 7 3 4 4 20 15 2 23 -7 12 -9 3 11 -7 29 -8 -28 2 34 -20 -6 -14 0 30 -24 -17 -26 -2 -11 12 -8 8 6 8 36 12 19 -10 7 -11 20 -23 0 15 1 20 -28 20 25 23 -42 26 16 -1 -19 -3 0 -16 9 -38 18 31 -9 26 -25 -7 3 0 37 26 21 -11 -11 18 -23 -11 -17 -12 -20 -31 13 -18 8 -38 2 3 -14 -26 -2 -8 52 41 -1 39 11 24 22 3 -23 -36 -4 4 23 26 -16 22 3 16 -17 -3 5 30 19 11 -6 10 76 -34 6 -17 13 -17 44 21 -17 -22 -19 9 27 -10 11 -36 32 -36 -11 -22 2 15 -21 35 -42 -3 -19 9 -54 -54 21 1 -40 19 -30 -47 28 45 -5 15 26 -1 22 -28 48 70 -34 29 -28 27 -1 4 -38 -33 -2 3 25 4 66 35 28 27 8 7 7 -3 19 3 -23 -21 -8 31 -13 -1 3 10 -7 -28 -2 -23 0 13 -25 10 13 -9 -25 -42 -21 -26 -19 5 6 6 16 9 5 -53 37 8 16 -50 35 -14 -25 38 -24 -12 -41 -16 8 21 -4 19 -9 -6 -7 17 31 57 -60 25 -32 -11 19 4 2 41 -6 20 -8 -27 29 5 -10 -9 -42 -5 15 -5 24 -13 -11 32 26 21 4 31 -53 -16 -8 -10 -14 26 24 15 -34 29 -8 13 -3 8 -9 -3 -17 -23 -8 27 11 -3 23 7 10 8 4 -4 -14 -11 10 -5 10 -2 -27 -23 -23 -34 -4 1 14 27 -32 -15 8 -34 -33 18 18 16 14 -7 -5 -6 16 14 30 5 -27 17 -8 7 -25 10 23 -39 -5 -3 -19 16 2 -5 20 22 -4 22 -17 31 28 -4 9 -10 11 -13 -31 42 -15 -10 19 -2 26 28 36 9 27 20 4 -14 13 -5 -20 -11 -29 25 -14 21 16 -26 -4 20 19 12 -67 -9 -7 -46 -10 -9 -47 -33 -1 -88 -45 10 -9 -75 -24 15 -11 -22 29 26 40 -32 62 -13 -11 -46 -15 -3 -40 18 -48 29 3 4 -59 -25 -29 -56 -104 -69 -24 -35 -41 37 -75 -28 -71 50 -43 5 -6 47 -25 24 -33 -3 -26 -11 -15 -76 8 -70 34 -34 -72 27 38 -61 -5 -42 -33 -51 -1 -47 -47 5 -32 -39 -41 -54 -58 -76 -48 -36 48 -44 30 15 38 -41 41 3 -42 42 44 -66 23 -51 -15 29 -5 23 5 9 -14 -25 -54 -45 -23 -17 20 45 -25 -46 6 12 64 10 17 96 -33 -31 20 -36 -9 -26 18 -5 41 -45 -23 -83 20 -2 32 -12 -98 7 20 -4 -28 78 -17 -72 4 -6 47 4 -19 -13 13 -8 -42 -13 47 5 -29 35 -38 -26 -56 -29 12 -8 -18 30 13 2 -28 -5 -35 -45 -9 -1 23 -54 4 10 23 22 53 -3 -28 -16 -29 17 -26 7 18 -22 -51 -44 0 -11 -25 -17 -13 11 -5 -20 -37 1 -13 73 27 -27 3 7 4 2 15 5 27 18 11 28 -32 24 4 -38 17 8 48 23 54 11 8 -33 9 -3 -3 33 17 21 41 -41 -15 -39 -29 8 17 24 -17 43 -64 0 -5 2 11 -23 -2 -8 -13 21 5 -29 -19 2 -21 21 9 75 -26 13 32 -10 -34 33 -33 32 -21 23 -23 -31 -18 15 30 -20 -10 13 -2 33 2 40 -41 32 1 29 -89 -37 114 59 -5 18 42 117 74 -81 -2 -40 -32 24 -51 -20 -31 -59 -14 -60 -93 -29 -93 -63 -33 -26 -62 62 62 3 63 -7 -70 32 13 -49 -1 -59 -90 35 -6 63 2 -7 -8 9 -37 -24 -60 -71 -4 -38 97 3 78 -13 45 -3 -92 -35 -49 -29 -7 -9 -124 -1 -9 -14 33 -65 29 -61 -59 -51 47 -114 -40 -7 -125 -10 -8 -81 -36 -29 -63 -2 -18 -32 29 67 23 16 33 55 -32 -78 47 -44 66 84 35 13 -48 47 37 46 -29 62 66 -20 -26 -20 -76 -34 41 43 -16 0 70 1 -4 -62 93 -13 44 -1 16 -17 -31 -60 113 6 49 -50 65 -66 -87 -34 -22 9 33 12 -10 -2 59 51 25 28 56 -16 -17 64 -47 -10 16 0 59 -13 -39 6 -8 -45 26 26 -24 60 2 -24 30 14 -92 -86 13 -1 20 91 62 -18 51 27 82 -46 33 -38 90 -35 34 3 -8 62 6 -6 11 3 -33 -19 -32 1 40 25 41 -5 27 -48 -23 -1 -24 0 24 3 -23 31 -11 39 24 -36 25 -41 57 27 -18 -24 9 10 36 -34 -36 -76 32 -19 27 30 22 23 -36 24 -6 2 -12 2 -30 25 13 -20 -13 12 -14 46 36 22 -26 26 22 34 -1 12 -2 -46 -8 27 -49 30 33 -7 -29 -10 -27 -36 -21 23 15 14 57 -21 23 13 14 -29 -16 29 -4 47 7 -17 29 19 3 -35 -31 3 40 12 8 1 75 -2 -68 61 9 59 17 93 18 8 -7 6 21 103 -37 32 20 73 23 79 -39 -10 -2 31 56 -29 -28 19 26 26 -50 0 85 26 46 -2 -7 -66 25 111 -1 -14 -8 35 43 8 -54 -29 -53 -25 8 12 65 31 30 26 -4 113 48 -27 -39 92 8 -7 10 -19 -43 -37 -29 76 28 -16 -9 66 42 45 50 36 -56 5 -10 -45 51 57 -43 13 35 37 -36 -3 2 71 17 -88 19 -65 -71 -59 47 -75 54 42 36 -17 5 -19 108 43 -35 -27 -73 47 74 -125 6 -30 97 -40 -37 13 19 28 22 10 -41 2 76 72 42 101 14 51 29 -20 -30 18 -22 20 -43 -2 -37 7 -107 111 -40 40 45 22 48 45 -70 -35 64 52 30 6 32 -91 35 -46 45 -59 -37 -32 4 83 71 24 -25 -82 -81 48 45 13 10 44 -86 69 54 -47 -9 -54 21 -97 -6 -17 -33 58 10 36 21 -7 -6 20 19 -29 -37 -26 80 33 -23 -6 27 -22 13 27 -25 -27 -26 62 -4 26 -16 0 -18 -2 26 -11 43 44 -40 -22 -53 -1 17 -5 22 2 7 73 5 1 -55 -15 -23 -3 -18 7 2 -20 -79 -105 19 -45 44 3 -20 -5 24 -1 34 -88 -57 -7 -49 -32 -21 -31 -34 29 33 6 -47 -27 20 -99 -28 -28 9 -34 -34 48 -46 29 2 -23 -19 -55 -10 13 1 -9 -37 18 -2 8 -8 3 -30 17 -22 -75 -2 -19 -54 -10 -5 5 7 -18 -75 -37 -62 38 8 1 -8 46 0 12 -15 -17 8 21 -37 -4 -31 41 -2 -49 -47 -5 -31 -15 -4 -7 16 125 -43 -104 -20 -47 17 -72 79 19 -99 -51 32 50 -105 -28 -78 -19 29 65 -20 21 -30 -3 15 -62 34 5 12 54 5 -91 2 12 0 -47 -83 -1 24 0 -97 85 1 -6 43 -33 -3 32 39 -4 41 -51 55 30 96 8 57 -40 -46 0 -45 39 -40 45 36 41 37 43 15 -88 -28 76 31 -48 91 -100 8 -45 28 6 32 40 -16 0 -27 -30 -42 75 -23 -43 22 -39 -14 27 -15 -8 35 -10 6 -28 47 33 42 22 -2 27 -3 102 22 -34 32 -1 77 23 43 22 49 -34 41 1 86 53 113 5 88 23 -59 29 3 18 15 39 3 10 4 -11 23 35 17 1 1 -24 11 -43 80 -46 -48 -52 -34 5 -24 -29 -35 10 34 -57 27 7 -18 -35 -8 18 -36 -20 15 -19 -4 24 25 72 -33 -77 50 -39 -8 -27 -26 -7 36 18 28 -42 -17 -34 44 25 -28 44 12 30 -39 -1 -48 -25 -18 7 -49 -23 45 -6 22 -19 -22 -11 60 -22 24 15 41 -31 25 38 22 -55 -15 51 -41 33 30 -9 -29 -16 -19 -12 -24 8 40 50 33 -27 -39 14 -64 -37 0 -23 -18 27 23 -3 -8 0 -14 -37 28 16 -3 -93 -15 -53 -58 13 1 -1 2 22 -29 3 36 23 22 16 30 26 -15 -71 -43 -20 32 -7 -15 28 -26 12 22 28 12 45 -38 5 39 -47 -52 -43 16 25 -57 36 -43 -23 63 -9 -59 21 31 41 62 -24 -8 -16 8 29 1 -23 8 30 19 -1 30 -15 46 -4 -65 88 -31 -17 -30 10 -13 17 -36 -12 -16 -58 26 -24 -2 19 -48 -31 -12 -6 -58 -86 -81 33 -49 47 -19 14 23 55 10 10 -3 -31 30 -20 -13 23 32 43 -32 -24 57 59 17 21 -24 37 -1 -54 44 -9 -20 -89 0 3 22 2 -9 33 -61 -1 -10 -29 -16 14 18 9 94 -21 -39 47 -7 17 -17 -11 11 -56 19 -24 6 23 -23 10 -1 -9 0 -87 -19 -3 16 -13 -9 -63 -48 40 23 -10 7 79 16 -35 46 -1 45 36 -7 -21 -14 57 -2 15 -4 4 32 -31 26 49 32 -22 26 -26 -32 0 -2 -19 -3 21 5 -13 -8 -23 -5 -32 13 21 27 1 5 30 -8 -2 4 -22 26 59 7 9 -9 -1 3 26 43 -33 -36 21 -36 -5 8 -49 -39 -44 17 6 -56 -23 0 16 -21 9 12 3 -30 -34 -6 21 -5 6 36 17 19 10 -18 -35 -34 -10 17 -5 -6 -13 -1 14 -32 8 -26 7 -33 9 -36 16 32 0 -23 23 -9 -14 -24 30 -2 -15 -17 19 -8 -30 -8 8 -14 36 3 19 -9 15 -85 -8 99 -42 36 7 -42 -1 -26 30 58 71 -2 -52 2 13 1 -38 97 -20 -33 -12 86 14 24 -52 52 5 -47 23 -37 17 -16 -35 -56 -98 -2 21 34 107 -63 37 5 -94 -12 110 -16 -24 -53 47 -16 4 20 34 -55 -31 82 16 -36 -14 21 79 30 17 8 19 -68 48 1 -1 -25 -7 -33 -16 44 43 -12 60 91 -34 -62 -33 16 -1 27 28 -38 39 -36 38 -26 -32 -21 -4 -23 53 -73 -19 20 -15 107 2 4 -19 3 39 -27 -52 -24 13 -37 -18 -25 17 26 -7 3 19 29 -76 -2 -50 -18 -10 48 98 29 27 62 13 -49 39 5 -2 46 -12 43 -28 28 34 50 55 -7 -17 32 -42 -38 -31 -15 -14 -7 28 78 57 -26 1 46 -26 -6 12 51 45 -35 44 26 55 20 13 13 2 -52 3 20 14 -2 127 -31 -82 14 -38 68 9 -22 23 -26 25 -43 -47 -15 -13 -1 -61 3 -31 40 15 -16 69 14 25 29 -13 19 -10 34 -8 -17 34 -9 31 -31 -38 4 56 -26 3 -24 -6 -43 -15 17 -2 -2 -12 41 -13 -30 -12 -29 20 0 38 0 38 18 -6 -52 19 29 -13 35 -12 5 17 14 32 76 1 20 -36 -21 -42 -35 -14 -9 26 6 -19 -28 -6 37 10 -47 39 -59 -27 6 24 -17 -32 7 44 -27 15 28 4 1 5 20 -1 -4 24 -72 41 30 25 54 -22 -52 42 10 -61 25 9 -7 49 -34 40 -4 -63 -11 17 0 -23 -41 -22 79 -5 -96 19 -34 -124 6 52 -21 45 6 -4 43 10 35 -34 -6 36 -57 -18 -9 -27 14 68 6 -46 10 6 -3 10 5 -34 -18 -31 33 17 31 22 115 -71 -54 20 54 -42 8 -53 -23 -7 -6 -21 35 -8 20 45 20 30 -24 75 -35 -45 -91 -59 -46 38 26 45 27 86 -74 59 46 -35 29 -18 -20 16 -40 -11 25 40 40 -78 16 9 -32 -14 34 -41 -26 -31 32 -10 -14 -52 14 -40 -27 -78 -49 28 -24 -8 -39 53 15 -21 -44 9 12 -30 3 43 -47 13 4 38 48 -42 -31 35 41 10 -34 17 36 7 29 9 68 -4 1 8 -37 89 7 7 -55 -24 -43 -29 -27 -23 -39 30 42 -59 -58 95 -2 -32 32 -23 -46 28 88 76 -41 7 -3 -7 60 42 11 -36 -34 34 -44 -38 -71 -6 -3 0 -31 29 -6 -29 -2 27 -2 10 10 7 23 21 10 -2 28 -21 7 8 18 9 46 23 -11 -21 -12 -6 -35 -15 -18 32 22 14 73 28 12 51 22 36 -44 14 15 -5 25 2 -12 28 30 2 -24 -13 42 -9 -14 41 -5 17 -22 40 38 17 -20 15 7 15 5 10 -20 8 -41 11 -45 -7 27 18 -17 52 12 -45 -9 16 21 -34 -23 11 0 -16 -5 -52 -6 3 19 77 -21 35 40 57 29 28 7 61 70 -12 -53 -20 -38 46 13 -36 -22 -4 20 -28 49 63 -14 5 15 -43 -22 35 -12 -58 -39 25 36 31 22 2 27 -11 17 -5 85 -15 -55 19 16 -27 21 62 -18 -25 26 -5 13 21 77 59 -37 -10 9 35 38 47 -7 2 -45 0 9 17 30 19 -12 21 -49 74 60 120 9 -16 112 60 64 16 92 19 -5 42 -2 26 22 -70 -45 0 -1 51 -24 -2 27 -4 -69 56 55 -26 33 -28 -38 13 -34 -12 92 -103 52 -16 -31 -32 22 -12 37 43 -49 -23 -16 20 -30 21 -11 -27 -29 -30 -34 -31 -20 -18 -18 -8 14 4 -25 -34 45 9 -22 29 -16 18 15 -34 37 -2 38 -1 -25 -5 0 30 22 -19 1 38 1 33 -25 -3 13 4 20 -41 -10 8 -2 -14 18 -33 -35 24 33 -4 2 29 54 4 13 4 7 -15 -8 -39 21 37 -31 -17 -19 -18 -27 53 38 20 13 3 3 9 12 7 32 26 -26 -15 30 15 43 -13 -47 5 25 37 -17 -17 -1 20 -12 -11 -9 -9 -20 0 -4 8 44 10 1 36 16 -4 -5 -13 29 24 -24 -18 -45 38 24 13 -33 -28 -4 46 -38 12 9 15 -6 7 10 -5 21 -9 2 10 12 2 26 33 -9 -17 6 16 6 18 33 14 -42 9 41 -48 -19 -36 -56 -8 2 -22 28 26 -31 30 -19 26 10 -39 -6 25 18 81 63 20 -23 35 36 38 53 -20 -6 64 19 16 22 39 82 -122 -30 57 24 -20 8 74 -9 16 -1 24 -11 37 -10 10 33 -4 15 98 -12 -17 28 16 16 81 -8 -1 50 4 13 -21 -12 90 7 7 64 -38 3 32 125 -4 -65 -19 -27 68 -34 -10 102 -30 46 47 10 10 -30 -10 64 48 -38 6 -12 -41 33 38 -62 22 -49 48 15 34 111 -27 27 37 -10 34 -2 -9 -53 0 -13 89 49 3 -83 -10 -4 -47 1 40 25 -79 84 -39 42 40 31 32 -57 50 -7 -30 -36 -15 -6 52 -44 -35 17 -2 -19 59 -68 -17 -52 11 24 4 -14 -22 22 10 11 -37 24 -43 35 114 -38 63 -5 47 -3 -37 -4 -32 63 -7 8 28 32 45 -37 31 -3 48 23 -25 30 -1 69 -40 -52 -40 9 -4 19 0 41 -73 37 -10 -34 13 29 2 33 -34 20 9 11 -2 -6 4 18 -14 3 26 5 -29 40 3 10 4 0 32 -24 2 22 -12 -5 49 -2 -4 4 -11 -3 5 12 16 23 5 -14 10 3 13 13 4 -24 -41 -3 17 -3 -6 29 31 -6 -16 0 -1 0 -43 -11 4 -45 24 -32 22 25 -4 3 -19 -3 -73 15 -19 -1 17 4 35 36 8 31 19 -7 7 -30 -9 -3 23 27 28 -32 -49 23 -13 -34 -22 -46 -5 3 -52 -21 4 7 3 -34 40 -2 -4 7 -59 11 34 1 -7 -73 -20 19 75 45 -27 -27 0 66 -7 20 0 47 -33 38 -50 57 -4 -34 -26 5 44 -38 80 69 12 -6 -6 47 91 58 69 -62 24 23 -26 -16 64 -27 59 62 86 75 -10 -23 12 -19 100 26 67 -14 -22 40 -12 58 127 12 30 -3 -1 5 17 91 -27 -17 46 39 -34 -8 59 33 -9 96 53 60 31 108 22 9 -6 19 74 75 -7 9 38 10 -30 -4 -49 -18 -78 49 15 40 -52 -66 -87 -10 -61 69 -5 51 -20 -28 61 -27 -23 41 -42 -14 4 13 -32 19 -40 -5 -91 -100 41 26 -54 19 -48 -9 34 -2 -7 -10 -3 50 -32 -15 -26 38 15 37 12 -16 -44 19 5 -5 -4 -5 62 -51 37 -8 104 13 42 21 56 28 -111 -6 -5 18 -12 32 32 -12 -41 18 -22 5 2 15 27 -27 -1 63 46 7 -17 -64 9 -7 21 4 -58 -18 2 -48 62 -2 0 -24 -11 -31 18 -5 48 43 3 4 31 -18 -33 14 -10 -19 49 -40 -25 22 -27 -47 -19 2 20 59 -17 -28 -14 -14 33 -29 39 16 -59 -47 21 34 28 -16 -53 -19 -24 13 -34 -79 -10 12 1 -1 5 28 -39 -20 0 -7 -16 12 -10 23 1 14 -45 -18 -31 -5 -2 16 8 -53 -38 15 29 -16 7 38 1 17 -17 20 -4 25 13 45 -6 20 -12 32 6 -13 -15 15 -23 11 24 3 -36 -16 -9 -8 -4 104 61 3 -8 -77 12 16 -29 61 -16 32 -55 -11 -25 -56 -30 -60 6 -44 -48 -53 -17 -9 -6 -11 4 4 -39 29 14 2 4 38 18 33 79 26 -11 -31 6 36 23 33 -76 -78 -24 -21 67 12 19 -74 39 71 -7 -35 -4 13 42 45 -6 6 -39 -29 -43 25 -66 16 -13 55 11 18 22 -8 13 -41 -28 6 23 18 -61 41 -67 -45 -53 -13 -56 -77 27 -37 -7 -27 22 -60 -14 42 -2 -7 -2 -102 -3 -91 -8 27 10 41 12 -35 20 24 0 68 -92 -43 5 -1 -36 -97 -40 -27 -50 -28 1 1 -53 -27 12 87 26 37 -12 81 -34 9 -32 -8 38 -36 7 15 47 -15 -15 -24 2 -7 11 -18 13 69 16 30 77 -43 -49 -29 9 2 -70 -50 4 1 -32 -29 -17 39 28 -74 -12 28 25 -56 -42 57 81 13 15 32 4 -19 14 -37 -68 -56 44 -49 53 -10 -8 2 21 -74 4 62 18 -23 14 19 -19 -13 -6 -38 18 -4 0 9 9 20 -19 3 10 -35 3 -9 12 -10 31 -3 -23 1 -16 14 -30 33 20 -28 2 -9 23 27 27 37 -18 1 -18 22 -8 33 48 32 8 40 31 28 10 -44 56 15 -15 2 -23 -10 21 24 -7 57 54 -9 -39 -8 28 -26 27 -12 -35 9 -17 -11 15 -14 22 29 -6 -49 -31 -12 19 -21 76 17 -15 -13 69 15 -29 12 -7 61 -6 23 25 14 -81 -15 -61 63 -68 10 -25 -2 -63 31 19 -16 68 37 -52 79 -22 -49 28 -44 -18 37 28 86 76 88 89 85 31 42 71 -16 117 -99 9 -65 -21 40 22 21 94 -126 124 -8 28 -51 50 29 -57 13 13 -67 -13 -11 24 -40 10 15 -44 -48 -18 24 37 -37 108 -36 -78 63 25 11 50 62 123 6 62 57 48 20 35 11 38 59 -36 -3 -95 -24 22 35 -81 74 -44 19 -5 -30 -30 -22 -63 -25 -11 -17 -57 96 5 -52 -13 -5 39 -20 104 -48 -72 3 27 12 -95 -2 -35 6 30 -80 -18 -15 -3 8 -33 -54 -53 -6 49 -17 31 31 89 -18 -7 -3 37 -37 15 -8 -61 85 -34 -23 40 -25 3 34 0 -28 -12 -14 10 -4 0 -16 -15 26 29 1 63 4 -44 -40 -25 63 -1 -7 19 -8 35 -67 -13 -13 39 76 -22 -82 20 10 -11 54 -45 119 26 -28 10 -10 -4 12 -22 -37 -8 57 9 2 -49 -31 -7 71 35 22 6 14 -3 11 -2 42 47 6 96 -33 66 -28 20 22 32 9 2 77 -26 -8 31 -25 13 -9 1 10 -5 -8 31 -17 -19 -71 22 -3 38 11 24 -4 -7 46 -36 -17 5 -19 9 15 -47 -18 -15 20 -23 -42 -6 16 -74 33 -18 29 -28 8 82 -10 0 31 5 -33 57 2 -35 -14 21 5 40 14 -28 -72 -21 6 -14 38 6 84 15 63 3 46 -33 39 -50 -44 -29 127 58 -14 -4 20 -9 -24 10 18 14 16 47 -29 36 8 38 -8 3 -9 44 -4 -91 -9 -34 -8 -28 -44 -9 75 10 -47 9 39 104 10 -33 -117 -17 31 81 127 13 -27 -19 62 27 54 33 -85 17 22 23 40 -5 5 -29 -20 -39 -10 -42 -24 -45 55 36 14 -25 47 51 26 -10 11 -33 24 19 55 31 29 25 -9 -50 -49 18 -14 41 19 -11 -36 -47 -46 -8 -15 41 47 -4 12 20 -38 23 6 -18 23 1 14 22 -33 40 -19 62 -35 -32 59 60 21 -24 25 72 -8 -25 -32 -9 -36 -96 -40 -41 35 77 35 65 -5 -19 -50 -7 -1 -31 9 -13 19 22 -30 -51 29 34 -65 21 -23 -38 10 38 -51 -3 -7 -29 -89 -36 33 8 -22 -35 21 -3 37 -1 -47 12 -32 -53 13 -63 -43 -43 36 13 6 32 -22 -97 45 -20 -19 -64 34 -25 -45 23 12 -12 32 -13 4 14 8 27 40 20 7 25 4 21 3 18 12 14 2 2 20 -5 4 4 -21 5 25 -14 -26 -21 19 23 30 3 -5 -9 -26 7 -12 -7 -21 41 0 -5 -51 -14 0 17 18 -13 5 -12 18 -25 -41 48 3 2 -22 1 15 0 46 32 -40 17 11 32 18 -3 -60 55 -52 -1 -7 -9 -4 -5 -55 23 13 22 11 32 10 36 23 10 -16 -36 -16 -17 49 44 65 -41 27 34 63 1 -48 15 8 -11 7 5 56 -30 -50 65 31 32 35 -24 -14 56 19 30 5 60 -55 67 93 2 -76 8 60 -34 -9 -61 31 66 -65 60 -1 10 -23 30 -50 -27 -18 -76 57 -29 -29 -23 -28 51 -59 -21 -21 54 48 30 69 -20 63 -28 6 -30 -13 -13 14 64 22 21 14 -37 55 -14 -38 -18 -41 2 -30 13 -42 53 -36 -41 -23 15 -15 31 15 33 21 23 13 14 60 -26 -28 30 54 8 -9 -27 -9 64 32 13 -20 -27 -7 83 -48 -12 0 -18 25 34 -15 -21 15 -20 -31 58 -41 56 17 13 -27 19 -8 -51 2 25 -12 -57 -18 -1 -14 21 66 -39 33 -6 5 59 39 17 41 0 -12 22 24 18 32 45 67 6 23 -13 -43 -46 -14 -29 69 32 27 -67 5 -24 3 37 -23 31 -15 127 -2 3 -55 -41 13 2 65 5 -47 -14 44 -1 -44 15 -30 -37 -105 -1 -25 -21 5 1 40 -10 28 53 -9 10 -24 -17 -3 -37 -30 28 9 -25 0 12 -14 39 -20 -12 24 -21 16 3 -31 -41 17 14 -16 -17 4 8 11 31 51 52 16 -1 6 -6 -14 -39 -17 45 -22 36 -34 8 54 14 -13 14 34 34 -9 33 -17 10 24 10 30 -23 -20 -12 -30 37 32 15 -57 8 15 -48 9 15 14 -16 -19 17 25 19 -7 14 59 15 -24 30 25 -59 15 23 67 -35 26 31 -46 41 33 4 -48 35 42 12 29 37 -56 -21 -31 -74 -76 37 -64 68 7 41 -45 60 21 43 -36 24 8 16 -15 -7 28 26 21 -36 127 12 49 -16 13 28 -2 -6 -4 -88 62 -26 72 -23 -5 48 41 2 -38 116 76 29 40 -34 42 -49 29 -9 -56 49 24 59 5 74 57 -19 21 48 41 -4 -45 54 33 -4 13 -9 -10 -77 8 50 -2 -17 -28 43 16 -14 -13 -9 -7 0 -14 0 -15 9 53 8 -33 6 41 -97 -10 -19 -68 2 -32 71 40 5 15 45 44 63 -41 -75 43 26 51 -26 28 32 -29 6 32 2 20 -28 81 8 -40 2 30 -13 -24 14 51 -4 -49 -44 9 15 -16 -95 -6 29 -23 38 -6 -64 7 -25 9 -3 32 76 37 -4 -41 43 0 -1 25 -22 33 -9 35 -36 59 9 69 15 -3 42 24 1 0 -3 111 -33 6 -36 -42 -41 0 34 -10 -11 4 30 38 -7 30 -5 9 -39 25 -10 30 -16 -15 20 16 5 -9 11 -29 -26 21 32 -28 42 -22 -39 -41 3 1 68 -3 21 0 24 14 5 39 3 -50 -11 -59 -19 6 34 -8 -15 -7 -2 -54 11 -11 2 -37 -6 -20 7 18 38 -25 -13 -31 -7 -14 20 -33 -7 -17 -11 3 -19 14 -10 -32 -2 -2 -103 -24 -22 -31 15 19 -38 16 -8 -8 12 18 -43 -13 -28 -14 17 1 -14 72 61 -98 -4 -2 50 36 -49 9 -48 17 20 -21 38 10 -46 5 11 -48 -18 13 -20 -52 -13 -49 21 -27 39 36 68 35 -22 -14 21 -38 -2 18 -17 19 -13 -22 29 25 15 -13 4 11 -11 -31 41 60 2 36 -60 13 -28 7 5 -7 -36 10 -58 1 14 -45 59 120 62 39 40 29 77 -32 -42 26 47 32 51 21 -34 -20 56 35 19 -14 14 21 31 2 45 115 18 2 13 16 -72 -15 34 -1 9 -1 -29 -59 -46 45 65 -23 39 -59 -25 -47 -5 -4 -23 60 -14 -4 32 31 -2 -14 -18 -3 12 -18 -15 -17 -1 15 8 51 19 -4 -28 18 -34 18 -60 17 48 63 3 -23 -32 -56 -6 -24 14 -2 -5 -62 7 70 23 -14 -38 52 -56 37 63 -11 18 56 0 10 28 35 54 -20 7 -35 -26 12 -14 78 -41 -1 -15 40 -75 -15 26 15 37 10 20 101 -5 -45 -11 13 -17 -44 13 2 9 -20 17 -11 -4 15 -3 12 -35 -12 -16 -17 7 19 -22 -5 -18 9 2 -32 -4 -24 48 25 -16 11 33 -12 -32 -20 -24 0 -15 44 -22 -14 -10 38 56 -8 -28 -30 8 1 -18 -14 16 30 25 -52 -30 13 16 22 31 -38 12 18 -41 -15 25 -3 25 5 11 -36 63 9 15 19 6 15 3 -16 -18 -24 3 19 -13 -4 -19 -6 -15 19 21 24 -28 12 -6 -9 7 36 -3 43 50 3 55 67 11 94 8 23 -10 -6 82 105 27 -4 57 112 1 20 82 127 103 25 70 124 65 1 94 -51 46 -14 21 31 71 5 48 40 -13 62 21 45 102 4 -25 25 15 -67 56 17 124 35 93 -9 89 64 50 24 18 -19 79 15 117 50 20 61 -24 106 24 47 -6 -15 70 37 36 -6 5 35 6 85 1 -26 12 23 -64 38 102 78 8 -25 -48 92 92 66 -84 0 -65 0 -9 -16 7 -3 9 -15 -53 12 -77 23 -10 26 -17 -3 37 32 21 -43 26 37 20 23 -39 7 16 5 49 -16 34 49 48 20 35 22 1 7 -6 7 34 41 -57 -1 -18 7 16 24 8 -2 34 -7 -11 17 -33 2 13 59 17 -6 83 13 10 6 2 -3 9 48 -20 49 -9 19 -1 56 97 46 3 4 26 -25 -84 11 -25 8 -12 -44 34 -8 29 -12 -42 35 -11 74 42 1 -41 8 -55 -18 -12 15 10 -13 9 27 -22 -15 -15 26 -1 13 9 -15 5 36 5 -51 -20 -11 26 31 22 10 -31 36 22 5 9 -24 9 -21 -19 -19 17 16 -2 43 -14 32 9 -6 -5 40 22 -34 -9 36 -17 13 6 -23 -21 -24 -30 -19 -2 -29 -43 -58 -15 -18 -22 10 -10 16 20 11 45 3 -12 -13 9 20 -11 4 -5 15 42 -20 -10 -41 44 -38 -8 15 11 -10 -20 -9 -14 -3 -5 25 -104 -54 -15 104 -14 49 5 -3 4 56 -33 -53 -41 64 2 4 -50 26 -5 71 -26 11 27 -28 -43 10 13 -79 -41 -32 117 48 10 -25 -35 77 -2 13 -14 72 4 4 8 2 -25 20 18 2 63 80 92 -39 1 -41 33 57 -23 -74 31 32 54 3 2 36 -51 31 -21 32 42 -2 79 94 37 -72 -8 66 -18 14 -10 -8 35 -56 45 1 -18 91 -9 15 40 8 12 43 41 -30 30 -10 -61 16 -24 43 5 31 -37 46 -19 23 -31 42 -58 13 33 31 19 60 50 -31 -42 21 17 -39 -11 -8 -28 -13 36 -30 7 5 -15 20 -40 -4 -39 80 -33 25 0 -18 -23 35 -9 4 15 15 28 3 -16 9 -53 -57 -54 -56 -4 -14 31 56 35 14 6 19 45 78 18 60 4 -11 47 -25 55 36 8 35 41 10 -36 -35 18 4 -7 62 -5 62 -56 -73 32 -40 -34 -30 11 -2 5 14 13 23 -15 14 -32 -39 0 28 2 -22 11 -20 -11 -17 8 12 9 -18 38 -14 12 -9 24 -28 17 -57 37 -7 16 60 24 -5 35 -5 0 -40 -47 0 -23 -29 -14 52 -36 1 22 -70 -10 18 -9 4 -33 10 20 24 16 5 52 32 -35 -40 -16 4 13 29 26 8 -9 29 -60 20 -39 57 17 13 -30 32 45 -50 4 31 -26 33 3 19 6 8 -26 -30 -22 -26 -21 -38 17 -13 9 31 4 47 -11 55 77 22 6 27 19 35 41 -26 -14 19 -27 27 -103 -29 -52 39 -28 -12 4 -39 62 7 28 38 37 56 41 65 40 4 107 15 1 -24 33 -52 -14 43 31 -7 11 -108 53 -28 -39 14 -25 -38 3 45 35 -4 -24 82 3 -76 74 0 55 22 12 -7 76 44 6 43 32 3 -63 -23 19 47 46 -27 2 -23 45 81 79 53 24 -36 -51 -91 -3 22 73 23 -19 4 -46 13 39 21 -16 -32 20 -25 -51 72 32 20 15 -20 20 -19 -44 -60 -19 3 -11 37 18 35 44 -41 -10 -19 2 44 60 -39 15 -72 36 -5 18 -24 13 -29 -4 22 -22 4 -11 17 -81 57 37 -40 9 -10 -32 -43 37 -51 -6 21 61 -13 -4 33 -2 39 -40 -26 -25 -35 -23 -46 -45 12 26 11 36 20 18 47 -25 45 -15 3 -7 9 -41 19 34 20 36 2 52 2 7 38 72 8 -21 17 -63 46 10 -27 20 2 25 23 29 8 -37 -19 -39 11 -2 -21 19 -37 1 1 -25 52 -4 41 -20 -14 -31 -1 7 -23 7 -37 -19 31 -24 7 5 0 14 -1 -6 -17 34 13 11 15 43 32 -12 27 -7 -2 -8 -6 -25 30 23 -13 -3 -5 -28 -49 5 -39 18 -7 -23 18 -45 29 -12 23 -26 -28 16 20 39 -2 34 -13 38 36 0 -44 9 -33 -37 5 9 -16 -24 0 30 49 47 -54 41 3 16 -2 52 -46 5 17 40 -43 80 93 -19 72 -34 -38 17 -25 -61 -13 17 34 -87 28 108 68 23 -24 97 -11 23 -14 -27 28 12 5 55 -20 7 19 2 49 20 4 71 -19 -49 39 47 -42 11 5 -1 -8 -21 35 33 15 42 40 2 12 47 0 35 33 -27 -28 29 15 -80 7 -37 51 41 -32 -15 61 -13 9 26 -89 12 -5 -34 -26 -54 59 -57 67 -25 48 74 -29 82 -1 -4 47 -35 46 -18 -79 -55 -30 31 30 5 47 -59 -10 -7 -56 58 -12 -13 -19 -68 8 -36 7 -59 12 9 -57 10 9 -13 11 53 -39 51 4 34 -119 -16 -26 -41 6 -36 52 1 2 -4 -60 10 -55 28 -17 -14 26 7 -43 4 -35 -41 -18 59 59 -2 -46 -57 -33 34 11 -12 26 -3 -3 -14 -59 -43 38 107 39 22 -45 1 42 -74 -1 15 30 -25 -38 48 50 42 22 28 -31 3 -32 -4 21 -45 -6 14 3 -52 41 42 8 -38 -1 -36 -10 23 -3 3 -2 3 9 -33 -5 -10 3 -7 18 -13 2 28 -14 11 -15 -38 14 -4 -3 20 -7 4 7 -28 40 0 -9 1 -6 -4 -6 -24 -32 -5 35 -21 45 -26 1 28 15 56 -36 -17 12 -18 -30 -71 5 25 -22 -26 27 -3 4 -10 19 26 -5 -24 9 53 20 5 -17 0 -7 -29 2 42 9 8 56 24 17 -23 25 3 -1 -28 -22 -87 25 -10 55 33 -48 50 -32 -59 -125 42 -71 7 77 -23 -54 7 -51 -3 -31 -50 -5 -16 49 -27 40 22 -2 -56 33 4 9 47 4 47 -73 54 89 -17 65 -38 57 -11 -20 -4 27 -52 -72 0 4 -1 -38 26 0 -56 -13 -8 -65 -4 28 -24 12 13 -47 4 21 -36 46 -18 31 21 -1 -7 15 32 -9 20 8 -11 102 12 52 -24 34 -74 13 -37 51 18 20 -24 -51 -25 3 -67 -4 -55 -8 10 -14 7 -21 23 85 -50 -31 -16 7 -33 20 -22 -1 47 13 -71 -15 -33 -29 42 36 50 28 47 23 37 -30 -19 -29 -59 -103 27 -7 26 -8 32 12 13 -32 -25 28 -22 25 29 40 89 47 -27 -41 -19 -28 48 23 -79 7 62 39 -120 -21 -49 -31 57 63 -21 -17 11 -8 -19 36 2 -41 39 76 33 -53 3 -6 -7 -19 17 27 43 -31 17 -74 -22 32 106 -30 -22 34 -30 62 31 49 6 31 30 -5 52 -28 -7 21 17 -26 13 21 -32 -7 11 -22 20 1 -15 6 -14 15 -65 -13 -61 -17 -25 9 -20 45 -1 -15 -33 -13 -2 -9 14 25 20 -7 11 -26 -35 1 -16 12 -5 39 -28 72 -6 -16 4 -1 -2 -10 4 37 20 -8 6 -24 8 14 23 24 -9 43 -15 -12 9 -28 36 -8 20 21 45 -16 2 12 39 -13 33 16 -42 -3 -40 -34 -32 -5 -56 -52 12 -8 42 -80 3 -15 -11 4 -14 -41 -3 -16 -86 -46 25 -66 -72 56 18 34 -11 -23 12 -78 21 27 34 24 -43 -21 60 -10 -48 -2 -31 27 -6 28 24 39 18 0 -12 38 -28 -30 -24 -27 -12 69 35 -5 36 14 9 80 12 -91 -16 72 23 54 -31 -55 -30 -44 -7 -73 0 25 -29 -10 39 -2 68 -13 2 24 -8 40 -14 4 -10 -48 -1 18 17 -11 -10 -32 35 -42 -6 -31 8 -9 47 -15 19 5 23 6 18 -4 -6 39 27 9 -19 8 44 -12 -2 -36 -50 61 15 36 65 -65 -21 34 -50 -19 -58 -73 29 -34 55 17 8 73 -11 -39 14 20 13 -1 22 42 -34 11 -25 -1 14 34 32 -34 -24 72 9 -3 20 -3 -43 -64 39 -21 -13 27 86 -22 6 -29 -43 33 -8 -2 92 -11 -42 32 -24 122 51 -21 -58 12 21 24 16 21 -20 58 46 -1 -16 -35 -15 23 3 -42 18 -20 -34 2 21 62 -18 29 70 39 6 21 0 47 -8 -40 25 -41 -20 23 -49 -25 -12 3 29 29 -26 -37 -23 -17 -70 64 -39 -15 20 7 21 -16 55 -11 18 -15 7 13 -17 24 40 23 1 17 8 -3 38 20 42 17 57 -39 -4 18 -6 15 -12 22 12 -19 20 48 4 -32 23 53 19 24 7 -36 -6 53 2 39 14 24 35 -24 -17 36 -47 46 -39 -19 48 -64 18 0 47 37 43 32 -57 -9 -27 -61 -32 2 52 38 9 65 6 23 -59 -23 64 10 -20 13 -42 -32 31 -6 -45 30 15 18 -12 31 7 -17 26 32 56 -18 43 51 72 20 4 35 56 37 1 -36 8 13 16 -10 -5 -73 -51 9 -60 -74 17 29 -3 -26 5 -6 6 -22 44 14 79 -33 31 36 49 79 67 36 -19 70 -5 27 -14 -41 -11 43 54 48 64 26 2 42 -43 37 -6 42 7 -14 -28 -2 -6 -16 47 60 55 -25 -11 12 33 12 -31 15 -22 -3 -35 -64 60 52 -36 -17 -46 15 61 -18 11 1 17 46 -25 -71 1 -44 0 11 -27 80 15 3 10 -34 3 -19 -34 4 -35 10 -41 66 -41 4 13 -94 39 33 -4 -19 -2 -7 1 -40 -10 25 -41 43 -16 -60 17 12 -20 -36 52 -1 -22 38 -11 36 4 39 17 -16 8 -29 26 -34 -28 -22 -22 -7 33 22 28 46 21 7 39 30 20 37 3 -3 3 -13 19 -12 -23 62 14 -23 33 -25 18 8 46 -28 -2 -11 23 -1 -33 24 -13 -14 -8 -11 -19 4 0 -62 22 -12 41 10 -6 23 -35 -6 -4 -25 2 22 -3 -33 5 -6 3 4 -6 11 -9 -18 33 -9 6 22 -47 -9 0 7 26 6 12 -34 -19 23 -15 -5 17 -33 3 -33 3 24 -2 -34 -10 4 -5 41 10 19 -24 -19 10 20 14 30 17 1 4 -34 -24 40 36 -6 -29 -33 1 18 30 40 -3 -1 -13 -19 5 -26 45 -30 -1 -82 34 -19 83 -48 74 33 -16 -27 49 29 20 -42 56 -37 -27 65 18 -29 23 24 47 -43 2 10 26 -4 52 -76 73 -2 -52 42 28 37 58 22 2 -11 42 36 -13 38 -27 72 -19 -12 -42 45 -22 64 20 -68 61 21 -30 76 -32 6 90 -15 12 -23 -40 41 35 -25 42 27 112 -28 -5 -124 -31 60 -23 79 -48 42 -39 -49 110 18 50 -1 -13 -31 -3 35 -36 -55 -22 -14 -56 -99 39 -55 65 -63 -32 -9 66 -57 -6 62 62 18 97 -22 22 109 -17 13 -3 28 39 -12 37 43 -43 -62 -11 19 30 -23 -24 -3 46 87 -19 7 1 33 32 -41 9 -49 80 -44 -27 -46 25 -41 2 -47 24 5 48 5 -36 -10 -77 80 15 79 -69 -8 11 -7 59 33 12 -61 15 -31 97 82 34 -18 -23 11 -37 -34 -13 11 -73 -7 10 -22 -14 -2 2 -11 -12 -1 21 15 4 51 -17 -47 35 4 10 31 7 -8 -14 -9 18 -14 4 -21 -28 -12 -15 0 31 -5 12 -11 -6 18 9 -25 -38 -48 -10 15 9 -57 1 16 -9 -40 7 7 3 -30 -14 -7 31 59 -16 9 27 -1 0 23 11 13 -40 -19 -20 27 -61 3 -20 8 9 3 -11 18 -15 -26 -57 38 24 31 1 10 11 7 -17 2 -16 10 3 6 -23 29 39 16 8 30 -21 49 -67 -6 31 -9 -22 3 34 -30 -15 57 3 -40 19 2 11 -39 -3 -13 3 58 37 -18 -7 -16 93 48 34 9 23 40 20 20 27 38 -27 -57 21 11 -44 -22 -61 22 4 -3 -12 -10 -33 28 -32 77 75 68 17 3 -22 41 -23 5 29 39 19 24 28 21 67 27 2 46 57 64 -48 19 17 9 -16 29 -4 -18 -40 -4 38 -94 44 -27 -29 29 4 -21 -22 11 -14 -30 -14 -46 -2 0 -71 -26 40 15 53 -8 -87 33 -45 37 57 -27 0 13 -18 -23 -56 -50 -55 60 -33 2 54 22 -11 -31 -72 -47 34 26 -9 17 42 30 -48 -1 -2 40 54 -27 15 -44 41 23 10 -1 -50 15 58 59 56 14 39 19 41 123 14 -40 13 -36 34 29 -32 -11 -51 45 -14 -78 -45 22 2 29 -96 -14 15 89 16 11 9 -13 -45 65 12 5 -49 11 -23 -8 -28 -70 20 -21 -39 62 2 -26 27 -19 52 -8 -13 -7 -3 4 -23 23 6 10 15 -24 -43 -6 -49 -7 17 -28 21 -15 48 1 -29 -32 1 2 18 -2 -18 18 -8 -21 62 -19 27 -39 6 -38 26 14 16 19 11 7 5 14 -11 110 -6 -34 16 -16 -25 56 10 6 -4 30 -5 -3 -10 29 45 39 -7 30 -33 -36 39 -1 43 -24 34 42 -8 3 19 -14 16 17 3 -8 5 -34 18 -17 19 65 -15 -71 7 14 -36 -61 -2 -45 39 33 -49 8 -13 35 -36 0 2 60 -30 114 19 -28 39 -73 18 32 -21 -22 33 -37 58 72 21 -9 -25 -16 8 1 -11 13 19 58 -5 17 -61 -9 6 -31 10 -4 46 -54 -21 37 35 -57 62 44 -20 65 23 -31 31 37 -27 -18 64 -47 104 41 22 -6 -10 1 -18 71 -48 3 -10 -57 40 -4 -17 -11 40 -32 32 -26 40 -5 -9 -54 -63 29 14 -71 41 -24 -62 66 1 -50 -5 -7 -12 22 -42 31 3 -26 51 -83 66 15 7 27 24 -14 9 -18 -5 -17 4 5 31 -38 37 32 -3 -2 12 62 -17 17 -11 -20 14 67 75 3 -11 36 58 13 -78 20 8 -30 -25 -79 -11 18 29 20 126 -7 -10 3 53 -4 4 21 5 35 -102 0 41 -39 8 23 12 -63 30 -35 -29 -78 28 9 -23 -45 33 32 16 -46 12 7 -50 -9 -44 19 73 24 31 -15 38 6 -9 -31 3 -9 -39 26 23 41 8 27 -1 -19 33 2 -31 15 -20 -7 45 10 52 -59 23 7 10 -10 45 -34 24 47 16 -38 10 34 -10 -9 -30 33 -8 23 1 37 -22 -11 -1 -30 37 -47 27 -6 -6 -22 42 1 -21 -46 47 3 -17 28 59 1 3 32 -39 -31 -64 -12 39 23 4 -21 -13 7 13 25 -18 0 -18 20 14 -8 40 31 -111 -57 6 25 -14 21 -22 45 11 84 7 3 -61 -21 8 32 -20 28 -35 10 -21 62 -35 22 21 -6 -22 12 -35 61 16 30 48 17 75 15 22 3 55 30 -12 -60 -15 -16 -26 -10 -3 -2 -25 17 56 7 40 -65 -45 20 76 -26 35 -1 -20 6 15 76 -13 9 8 28 62 -8 17 24 46 17 -3 -8 -44 0 52 1 24 -11 5 -12 8 80 27 25 37 32 55 -12 49 63 37 -7 -41 27 -4 71 -50 -6 -13 7 41 67 12 55 6 -19 14 -25 -2 25 10 -21 -25 -1 0 -65 20 -15 -10 38 -57 -4 34 10 -2 31 -13 48 -3 -26 105 9 16 -18 -22 -31 -35 -12 -14 -43 -3 25 52 -7 23 39 -9 89 -47 43 -3 -44 -9 39 2 -26 70 18 30 48 8 17 4 -31 -20 20 18 -14 19 27 40 16 46 19 1 -30 -68 84 57 -66 35 -14 31 -50 9 -43 -71 -31 54 20 6 27 10 -29 -17 -11 18 -33 10 9 -3 31 -10 24 4 6 16 36 9 16 -28 1 -41 8 -17 -7 42 -17 -2 -14 -12 8 -4 47 -35 21 -16 -28 16 10 -30 20 8 6 32 6 -9 -9 -17 -4 11 -24 14 7 5 30 16 -3 37 23 57 33 23 -5 5 -15 35 23 -8 1 7 -16 -6 20 -85 -21 -44 5 -41 39 13 -7 -29 -36 24 -2 -29 1 28 -45 6 -12 36 -7 33 -30 -1 -22 -5 17 -2 56 39 23 18 15 -37 -5 -35 25 -5 5 -45 54 44 -17 -7 54 -17 -13 1 -75 -21 38 22 -30 -10 57 -45 -7 -9 -7 -33 -85 22 -3 -20 -23 45 9 8 -9 68 8 33 -29 -11 17 -24 42 -9 36 -42 22 4 8 51 57 31 -2 13 -12 14 25 1 47 -4 29 39 -17 7 11 -6 -29 -39 0 -5 5 11 -11 -7 -29 18 16 -27 -14 31 -9 -12 -31 36 -27 9 -6 -10 -18 20 8 57 21 11 -6 -2 -19 0 -11 -46 61 31 9 1 7 -12 -10 4 -46 -10 -10 13 27 -2 -7 17 29 -45 -9 -26 -16 45 -18 -33 -16 39 -25 -26 50 19 25 33 23 47 27 61 6 10 31 2 -11 -37 -4 -12 47 -5 -39 -9 -58 -4 38 -4 -46 10 -74 13 14 1 -17 32 8 24 6 -9 -36 37 45 -9 -32 0 45 55 1 -10 17 43 42 18 50 89 5 36 67 2 -26 -6 -47 -21 0 44 -6 26 -7 24 -9 -4 1 8 0 -11 68 -3 0 6 13 7 21 -15 -25 10 -27 14 15 0 -30 2 -30 -1 55 -18 7 2 48 52 2 -29 2 6 3 -16 -10 -26 14 19 24 14 -28 -15 -15 -7 6 -36 7 11 -2 -5 37 -4 20 1 -63 -9 -30 54 -3 27 32 29 32 -5 -23 -22 -23 -5 -52 -42 16 -5 -4 19 34 7 -3 8 17 -12 37 16 -6 31 -42 -14 -52 -10 16 -49 32 -24 2 4 36 37 -50 32 -13 -35 11 37 -51 -23 22 -63 -25 23 19 32 0 10 -10 -11 -4 -28 22 69 38 -6 57 -16 7 91 98 -6 29 40 56 30 20 -20 -67 8 -5 -26 22 59 -71 21 16 91 17 88 -24 69 -43 -21 -64 69 -78 31 -32 38 -61 -30 24 75 61 -20 -5 -5 -1 -28 56 20 -31 11 -41 20 4 1 51 50 -20 -29 49 10 4 28 9 17 55 -45 19 8 -24 27 68 -10 -20 -58 -41 34 -14 20 -62 16 -35 13 -17 11 -42 34 -47 11 -6 21 -38 27 -24 -31 41 48 -75 41 0 -82 -3 -73 50 25 -51 47 -27 -21 -17 52 -8 -20 13 47 43 -2 58 -32 83 -13 2 -42 -65 119 9 -59 -78 28 -28 -20 28 18 -126 -58 10 46 52 -7 40 -29 63 -44 -6 -13 -28 52 25 -8 25 -19 -56 -6 -34 75 42 27 -14 -48 -43 -19 47 0 15 20 -25 11 37 -1 -32 -22 30 47 -26 11 21 -3 -6 22 14 1 0 -12 -9 22 -14 -15 -6 3 5 17 -2 13 -29 -9 20 23 -5 -36 13 -19 39 11 16 -20 12 4 6 5 -4 13 -31 4 9 25 2 -4 21 -7 -19 -26 30 3 -27 -1 5 6 18 41 59 -13 4 -34 32 21 -4 -6 32 2 -44 -38 -37 -2 -15 22 29 8 -17 4 -6 1 -10 5 17 -37 22 -23 70 25 -30 -15 -40 26 23 -8 54 30 31 -90 73 3 -26 16 5 -76 -21 -7 45 23 20 -11 -69 38 -85 84 -87 10 -23 80 5 9 -45 -64 -24 -104 -28 -22 -83 -12 27 96 -46 -48 -55 -51 60 9 1 -15 -8 16 -66 -20 99 68 4 -12 78 4 65 -27 -24 -40 50 -123 42 -6 -46 -29 59 -49 58 -34 44 -3 120 -14 -59 -92 -123 -11 10 47 47 -20 64 -13 -8 102 27 -13 53 -8 3 -7 -27 25 -4 30 30 -5 -41 24 45 -21 -53 -123 2 32 29 16 41 40 61 9 -7 10 51 -45 -29 10 50 26 28 39 33 -33 33 -27 45 10 -37 24 -3 -89 0 33 19 -17 -41 14 -3 -16 96 60 43 9 -41 39 90 -16 51 44 3 4 22 -31 1 8 18 6 18 58 26 -42 14 36 13 -2 40 77 107 -13 52 -16 21 9 74 30 6 38 -8 -5 6 -54 1 23 0 -19 -33 26 -31 -38 -25 48 45 -22 22 7 9 21 6 -34 3 -10 5 2 55 -17 -24 34 -20 2 -14 18 9 3 -31 3 26 0 44 -45 -15 -20 -26 0 -3 48 36 18 -46 -22 18 -15 23 -31 21 4 36 26 -8 26 -5 70 -12 -42 10 60 0 14 -7 -13 -3 -8 54 19 -33 -37 -20 -34 80 3 -17 40 -35 -76 -2 21 -18 -2 -54 33 -16 17 13 21 -7 22 8 37 0 59 41 31 -73 28 75 8 7 27 80 -15 57 0 14 -78 17 12 -78 50 56 17 7 21 119 12 -44 60 49 17 20 31 15 -10 4 -26 -29 7 76 94 -49 50 85 -8 34 66 63 90 31 -10 -4 -10 18 56 62 21 -22 14 75 -38 38 -7 22 -10 -7 43 -18 -44 -14 -13 21 87 16 -57 26 -36 72 -58 37 2 -32 29 -1 -43 106 73 -3 -8 -48 -39 40 10 0 -3 24 33 72 -1 28 5 7 9 -7 127 -92 -21 34 -54 35 -5 76 -38 13 -75 54 99 98 -107 -3 -19 87 -60 35 10 8 -45 95 -33 31 36 72 -9 13 111 34 39 10 11 -35 6 69 42 -51 23 12 96 -122 -82 -43 4 -124 50 -44 11 1 45 -41 21 -18 67 -46 79 -6 127 18 40 74 -8 50 -50 -25 17 -64 -15 3 13 54 -41 -34 -4 44 124 31 49 -19 127 -10 -56 -22 -48 33 -65 10 88 27 9 -85 62 30 53 9 16 43 13 6 9 22 14 -23 -45 27 -2 16 14 44 -26 33 57 16 5 18 17 -9 -41 40 33 -27 34 0 9 5 32 38 23 28 12 10 -55 -61 -102 -12 -7 -64 39 5 -40 -18 21 -30 -50 -9 15 -77 -26 -14 38 -18 -2 58 -15 -20 -5 16 -2 -38 -2 4 -2 -14 -15 -31 -46 -5 -49 20 -41 -2 76 11 -66 54 -20 -11 -8 12 26 41 43 10 -20 -43 -33 -3 2 41 -7 29 9 -13 -52 19 38 39 -29 27 67 52 -47 72 42 21 40 -13 16 57 67 49 -1 42 -29 -24 -18 45 5 -8 20 40 16 26 12 -33 52 121 6 -17 22 54 30 -35 20 47 -19 62 22 37 -36 23 -28 44 40 96 21 7 12 95 68 -28 11 9 54 29 -99 86 -79 -59 20 -34 -24 23 89 -28 60 97 82 28 118 67 42 49 4 -4 22 28 57 -18 29 -4 13 12 -59 8 26 40 66 -26 65 15 41 13 1 58 19 6 71 29 13 -16 27 19 -74 35 -49 18 -37 -45 65 -3 41 67 65 -16 -10 -63 -5 -64 4 22 -44 -27 -32 -26 33 17 46 1 -20 -30 17 -13 -72 16 -49 6 25 -36 -52 33 22 -26 66 62 -14 27 9 -51 0 -46 -40 28 3 -11 -9 65 -22 0 45 -60 -71 -60 22 -32 38 21 -8 23 -70 -31 -33 51 21 10 8 -3 13 -35 23 40 -49 15 7 -16 18 -51 -11 50 -23 9 41 -53 -24 24 7 -10 61 -7 16 8 17 3 16 -46 -20 -22 24 -15 4 -56 25 -26 19 31 -18 -40 8 -39 -17 -9 16 25 23 18 54 -18 -18 46 -12 20 -31 41 12 -60 11 33 9 -22 21 24 34 4 31 -11 0 20 13 -29 27 6 17 -16 -2 8 11 8 6 30 -18 18 0 -20 -13 -34 15 17 15 -7 11 -19 34 17 14 -36 10 101 19 21 21 0 -46 2 -15 65 3 10 7 -36 -4 -101 -64 -47 19 2 5 -4 34 -52 -7 70 -30 20 -37 37 -54 -49 44 52 37 -35 -39 -2 17 25 38 18 6 -9 22 -33 0 9 11 70 19 -86 14 62 9 -56 9 34 -25 -14 58 -11 -32 8 -19 -5 -22 21 11 34 38 -67 95 2 -44 49 -32 -57 40 -34 15 -13 -20 58 -65 21 -37 -87 -74 39 19 -5 9 -22 -56 10 -40 -42 29 -34 -35 49 18 -15 -22 5 -41 -82 21 -82 -50 -23 17 71 22 -18 36 36 -1 -71 -73 94 -65 28 12 -11 -42 -23 35 -33 -61 28 -18 65 -15 -37 83 -50 -36 7 -79 61 -6 -5 -14 1 13 2 20 -26 -110 -12 15 19 -78 -32 16 -70 10 -23 -9 -73 -19 49 24 25 18 -16 47 -35 -51 20 -28 -74 -15 -56 11 -60 -34 -73 4 25 -101 -29 -73 -15 32 3 -17 -10 -14 0 4 -28 32 -9 -5 -12 37 30 12 13 -31 -1 19 -19 -7 21 34 -25 21 -53 -6 -8 13 23 -34 -35 -35 5 3 15 1 38 25 20 4 -9 -9 -34 -6 37 -21 19 -5 1 16 19 30 10 26 -20 32 24 25 20 -25 3 8 22 -48 -5 13 -19 -4 -11 26 -18 -1 -9 -2 -2 -18 -51 57 -60 30 41 50 -3 0 -5 -11 26 -35 23 26 -19 26 -10 15 53 -33 16 -7 -26 37 34 36 -4 -11 -72 35 20 19 -18 -32 -1 6 45 -5 61 -26 41 33 102 21 -78 -15 -27 82 -2 11 69 -34 -7 -39 -5 41 38 -25 34 36 42 79 -21 45 -12 4 0 39 66 73 28 89 -5 45 -12 120 -30 -65 101 -6 25 36 -62 18 74 16 -11 -12 80 -42 -54 73 -3 29 7 24 17 -32 -43 45 47 -21 30 10 -10 32 11 -25 108 -16 -9 -24 21 -38 0 18 21 -7 35 -2 0 -6 7 -9 18 52 -10 -7 45 29 33 10 -43 -18 1 -22 -21 -26 -48 26 -1 -28 -41 -31 -44 -3 -5 8 -77 -57 26 -13 28 -14 11 -39 8 20 -66 -7 2 77 -1 -11 7 24 -45 -22 13 7 -13 -63 -31 -17 -6 73 37 38 35 -68 -15 -6 22 -18 6 -21 49 16 12 -40 27 9 -31 -22 -17 -2 37 -38 -22 38 18 9 26 31 15 -8 -40 -54 109 32 -11 -57 -15 6 16 34 -5 20 26 0 16 35 -41 43 -26 7 1 2 17 0 18 15 -1 55 -50 44 -5 12 4 -49 11 -9 9 -2 -44 3 -43 26 4 4 31 -1 21 -35 -32 -39 -10 -1 -15 -31 22 26 -15 25 5 21 -28 -36 11 23 8 -17 13 9 17 -55 22 -43 14 3 78 6 7 -51 -1 33 -18 -28 -32 -41 -22 -29 17 1 -1 5 52 33 22 -2 18 6 -18 -13 -17 -3 24 13 39 -47 -34 20 3 -42 -2 6 25 -22 -8 -17 -39 -10 8 35 -17 -77 34 -34 68 46 22 -3 -6 -70 21 -55 -16 -95 -38 27 -25 -92 -65 -45 -1 5 25 -9 -24 58 31 19 17 2 22 84 -4 4 2 -17 -22 -12 -21 2 -6 7 -73 52 0 -27 98 -27 -24 2 -7 -6 -3 127 -41 45 27 -97 -18 -4 3 -13 -31 -23 -10 25 -15 -26 32 17 12 63 28 5 -27 40 59 55 -34 -40 27 -13 -35 22 -27 19 95 47 63 -10 -16 -68 -101 8 -21 81 -14 -62 49 45 52 -59 -36 -18 24 -77 106 -46 31 21 68 21 -28 -76 22 100 36 -78 -11 -72 -33 25 -75 29 13 34 -61 43 50 -23 91 33 29 30 25 -15 21 46 44 -12 -12 55 76 -3 86 39 12 -47 -4 -52 41 41 -45 54 21 45 14 7 15 73 -3 39 -44 2 83 52 10 36 19 15 10 -37 -2 -41 113 -81 11 8 -7 16 -25 -1 3 1 20 -10 10 -5 3 29 17 -23 21 -19 -43 10 -26 -20 -19 -17 -5 28 -6 24 15 12 14 -10 -59 -44 6 -42 -14 0 18 -27 102 17 -32 45 25 16 -13 -9 -15 -20 -10 20 19 -8 -28 -11 10 15 13 27 38 26 20 4 76 24 -42 -1 12 -4 26 22 -42 -11 -2 14 7 -45 -14 22 -4 -40 -32 56 -3 2 -44 31 -34 -25 -20 39 -17 37 64 43 45 39 14 -17 -6 11 15 50 -14 -16 -7 44 28 36 45 38 -35 15 -52 -18 0 34 -41 -14 17 -16 16 -31 58 -10 -26 25 25 16 5 -24 19 18 50 -20 49 44 -13 23 -26 -23 33 -10 -38 9 -3 39 11 12 13 -35 16 -33 -10 -17 7 -9 72 33 2 14 -4 -76 -43 1 43 53 24 -9 26 -26 -53 20 3 -48 -7 -12 -39 16 -37 22 9 30 0 22 44 -99 -3 37 69 6 78 0 7 -41 -33 0 19 44 13 -18 -57 -4 11 17 52 3 8 4 39 -25 -9 21 19 10 19 -26 24 -5 -18 -53 -10 -17 14 26 5 -55 -48 8 -17 14 39 14 -61 -11 -15 -34 15 26 -17 5 -10 11 17 37 42 16 7 -2 32 15 0 72 2 -19 -29 1 -52 13 -47 -6 15 11 -7 -106 -15 -13 9 1 -44 25 6 -51 -42 57 49 27 27 -53 2 45 -50 18 48 29 36 15 -31 -11 38 -13 -29 -27 1 -25 -3 4 -40 -43 -26 48 7 -2 -21 -8 17 -22 -36 -26 -24 -9 -38 37 1 -25 -18 -8 8 -2 32 38 -21 -43 1 -42 10 2 5 -16 30 9 36 3 -19 -16 -22 13 4 32 -5 -21 25 -26 28 -3 27 -4 2 -3 -57 -14 24 18 -7 -12 27 2 -9 -8 33 -18 15 31 -30 -8 9 2 -19 5 9 40 -13 -13 36 11 -14 -10 19 64 33 -6 54 34 23 5 -24 -21 75 8 9 1 -54 -92 -88 -1 4 19 41 -34 -78 22 -26 -43 -13 82 48 15 -36 -2 -49 -65 -18 -90 34 12 0 -37 -31 5 57 0 33 -24 22 18 34 5 82 19 68 35 -44 -55 15 16 47 13 23 -26 -63 -42 41 7 58 34 54 -18 -9 -12 -5 -40 -38 -12 -21 87 -68 4 49 16 51 12 36 9 34 -27 98 3 -11 8 -41 0 -34 8 8 -17 -48 -59 8 24 -21 35 42 -17 18 24 -11 70 36 11 -44 -27 -24 -14 -16 65 84 46 3 11 25 12 -48 -35 22 -15 -35 -5 -12 15 -14 1 -31 21 41 50 10 -20 -24 -7 -45 50 11 -27 9 -32 4 17 -23 41 -46 29 15 -89 37 -72 -18 10 -5 -4 31 5 -16 55 -10 -11 38 -26 -17 8 40 -9 91 -31 56 -55 -20 1 30 -47 -1 17 -23 -6 -47 66 49 -36 37 28 7 32 83 23 111 -36 -29 -77 6 -4 -36 35 23 32 23 -2 28 15 -27 24 8 -14 35 -18 7 8 6 -14 -12 -2 24 -5 21 47 15 26 -18 -11 -29 -13 2 28 3 1 -23 11 70 1 7 8 41 -33 -67 45 24 -1 -76 -39 -8 17 -13 24 -12 -19 -22 -7 -17 -35 18 10 25 -29 49 8 48 21 -18 -24 -8 -13 -10 -21 11 20 6 33 -3 4 21 12 24 4 13 3 29 -7 3 53 0 15 28 33 -8 45 46 -28 31 55 -2 8 46 -86 59 36 4 -30 38 50 -16 -33 37 -6 46 40 38 -44 11 115 54 48 21 -71 38 55 52 101 29 96 70 34 50 38 -30 -30 15 -38 116 8 46 123 -23 4 -56 24 88 9 8 46 -67 24 48 35 10 50 60 -17 -9 60 76 -15 11 32 10 19 96 -30 -27 -15 45 53 127 75 98 64 -23 -8 -26 97 -3 -4 -25 -10 61 5 3 -23 -6 81 -41 14 1 -1 2 4 -30 -40 16 49 -16 -59 32 8 -53 -84 -42 -28 -34 65 21 -81 20 -6 4 18 -10 11 -1 54 4 -1 -14 110 25 40 -43 65 29 19 -38 53 16 -47 17 -30 -38 49 -16 11 75 27 70 -21 -38 3 -8 -15 39 15 41 31 24 34 4 -40 32 -10 -43 -24 18 -47 7 43 -17 -31 -35 27 42 16 12 -54 -25 -29 63 2 -15 -13 -12 55 -77 -12 -6 20 39 -81 75 -64 18 -25 -16 -9 -34 33 14 13 22 -1 25 -59 -4 18 16 8 54 39 -15 46 20 -4 25 -36 -61 9 16 9 12 32 31 5 -23 3 30 -6 -44 4 20 4 41 28 3 33 -15 -34 -11 -1 14 -44 -30 37 5 30 -49 27 -15 -7 -14 3 -28 4 41 -8 5 -3 -10 1 12 14 22 -9 4 -18 42 -14 -28 35 7 -10 -82 10 -15 -16 -3 32 -33 35 -9 44 -3 -29 23 -11 42 -8 61 -12 85 10 -42 34 98 -12 61 -9 2 51 32 -23 10 38 -54 -24 -19 -93 77 -3 6 41 6 22 -42 2 10 27 26 25 -9 14 81 3 49 4 20 6 56 1 20 16 -41 74 25 -5 25 -23 -27 27 51 11 33 38 -12 32 -5 54 125 20 1 -57 28 -18 -31 -13 17 -1 19 4 34 42 -39 -3 104 113 14 -37 127 3 93 55 -36 36 70 -36 19 31 29 11 -22 41 -20 34 -41 7 6 -34 -37 -5 1 12 61 33 6 32 21 -31 -20 -57 -6 62 42 18 -39 -1 -35 3 -28 -2 -3 -41 -19 58 -33 29 17 36 -54 28 63 -16 -87 19 -27 6 -53 29 -13 2 -31 12 13 -20 -19 38 -20 -20 28 63 4 40 13 -1 25 78 60 7 55 -15 -20 3 -23 -26 30 -2 -44 81 4 -16 -12 -18 15 7 31 -34 -83 -29 14 0 15 26 -44 12 -6 3 12 -8 -31 -31 -31 10 52 28 10 38 17 -17 -17 9 -20 -15 -1 4 37 21 -23 2 2 -10 16 8 29 -22 8 18 3 5 -9 14 12 1 23 62 8 4 4 24 -31 -1 -20 -7 33 -20 35 -23 27 -15 20 -27 35 0 -30 -24 9 -5 -35 -23 -13 24 47 -9 33 -31 7 -19 14 40 -7 -7 49 -15 15 -28 -7 3 -60 -53 -1 -28 38 -16 3 -14 15 -15 -6 12 10 14 -19 -14 -50 -45 29 -9 19 2 114 24 17 3 49 -5 68 -6 -9 2 -24 40 -4 -48 56 -17 60 -22 -4 2 8 -13 -4 -16 54 -12 -83 32 -7 24 34 52 -38 -9 5 11 62 -12 14 11 13 43 -2 89 -34 -3 -86 -4 -26 -10 52 12 -23 -7 5 27 92 47 -33 -73 4 17 79 -72 9 -48 9 10 32 95 23 37 63 30 24 58 22 61 -53 44 -46 -34 45 32 23 -8 10 47 -5 11 -7 65 -2 55 7 42 2 -34 -13 15 39 -7 -44 5 3 18 51 53 -52 22 4 -39 4 37 57 -5 -7 -40 -29 -6 -26 9 8 28 73 75 -7 -2 -16 24 26 16 57 -34 -21 18 -33 30 -1 8 12 48 -5 50 52 3 30 27 18 -9 37 1 -65 -4 25 34 17 -39 42 -19 -9 -34 68 34 32 -21 -57 46 -31 9 1 -46 -21 -1 -44 27 -20 -22 -3 4 -7 11 -22 2 56 44 40 35 -18 13 29 -34 -8 -33 -12 16 -10 -15 6 8 -2 30 25 27 -52 5 27 -4 -1 24 8 17 -17 26 -29 -17 11 13 34 -32 21 -3 -21 6 27 21 8 6 -1 20 -62 20 -4 26 -33 -10 -7 22 -42 44 -23 8 -17 -9 11 37 -20 -26 20 75 -7 17 71 43 -53 -4 6 -2 41 29 31 -45 38 21 -2 10 17 -39 -9 24 15 -7 26 37 0 18 -14 50 -37 -32 -5 71 14 8 0 -22 35 -8 -22 -17 -42 68 51 15 25 -70 52 -31 51 36 28 -103 -123 45 -37 -15 -88 -48 42 61 5 -51 6 -49 -28 89 -34 62 61 106 6 -12 -30 -15 -18 -58 -14 -45 -58 -3 44 28 -89 64 28 -36 -6 107 -40 30 -62 35 -6 -24 -11 33 -41 -47 -45 45 87 2 -8 -114 -4 -21 48 -125 -99 2 43 30 96 28 -26 26 -58 58 -28 4 -89 -16 6 22 55 -55 20 -33 68 86 58 22 81 -20 -56 13 -37 30 -41 -18 -17 37 4 -13 38 2 -52 54 49 -32 -9 14 25 -70 42 -13 39 -5 -22 -44 2 15 -14 20 17 62 25 -5 -51 -58 -73 -2 52 4 2 56 -22 27 43 10 29 23 29 -23 17 54 -41 5 -14 63 10 29 45 24 8 -33 14 -88 -44 29 -29 0 44 72 4 7 -10 18 -2 -6 69 1 59 -52 3 -5 33 -35 -9 38 40 -1 -24 24 64 -27 15 43 -59 -72 -25 -27 26 -15 18 6 63 -26 -25 18 -43 -28 -8 -43 -13 14 -39 -25 30 11 -3 31 -7 10 -23 22 -41 -78 60 1 4 -52 24 12 -26 -46 -28 10 55 1 29 19 17 -25 -42 -23 10 7 19 29 33 25 -4 19 -19 71 9 34 35 -17 18 -17 4 -6 -19 25 3 14 -17 -20 -47 -62 -24 14 9 2 -2 -20 -42 -28 -10 -10 4 28 -41 8 -46 -7 29 -10 -7 -11 -27 3 -4 25 -13 -25 -8 8 -6 -32 -45 81 11 2 25 10 -38 16 17 -43 -22 50 -24 -4 -62 -3 -57 -22 -21 -44 7 22 4 25 34 54 5 -32 58 -4 1 46 2 66 -34 -14 78 55 12 -2 -52 -1 30 -16 -3 -11 -39 29 52 43 12 23 9 -12 43 3 57 28 -4 67 -24 50 -19 -77 6 8 -42 23 -3 -42 -8 3 -34 -3 4 25 14 64 -20 8 0 42 20 53 39 -22 38 32 42 39 28 13 18 1 8 -28 -56 -14 -37 10 -24 8 7 -17 -12 20 26 37 -2 -15 12 -24 34 -21 -37 -12 12 35 -2 -47 22 39 16 18 -7 -4 14 -10 -52 -19 -50 -11 -29 -11 -4 7 -9 -3 29 -13 21 28 -58 -50 5 -18 -28 27 -14 35 -17 68 15 -23 -52 -14 -21 60 -21 1 38 16 -64 16 -15 -31 42 25 -13 41 23 -1 -33 12 -10 5 2 -34 29 56 41 -20 33 45 -12 4 34 10 9 -5 -25 -4 24 -37 12 32 15 -38 -7 -15 42 11 -30 10 -6 -16 12 43 -1 2 4 -6 -9 7 31 31 -27 -7 18 -1 6 -1 -6 -39 -9 -8 20 -21 11 9 -7 -7 -7 9 -14 -14 4 21 -13 -24 4 -19 2 51 0 -4 -29 -1 6 -9 -7 7 30 20 -13 -63 -7 -8 23 -4 7 5 -9 -14 -21 45 26 -63 -4 -12 -4 27 23 42 0 12 35 48 -9 25 37 -19 -14 2 22 17 0 83 -22 -8 -31 22 23 14 28 5 -35 -10 -21 24 -12 -10 10 -3 -2 -94 -31 -55 11 40 -2 55 10 12 6 25 -11 5 35 49 34 -11 -14 59 -4 38 23 -14 5 1 0 0 51 -21 -3 11 -16 31 -26 -4 33 18 18 -16 19 -56 -35 1 11 26 61 72 61 -19 19 28 28 -24 -34 -22 -14 -15 -21 -5 97 -48 -42 -60 -7 81 36 10 34 -11 56 -15 -6 -18 3 5 25 32 -14 -9 -69 -13 20 -34 37 70 -13 -6 12 -14 -21 19 -35 51 18 6 8 -7 -74 -79 33 6 34 -17 -4 -19 -11 -22 9 -22 -2 -12 -18 19 12 -13 -27 -23 28 -11 -57 -3 -18 -23 3 -30 -7 -41 -21 49 -8 37 -16 -55 -20 -23 -66 -3 17 -36 3 -20 -47 -3 -11 -18 38 -11 11 -7 69 -4 -122 7 -54 -19 -6 -8 -14 -23 11 -60 -3 67 0 24 37 32 9 -6 -55 -14 -20 -28 -27 28 -43 -2 -13 50 -6 4 -10 -14 4 -1 -1 -19 -17 0 -6 14 -44 -62 -16 -5 43 -8 -6 2 33 20 61 -24 23 -2 13 -3 -20 16 -18 8 -30 4 -16 5 21 29 -42 -19 31 -3 -1 22 41 4 -3 -39 -4 4 31 0 16 -11 -20 -10 1 19 5 58 15 15 40 -42 4 7 -20 -3 6 7 14 25 -7 15 31 -18 -30 -18 16 24 44 25 9 -9 39 1 10 51 -98 19 49 21 15 -43 -26 21 34 12 69 -18 15 25 75 -114 4 -49 4 90 -29 10 -107 28 18 -20 62 8 -38 95 -22 -21 -15 11 -53 -50 -33 -44 -36 26 -30 57 -35 22 13 -23 12 45 -4 -33 -28 -97 -37 18 -3 64 22 -21 2 29 48 -46 -21 -68 43 -58 93 -89 58 4 56 -65 11 3 8 16 28 37 51 -34 10 -24 30 20 -3 14 -31 -16 -40 56 92 -55 60 8 25 21 -77 68 -7 -8 58 -72 -84 -27 30 -27 -38 -96 66 36 5 45 -40 -54 72 25 36 -31 -20 -30 -55 81 -3 -9 49 55 43 29 -21 34 26 -25 3 -47 14 13 -50 39 51 14 18 -13 8 8 51 -29 -31 -123 -71 -82 78 2 51 -9 30 59 56 -42 -27 -2 114 -52 31 -6 23 22 23 75 32 13 -9 -1 -4 -78 -6 21 108 2 -21 6 -19 22 -27 23 53 13 53 -48 -10 -27 40 -3 1 -30 -56 -19 18 -50 23 14 -75 3 43 -50 18 0 -39 -6 43 -33 7 -12 2 0 -35 9 14 -37 -32 8 -13 12 15 -11 18 15 48 31 47 -22 16 19 31 -25 -7 -14 9 39 25 3 68 32 -25 41 32 27 -33 26 -29 2 8 -21 -56 -18 -37 -26 -7 40 18 -56 42 -33 38 -9 46 8 -23 -32 -42 16 6 -12 -60 -31 -18 0 19 -60 4 7 -50 7 -9 12 83 21 40 -4 -6 -11 8 47 33 -29 -29 22 -1 29 1 14 46 -94 46 12 -18 -38 0 -26 23 14 -3 30 11 53 77 108 -15 20 3 40 -8 21 37 27 5 54 18 15 -21 -21 0 57 19 21 -32 39 3 32 -39 7 39 11 47 54 103 5 60 -27 44 -13 -1 21 29 42 45 13 46 46 9 34 -14 -6 -28 19 -25 -23 -7 -1 -4 -20 -31 108 -48 121 2 54 -5 20 -8 33 -17 -51 22 33 67 -24 85 -41 -31 -15 -17 38 35 28 -16 42 -24 -24 16 -29 -41 43 2 0 24 -33 7 -61 33 -7 18 17 -1 29 -39 27 26 -23 -23 -65 -6 -5 -37 -22 23 29 22 -15 -22 12 30 -5 -15 -54 6 24 26 -9 -48 -13 6 53 43 -11 -23 32 -2 -17 14 10 -39 43 -15 18 5 -11 9 29 -8 -22 -20 19 -54 41 3 7 -51 -18 -32 -29 2 30 13 15 6 12 -19 -23 -5 1 -11 5 -37 -5 -4 -3 -11 7 24 -5 20 7 -2 -15 18 -32 -9 3 -7 20 17 1 -19 22 13 6 -10 12 8 -29 -17 -18 -6 20 29 -20 -22 -8 -8 -6 -7 22 -29 9 -33 -37 -3 -17 2 -8 18 13 16 10 31 47 -24 14 13 22 15 12 -7 -2 -13 52 -5 -20 10 -7 -26 2 -6 -25 2 -28 -5 32 27 15 9 7 -19 -22 -20 39 -26 -34 13 40 -29 -10 5 -4 24 12 7 -3 35 -20 -36 -1 20 -59 -1 -70 11 -21 -12 19 -5 -9 9 43 -9 18 13 48 -13 -57 -6 2 5 -28 -115 19 22 10 -1 43 49 35 -81 3 -32 3 -22 16 -37 -21 -63 -24 1 -4 -5 -6 -8 44 -33 -11 -16 13 13 9 -29 -16 35 -25 34 46 10 81 -39 -15 40 17 7 -3 -5 -57 28 8 -76 -23 11 61 -34 27 -17 -21 59 80 5 -22 28 -20 29 0 46 26 48 -16 -46 6 -50 -23 -23 -4 -12 -5 -10 0 -61 -14 12 -32 28 -47 -4 -9 12 -18 -19 -19 -8 -7 -6 -34 26 4 -62 20 19 -69 10 -13 13 -60 0 -13 17 -33 -7 -12 17 -46 -64 2 19 -16 -27 -9 -35 -53 -15 9 31 7 -18 21 -54 57 55 31 -24 -15 -12 55 0 43 18 4 18 -27 23 -25 -8 7 -6 5 26 -24 -47 -5 22 -4 -10 -29 -37 40 -15 -1 20 -18 1 -34 -14 -11 27 -5 33 -1 36 18 -15 17 32 30 -19 2 -12 12 6 -4 -13 -1 -23 -25 -5 16 24 44 11 -9 25 42 22 -23 -30 44 -6 -20 -2 -42 -34 14 -16 19 10 19 -13 27 -50 -42 -2 29 10 -1 -10 26 21 54 13 -27 -14 -21 19 19 -10 7 41 -4 22 25 -19 30 13 -22 4 -3 8 18 18 -59 -56 -48 22 -9 -21 7 30 30 -7 10 -11 -22 27 33 -12 6 37 32 -56 33 57 7 17 24 16 0 -8 -30 -17 -68 64 -56 -34 -128 16 32 74 -26 -3 -28 -1 83 -31 33 -24 31 47 38 -30 -1 124 36 -53 56 -42 -6 20 -8 53 -59 -8 22 16 -104 27 35 -25 -19 58 -11 -51 4 83 -15 -4 -3 23 21 -73 5 39 -65 -8 -29 -74 74 -57 -38 10 11 45 -38 17 51 110 -2 44 -31 0 -7 10 7 100 7 -7 21 43 2 27 92 68 -20 -12 -14 -19 5 0 5 -42 21 53 7 5 8 67 30 21 18 57 -32 55 5 34 -25 -35 -32 -73 28 -28 -20 -69 30 42 -110 -12 21 59 59 11 82 -39 34 36 7 -2 28 -47 -8 -18 11 -3 23 27 -37 3 35 -96 43 23 -9 -8 32 -19 -57 -105 -30 44 31 23 70 28 0 20 -33 60 40 49 48 30 23 57 18 -41 -19 67 -25 -7 -38 25 36 -125 18 33 55 67 36 0 -37 -8 -44 30 -17 3 7 -2 6 -100 -3 -14 -39 26 -7 33 -37 14 -17 14 -26 -46 14 -32 -15 35 23 1 -11 -14 1 12 50 -23 18 -66 -13 18 11 14 -8 -41 -49 37 15 7 4 21 -37 36 35 21 -1 -38 18 -19 6 4 -13 -26 -36 17 19 49 -51 -26 -2 -13 37 38 -31 31 -13 24 -34 0 43 -24 30 68 3 -45 -4 15 -20 83 -6 13 -36 -36 -14 -1 21 52 10 26 12 41 14 24 31 -5 0 19 12 31 -40 -3 18 -23 -63 40 -51 -6 -42 21 -18 41 20 3 -41 13 77 7 55 -9 31 8 70 37 -38 25 -30 -31 71 -1 3 -17 -20 47 36 -106 9 -22 -16 5 116 19 29 5 12 22 -3 31 74 -30 -20 -55 20 -11 80 26 8 37 16 -59 72 -23 5 15 64 -46 11 -15 -23 -6 77 -54 -30 -15 22 -12 -27 26 85 1 -5 -67 -22 -35 36 -25 6 -25 -47 -12 0 19 -34 59 29 12 -16 -11 29 -22 26 31 24 9 1 125 11 -20 14 28 -50 30 -36 -9 84 14 3 -14 -14 -22 -14 7 28 -52 15 -27 -19 1 6 -9 47 9 35 50 -38 11 -12 22 -46 -49 -33 8 46 5 7 36 -13 -47 -39 -36 24 55 -14 68 36 30 12 14 -7 -7 9 -72 42 30 21 38 25 -22 -20 51 -46 -43 -18 39 64 21 -46 -21 -20 23 32 14 -2 -2 0 -34 -39 32 25 -44 19 21 15 -25 -6 -13 -2 36 21 -50 -4 -14 43 -32 -11 30 15 -12 -10 5 -32 14 -52 64 -11 20 21 -29 -3 10 27 23 -26 19 -11 13 -1 -5 9 16 -10 1 59 12 -20 15 -35 0 2 -4 -34 -4 -57 -44 33 24 28 -7 16 18 17 5 19 2 2 34 -2 27 -23 -4 -37 -10 10 -54 17 9 31 52 -7 -15 -18 -68 -32 15 -29 25 28 -15 34 29 49 -4 30 2 72 50 -24 67 -21 -56 -7 18 -3 50 -60 -15 -60 -22 -50 -7 11 12 62 10 43 -78 39 -58 21 -15 -3 -41 121 0 -32 -36 -30 8 6 58 11 -66 31 -13 57 -32 4 38 -64 35 -67 68 -73 21 86 2 19 80 72 14 19 12 -1 -7 -4 -51 -36 0 58 -27 -20 -68 -123 -2 -20 -16 -4 26 -31 127 3 69 -66 -102 67 11 -1 -38 57 0 15 -29 98 37 31 59 2 -42 53 -5 37 5 17 -29 -71 7 13 -29 -41 12 1 -5 41 47 -13 40 -19 -4 -62 42 13 66 1 46 34 -41 62 -28 25 31 47 -9 25 55 53 18 -29 29 16 -12 82 -12 -27 72 30 46 19 -88 1 -112 38 -49 -8 17 62 31 33 7 33 17 -71 -32 -29 20 -25 89 26 44 43 -5 86 26 -14 -17 -41 19 35 -23 -12 -40 -82 13 58 40 -17 48 -26 47 -48 -23 -51 21 16 51 -56 -21 -34 23 10 -57 -3 2 48 -20 40 0 18 24 15 -2 11 56 -16 24 -44 -32 3 -30 -4 -1 33 -7 -52 11 -31 32 -38 -48 5 -14 47 -18 -4 -11 7 -6 -15 11 -32 19 -21 -5 35 -70 28 5 40 -38 -3 -1 92 47 4 -3 -16 29 -1 -13 -11 -9 15 -45 1 -29 -44 -49 24 -13 -19 15 -34 7 8 -13 16 -29 31 -5 -17 3 -8 2 9 63 23 -30 16 9 94 49 24 0 43 71 -109 15 88 99 50 82 39 -2 85 111 -47 60 -24 62 22 78 -36 22 52 31 16 48 -51 20 52 17 -17 59 53 127 30 110 65 -5 71 59 -37 -23 -25 54 26 -15 38 49 -4 74 -18 24 -40 20 46 15 44 23 74 -42 -35 -56 -56 22 90 -47 39 7 -43 103 -49 43 79 95 48 125 -21 42 51 -49 53 -9 70 50 17 -84 7 112 -42 -80 68 31 29 -16 29 -9 -55 9 32 -56 -53 -51 32 6 80 4 62 49 -47 -45 -69 72 12 -35 -24 -25 31 -9 -55 -22 6 -31 -2 -10 -32 -54 -29 -27 4 9 -45 -48 15 32 15 61 51 -24 -38 -2 -9 -30 2 -48 -43 -39 -46 -34 26 -38 25 -20 31 9 -18 20 23 -38 33 -16 -77 -34 4 46 29 19 14 18 -29 -45 -64 11 30 51 5 -23 -22 -1 24 -34 47 -41 -29 -51 30 15 7 -43 30 19 34 8 -40 -9 4 -2 -22 -19 26 10 -22 17 -43 6 27 6 20 14 -47 -51 22 -11 -6 12 -45 6 -26 -24 -32 -9 -10 -29 -4 -34 8 33 20 -21 8 -57 12 -11 18 -38 13 65 21 -15 -2 50 -50 -30 -47 -14 -9 21 -22 19 63 -24 -55 -6 -22 30 3 5 6 32 -35 -31 54 17 -23 -11 5 51 21 18 25 17 21 -10 -9 17 -39 -11 36 -15 27 -35 -33 34 3 41 53 -54 43 54 68 28 16 -12 2 1 -17 -42 -62 -43 -38 -22 -21 44 0 53 54 -5 30 33 7 -37 50 13 -42 37 63 -77 -20 -17 25 -45 60 31 -7 127 47 55 -6 -67 44 79 -27 57 33 56 53 -20 0 54 11 15 2 -12 65 -2 -8 19 29 21 64 62 -33 46 21 59 12 35 18 -12 -56 38 63 47 -34 28 -49 -16 -27 -12 -15 57 -31 30 89 19 34 35 14 -32 111 -37 -5 -21 -23 22 2 8 1 70 -54 -71 44 -111 25 -72 -15 -4 -68 11 23 -35 -1 13 26 -29 -70 18 28 19 19 30 18 27 -96 -5 100 -30 -23 0 -40 36 -8 -10 36 10 -36 67 -7 -18 36 7 8 -23 0 10 -12 9 -13 11 27 -5 9 29 24 -70 31 -7 -6 26 -17 -10 66 -4 -39 4 18 -11 16 -60 -1 12 51 87 -26 -64 18 50 18 -54 8 6 -7 -49 52 -27 -4 -6 8 -24 1 35 2 28 -21 -37 -18 -16 13 -14 -41 -18 27 -6 24 50 13 61 -4 -25 -3 10 -9 9 -29 -13 -26 0 -45 9 15 16 -36 6 8 18 -2 38 -45 30 31 21 52 -11 -4 -13 -10 11 -9 -18 20 44 -13 -33 16 23 22 6 -31 -33 -10 -15 -1 -24 -3 -23 25 9 3 -11 -49 -48 21 22 -40 8 -14 -21 -21 26 24 -3 -2 -33 13 1 -13 32 68 -19 -33 0 -22 -5 -17 98 -56 -64 19 -28 58 85 8 66 4 76 -36 -5 71 -20 17 59 61 74 13 6 -7 10 27 4 -50 99 49 9 56 85 19 51 22 -16 73 3 34 18 -28 7 19 -44 59 23 1 69 30 -48 95 9 39 -46 126 28 45 115 88 16 24 16 21 29 -23 62 -60 30 -25 83 -32 -53 -58 65 14 18 74 24 24 85 -14 70 -8 -24 62 105 13 -10 5 46 68 -123 -38 -21 68 124 -28 29 9 -31 13 -29 -2 -7 -127 41 -6 -10 21 53 60 -40 -33 50 44 67 17 -66 -49 3 6 84 18 -20 -50 -17 23 -4 -9 40 30 -34 -29 30 -85 -55 41 -2 50 60 -23 -16 -31 1 17 -35 -35 16 -10 -19 -23 82 -97 2 -41 24 38 40 -5 13 14 96 54 -19 -15 73 -21 25 -83 -5 -31 -2 40 3 31 60 15 31 -40 -14 -13 -9 19 -21 19 -60 -5 -3 -5 -55 -33 -45 82 24 -5 -7 -6 -1 21 -22 5 21 -6 29 24 -9 -39 14 -13 -1 -9 12 -24 -2 -9 0 0 -1 20 11 9 -35 -54 24 17 -2 6 -35 11 12 37 -22 -33 -7 -26 -11 -51 -28 -8 14 11 -18 62 13 15 12 -3 -16 -24 -7 26 34 -31 -27 -39 -24 7 -11 6 -26 -41 -25 47 9 12 -1 12 127 -4 9 30 -47 -8 -9 1 3 14 -4 1 -11 73 -34 -20 22 48 6 28 -11 -7 67 46 -3 -31 -15 -21 -8 -18 -25 34 4 10 35 -93 -35 49 45 44 94 40 -48 6 100 17 -14 -16 -3 -87 55 -4 108 26 50 -71 96 -7 -76 24 9 12 -37 -26 32 -14 12 117 -44 31 -2 81 63 33 7 4 -34 71 -6 50 57 28 91 4 8 44 15 0 49 -26 14 23 111 52 0 127 59 22 3 -24 4 1 -34 25 32 77 7 -4 19 -38 -8 78 -1 36 30 -3 19 99 -14 26 -12 -27 9 -57 -32 58 28 -6 52 -52 -25 0 -63 11 49 -30 -31 -21 -13 -28 10 -5 60 -52 -54 0 -92 -32 -1 3 19 7 25 28 -9 -4 45 46 0 5 -14 -28 45 -41 42 4 -1 88 32 -6 -4 58 -28 -63 -51 -28 -31 -9 -16 7 27 6 -9 -17 -35 44 17 -4 -8 -62 -36 5 90 8 -58 64 57 -23 -34 -6 10 1 34 -21 18 27 35 57 30 -42 -27 -10 -31 -19 44 -1 4 -85 33 8 -16 -7 -39 11 14 -18 -28 7 24 -36 20 30 -29 -5 28 18 11 28 20 -4 3 -3 -5 -14 -47 9 33 -34 39 15 0 -7 -45 41 -1 -2 5 32 -9 -43 25 22 28 42 -13 -11 26 -8 -10 23 17 -29 22 6 -8 -16 -13 -15 -77 8 26 34 35 -24 -64 12 -24 -2 -5 26 -16 13 14 25 -3 2 -19 26 -3 3 -33 15 -44 -38 -6 -10 7 -35 3 18 27 54 25 55 -1 -80 22 21 9 -61 3 35 -15 40 -36 6 0 -23 -28 9 -47 9 15 -63 16 -26 -19 30 77 -17 39 -78 29 44 -2 -22 -5 27 50 -22 46 39 -38 76 95 34 -9 -33 33 3 26 71 36 -63 -46 -1 42 -21 -38 41 9 -9 23 -32 65 -26 45 8 35 -21 27 -67 65 32 41 3 20 -41 1 14 -19 2 -3 22 9 50 -11 5 -13 -113 36 58 44 -54 49 -16 53 37 22 -3 10 -9 35 -67 -79 -40 -3 -1 6 57 43 38 -33 -57 -16 -53 -30 3 50 -31 -9 11 -127 -76 65 42 -51 28 -37 3 -32 20 42 0 -66 -9 52 -16 -1 40 -15 -48 21 -49 99 13 82 29 47 -55 -43 -65 -75 -13 5 127 27 8 21 -10 11 -25 -10 -32 6 47 18 23 4 42 -10 -68 35 1 17 -31 -86 -1 -34 4 12 8 -16 58 2 -36 34 39 124 -62 56 38 15 -22 -9 27 -7 -39 9 -19 27 -45 21 73 -73 -16 -21 32 21 -1 -11 18 2 -39 -2 -11 24 13 28 -33 18 21 9 -20 14 -26 -9 11 -1 3 16 3 53 16 27 11 -45 -12 0 -4 -14 -30 21 12 28 9 -13 10 61 -2 -10 52 31 26 17 -11 12 -5 20 12 -2 -3 2 41 18 4 -13 3 9 0 -19 -6 -12 62 -2 45 -10 -9 -38 -53 23 -49 -1 -10 13 3 -1 16 -1 -11 -4 1 6 8 -6 5 4 8 16 -12 -11 21 5 2 -2 -7 0 1 -21 -2 -11 -20 8 -23 11 0 -6 11 14 1 9 -2 -16 13 -7 9 1 -11 -24 10 -18 0 4 -5 3 16 2 -2 0 0 -12 -14 0 -4 2 -2 16 -20 -9 -10 -4 -1 4 -2 -3 22 14 -6 6 -1 9 -19 -16 1 -11 -21 -20 -27 -5 -3 -6 -3 9 4 -22 13 -1 -3 8 1 19 5 11 -6 8 -17 21 2 25 18 -4 -17 -21 -2 -14 24 -26 24 -4 10 -5 -9 -46 -9 -12 8 9 -12 21 -15 -1 2 9 10 15 6 9 -30 12 -6 4 7 10 -6 -18 -10 -12 -1 5 20 6 -10 -6 -7 23 0 -19 11 0 4 -18 16 -9 -33 8 -16 11 2 -18 -4 -1 -14 20 7 -18 15 2 -13 7 -3 -32 1 0 -28 -34 18 -13 9 0 5 -25 4 -8 -30 18 10 -3 17 6 18 -4 -16 -17 4 -7 -7 -14 4 4 -7 10 10 -6 -10 -4 0 -8 -3 -9 -12 1 -1 -5 12 -6 -12 -2 -9 14 -11 9 -17 -2 -17 7 -12 -6 -15 13 0 -6 10 8 15 -14 0 -8 -4 -11 3 -5 -5 18 -3 4 -3 6 12 21 -2 -15 6 12 6 -5 -2 -8 -14 -6 8 -11 17 7 16 -5 -12 -1 -5 -10 -18 4 14 17 -2 -7 3 -20 1 0 -26 4 10 20 5 -3 0 -11 -3 37 15 -11 10 15 -35 -13 6 4 2 2 38 -22 -2 -3 31 14 -13 -22 22 6 11 15 -7 -17 -9 13 8 1 -10 20 1 19 6 15 10 11 -23 2 -3 8 -1 37 12 -7 10 9 -14 30 -1 -13 2 -6 21 -10 15 13 -17 -12 -32 -27 -8 8 9 15 9 23 19 -1 -5 -23 13 23 16 10 -44 -2 -12 12 -12 10 -14 -6 28 -13 10 26 5 34 -1 -44 0 15 32 35 -2 23 40 -5 33 0 -32 -6 -9 -2 -18 -24 18 50 -55 -12 23 -36 -11 32 26 -7 30 1 6 -12 -22 25 -33 -28 47 -1 -15 22 -28 30 -13 11 -27 9 -11 31 27 9 8 -5 -3 -26 -9 -1 27 3 -53 -19 -38 17 25 8 13 -46 -31 9 11 8 -3 1 12 20 22 90 17 38 22 -14 -5 -9 -16 11 29 35 -8 -20 -32 7 4 4 26 -1 34 38 10 8 -41 20 -33 -19 0 15 0 3 -37 -1 -14 19 1 0 7 5 -17 -18 9 -3 -4 15 22 8 5 -18 -1 13 0 24 13 -11 29 -8 -20 1 3 11 18 -11 -21 -7 17 -13 14 -5 -14 -27 -20 3 -2 15 -6 -2 -16 -28 12 5 17 -3 -22 2 -8 16 15 -4 19 31 2 24 23 -11 5 -17 -13 -15 -1 0 11 -36 7 -3 -3 7 13 -14 -16 -8 -18 -17 4 3 5 -15 31 -24 -20 3 12 -20 0 -27 -13 -28 12 10 -19 4 -8 14 12 23 35 9 19 35 15 18 -60 6 40 -4 1 36 19 -5 23 17 -28 24 -8 -24 -28 5 22 18 28 -11 -6 -1 28 40 -3 -2 -10 29 37 119 -20 27 4 4 27 -16 5 15 26 -29 5 6 -30 -24 -36 -10 8 -31 -3 16 12 -13 -44 -9 38 -19 -7 5 -28 9 -23 25 -4 -3 -13 -5 5 0 25 12 -5 57 -40 -12 11 -21 -27 31 -16 12 -63 -47 34 -39 -17 2 54 -6 30 -3 11 -65 -4 -16 8 -45 2 23 38 -10 72 -38 32 -5 86 -25 -48 42 25 -26 1 -8 -59 58 -37 42 24 -3 -15 19 5 35 16 14 -5 54 -9 25 -31 4 -17 -4 -26 42 -27 15 -1 35 -8 -15 7 -10 -10 -32 24 31 -29 11 14 13 28 32 -10 15 -20 24 -8 -1 -26 -11 -15 -35 -16 -24 -6 30 -2 11 -19 -26 10 -29 -72 -44 3 -6 15 6 5 3 6 27 19 -28 10 14 -17 14 13 7 -8 -24 45 -5 11 -15 -19 -15 -6 18 16 3 28 38 22 -17 2 -19 35 -7 -21 -6 8 -17 3 -14 2 -17 -17 8 -6 37 7 -24 2 -39 4 11 38 -22 21 -37 -10 -7 7 -5 38 34 -5 8 19 -30 -11 -16 -1 10 -11 -28 26 -54 9 19 21 -4 -25 -38 -13 17 7 9 22 -15 31 -19 49 0 -7 -1 -9 -7 21 -15 31 -39 -12 -33 20 22 -13 15 10 8 1 2 21 14 21 4 -22 15 14 -24 -40 4 -30 -18 21 -22 9 0 -37 -19 -5 57 7 -14 27 35 33 39 8 18 16 18 0 22 42 12 -43 -12 35 17 2 -18 42 10 42 33 26 -16 2 -14 -6 33 -5 31 4 30 -10 -5 -7 28 29 23 15 8 -21 17 -52 -27 20 -1 17 -16 -17 11 43 17 29 0 -24 49 41 -39 -32 -1 -37 20 62 -3 28 38 7 -25 8 19 1 -14 23 23 10 -3 -56 -1 -8 23 28 -15 -15 -37 -10 8 -55 0 20 -47 -44 -27 -8 25 -25 -7 -3 17 27 31 -42 2 24 -9 -7 30 16 33 -30 29 62 -6 39 -33 -49 37 -11 11 -27 -67 -20 35 -54 -10 27 -17 62 17 -18 -33 -22 -1 -15 49 -8 -17 -1 23 14 34 9 67 -40 -41 -13 -11 -24 0 -20 0 18 106 81 7 22 3 -4 11 -20 -5 -6 -3 10 -8 5 6 -4 -25 10 -63 6 24 7 -31 3 0 -26 -20 0 -35 -4 -8 -27 -1 -8 -22 40 20 -22 3 10 0 -18 13 -12 -30 -13 3 3 -15 -17 -8 -6 -4 -14 -5 -28 12 -27 0 22 6 23 -9 5 17 -23 -22 13 -21 -4 0 -21 -39 -25 5 -2 -2 -15 -31 -7 -29 -6 19 4 15 -36 -8 4 27 -21 -6 11 0 -10 -16 13 40 7 -16 -5 1 -13 69 31 31 -45 -40 -56 -23 -11 31 -30 20 -3 32 5 -6 -44 -19 0 -13 -15 -19 2 -14 -40 46 -22 -9 13 -13 -34 -43 -12 -13 -1 -25 14 -16 -1 9 -5 -27 -35 -59 42 8 -33 39 -15 -48 -6 -21 -5 -17 -12 4 -50 -19 14 -19 21 -17 -23 18 25 -12 21 18 1 6 -2 -35 -36 17 11 21 -9 41 9 -2 17 -24 -23 -4 11 -10 36 4 22 -95 -32 -60 -4 -15 71 28 3 -16 -74 -56 26 12 33 50 18 -79 25 -18 -26 9 9 -30 7 -3 4 -10 -17 -15 -50 -1 32 38 16 -25 51 -16 34 -70 23 24 10 -85 14 24 -73 44 -29 24 -7 26 48 -2 -36 21 33 20 -112 -29 32 -27 91 37 100 39 58 30 37 36 -57 -17 -20 -33 -49 0 -33 72 34 79 -39 38 -8 12 -9 -8 -26 -36 10 20 -9 -36 11 -47 10 10 59 6 10 -26 -11 42 49 2 -9 -1 50 -12 -22 14 -9 15 16 12 -18 20 -5 1 8 -13 4 -16 -17 1 -13 3 -7 13 15 -23 -6 -20 -18 -4 -12 15 -14 22 20 4 -20 11 -29 -8 -13 -16 13 19 -18 -6 -6 19 16 4 66 -30 23 15 -50 15 -57 0 12 -29 -5 -49 2 -2 8 9 -15 24 13 4 5 -30 9 -70 8 -8 16 -26 -33 -18 -25 29 -3 4 8 -27 1 -6 -13 33 8 -20 14 -3 18 25 12 -26 69 28 9 -26 24 6 -35 -12 70 59 -26 10 -38 -4 -34 15 -10 44 -3 -21 0 8 -5 49 -15 1 -28 -5 -9 14 15 -34 28 -13 25 37 19 23 -9 -10 -16 45 23 21 -13 -21 59 14 -15 37 -13 -53 -46 -1 11 1 -66 30 44 28 0 22 19 -14 5 -30 8 38 57 16 3 -1 46 29 3 31 35 3 13 32 -16 20 7 7 37 -12 -15 -17 -23 -2 46 18 -76 22 3 107 30 -21 10 19 53 26 47 0 -24 -26 -51 5 -20 30 -38 -4 -18 -5 48 -11 -8 11 -9 -24 -36 41 19 37 4 32 8 -14 60 -49 19 -4 25 -14 -27 -12 -62 -54 -35 -10 26 83 -13 49 98 3 -3 -38 64 8 28 75 60 27 0 78 -10 -34 35 1 19 -18 9 -44 21 -67 -57 42 5 -21 -16 20 -34 -8 -21 37 34 72 -4 -37 39 -16 -52 -44 91 -3 -29 2 13 18 -22 -38 2 -18 1 -38 14 -26 1 -30 -26 -9 -6 -11 14 21 34 41 -24 -5 6 -3 -16 31 -16 9 45 -13 21 23 36 6 9 19 -13 9 23 -1 -12 -14 -32 -18 30 18 -37 -10 -8 3 20 32 -23 -20 14 6 -30 -15 -14 13 -29 8 24 -22 7 -17 12 -6 3 49 2 10 -8 26 50 -39 -33 0 -4 -16 5 -8 3 -17 22 -4 -1 43 -6 -30 25 56 40 7 15 13 25 -42 -48 -40 -69 57 -96 -66 -34 -73 -36 33 -59 14 -58 -58 12 45 -60 12 -32 39 -62 -26 -119 -62 -5 121 -58 110 -36 32 26 -13 -38 126 -5 18 113 -30 -123 21 1 -32 -68 -56 -23 103 -114 -59 76 19 4 9 -27 -76 -40 -52 -65 -126 -85 -125 68 48 65 -57 51 40 -82 -11 4 43 54 127 -48 -14 25 93 63 44 36 -42 23 -55 39 123 94 59 88 27 -57 -17 -126 86 46 7 31 -4 -87 8 95 112 22 -14 -128 60 -63 117 53 8 29 0 5 -90 -92 24 -84 87 -86 -85 11 -85 87 -60 -15 38 21 -102 -127 -61 -29 123 53 -46 -8 39 -19 4 -109 -30 105 57 -13 -20 43 -66 41 -32 -128 -33 -18 -125 93 77 68 -45 -91 -122 57 -72 -14 -128 41 127 23 29 67 -100 -59 98 -82 8 -43 -63 -101 16 -60 -26 -49 36 -70 92 127 -68 -13 -38 -65 -26 21 70 -64 11 53 120 97 70 -13 68 -4 40 -43 -22 47 -22 -125 39 6 22 -2 -24 63 94 32 -43 60 -50 8 19 -112 -127 -22 -4 85 -48 -15 99 71 -54 -29 12 82 -24 -15 74 -54 -22 -127 74 -30 -9 13 -75 126 -4 49 -64 -62 80 2 -30 -68 -47 -10 8 -22 54 -3 58 127 58 -6 84 -70 67 32 8 21 -96 -73 -12 19 49 -49 -2 36 -7 89 1 -8 -33 27 -61 39 73 30 89 -15 65 102 72 94 -22 -38 73 25 34 127 35 75 33 -86 7 -71 42 112 25 -28 -126 12 78 -7 -72 125 -35 -109 69 -78 39 19 56 -23 42 25 -128 8 -18 -20 115 89 -36 -77 -30 125 -71 87 123 -128 36 56 113 68 -81 29 34 73 -38 -14 -81 -39 45 -90 4 107 3 -82 3 30 77 -14 126 35 -79 62 -127 28 121 56 38 -3 -102 59 29 84 127 -118 55 -48 -49 41 93 54 14 -73 82 -40 -94 -45 96 -49 41 84 93 -127 127 127 36 -2 -30 -79 72 -101 -13 -111 116 -108 118 124 -33 -122 24 92 119 -56 94 30 127 26 -46 39 -124 -52 -15 98 8 -75 -37 -14 94 -53 -50 -57 -114 35 103 96 -2 125 -128 10 -37 33 -78 68 85 -4 124 16 83 -75 127 93 -127 60 -66 -123 -102 34 -119 107 125 -60 -11 38 6 1 -4 -72 69 114 -13 -126 -20 -36 -70 -54 -93 39 -124 5 -15 61 105 83 -17 5 40 65 -6 -126 -34 -64 40 35 64 -8 -7 -40 21 71 -5 -75 9 -12 -62 -30 40 -30 -84 -6 91 -74 17 17 -31 25 -53 -50 32 127 83 -6 7 -56 39 126 74 -91 -51 -33 95 118 -43 -81 60 18 -24 1 31 55 3 88 -41 -44 -21 -5 -40 47 -121 20 -4 -44 121 85 -19 11 -16 -48 66 95 42 100 113 8 9 -8 85 9 85 -99 -30 -29 -11 32 4 64 64 80 -14 -18 49 -72 125 -56 -72 -121 -79 61 -71 -61 9 -4 22 -3 -51 35 -113 48 -38 8 71 10 44 52 -8 -27 94 84 -54 23 57 8 59 23 11 -40 26 4 -104 -75 -68 -127 -85 11 121 -127 -35 3 -88 25 -64 21 -39 49 -26 -2 -128 -26 -36 -19 -78 47 22 -1 -88 -88 28 3 4 -117 7 79 -41 3 15 1 28 113 -44 17 16 45 126 34 94 -97 94 52 -55 -62 -61 -85 27 -58 -15 59 -28 -74 -37 63 -90 124 89 -118 25 -15 30 -40 -119 44 -63 -71 49 -105 67 2 34 33 -96 47 40 -57 44 35 -108 -38 -124 13 102 -96 -36 -27 -55 -111 84 95 53 65 -124 30 -10 127 -24 -36 -105 32 63 -76 -9 -50 78 4 -101 -23 -127 -32 56 0 -53 -81 79 126 -59 13 -123 -70 119 -72 -1 -122 -60 -3 -38 7 -125 59 108 -18 19 72 -83 -37 -127 -44 -121 16 127 -79 -12 107 58 -35 -52 -38 -42 7 -29 -9 -122 78 -49 -11 -82 -89 -64 -35 -5 -1 83 -19 -1 42 34 3 40 -18 -2 -22 12 -84 -42 -38 -1 24 14 6 16 108 56 -123 -33 -33 17 -106 -89 8 -37 -38 -18 7 -46 -40 -85 -15 -36 19 -37 26 3 6 50 -49 -65 -29 -21 109 35 10 61 10 127 -45 12 -10 16 -53 58 11 6 6 -124 -26 -73 -5 28 -11 24 -23 17 18 21 45 -26 -115 12 -38 -74 41 64 86 -30 49 -30 41 -32 105 -31 43 30 -95 32 -79 -73 -62 -99 -8 77 -56 -3 -26 -26 -34 -50 64 44 72 116 -1 126 99 -68 -53 -65 35 -14 -83 -20 -118 77 75 37 35 79 -128 -1 114 -99 127 39 5 -98 42 -22 -45 -53 -40 59 -82 51 121 16 -87 7 -84 33 93 127 -25 -15 -13 -67 98 -51 41 69 -1 6 -108 66 -126 127 21 30 -39 121 13 -128 21 -41 38 -27 124 -124 60 -28 -17 -35 83 -36 44 8 126 -25 -23 124 -119 101 -26 -1 -109 25 -9 -103 -125 -120 95 56 -125 126 127 43 -86 127 -127 -128 -84 -99 -127 127 41 -27 -122 127 -6 54 54 -128 -44 126 119 32 68 125 -62 -64 92 10 -94 38 -123 -56 -21 127 88 127 -117 31 41 126 46 122 -127 83 -53 2 96 110 127 30 -12 -111 -106 18 116 -91 -104 127 20 10 -23 -126 -40 -4 127 -42 97 -72 -126 48 0 11 72 -29 -9 -128 -4 -5 -76 -22 -19 -18 -123 113 43 29 -43 -42 23 17 6 59 1 87 68 23 -11 -126 48 55 105 127 58 -10 -19 43 102 3 -68 -28 -47 42 28 -106 -107 4 -126 -65 48 62 5 23 -5 -41 -62 87 -66 -90 -124 -124 15 -16 30 35 44 31 -14 24 -94 62 -76 6 54 9 99 -35 -71 83 15 3 -10 -123 127 2 -16 70 49 51 -79 -57 60 45 -100 126 -127 -113 -31 -75 -26 33 -15 -87 112 -124 -30 81 -63 -48 44 35 -125 4 -84 108 -57 20 49 45 -8 79 -84 -113 -56 107 -78 -60 81 -124 71 -116 -57 -87 -71 97 -105 -32 -75 64 116 -73 -108 124 -127 63 103 -64 -14 45 -4 -34 109 51 111 -21 2 -22 29 -36 88 20 -29 -11 -23 -93 35 -24 -17 40 5 -79 -26 -117 48 -33 -101 -115 -13 -33 43 126 0 77 -93 29 -103 -119 -67 54 -10 47 -119 -36 -108 97 -31 -45 -1 90 123 29 -126 -79 -33 -53 -122 -73 127 -27 -100 -73 -33 -92 -28 124 38 -120 -38 -125 37 -35 125 -125 53 -79 -11 -82 17 127 48 -126 -104 116 -45 -126 -99 13 -59 -110 113 89 -108 51 125 -75 25 -125 120 60 71 -24 -65 47 58 23 -37 -4 -4 27 110 118 -127 -106 -40 -21 15 -65 -125 25 99 -125 58 -126 -126 21 -52 -124 -125 124 127 -93 -90 -100 -28 107 -21 98 -122 49 -43 21 83 -33 125 -58 -6 69 118 1 -23 -62 -104 -2 8 32 -75 -102 42 -32 -111 73 -13 -58 75 -88 47 74 -47 -16 4 41 -71 -45 -126 17 111 25 -98 -2 25 -29 126 55 -91 -8 -127 -127 6 74 -101 -42 88 -37 -4 -38 62 -58 24 94 20 -10 -8 -82 -39 -48 -90 -11 -45 41 74 -9 -31 16 -79 -7 -51 19 87 11 85 -23 -2 -96 113 -13 -127 48 -4 -50 -61 16 3 3 65 -127 -70 63 -92 104 -77 -125 -38 -124 -14 79 24 69 -23 -43 -99 -67 -127 107 -92 29 -44 -113 66 71 45 -53 -17 125 12 -43 62 82 -111 92 -123 -122 1 -30 65 -5 78 -25 -77 -120 -75 71 -126 1 97 -32 -105 -124 116 -31 54 83 27 122 48 -55 -118 -58 4 102 -23 51 34 -45 68 -128 127 106 -55 -81 -126 -126 -13 -24 5 30 -58 -116 113 77 85 -6 -54 44 -49 -128 126 -112 -121 -60 -32 19 21 -32 -61 -16 -13 101 -128 -16 -62 -76 33 -23 -28 127 -100 47 125 -119 38 -11 -11 21 43 -78 111 28 114 125 18 122 -123 -27 113 42 127 -43 105 -59 73 -56 113 60 19 118 62 -103 85 47 -3 -54 -128 96 -104 27 103 -6 -25 -122 9 -2 -89 7 12 126 -118 119 -25 126 -16 127 50 116 39 79 25 -11 -73 118 -104 106 -111 56 -74 -60 118 5 72 100 105 126 102 -77 -121 -83 -120 23 36 123 44 114 -23 -29 -22 -33 -32 12 -60 49 -45 19 -58 31 -127 103 95 67 5 -47 22 -29 99 -13 -55 -6 -26 -63 20 127 58 85 -12 -4 127 15 87 -91 81 -27 -56 36 -14 -3 -126 0 29 -24 101 -75 -24 47 -49 100 -4 -118 82 -86 -30 127 -5 10 -48 111 -4 122 12 -60 51 -19 -21 56 68 60 -52 -26 -6 -7 4 -8 -58 -88 -39 30 -29 -20 -71 -34 82 -8 -61 45 27 -123 55 -43 32 -6 -34 -62 69 -126 53 -40 11 -125 -99 66 111 3 -66 -11 -27 95 -31 -85 10 -19 124 -128 -47 89 -2 -4 -91 89 -66 -126 -30 7 58 127 55 -41 89 45 1 -95 -29 -4 -127 -38 54 57 121 -105 13 24 -73 -86 51 -47 -91 42 6 15 4 -30 80 -89 113 42 -3 17 50 -4 78 -126 -16 -121 66 42 28 -7 -40 -31 67 43 -94 -11 -32 18 -33 127 -40 -68 37 -102 -95 59 59 28 -35 -27 17 -22 2 -78 127 101 -81 32 72 36 -30 -102 98 -8 7 -123 124 98 54 -118 -59 118 4 -100 -5 -24 -127 90 -44 -128 -87 110 -15 40 24 -59 62 -1 -127 -63 34 -128 127 49 27 -95 95 52 47 -7 124 29 -10 -127 -126 -15 -23 -72 -125 10 113 -82 70 34 -8 -20 73 -46 -97 125 -128 20 80 -22 8 75 12 -92 -58 126 -31 48 -49 7 37 -81 18 -49 119 -42 -122 125 57 -62 74 -20 87 -44 -27 40 3 3 1 -91 -78 8 -39 -9 -127 62 -71 7 10 29 -54 -122 61 7 103 53 56 91 -19 -37 37 102 -3 56 127 -45 2 -26 77 -14 109 47 -7 87 -128 97 59 -13 -50 31 56 -55 -24 50 -8 -124 20 84 -77 -26 46 -12 -92 -61 -12 67 -36 35 -14 24 127 38 -37 16 -10 12 -26 -67 -65 17 12 -84 50 64 32 43 20 17 -29 -13 3 4 -119 -126 36 42 -38 -128 -84 50 -114 -126 17 -59 56 -29 49 29 -25 -10 51 116 32 32 92 38 94 79 119 -106 78 93 127 24 -126 69 9 23 -100 94 -7 31 77 -6 -47 126 32 1 125 -30 -128 -77 123 101 3 125 -17 -55 -20 -122 2 28 -11 -74 -116 -104 45 -72 119 126 -35 2 -64 4 -115 4 125 -11 125 7 -20 93 -51 127 14 7 -89 -84 54 -28 -97 127 36 119 23 -65 71 0 36 -94 -6 115 4 -59 -41 -88 122 11 126 -49 2 -6 52 127 -47 125 123 123 -44 -121 109 -58 -109 106 43 -67 -127 46 64 -67 -123 28 67 125 -125 115 -127 -127 75 70 -114 -8 127 70 14 84 70 126 119 21 -45 -15 -115 -125 -38 119 -80 -75 26 87 -26 -128 54 125 -64 -128 28 -40 -14 119 10 97 -41 -84 45 -68 -5 -62 52 71 -115 34 -29 127 -34 -84 43 -61 -57 -55 86 5 -35 9 -68 29 103 37 -36 -44 -17 -67 -13 44 -36 -9 60 -1 52 -14 -72 -84 -126 126 15 40 110 2 6 36 26 -81 -50 65 98 52 12 65 -48 -109 86 -59 124 -33 116 -60 -41 17 -30 -122 -106 67 -127 15 71 -45 38 48 -73 -20 -41 -36 -44 -87 -72 56 23 15 111 4 9 -14 99 103 44 -18 126 -15 1 48 53 112 -24 24 -32 -67 -104 -17 9 -22 5 83 -104 50 79 -65 11 104 25 24 69 -128 -28 66 126 -91 0 127 127 -55 -23 -79 -14 -44 -128 -123 110 -72 64 -127 90 127 -8 -125 32 -19 123 -120 111 -1 127 124 19 -118 -46 -17 -123 -15 -71 -114 -25 -127 -29 16 98 -110 -1 -3 -128 -41 23 18 -32 10 121 -42 -38 -25 -32 76 -127 11 -99 -125 -25 -58 -77 -20 18 27 35 72 -37 52 51 26 -128 -46 -76 89 -24 121 28 25 -14 80 -98 -36 45 -88 -16 -54 -91 -78 -46 -91 -49 63 86 -46 53 57 51 64 -125 40 67 -99 -16 -123 126 50 84 5 105 46 -66 95 -74 119 -127 29 127 -22 9 90 121 119 -73 95 -119 2 -76 74 -48 16 126 49 -127 -128 109 50 120 -103 -81 -102 -7 44 -87 33 -82 -71 9 -30 83 127 41 -54 48 8 127 -23 106 -126 115 121 -28 43 10 126 120 -36 119 9 -7 -3 -127 -32 -128 -127 -100 -123 34 127 -45 107 -10 -17 19 64 -29 -11 31 69 -5 -73 -32 10 101 -80 42 56 -95 49 -113 -6 -36 -10 47 -2 -101 -127 -39 49 -67 85 -70 -120 -53 -65 28 75 44 -5 -17 -39 -79 90 -29 -94 96 -28 66 117 -11 56 42 2 -47 67 -128 -59 80 -15 127 50 -58 -127 -42 -83 37 37 -78 -68 6 -69 33 50 -27 -30 -41 41 98 -37 79 -27 -20 89 -103 -12 -63 -127 -94 -45 58 -32 1 2 87 77 -127 6 43 48 72 -9 -44 -14 42 -126 42 6 32 62 14 -53 69 -128 55 -58 44 43 66 -38 -128 26 -72 -103 62 1 34 21 -3 -42 -115 63 -105 42 -38 64 77 -28 -71 -108 -125 122 127 -127 -1 40 9 29 -28 -15 -43 24 -115 37 -13 127 115 -51 -47 111 67 7 84 -122 30 -94 114 -49 -32 23 62 43 -92 -6 11 100 77 -22 -41 108 -86 -16 49 126 99 -80 -23 -128 110 127 14 -27 -82 18 60 -19 -36 -122 -19 -83 -25 15 23 98 48 -108 87 -33 -102 64 23 44 -1 102 34 -7 13 -122 106 -44 -127 103 -117 72 115 45 -38 121 0 15 -17 -95 -112 112 60 -20 127 -78 22 7 -127 39 -128 51 -33 -128 99 -125 97 -126 -9 -69 99 -103 95 123 71 -36 5 127 -10 127 -92 -58 101 86 -78 -75 -62 126 -36 -21 6 126 49 98 121 23 12 -26 -15 -128 -5 -104 19 -123 -127 117 126 -124 -42 -73 -35 26 -122 -32 88 109 -71 65 52 -111 -65 -92 -31 -45 -104 -27 58 64 57 37 -53 63 -53 -20 41 60 -45 45 -23 -128 32 -3 -8 40 42 113 -24 -67 27 102 -111 -74 88 63 -18 38 15 17 -46 -37 44 41 -128 -36 -68 50 -128 -34 125 -121 -18 -35 127 88 125 125 51 45 40 32 31 75 41 127 39 8 12 -96 76 82 -17 127 -44 1 49 -5 14 -86 -56 -37 93 -120 -128 -25 -8 127 97 97 83 -39 35 -46 -125 -97 -128 117 72 127 -127 -127 10 115 64 -3 -14 -119 5 -65 124 -114 -81 87 -80 -96 -61 30 -128 -67 31 52 37 -53 -56 55 -8 -89 -117 68 127 -96 126 -126 37 127 -28 -123 122 25 -127 43 125 -34 1 88 40 127 6 -85 29 -59 -116 127 -78 -128 -1 -116 78 -4 -88 64 36 36 56 -33 20 -123 -9 19 -40 12 125 -127 93 -49 -128 122 -30 42 -127 -57 -89 -21 -19 41 -47 -5 63 125 -119 -127 -125 -37 25 -47 -76 -57 127 127 23 -24 -10 77 37 26 116 49 -127 65 119 5 -36 28 124 46 -5 62 48 46 66 19 -48 122 -88 -128 -80 -115 -58 -116 -126 82 107 21 14 -4 25 -85 5 -128 -1 -46 -128 75 -128 -17 -123 -43 44 23 -105 28 111 -81 115 127 127 127 43 -35 -9 117 2 121 -101 -96 27 72 -55 19 -103 -121 -45 -23 125 -30 56 -3 88 109 -18 16 -50 -42 43 82 -104 96 -6 -22 29 103 61 2 -6 -4 -24 114 121 -21 -6 80 -23 -41 -13 -48 79 -79 29 -35 -111 24 7 83 89 104 16 104 -67 12 35 -110 -14 127 -66 78 7 -79 25 -38 -63 52 -127 -121 -3 15 93 104 -52 -125 58 -50 99 -61 -78 -24 -4 97 -22 -48 -22 41 12 81 -58 106 13 -30 1 32 -30 23 -98 -47 -38 -16 57 20 59 -82 -120 54 -39 75 14 1 -81 0 48 35 19 -57 83 4 9 -80 126 -104 -27 -127 74 -98 86 98 -17 25 99 -32 43 42 102 -10 -17 -128 -80 -89 -41 50 90 -114 -17 120 3 125 44 -21 -82 126 112 -113 -27 64 -125 127 15 -60 114 -11 -127 33 82 35 127 -55 79 102 59 -41 65 -25 -107 -110 -46 -123 -56 122 -54 -92 -37 27 61 36 -128 -21 -122 123 124 -109 -9 -19 -92 56 113 -116 107 125 -79 -50 -120 -101 127 32 57 -128 13 34 127 -37 -29 86 -96 -88 127 -90 -62 -63 127 22 69 41 50 126 78 37 -123 51 -127 -99 -85 -127 -86 127 -29 -118 41 -122 62 73 22 -87 -18 -85 -127 -127 -124 -18 119 3 -127 41 -88 -32 -53 -128 88 -121 -2 -65 -125 -52 -66 -121 21 102 -125 121 -47 52 -15 113 127 76 125 -127 127 125 -128 69 -13 87 -127 94 127 -79 92 127 91 48 127 0 -17 -128 92 -67 54 -86 -24 -31 10 6 126 64 -9 127 64 70 -125 23 -10 -56 -82 -36 119 -73 -1 -38 -26 -75 28 -45 -9 -26 2 -68 77 118 -8 -79 107 -22 1 48 -15 3 18 -32 28 -128 60 -59 38 -68 116 -43 -22 48 12 -3 -30 -62 -128 -86 -127 -70 -91 -1 56 -128 -25 -54 27 72 -19 14 5 -8 38 -85 -68 -121 61 -90 34 73 -95 -7 104 -9 -89 87 33 -87 -11 100 -25 -3 87 -68 -45 67 -127 105 29 -15 -71 116 96 56 -128 45 -40 18 -100 -23 121 115 106 108 -75 29 -41 -71 19 21 -127 69 127 122 67 -55 -4 -16 -32 121 -24 -121 -49 127 -92 -50 -128 59 -97 -55 -33 33 127 76 71 -30 -124 44 -34 -96 66 84 -127 5 -61 90 -56 -75 -54 9 -42 -126 -127 -74 -105 71 0 1 -15 -128 122 -33 -128 -125 91 -59 111 -31 -127 -72 33 -97 42 67 -1 -125 56 -60 47 -44 127 76 123 -116 57 107 -125 -89 56 -106 127 35 116 -90 127 -120 0 -98 -128 -38 -21 -78 50 -61 -30 -117 -115 -68 -104 21 -68 125 27 -59 91 -107 -74 8 -63 -5 -6 3 -90 -95 -124 -38 22 -31 -118 -20 -36 24 71 -52 -99 -116 -30 -100 127 -125 -33 14 -23 -111 -108 77 32 2 -119 8 -105 -43 -121 -123 33 -14 -118 -63 11 82 127 113 0 78 127 116 -125 -77 -48 -125 -123 31 95 82 -70 -63 58 -113 -21 -127 -100 121 -56 67 -122 -109 -79 86 21 -51 -79 -128 -4 35 59 -23 86 1 -30 65 97 -126 -2 8 21 2 5 31 61 -7 -51 46 -62 -42 -62 52 31 -7 15 -31 -14 -89 18 -115 -25 116 3 -78 -37 56 3 -18 33 74 -125 -18 -36 -58 -51 -82 96 -126 -26 -35 24 -126 127 115 -63 -27 54 7 27 -63 42 -128 63 42 6 -13 111 -35 2 59 -74 39 -4 14 -33 -109 -45 55 -19 -109 -60 23 56 -8 -30 -33 -50 8 -43 -116 -77 -126 106 -75 -6 -3 -104 -72 65 -117 18 -38 -9 -80 -126 123 72 126 -115 -116 -103 -87 -93 -61 3 11 -39 -96 -25 -20 -128 124 -55 -125 -71 0 127 41 119 -128 60 -6 -59 -44 93 63 -93 -44 -125 -67 33 -72 -8 64 34 -126 -128 -20 48 90 -2 -93 -25 28 126 7 -75 -126 100 -122 119 95 60 107 -98 -111 -47 78 123 -66 -93 -123 -117 110 98 -42 126 112 -128 -94 -121 -22 -50 -128 -17 127 97 -115 54 70 38 -42 -128 127 -128 20 127 103 61 -113 57 49 126 48 -95 122 -122 6 44 -55 116 62 -111 25 -109 15 -128 -102 16 -121 117 -127 -66 -43 -124 -59 -79 20 127 -6 125 7 114 108 -127 81 -79 -33 122 -13 -66 -123 123 2 60 116 -25 -11 -104 22 -59 119 107 28 96 69 63 45 126 6 -60 -81 -28 -63 -28 -119 16 -40 4 -128 127 120 92 -25 -100 124 -75 -81 12 -36 74 102 -25 72 -15 -71 29 9 -30 7 49 -36 -1 48 37 -62 55 37 -32 -127 83 63 2 -86 98 54 2 -39 -102 -128 77 124 80 127 13 -50 -28 3 84 49 -125 -87 -125 59 -67 28 -30 -8 -102 127 126 41 29 49 -38 -34 -10 -119 5 -59 -126 -73 17 126 -63 127 -28 19 -7 -10 -57 -105 80 11 -72 -96 -21 52 7 111 57 -88 1 -111 -15 63 95 -124 -111 98 63 127 -44 125 98 -127 -60 -101 -58 124 -54 -93 122 127 22 47 14 -11 44 127 -61 -33 -57 -67 28 79 -8 -20 -7 8 -3 38 125 -51 127 -125 -88 -17 -109 33 -17 -117 118 23 21 99 127 -46 -48 -4 124 120 -42 -99 -127 127 -6 110 -128 12 6 76 9 -125 -115 -51 127 97 127 37 -66 -67 -19 32 -114 -125 -11 -125 123 60 118 127 -128 -13 127 39 -89 101 21 21 -97 3 -106 74 -125 77 18 124 127 -128 -127 -128 -127 -101 127 35 46 68 38 34 127 -18 -126 -7 46 27 -128 -49 -11 -98 109 -111 -127 108 127 -88 -49 -89 -102 5 26 124 -117 -60 -128 -91 66 75 22 -46 -84 -55 43 -117 -57 -118 13 28 99 -30 -123 26 6 127 29 62 37 37 126 -109 -2 56 48 13 -112 -73 93 127 -43 -83 85 -58 27 -18 127 -80 127 51 -128 7 -86 34 110 81 94 21 -46 -123 -127 6 -33 -3 -18 -118 75 -109 31 124 -127 15 34 -18 0 -29 -10 -124 -31 46 91 -41 -20 -31 68 39 -58 60 16 -75 -12 -55 -45 -60 -58 79 36 18 -27 61 -128 -120 -8 -39 87 -46 -105 125 -9 14 76 126 23 -39 -48 -38 13 122 -69 27 -98 103 113 -49 -12 9 -23 -127 85 -12 -39 39 -17 8 -76 -66 -51 -26 47 -32 13 -95 -12 -33 -128 -116 43 100 81 -124 -104 -117 -59 -83 -107 127 127 53 -113 49 -73 12 -120 66 105 -39 -4 -127 35 -26 -62 -25 -15 75 -113 -114 127 -70 114 40 -128 2 127 12 11 64 126 -107 86 28 80 -62 -57 -100 -120 110 127 -127 -128 54 21 -113 55 30 36 15 61 -84 96 -125 77 -60 -127 -56 25 -44 127 74 42 -74 100 -38 -53 -15 -38 -15 16 91 12 -126 5 106 -102 -122 -15 62 -128 28 38 -30 123 92 -99 127 93 -127 98 15 74 -89 -89 123 121 -83 9 -120 22 61 32 21 -124 33 -89 -32 -128 -1 -127 127 -40 7 84 64 126 93 -8 -128 -127 13 -123 -127 -40 -127 80 -22 127 -125 38 122 124 62 118 -121 54 126 121 86 -92 127 -128 127 -27 95 123 127 18 -59 -65 81 -92 -128 -31 74 -78 29 -49 -5 -122 -119 -76 96 -74 -111 -80 -4 -17 -45 125 -125 -61 -118 123 74 57 -128 22 126 -123 127 -14 -16 -127 -29 -49 -33 78 -39 3 126 127 -124 44 -128 -128 -117 -127 120 22 21 126 3 124 -125 41 -17 -40 44 -53 30 127 -50 33 -4 36 -120 -91 36 -16 99 -6 -23 107 93 -84 -27 -123 44 -42 127 -30 28 127 19 62 103 118 -114 -18 -113 126 20 60 38 -128 -23 -59 10 -63 35 -89 -122 78 -123 -113 -70 -3 38 -95 72 -18 -75 102 1 26 -123 2 -126 109 15 -64 -69 116 -114 124 -85 63 72 127 -14 31 -86 48 51 25 -128 -18 49 124 58 22 101 -37 48 -13 -68 -59 14 40 -5 -32 -27 25 28 21 15 -2 -79 35 30 -34 38 42 -15 71 9 2 -64 1 52 -122 -47 -14 -1 -54 64 -2 -16 1 -54 12 -7 11 -12 -38 81 99 12 12 1 27 -13 -9 11 -33 -58 8 -25 -18 37 -27 -13 -19 15 33 23 31 15 -9 37 -73 21 9 -34 35 -24 -4 26 12 11 -23 3 6 12 2 6 -3 -41 -9 13 -74 1 -30 -2 -8 -14 29 51 -20 11 -36 -72 -28 17 -41 25 19 -42 51 -79 -29 -59 23 27 97 -11 84 -24 61 19 13 -106 -116 -59 -15 47 -76 40 -38 -34 -56 3 79 42 -2 77 22 8 78 -40 4 -54 -21 -77 -24 23 1 -31 10 15 -32 -39 0 8 32 84 -46 -52 21 -7 -46 -1 -43 32 2 43 5 -125 1 -30 -112 79 -47 -42 -20 7 -82 48 5 -78 -65 63 -12 94 122 -70 17 19 -13 -12 -116 -5 -38 50 27 -5 82 -62 7 5 -81 90 23 6 19 55 -16 5 7 -18 -25 -38 32 -73 2 -50 20 66 -10 -30 0 16 -20 29 -16 13 -21 -29 122 28 5 -10 -58 -14 27 29 6 3 -33 -25 -9 -90 39 -81 45 28 -8 53 -78 -7 90 12 30 35 13 127 91 89 56 -43 -3 108 59 -49 17 16 -1 0 -8 -73 -3 0 10 -4 -91 -90 -79 53 -33 109 127 127 -15 -46 -52 -21 -75 124 -102 -39 53 70 52 5 -35 -41 -124 -12 -20 -26 -20 57 59 -107 -56 23 -17 71 -23 -1 -23 38 -54 91 9 -49 20 30 19 -54 -28 -87 8 120 -34 6 88 58 -82 29 125 66 -79 1 7 2 -20 64 -43 19 -115 30 -73 -112 44 -17 42 56 42 4 0 19 -72 -23 50 9 -80 -43 -81 -67 10 60 68 39 47 16 -31 -27 6 -11 25 19 100 111 55 103 -63 -60 -54 -11 26 -15 -19 -67 23 37 -119 -63 -69 8 -2 122 -54 12 28 -116 123 8 -104 -43 13 -120 92 82 110 52 -127 -32 2 32 -94 65 61 51 58 16 -120 -114 85 57 -113 -112 -45 62 76 33 -127 77 -85 30 -61 -101 15 121 103 107 9 -23 125 -82 -50 17 15 57 -13 -72 -78 -23 99 66 -34 -116 -49 3 13 127 32 65 75 50 6 59 37 125 -3 -68 17 -8 -127 -85 -39 14 -87 -69 -112 -51 24 27 65 53 63 -115 76 115 -127 125 -70 46 -53 -32 25 -53 -60 77 -49 43 12 -22 12 60 -9 -19 25 2 -21 44 60 -12 -4 -11 -30 54 37 43 30 -14 -28 -1 -29 -34 109 -19 -50 -31 -106 79 -1 -35 -42 -127 64 -105 28 20 -8 -50 110 -1 -126 -117 -125 26 7 -55 -13 -64 47 17 35 123 100 16 0 -49 17 -47 -107 -6 -51 40 -59 21 75 26 -13 -40 20 8 44 53 -25 -99 -3 -45 2 127 67 -27 -6 3 40 21 84 -5 31 -128 -17 16 18 -7 -33 -60 34 126 -53 38 66 -87 101 44 -21 -58 -82 -50 125 11 59 -21 -51 5 44 -30 33 106 -23 4 -29 -97 -63 -74 -113 -22 -60 -23 -30 57 94 5 59 -44 -50 -11 -65 -1 -17 60 4 43 80 10 81 -128 24 7 127 69 -16 50 75 -80 108 42 45 -109 -13 40 -47 -36 5 -10 35 85 19 43 25 -76 -21 -32 -46 41 -26 -69 -61 -74 -36 -8 7 111 -2 126 -51 68 -68 -33 88 38 -32 -22 39 100 70 -39 32 -107 -81 -12 83 -44 123 -18 38 21 124 32 93 -6 -5 68 -124 125 94 -74 -91 -37 42 127 -120 17 21 119 -9 -14 -53 40 115 34 125 125 18 108 -53 11 53 -51 -127 -57 -103 -31 51 127 -9 17 -104 -127 22 -127 -6 -19 -74 124 91 -2 28 65 89 54 -125 39 -47 -77 -122 127 -10 103 -120 -63 111 89 7 -38 61 -33 -19 -123 -119 52 4 25 -71 -23 37 59 16 66 41 -6 -5 39 18 -5 25 -67 25 -98 2 -50 43 -29 -28 -18 -65 36 49 25 -62 0 -52 -10 26 -18 -15 14 -32 50 18 4 -11 54 -105 5 19 41 43 26 33 -89 96 13 16 14 11 -19 0 -12 -63 -88 52 -122 51 -15 -21 113 -126 -18 9 -68 -42 5 -32 -20 121 -125 -22 -6 24 -50 -82 -121 -66 -5 -84 26 87 92 -26 17 72 15 -21 65 -29 -36 35 -53 -4 49 22 -127 20 -96 30 -5 18 2 -50 123 40 37 19 -27 -75 63 -15 48 9 121 -14 0 13 -70 -104 -119 -26 -17 8 98 -66 20 -120 35 117 43 94 21 19 41 -66 -101 -81 -12 -99 -100 33 105 -115 -17 125 -123 124 -36 48 66 127 -124 77 8 -46 127 53 29 57 13 123 76 -21 -106 -114 67 -37 -53 -15 12 56 64 53 0 97 12 -1 -38 63 -27 121 46 121 28 -64 -126 -65 68 126 15 80 31 123 -128 -37 37 -81 -41 117 42 126 -25 -114 -10 -47 64 -10 2 53 -76 -57 126 40 -94 54 -123 -82 -14 -45 45 -17 88 -14 -61 102 123 -99 86 74 -43 -128 127 -70 -34 127 -3 127 -44 -59 -125 -108 22 -126 91 -118 -126 18 78 -77 -46 39 121 46 -40 28 -127 -116 63 -83 78 5 -60 7 -3 2 110 -19 38 -92 -54 34 113 -12 120 -50 82 127 -59 127 17 -90 31 -50 115 -53 -52 58 -62 30 32 18 8 33 -127 8 -24 -24 -15 13 27 -44 -2 -52 38 40 -51 -102 -65 -117 -61 13 -32 -23 -34 -8 65 60 -67 -39 -93 28 23 103 85 120 9 126 37 -10 97 -98 17 -93 17 106 22 78 80 -9 -60 -41 27 74 -25 56 40 -11 -63 -101 -83 -3 -46 82 -23 92 -7 -111 106 -13 16 -33 32 -82 127 -7 -17 77 -76 -10 28 -37 -58 110 -6 8 89 46 75 53 -93 49 -47 -48 -38 13 -61 127 -106 30 -77 -19 -7 -84 -117 -72 24 -6 47 -52 110 -8 38 -123 29 99 46 -123 -8 -110 -94 -5 -114 23 126 -127 122 -27 89 60 71 62 -4 14 5 36 -25 -42 -89 -126 102 -37 46 -115 -19 -128 -49 73 27 -77 -126 57 -54 -16 106 -121 53 55 -123 -22 14 -9 28 113 29 -120 5 127 -103 20 -6 -54 49 -75 24 -2 9 -101 -24 -127 -18 -71 -127 93 113 1 23 -52 -47 116 28 -61 113 101 -53 70 12 -126 -125 124 -42 -61 -4 99 17 -109 -3 -123 70 122 83 -5 -26 127 15 26 68 -61 14 -127 -10 26 117 -80 121 -123 -65 -47 65 127 -15 71 3 -59 -36 -126 59 0 -82 126 24 127 120 11 65 25 126 -70 -59 126 -3 -114 -63 -124 125 -12 126 -124 127 34 -6 -42 4 11 -48 74 19 14 -120 48 9 17 2 41 71 15 -78 41 57 50 120 -93 84 81 47 -21 -88 -12 78 -37 17 51 -18 -53 123 14 -82 5 52 -10 33 -13 32 13 18 111 -43 31 -103 -125 -2 29 -29 12 -42 -24 -47 -10 102 -21 -26 16 7 -11 86 -29 12 -26 123 21 71 44 19 -116 29 -51 37 -68 57 -43 -91 -50 16 -29 12 4 -27 38 -6 18 -20 -19 -13 3 16 72 -67 -34 -116 -30 75 -31 36 -57 -28 40 40 -73 25 5 -4 -60 -39 35 -51 55 74 -78 94 63 -61 79 -102 15 -53 109 106 8 125 44 5 68 21 127 -98 -100 30 15 88 -65 -35 1 -49 47 2 87 -39 -121 -74 29 28 -116 127 -10 127 -60 -10 97 19 127 -54 27 95 -103 -25 -4 24 15 74 -44 56 -25 127 -64 -53 50 -3 -99 122 19 29 -41 2 21 27 -99 127 55 88 66 -25 26 81 -71 34 -26 -58 -65 -112 -72 52 37 71 66 -25 -34 -45 70 107 64 -126 -15 -50 92 124 -20 -32 36 70 80 42 108 124 36 -34 -27 -76 8 -34 -123 3 -115 -6 117 -11 -8 45 103 -119 38 -89 -8 -30 39 48 -48 -70 71 7 -52 101 71 74 -30 7 -66 -61 -69 -22 -45 59 61 41 127 3 78 -100 123 -61 75 25 -72 39 -87 111 -72 -23 23 -123 -18 -46 -1 15 82 -42 -118 127 -14 -43 11 -89 51 -85 -53 -16 -71 122 7 80 79 16 -43 -68 127 -28 -39 -98 -35 125 -115 -5 74 -63 -27 -57 56 -34 -52 10 32 -77 -46 -28 -23 4 65 -128 42 3 -32 123 1 31 -89 -19 81 52 98 0 -40 76 -37 -32 47 -73 22 64 -76 23 38 109 36 10 58 9 -1 69 52 46 108 93 97 66 -34 15 48 80 -97 -60 -49 -126 -29 -68 15 0 3 0 -62 85 -53 -60 26 74 -127 126 -54 -17 127 24 3 -33 1 12 61 -29 -102 -18 -26 124 76 12 59 -101 -6 -29 -73 19 -31 -7 34 10 -3 25 27 -128 -28 -46 -79 -11 24 -19 -89 9 102 -18 -28 -30 -30 -81 -54 4 62 100 19 31 23 -7 5 41 -125 -33 8 -94 -37 15 -32 3 7 54 8 -111 -45 -22 -19 28 31 -22 1 -38 -36 50 54 -34 34 -89 11 22 -51 -40 -32 -49 -88 -67 33 111 47 -23 4 -37 -11 -13 48 -4 7 -46 0 -44 -117 49 26 44 -40 -104 -25 15 -7 -5 -25 3 27 16 -1 -50 10 -107 38 -35 18 -9 28 -22 -23 -62 57 -13 51 25 14 -38 46 -27 -45 56 11 -114 -58 44 3 63 45 27 26 27 -51 26 18 -81 45 -17 48 -125 -27 -48 -19 8 72 -55 9 24 -40 3 -1 115 33 20 35 43 32 84 -36 31 41 32 -57 -62 0 -21 -104 2 -13 29 11 29 -25 40 -53 -23 55 45 -80 9 127 -67 -7 -7 13 22 -128 2 -17 -33 1 -40 22 -24 -22 36 -21 89 28 23 2 14 -18 -42 -29 -14 7 -8 3 -70 -26 -51 21 19 68 -2 6 0 16 -20 19 -28 63 -34 39 -123 12 -67 -40 -65 25 2 -61 -7 -7 3 15 10 42 9 -6 74 -10 7 -59 17 53 -36 76 10 27 49 15 26 42 44 17 91 80 31 9 43 56 -19 31 -60 -80 -35 -30 -51 67 9 -10 101 -32 90 47 42 -8 -89 -1 0 -37 94 45 -83 69 -38 -48 -80 -86 -3 15 18 22 -50 9 -46 -14 -11 -12 -74 -17 69 1 102 -82 33 -125 -42 122 -45 59 -19 -18 -3 92 86 -80 -6 -62 -4 16 3 5 64 127 46 -39 -15 -8 31 -84 103 -2 0 -51 -70 -92 2 39 98 14 42 -25 55 67 1 -31 -64 121 92 41 76 -58 93 11 107 74 3 -57 108 24 -50 -32 92 68 -2 -75 82 118 109 -27 -32 -81 -17 50 -13 -30 -128 24 -21 -85 4 15 45 -46 120 -36 12 46 60 31 -47 -89 25 -43 7 -31 -65 35 24 -126 -71 -4 -13 -90 46 74 -15 65 -28 -62 -77 -51 50 -42 -47 7 52 44 1 -8 24 -74 77 30 -107 -97 23 40 34 -1 -60 -8 -45 127 -16 -11 31 -91 -58 -26 69 5 92 -15 -43 -10 -70 -1 67 110 59 122 3 -35 76 11 71 14 -21 101 40 -26 -17 -86 47 -52 -3 62 -77 14 29 -9 30 63 0 -36 -28 -56 116 16 27 -3 14 8 15 106 11 -4 -35 6 -4 4 -27 2 -1 51 67 -1 -81 38 0 -33 -11 31 10 17 24 -16 -33 -29 -12 40 30 56 24 -73 57 -128 50 -66 -22 -33 -71 91 11 -17 72 -13 -59 68 -84 -12 -106 -96 11 -55 4 -55 -30 104 46 29 17 116 -127 4 -71 -24 -68 -87 -4 35 52 -89 67 -58 46 6 5 66 1 30 -18 -23 -128 65 110 -70 92 -55 -45 28 -22 119 -71 57 -98 44 29 43 80 68 40 82 -37 -47 127 -86 12 122 -40 38 -44 -18 -127 -38 -20 120 38 0 -8 61 4 74 -99 46 44 12 24 -81 -43 -3 19 10 22 88 -59 -77 -99 66 -121 120 -91 -13 -88 -1 -25 -100 -60 -28 37 102 -76 -73 -73 -27 -63 50 -2 0 51 -10 42 -23 46 -33 -1 99 75 -127 1 -49 23 36 27 70 34 54 -124 -30 -47 37 96 -46 -44 74 -62 -84 -40 -32 11 39 0 13 107 -29 127 82 -97 39 -12 -44 -15 125 26 38 -38 -49 -9 87 10 -7 -61 4 -51 14 40 97 35 -25 -4 -17 64 -55 41 72 62 20 80 -104 63 49 17 -3 -117 8 -13 66 36 27 22 -13 18 -17 -55 57 1 -5 -79 -59 -26 -39 92 -90 56 32 -33 -101 -2 -57 43 -13 14 -11 -4 26 45 -12 53 -13 -3 42 46 -113 30 -56 -3 -9 37 124 -124 -26 69 31 -5 5 -50 127 64 -44 7 -73 -25 -31 -58 20 68 6 5 -28 114 75 73 26 -53 8 -128 -123 -59 7 13 3 -35 48 -10 55 27 -39 72 30 -25 43 -8 -28 37 -66 -30 54 -65 -10 56 -85 -128 -29 87 37 -24 -37 -38 -35 58 66 19 -17 12 -12 -17 -81 -23 -3 -31 -22 -60 6 48 -127 -75 -47 19 -9 97 -30 48 76 55 64 -8 -19 -82 -46 -75 -17 -1 5 -22 96 38 -71 84 26 -11 32 35 55 -61 -11 125 -66 29 45 127 -38 -19 -20 -42 -22 -14 -26 44 71 11 -100 123 -22 -40 1 -8 -114 1 125 6 16 -38 -89 -51 0 32 2 29 -127 -2 -8 -87 52 34 46 -37 -23 -126 -84 -82 -117 93 -56 -12 -23 33 -5 33 -94 -98 -48 52 90 70 106 -15 52 -117 -37 -67 -65 -88 10 -42 -42 -128 -25 -36 16 19 28 -18 -75 16 20 87 56 -28 14 -34 15 -12 -128 -38 114 -57 -20 -32 -38 -15 11 48 40 -6 -47 88 127 -79 10 -55 -92 10 83 -12 127 -11 26 -2 28 35 -13 -62 -51 47 1 -52 44 113 -34 -99 -20 14 49 -11 -67 39 -128 -55 -121 24 -86 42 13 -22 -73 -45 9 -121 -118 81 90 36 23 -125 -57 83 -19 53 -18 -92 -85 -36 -13 20 34 37 -47 -32 26 -61 -59 -4 5 65 -46 -14 53 -54 -42 -4 0 24 2 96 -9 39 5 -13 -100 53 -17 80 32 -64 -109 -10 -27 15 -19 25 5 -127 9 50 31 2 -40 15 22 -32 -45 12 2 104 -33 -23 -7 62 14 2 -31 -21 -74 -5 6 78 104 34 -93 34 33 7 -33 -67 -31 14 22 85 -6 -72 -10 109 -48 73 -60 -5 -10 8 127 7 49 12 66 62 0 87 13 35 25 73 5 -69 11 -20 -33 -71 52 65 -76 48 33 127 -5 -25 -51 44 -32 104 14 22 17 -49 56 -9 45 -20 66 -14 -91 106 9 -83 12 55 8 56 30 2 -67 -101 2 -88 74 -81 -39 -14 24 16 35 -10 113 -19 -25 -48 111 -11 -17 -122 -32 70 4 -24 -26 70 -45 50 -18 3 -60 102 127 -42 -38 124 90 126 64 -99 -120 68 39 106 29 61 118 -56 75 -76 58 29 22 127 -24 -109 70 95 -68 8 27 -34 -23 24 6 -128 -48 -97 -62 -48 -14 18 126 -84 32 42 2 -70 83 29 -125 26 5 94 -100 76 -20 36 -7 33 68 29 -11 -77 93 6 -74 -50 -16 95 22 48 0 15 118 16 -33 -36 -43 -77 -50 52 -9 -19 95 -61 -24 83 67 13 -40 70 116 101 -95 1 26 95 -21 72 -7 -28 -80 59 123 -97 44 -15 118 -57 -81 -18 -124 73 89 123 -16 31 49 1 -86 64 34 -56 -43 -25 52 -92 -67 127 55 80 -33 28 62 -3 -125 -6 53 -7 32 27 -93 38 2 -37 -40 -59 -36 5 -44 3 28 44 -50 44 -29 14 8 21 -20 111 15 -4 -28 -3 127 3 -1 -35 -9 124 -8 -5 97 -13 -2 36 45 -5 32 -43 27 -63 42 20 126 -27 78 -33 -66 -45 -11 16 10 29 55 -122 71 39 -1 85 -37 97 36 27 -88 91 -68 25 -29 -47 -30 21 7 14 13 -85 -75 -127 -5 -42 39 -29 -124 12 32 30 40 126 -46 -107 6 50 80 -1 40 20 -18 17 -19 -1 -30 13 -118 -65 6 -25 -113 23 3 -83 58 103 -12 -88 -50 26 36 29 104 79 68 -89 -62 -17 -10 -17 125 -41 -71 19 54 39 111 65 -23 48 -33 -56 -38 23 -125 -50 32 122 -60 7 86 120 13 16 4 60 27 59 50 -68 -70 -14 20 -117 -122 48 -65 78 0 -50 73 14 34 -46 -118 -64 -29 -77 10 16 73 -124 -60 4 -57 35 6 33 73 -74 -113 -35 69 79 -34 -106 98 -39 10 75 -32 110 -107 -92 125 -121 -21 -42 7 -74 1 126 -25 6 68 71 15 -39 30 66 67 -101 -47 -16 66 -41 -79 18 14 -32 22 -74 -41 -59 27 10 59 -30 54 15 -55 109 52 -91 52 13 -39 -82 -66 -27 27 1 17 -10 27 -6 -28 53 -75 94 68 3 26 -18 45 38 127 40 -13 30 -60 65 51 -48 112 -3 99 10 -16 15 19 9 -13 42 -66 28 16 -36 -14 -59 -24 -26 31 -40 36 -43 55 4 9 58 34 -9 -12 -51 44 74 -67 13 -22 40 12 98 24 9 -41 -13 -22 58 6 -10 18 -30 28 -8 -113 17 -13 6 -20 43 21 8 -4 53 122 -3 0 48 -81 6 8 -57 5 0 -7 53 30 127 4 3 -27 96 7 64 -31 85 -37 63 21 21 -13 -7 57 -87 0 103 -79 -35 15 97 -5 -62 18 -34 10 1 -42 53 -2 55 -15 -125 -56 32 -11 -9 18 1 -15 23 78 34 90 6 35 73 104 -24 27 -31 27 23 -124 -1 -69 -23 1 -44 -127 39 -124 124 -30 -58 127 -31 -126 -121 121 -128 -95 -128 37 122 49 26 -125 46 -128 -127 -26 -128 22 54 43 -33 126 -81 -126 14 -36 40 -127 -22 -66 -6 36 -122 -6 -22 -112 -40 51 34 -126 27 -8 -32 -121 -55 -26 -63 -127 -17 7 -127 90 -83 -11 62 -128 9 -95 -110 24 63 112 27 -106 -64 -18 -62 3 -119 -128 -83 -46 -121 -25 127 -24 3 -40 118 65 123 2 4 86 -51 12 -77 52 21 43 75 -77 -121 -115 50 25 -11 85 37 71 91 80 -35 -52 48 -45 -56 41 29 73 71 45 34 -91 -33 53 -61 -125 127 2 -78 -127 95 51 -45 123 78 -49 110 55 49 121 -2 -50 -32 127 -26 -112 -38 36 -27 6 -5 104 111 -12 -11 -20 -48 84 -92 -10 -31 74 -25 -74 4 -49 24 -63 -46 -14 -1 50 78 45 39 -17 40 -38 34 53 -113 -47 -10 32 -59 -23 3 -89 -14 44 -5 -3 -6 -14 91 -93 -75 39 -24 95 -21 -128 112 -65 -88 -49 127 13 -113 110 5 127 39 98 -12 42 47 26 127 28 36 21 -127 4 127 31 -43 48 16 -58 8 28 -107 10 22 -27 40 -13 51 98 12 -19 29 -1 -20 -29 61 78 3 -57 45 27 -34 -26 -54 83 31 -51 -52 32 75 -18 -70 67 -41 -16 64 -43 -48 -39 4 116 -38 -14 -69 51 14 21 -34 -1 -86 105 101 -29 60 -55 -72 55 87 124 122 -6 63 -2 13 -72 16 -84 -47 103 -34 -67 -128 40 126 -42 78 -15 -15 124 -127 3 6 -33 34 80 48 61 -126 -92 57 16 41 -106 -55 127 57 1 -113 43 -19 -84 31 52 25 113 69 11 -42 -69 89 12 39 -17 19 32 80 46 117 -7 -15 -125 39 -66 -104 56 25 45 70 -62 -128 9 -77 11 27 -56 2 -9 -74 95 112 -8 52 43 11 46 101 27 79 -69 -34 14 -32 -128 49 82 -69 -36 36 -36 16 -128 5 -22 -22 22 3 32 -1 25 43 -50 36 52 50 -45 -19 -128 -25 114 -55 75 75 -113 112 -58 -111 -25 96 16 53 -42 21 -40 114 93 -19 99 5 -70 30 16 127 -54 -69 -73 -34 -15 -65 41 7 -5 -13 -18 13 117 -4 63 75 126 74 -6 -1 21 1 -3 26 29 44 -20 -45 34 51 -23 49 48 127 37 -12 -76 -44 26 5 -7 -14 -17 24 -12 -126 -16 -38 -40 78 51 26 85 -57 8 -27 -97 34 -29 124 25 127 2 32 -34 -12 93 -18 -25 -57 -30 91 88 21 -57 -25 14 -123 17 -29 54 20 126 -2 80 34 -96 -127 64 -31 -96 16 20 39 -2 4 -8 -4 91 0 -26 -11 41 -32 -96 -105 -19 16 -19 26 83 40 -30 -90 39 -48 47 -41 109 -45 27 -126 -34 1 92 -14 -14 -31 45 -85 -26 29 12 3 -27 -69 18 92 127 22 -46 72 -11 68 117 88 33 -128 11 124 -127 8 127 110 -57 -9 -27 124 -90 27 -51 -16 124 -127 126 -35 -35 119 -29 11 -23 122 -60 -93 -69 69 89 6 127 -45 -51 46 85 -113 -123 -22 -12 89 35 58 40 -3 83 69 125 60 -36 96 127 -39 69 120 -90 26 -28 -54 75 15 54 7 3 -92 -120 32 -27 -38 37 -64 38 112 123 51 -2 112 126 60 41 -119 -14 -116 23 52 50 83 -127 -2 -113 29 -10 -55 64 -77 50 84 51 -14 -106 73 101 -1 -35 24 20 19 -58 10 13 -33 -71 19 -43 -17 -79 -93 47 -16 -4 2 96 -60 2 -115 30 -65 -28 108 -102 -111 -53 126 -4 -93 67 -22 67 -40 -72 124 -67 -87 -28 -27 -49 9 -25 62 -127 -94 121 71 -65 -57 7 37 31 -4 21 46 -122 -10 80 -26 48 41 -113 -127 -3 79 15 47 20 127 73 20 62 11 -54 -45 -30 69 38 -31 -27 -128 86 51 0 58 -15 7 -16 55 -8 2 127 -50 10 127 -35 114 24 87 -122 -64 -74 -33 -79 -11 46 -117 64 -127 119 -68 -81 -101 -42 19 -44 111 2 43 -127 -11 114 -127 -9 9 -100 -32 -21 126 -60 17 127 -96 -69 -121 -126 55 -119 7 -20 54 -47 -126 40 60 -15 -22 11 -95 -27 46 -128 33 -3 4 -83 -104 49 -53 127 30 123 34 -33 -27 -69 -10 -69 69 -91 87 -113 20 -83 -48 17 81 120 -58 -124 -51 -40 70 67 -49 29 -9 95 25 -126 -83 61 127 -51 -126 127 29 44 49 -128 -10 -32 37 112 127 62 18 74 127 -78 -116 40 10 68 50 65 0 88 -97 73 -14 -53 -82 -72 46 -128 -62 127 66 125 127 97 26 127 74 -28 -70 20 -26 -13 110 45 93 50 34 96 -23 -23 -111 -90 -3 111 124 -45 -27 18 -38 106 13 127 94 127 -67 101 126 119 46 -12 -43 55 -7 66 -127 127 -27 -15 -33 -37 -92 -85 13 8 -11 0 64 52 -28 127 -123 -124 39 -53 -71 -31 -48 -112 20 23 79 4 81 74 -16 64 3 127 119 2 5 59 -31 2 68 -65 127 -35 98 100 -124 -8 -127 127 -10 -111 16 9 80 7 23 83 61 -127 17 107 -24 60 -50 -77 -127 -44 0 -29 56 19 56 -42 -53 -17 2 -96 34 27 92 -60 -37 85 77 -53 76 9 -3 -23 -63 -34 47 -39 -14 6 -22 20 -6 3 -4 -35 19 41 119 84 115 -11 16 16 -60 -11 -114 1 -42 33 -82 42 19 32 -19 14 -63 -62 94 65 -40 3 -109 -42 55 -105 -97 -118 -11 55 10 67 -127 52 43 48 -55 -37 44 31 29 -27 28 -128 -64 -127 -35 3 69 -11 74 -6 -79 33 -29 31 -22 -55 -60 35 68 -16 -11 20 -94 -27 61 65 14 49 -2 57 -72 -61 47 -17 0 -31 8 7 29 14 26 78 31 2 -3 127 -51 127 -75 -69 82 17 64 -54 -128 3 12 -100 19 -36 84 16 -47 127 112 -2 88 -106 127 -53 -23 -17 83 32 95 -55 126 -57 -25 -24 59 10 24 112 98 42 -101 -4 -53 82 -59 51 44 37 -57 -115 -42 -122 -46 127 -122 -101 10 31 -16 -13 119 -84 -29 24 1 25 101 117 8 36 114 -6 33 127 1 56 -69 31 31 -53 -9 123 46 -31 -25 -3 32 -33 -60 -20 30 -72 -64 52 21 117 81 -27 28 0 8 9 8 -52 -39 17 102 67 53 44 -28 126 -16 -10 30 9 -37 -124 -23 69 -43 14 -40 50 -8 16 -15 127 90 30 6 -4 -48 -113 2 -33 127 40 77 34 -115 50 -87 -20 41 27 105 14 91 -24 -33 3 0 22 -65 73 -37 100 13 -64 -63 23 39 -46 30 17 36 112 -10 -80 24 3 21 22 15 64 65 125 95 82 78 -68 -36 11 127 61 101 -21 4 123 -21 -64 21 10 -25 -5 -15 -73 32 29 42 37 9 -29 -72 -62 -126 -7 -73 -37 16 35 11 122 45 -52 -29 65 -51 82 86 2 -10 0 27 38 -39 -119 6 -40 -6 68 -127 9 30 -21 -95 42 54 92 5 -68 -4 67 54 -25 -35 126 -72 -37 68 -11 127 11 31 -84 -47 -40 -120 70 8 -35 127 -59 -40 55 -59 47 -19 10 3 52 40 -67 17 52 70 -3 2 29 -13 -49 28 71 -67 -91 75 1 -22 -88 1 31 -33 -48 59 -36 48 78 -45 -118 -50 69 25 58 -3 -109 7 115 -63 84 -13 -43 100 37 87 -65 113 -46 127 5 -16 -93 -117 14 15 8 45 59 -2 -100 -83 17 28 -15 11 -49 -12 -58 7 15 -116 86 50 -50 -73 -95 -106 20 -76 1 11 52 113 33 2 -45 -6 -62 69 10 118 -12 127 23 100 -10 28 -2 46 18 -73 68 61 -60 -52 38 -76 70 -69 -73 21 -35 -9 57 41 127 -119 11 -36 -10 16 -51 -121 -13 76 -126 -14 20 1 -34 -44 42 14 -110 -33 -123 -3 -77 -19 64 -21 53 -12 19 -53 127 -14 86 -24 121 63 34 -19 56 120 49 6 126 -106 6 96 -25 -120 34 38 -45 25 -16 45 -74 70 -59 -54 -44 -3 -10 -50 -22 -62 61 -39 -125 79 -120 -30 37 -1 52 33 -113 20 -13 127 -30 -13 14 125 59 -124 -27 -3 -56 -25 -78 126 84 -86 77 -41 -17 -22 37 -5 46 37 -128 54 -49 -35 -54 -43 24 40 10 -77 9 12 -5 -6 -79 1 -31 -33 -85 -32 54 -53 -5 43 69 74 -34 -109 3 -10 -96 -80 -100 39 45 -64 41 -11 13 -33 -47 47 -56 1 14 -1 -9 123 5 14 81 42 -49 -20 5 -51 18 -16 -35 -23 59 -127 -29 -127 -11 125 63 -18 18 13 48 12 85 -27 28 -99 28 8 -69 -29 -7 8 101 -60 -62 109 64 33 33 25 -7 -18 24 15 27 14 -11 93 -14 -24 10 7 -53 -23 -31 -1 -14 -11 -14 6 7 1 37 18 -1 -29 22 -30 -8 14 19 -64 6 78 -24 8 -26 15 74 -12 -7 23 -36 127 -34 -12 -19 53 7 -73 38 -15 50 40 32 28 1 16 -9 28 1 27 2 -33 63 83 -82 -19 -42 32 -22 35 -17 -10 10 76 2 23 18 28 -15 9 -18 -42 -6 38 24 30 7 11 84 -75 -41 26 9 12 15 2 -14 -2 12 -11 9 -46 -24 -9 32 21 -64 9 -35 13 -12 29 5 25 -52 -49 -2 25 2 9 34 -62 -5 -26 -11 -6 -72 13 61 18 13 -17 -9 14 -17 -50 -36 38 123 -4 12 -7 -18 -78 34 -41 -16 11 9 -14 2 14 19 27 31 13 0 40 -32 -13 51 19 -12 32 53 -8 16 32 5 1 -2 2 19 77 -15 -1 27 48 -20 47 -22 78 17 -9 -59 12 -18 -4 -101 -28 10 1 4 12 12 -3 -9 38 1 18 10 -14 5 -13 28 -19 -9 -23 5 -6 18 12 -6 12 9 43 -68 -9 7 -32 -1 5 -10 -22 -11 -26 -8 -30 4 -36 -27 8 0 -24 -8 17 16 -42 16 -4 18 -30 13 1 62 8 22 50 26 -36 4 -32 -17 5 -64 -10 -34 -21 10 -94 -15 8 11 -39 5 29 0 1 40 -2 11 -14 -36 -23 -23 -28 -44 -3 -13 73 11 -9 28 50 -9 0 -45 15 -17 -48 -10 13 -74 11 -11 37 -8 5 -28 -7 -58 25 -33 49 -7 -53 -9 -4 -8 0 49 -19 106 -11 -16 25 -26 -3 49 0 -66 -26 -24 27 -3 -23 12 6 2 13 27 -40 32 -10 26 27 27 66 6 -22 7 0 -44 -1 -22 2 -1 -15 -33 -8 -4 -8 -2 -33 -89 21 4 14 -40 1 30 -25 -16 10 -8 10 14 8 -16 -39 -31 -61 -9 -36 22 -15 16 -16 -69 -32 -15 -24 -13 -16 29 4 4 -26 -51 -16 0 -14 1 3 4 12 -33 -11 -13 5 29 17 -16 3 88 34 -42 -18 -21 50 36 16 43 -51 -40 64 19 -35 44 -123 -14 -59 -46 30 50 21 -64 -47 -88 126 15 -33 -8 -5 50 4 -68 14 -29 -36 -46 6 -36 16 3 -16 -11 25 -6 -8 -14 -2 -7 -12 -84 -50 -14 35 22 -9 16 25 -1 -1 -9 -15 -59 10 13 -20 -38 39 13 26 20 -6 71 0 -1 12 0 -60 -2 5 -26 28 -16 17 -6 -16 28 -5 -21 15 19 54 25 11 21 4 -5 18 -35 -16 68 -10 14 41 -7 23 -3 -33 1 -14 -1 36 -1 -7 38 15 15 -27 -70 -23 34 13 1 -12 26 35 -31 -13 -26 33 -26 5 8 55 -14 0 -25 14 0 -12 10 -4 -7 45 -3 -28 32 1 -14 -96 8 8 -9 12 8 -23 1 10 66 -13 9 -12 20 11 22 -62 32 -27 24 -55 82 -19 59 127 -36 -23 23 35 12 -11 15 -21 15 -65 -39 -23 -9 48 28 33 -120 -7 5 41 -126 99 37 -120 -33 -34 -31 27 -66 -124 -20 -78 -68 -36 9 50 41 -48 33 -53 48 31 -21 -24 -34 -115 23 26 -13 -125 39 66 -43 82 -48 12 -81 -28 -117 68 -42 46 -23 10 -13 -32 -49 126 -12 -25 -14 6 -19 56 0 101 35 -11 26 37 -77 -6 90 12 -3 4 49 88 -27 -46 102 -99 37 29 -37 -8 24 24 24 -11 -28 -20 69 -36 56 0 -8 14 -51 109 101 5 53 -11 -43 -14 -59 60 71 -4 -40 -5 59 21 85 119 -5 -71 33 -29 18 -22 37 3 21 74 113 95 56 -81 6 33 -82 -2 35 -3 121 12 -32 -74 -12 -110 -35 19 28 63 -13 24 -11 -18 -52 35 -9 -11 60 20 -8 48 -120 -67 64 68 28 108 98 6 42 13 -43 -7 -57 -128 -60 80 27 -32 28 -18 90 44 -55 -76 -124 -8 -13 4 -83 -40 -42 68 58 38 -58 107 57 65 -51 -115 1 -62 54 -5 -14 78 32 -93 7 -23 -8 -54 40 -79 51 73 99 22 -119 -10 90 -54 -70 49 38 -96 -24 13 -91 -90 35 -35 -62 41 -40 71 60 -17 84 6 -126 42 32 47 65 46 42 -50 -26 82 -21 81 67 13 -47 4 35 11 -125 -73 -41 57 -69 65 11 60 40 7 15 56 18 -35 127 -81 -41 64 -30 -18 -84 -20 -5 101 84 -69 3 -69 -26 15 -47 -11 44 61 -11 -32 -49 -25 -111 -46 0 -9 11 -14 21 -21 -40 -94 34 116 31 19 26 87 41 -74 -50 119 8 -30 47 90 34 -5 -23 -4 -64 46 -62 -109 -39 27 -59 13 -10 -63 17 27 40 -4 83 -54 34 32 -61 -25 113 4 -114 -13 -41 -79 -20 45 100 -122 -38 -112 2 -127 63 -111 -17 -13 78 -6 28 93 65 43 25 -100 19 26 107 -25 85 -22 -57 -8 74 -66 33 1 -2 51 95 -7 8 8 9 -65 -63 84 -77 -18 -65 68 45 -15 -21 -15 12 -18 -47 50 47 5 56 -80 17 -5 -119 58 16 -1 10 -102 24 -111 47 -20 -96 -36 -58 55 -20 59 -96 34 -79 -22 122 -7 1 -13 5 10 -40 17 27 39 46 -57 38 -9 -31 -27 46 -34 -58 -38 7 -1 -58 -45 34 59 -17 -13 -4 -71 -14 20 30 42 29 0 -6 -11 -37 -20 67 -37 105 -49 20 92 -27 -42 82 1 25 51 32 -78 19 -5 57 34 -103 109 -72 -77 -48 12 -119 23 4 -51 78 64 -4 -12 124 -43 2 -82 10 -47 40 0 -49 -53 33 47 -38 -54 6 2 10 -46 -5 64 22 11 -79 -7 -61 -28 95 20 113 -10 11 -60 55 -121 121 39 22 -22 49 27 -68 57 6 -15 24 6 -44 4 3 -72 -47 63 -49 61 52 12 -7 -17 -68 -77 -28 110 4 23 127 -33 54 23 10 23 31 77 -18 -30 -60 -34 -8 -27 43 -32 -14 -116 74 53 125 -10 -81 38 -11 -42 -73 -37 123 -50 -21 65 -65 -103 49 -55 70 54 7 -37 111 -78 43 59 -52 31 10 48 1 -87 -3 8 -51 53 7 62 -7 -103 -3 70 95 3 46 65 2 -33 -39 31 104 37 -17 37 106 -31 5 20 -100 66 -45 -32 7 55 -82 37 -53 45 30 34 -8 69 -118 41 44 51 31 -68 56 -122 33 -36 71 -123 52 76 47 46 76 58 78 -12 -28 -56 6 123 -39 -52 -33 67 -36 -33 25 5 14 21 46 -19 56 37 0 26 -26 -17 -109 15 -47 38 -74 -83 1 -53 39 40 50 64 25 -49 86 -40 -30 122 -127 71 -61 7 -80 -88 -71 -85 -4 -65 -27 125 -124 26 66 -127 -63 -35 -72 35 42 19 84 41 -73 56 48 -71 -32 -66 21 -72 -4 -52 -1 -29 -13 105 -18 -13 -90 -51 40 17 68 74 57 114 -6 -16 55 -45 -13 42 28 9 -30 -50 34 34 -84 80 -82 109 -1 10 -13 40 -117 32 -39 -12 -26 44 -14 -116 -13 -50 64 73 -1 -24 87 1 74 36 -77 12 -26 64 13 103 65 40 -55 -127 -33 -12 5 -104 62 17 -46 6 34 -87 55 30 94 -53 46 -30 -2 -5 72 -29 20 69 -3 2 -43 -30 66 -46 -82 55 61 -11 -59 -38 38 1 14 12 58 66 -126 -91 63 10 10 -40 80 -31 -24 53 -17 -10 46 30 118 -79 -50 13 34 -111 46 -29 41 -1 -63 -65 126 108 -116 -14 -22 20 4 -46 -29 1 51 3 10 -53 -53 -27 -38 -41 5 -32 -65 -21 49 47 -56 -38 -3 26 43 -102 -16 44 13 -31 46 -29 -104 -26 25 -15 47 -54 -13 -30 -55 -74 -53 96 11 -53 15 -61 12 -67 -107 15 64 -36 -14 -68 66 31 20 -11 -21 28 24 28 -18 32 -80 49 62 -12 -59 -88 -96 79 0 90 -25 -64 -17 -27 15 1 -22 55 65 1 87 -9 -13 101 81 6 -71 33 -11 18 81 3 107 1 112 33 5 -112 9 -23 -55 3 -9 24 41 33 -26 -31 4 24 15 -47 65 50 56 -13 42 -5 24 11 71 11 45 26 13 -51 50 20 3 -73 33 127 127 43 55 -4 -55 -6 109 53 -6 -24 54 14 -92 -35 47 -88 -37 80 -46 6 -7 13 68 16 -6 -20 18 -53 -118 7 -66 -33 -22 44 -82 31 43 -59 -6 30 -75 4 -18 -70 42 -19 52 5 61 -15 -23 -91 17 23 -5 56 105 -54 3 31 17 41 -19 21 47 -23 -80 77 66 -59 10 11 80 -70 46 -48 -36 -97 -107 -108 -33 -87 28 9 -55 -38 10 -27 -46 -17 36 -3 -26 -16 -13 45 63 14 18 -18 -41 -58 -39 1 -43 -8 -47 5 38 57 -37 28 21 30 -68 -87 44 23 73 67 15 -35 -14 -90 -36 -44 55 -62 -58 114 87 37 -31 4 32 44 -28 23 73 -9 112 -24 56 106 -36 127 88 14 20 -66 -19 13 69 24 96 125 86 -42 -4 12 -18 53 -11 -18 117 -18 -37 87 81 25 79 1 49 -6 3 -7 14 -10 55 42 27 7 101 9 24 -19 53 82 -81 -121 -125 -112 -47 41 7 6 -15 38 73 33 1 -17 64 -72 -34 127 69 20 12 22 58 5 -122 21 7 35 23 -8 -12 21 28 -42 14 -13 -30 13 24 12 57 -13 8 70 73 0 50 64 115 -24 93 -43 13 17 -10 1 -14 23 4 65 55 -33 -30 -3 -20 -19 -26 45 32 -46 -39 -69 -41 41 8 -19 -23 2 42 -27 -1 26 -37 6 2 -63 52 39 18 -2 -47 -63 -6 -2 -118 50 -10 20 62 44 -6 10 -15 -37 -39 -38 7 -36 32 -39 16 -3 8 -14 41 8 -36 -5 63 -58 -55 4 -19 -28 26 -20 12 -18 -20 70 23 9 -76 -7 -52 -42 86 1 -109 -12 51 98 30 -64 11 -63 26 42 -10 -87 -4 -7 -58 64 -128 -41 -88 58 25 40 88 12 -46 -52 -34 -9 -1 -79 -51 -23 31 -9 21 -94 -47 65 -6 83 32 25 60 45 23 -10 -88 -36 -126 24 57 12 -60 104 40 45 -1 -44 -6 -33 -1 24 113 65 -78 -26 15 -22 34 12 104 32 38 33 72 48 -41 41 -14 41 -54 39 91 -27 -18 -66 56 -59 -48 -46 17 -34 -76 -16 27 43 39 20 7 -83 -96 -80 -77 -29 -23 14 33 -23 -68 -13 45 -11 54 -58 16 2 7 -91 -54 -58 28 56 -14 -86 -128 -93 63 -59 25 -44 -71 -44 127 42 24 77 11 -119 -66 -94 -63 -1 24 118 51 -15 -21 -113 -85 -42 123 25 -70 -1 -97 -64 -14 0 9 24 5 -23 49 -126 10 70 -20 22 84 26 57 -36 20 46 29 -13 15 1 20 4 -70 -10 -38 9 46 -23 5 -2 26 -19 20 59 21 10 3 -6 28 -92 -9 -35 69 0 21 -57 47 -32 23 51 1 -23 -58 54 -31 -5 -77 -43 86 30 5 40 40 81 -10 -11 -66 -51 57 -78 -26 32 23 -105 69 -22 -20 80 -104 21 -17 66 73 89 39 42 58 -32 18 -69 -8 -45 -8 -39 -44 65 38 -69 -16 6 -1 -12 108 -73 0 6 104 -5 113 28 -19 1 -36 14 24 -48 -43 -16 -26 74 -89 14 76 -14 -20 -55 -27 30 -39 -70 -54 32 20 -82 28 45 15 5 -35 -54 -11 28 -23 -62 -39 -17 14 -73 -116 9 122 -59 6 8 -15 9 -75 -56 -97 34 -42 -33 -53 68 -39 -23 14 36 14 84 -3 14 -23 123 12 31 -101 18 36 -35 20 -50 63 -75 -10 46 -25 -52 -17 60 -33 8 14 103 -76 -64 -33 -25 -52 32 38 -31 28 -11 15 -18 58 15 74 19 20 8 12 -112 -13 -73 -12 -25 -48 -45 67 -109 4 44 46 -1 127 -62 -8 2 19 -7 46 88 -99 -30 30 -87 81 -4 47 -1 120 -62 10 -6 57 -12 37 62 58 107 -8 -19 69 -55 -64 -128 -59 69 -7 -68 -41 -54 12 -8 -44 20 -48 -3 31 19 12 -36 40 -22 22 -43 11 -48 -120 59 58 -92 -56 24 -75 -35 90 -20 -48 108 -3 57 38 18 -39 34 -125 57 -15 -18 43 -10 44 64 0 76 -53 41 69 -42 127 -17 -9 -75 -126 16 17 90 98 16 -54 32 42 -42 28 -48 54 -6 7 -5 -48 85 -45 19 57 12 -33 -86 -99 30 24 -26 -63 3 -28 92 -6 -38 17 42 8 12 -30 -38 -25 -28 113 55 53 -1 82 4 -24 -40 3 8 31 -10 16 -28 -18 27 11 71 -66 -14 -103 24 8 -50 2 -10 -20 -21 45 -43 -41 27 -27 -78 -13 -27 -66 -73 -31 -1 -60 17 -59 -4 -37 91 9 114 -27 49 -25 -43 26 68 74 61 -1 -3 36 30 -66 13 33 -22 -46 -22 -16 55 7 37 -36 -103 124 36 -36 55 26 -18 -14 -2 4 0 7 -1 6 -38 -4 37 -14 41 -55 45 38 38 22 40 56 0 -8 -17 -4 103 -41 -59 62 8 -10 -46 -19 22 63 60 -83 -24 -126 -14 -60 23 -55 29 -31 17 8 -8 -31 3 70 -28 22 -15 37 69 74 8 53 5 -31 -29 83 -15 -127 16 -88 -39 -39 -6 30 28 -78 42 -39 -24 -52 -59 -44 55 57 28 36 11 40 45 73 -84 15 14 -28 6 -22 -52 -14 -62 7 8 66 -38 -103 30 -66 -62 -70 16 -72 5 -78 59 51 -40 -25 9 -126 -17 -17 61 -107 -54 31 -46 75 32 24 -101 94 -24 91 -27 73 -109 -40 -34 -64 61 43 -29 -39 60 3 -27 -55 -22 37 18 -73 8 -64 -22 57 37 43 1 -35 -51 41 -61 22 -59 -26 -7 -23 -27 -58 27 21 -4 -33 -91 -11 -80 48 99 -5 -6 -12 110 -22 -5 -37 -43 -24 -13 -26 -24 33 -59 39 1 -62 -22 -8 -52 -53 20 -38 -42 34 46 -69 -23 -27 6 -33 -21 16 -39 -7 29 -94 -57 52 7 -28 -10 0 0 47 -119 -3 -12 -79 60 18 17 -48 52 -71 -110 38 -17 5 11 -22 19 91 7 -100 5 -8 -1 -12 -32 7 -13 67 21 1 -12 -79 -32 -29 24 -4 2 19 57 -32 44 -3 43 -12 -78 65 -18 6 -12 39 81 -17 39 43 12 74 -20 127 3 -97 17 -40 -82 -1 -31 28 100 65 -11 63 -66 -25 1 -39 -111 -84 -78 -22 -6 105 11 -3 45 72 54 -46 -37 -69 15 65 -13 -48 -70 0 89 14 -19 -55 99 121 68 58 -103 -41 -101 -22 66 -40 7 127 -28 4 -65 79 97 1 7 99 -20 -29 27 27 -1 55 -66 69 0 15 -46 110 -124 15 -76 -41 -26 -126 -118 126 0 22 -78 9 -16 -76 -9 -12 -46 -58 -77 -86 24 -5 -7 -16 -71 -60 -51 95 -2 -4 92 -24 77 0 30 -16 60 23 12 -27 -128 60 -36 1 33 -4 127 -104 83 -2 -101 26 -2 33 25 20 -32 -31 -11 -65 -29 11 -35 3 -10 -11 57 12 -125 55 -116 -35 -82 35 -113 -58 -72 -48 -32 36 -1 51 46 58 -75 0 2 -53 -118 -58 -46 -74 9 -14 15 -32 -57 -19 40 2 67 21 13 -57 0 22 9 -19 21 69 -44 44 24 -91 1 -4 -33 8 19 59 -37 -57 -120 39 -18 5 34 -112 77 32 -83 -9 2 -44 0 18 21 11 9 47 21 32 42 -117 19 10 -74 -18 18 -13 6 11 -64 34 40 15 75 -17 -34 10 -14 -50 7 -123 -82 -29 -24 -26 -81 4 32 5 -6 -102 -53 63 54 81 -17 -67 9 -97 63 -35 82 32 -48 5 -35 52 -38 -5 43 -4 -41 53 -34 26 0 86 63 -22 75 123 62 -33 1 60 -16 2 -3 -87 -13 -9 -42 -44 -4 86 -60 -43 -19 -13 127 28 4 -64 -24 25 -84 -112 -15 81 -6 -6 -8 91 26 6 -29 56 9 -8 93 -31 -30 -34 -55 -3 25 17 -33 -28 -97 5 119 14 -34 15 -18 39 -32 48 -115 66 14 56 -63 30 -49 36 -13 -74 -63 14 94 54 -88 12 -77 8 108 -15 -62 -94 -52 65 88 32 -7 54 107 -52 -1 -39 -11 -14 42 -44 -8 127 10 -36 -55 28 127 -105 38 -84 -54 19 -30 -39 17 44 -95 117 -6 -18 120 -77 -10 14 62 42 -58 19 105 127 24 119 71 -108 7 71 18 -41 61 -74 62 -105 41 -116 40 -56 -77 -17 4 -59 84 54 -46 -122 5 18 44 119 -87 81 -86 15 59 60 19 0 -103 -40 39 -63 82 95 -6 82 -120 69 48 1 -100 -10 63 71 -72 45 58 -108 -34 -67 -96 40 -7 3 -25 -43 -56 -5 -2 29 -36 -56 63 -58 18 -65 -61 29 6 -10 -7 10 -13 -87 -29 -33 -128 -51 -26 -88 -51 26 -69 -42 67 -125 -10 67 20 47 41 -124 71 36 60 49 -27 -9 -64 17 12 -15 9 -21 66 21 47 -21 -19 28 26 84 -35 -53 43 111 4 104 -33 -8 30 114 -39 15 -9 -25 26 58 22 24 43 -5 6 3 40 35 0 41 53 -126 -20 -5 -14 20 47 76 57 -3 -70 82 76 11 -26 -58 98 67 108 -121 -41 -99 -63 127 -12 -7 35 -94 30 -127 -124 15 -126 5 42 42 52 82 -47 -54 -120 15 8 30 2 -116 3 1 -64 79 12 -38 -42 -88 27 -93 118 51 -12 -24 -90 19 40 41 -27 9 -12 60 -1 73 -20 -78 127 -39 12 -20 -7 63 -72 -9 -47 18 -56 -21 -60 41 -120 -8 50 -45 -92 -89 -53 -15 127 9 -12 109 14 12 24 -7 -20 -90 21 55 101 38 117 23 -53 -64 -96 -47 51 85 13 -81 -48 62 -68 -87 -30 -23 -11 94 61 -33 -5 -14 16 6 39 30 -94 -48 -24 -106 -33 -42 -41 -24 0 20 -24 -7 35 5 20 -5 13 25 -8 -7 25 98 -18 76 103 62 -9 -6 23 -55 -6 120 6 -7 -67 -58 -45 -24 14 -23 -57 69 38 2 57 22 -26 -57 24 -1 20 29 61 21 16 93 -42 -12 -116 14 -36 25 -11 -33 -13 -115 3 -12 122 -79 26 -37 -29 67 -25 64 -35 40 -45 20 -40 42 -73 10 -19 -73 22 16 91 80 40 72 83 41 -13 67 66 13 58 37 -41 116 38 45 -27 -92 10 -22 26 -24 -62 -65 -62 -27 57 43 -25 8 44 35 -42 -63 -22 -34 66 -1 -21 -72 -7 78 16 27 -7 -24 -5 -45 -6 -71 19 92 -73 48 11 5 15 -65 -109 -24 -53 21 1 65 -19 -61 96 -96 101 8 -2 84 72 -77 -13 -10 -115 -11 -41 56 -60 -101 15 -24 -37 -39 18 58 53 -13 37 -43 -30 53 9 103 9 -36 14 -60 48 -127 3 -84 40 -119 69 -22 7 4 -23 -30 71 26 44 11 -47 -70 17 29 65 -25 -124 72 36 -36 -4 -62 -69 -65 18 20 -43 15 -10 -7 -63 -46 -95 5 1 28 20 4 17 65 -39 -38 29 13 56 -49 4 46 -76 -18 25 66 -15 41 -90 2 50 -3 0 67 -67 -56 57 46 33 12 70 -29 -58 -73 -1 110 -19 18 -3 93 -81 81 -58 -3 16 127 68 -22 -37 30 50 5 17 -45 63 61 0 -38 16 37 23 54 66 6 -16 -19 10 55 -31 -7 66 86 65 21 -19 70 28 62 36 68 -34 14 -96 51 -18 30 17 46 -34 50 13 -89 17 5 31 91 -69 -32 49 -127 -58 97 110 -11 80 -40 -22 27 -4 112 127 -15 -67 42 114 45 94 65 45 44 19 67 19 25 110 -1 87 -3 -19 47 12 -8 -42 15 7 -51 57 -111 108 -47 -18 94 -15 -39 45 -63 3 -90 -37 -13 32 8 -43 -8 39 30 -51 28 -19 -34 -10 42 -47 59 123 -10 63 50 17 42 47 19 -67 47 56 50 -35 12 6 -36 -96 47 -9 104 50 83 46 -54 -66 -31 -55 127 54 12 64 -72 27 38 -64 -56 30 125 -35 34 24 75 23 33 -27 -41 -84 -3 -15 33 80 44 29 54 -29 -101 -93 47 18 79 26 13 12 46 15 68 39 82 109 42 -19 -59 -50 2 -72 -26 31 76 69 -35 76 -37 42 13 6 -37 25 -62 -32 99 26 -36 -70 58 -38 2 1 34 -29 -9 -11 -14 32 -5 35 11 -26 12 11 -17 -11 -61 -33 -11 -33 -29 -23 -39 -26 33 19 -18 -66 -33 -35 -14 -92 -68 -26 -48 69 47 19 127 -80 30 49 28 8 -93 48 -62 -94 13 -34 40 -61 31 -2 19 45 20 -39 14 37 78 18 -9 -20 -10 -25 -27 104 75 47 38 89 -41 43 40 -20 -6 -66 -17 11 32 -41 26 34 26 55 -53 -89 125 47 -58 -116 28 -14 27 -12 -6 100 99 -14 55 1 -83 36 10 105 25 106 38 -1 -66 -100 67 -30 17 101 -21 21 -65 76 -16 -97 16 42 38 -89 72 75 94 55 32 7 82 16 44 -77 -35 -22 20 70 26 2 -46 -18 28 89 41 70 -64 -21 -60 -23 66 -23 -70 46 8 22 11 -55 93 87 60 -27 23 -44 15 10 -21 -30 -17 64 14 -83 -5 -19 -22 -32 15 -72 -17 40 -81 -29 -3 -5 -64 -35 -43 39 -56 28 -51 93 50 97 -29 -14 -28 -13 -12 12 14 18 -3 -24 37 10 -66 -21 -36 70 3 -24 21 -43 68 -9 -40 -51 -48 -50 -2 18 12 -17 33 -34 -18 -24 -4 81 -4 -52 -66 -46 -61 -19 -25 48 44 -24 -67 -52 -33 71 -84 5 44 -35 35 1 47 84 40 -20 25 -38 -21 127 92 24 26 53 -21 51 -45 -45 43 -116 7 -9 -97 -44 -47 20 -49 1 14 78 4 -105 23 -16 13 -24 -19 -5 -32 -53 0 -35 -11 -7 -45 -25 8 7 -21 27 -37 -57 13 8 79 66 15 -20 -36 -55 17 8 22 69 75 -25 -2 48 -8 0 -24 -24 -9 -50 -40 19 9 -21 5 -1 11 22 105 22 10 -15 8 -19 -20 10 80 -18 -11 46 62 54 -8 -77 -60 -92 -96 -124 77 95 -72 40 -13 16 0 63 -17 56 15 -118 19 -50 -40 -42 2 -39 -50 23 101 -125 -39 -64 59 42 122 0 98 14 23 -42 -10 117 -18 98 -1 51 -124 -48 -49 -12 -9 113 -115 -55 -112 13 4 30 70 52 14 1 -79 -108 15 116 105 13 51 -125 86 -11 -51 -44 65 -45 43 31 61 16 -2 6 -42 -92 -124 49 -105 123 -8 -44 -12 84 -76 13 -39 3 -19 1 -9 -82 -41 37 -23 31 -3 46 -50 -22 8 -33 8 91 -8 17 37 67 64 -60 -20 -62 -20 -55 65 20 -19 54 -124 22 31 102 17 29 -15 -21 -34 -12 -27 82 -44 -3 46 21 -55 -70 15 -48 -19 7 -53 19 -12 -78 -5 -102 13 3 -25 -67 64 -43 -118 68 -91 -66 -2 -32 -92 -81 86 6 -49 15 -103 -40 28 15 45 70 13 3 -1 -18 21 -11 28 -14 52 -58 -22 67 -53 6 -38 -88 11 73 68 44 -39 45 88 -43 116 -76 -1 21 17 -2 -87 -1 75 -66 -18 -7 21 59 -123 127 -55 -49 47 -6 89 19 40 -13 55 37 7 27 -53 -88 -104 -47 -72 -40 -54 36 8 -6 47 98 7 -86 -18 5 5 126 -19 -51 -78 44 -75 -53 -44 -2 63 42 95 87 -31 13 5 86 12 20 -25 85 40 -20 19 -125 122 76 61 53 -80 -49 58 -123 -41 -15 42 81 58 -17 1 32 19 59 5 -98 7 -27 60 -59 30 30 53 -36 59 -9 7 51 8 71 50 -21 -13 17 -15 -60 13 16 36 -74 87 -17 30 59 18 69 41 -52 61 33 43 73 -7 46 93 102 67 -1 51 -9 7 -52 -56 -15 -50 63 -23 -8 19 40 14 -36 27 -70 35 -19 32 63 -11 15 22 39 67 37 3 106 -5 2 -79 25 39 -105 74 -58 -45 68 21 -8 127 85 -32 -9 2 -2 -3 7 3 15 -14 -16 2 68 -8 58 13 -1 -19 -45 31 36 13 17 -14 48 12 47 27 -70 93 14 0 -20 -15 -27 -63 55 34 -121 17 31 17 104 4 -29 108 -6 1 -32 -84 -27 79 -48 64 -6 -31 -46 -60 82 34 -22 -29 -12 -7 -69 -1 92 40 -78 -15 28 -92 15 -18 14 118 -14 -26 19 58 -32 44 45 0 -55 -11 30 55 64 8 -98 19 -26 18 -6 12 -88 39 18 73 -70 -7 78 1 75 11 39 85 -44 -28 -54 4 -14 13 15 99 -79 20 33 -26 34 5 62 -100 -30 -4 2 36 33 -27 114 -88 29 -10 51 15 17 -17 -42 -58 42 20 -42 62 -14 45 7 14 -51 35 31 3 -43 70 39 -90 -7 -44 11 -37 -10 -5 36 -72 -75 -52 36 6 14 91 -3 -78 -35 -62 -15 32 -16 24 58 -52 42 1 -19 21 -24 4 34 88 62 -40 3 -89 66 95 6 62 11 27 12 27 16 30 94 -42 89 -37 59 -15 17 -64 94 -36 57 62 88 -34 74 -83 -23 -3 -84 -3 -128 -91 -55 42 -45 8 -3 24 -26 -54 49 -47 41 37 -65 -4 -27 52 81 -6 18 -110 47 4 -63 -81 3 -44 6 75 20 -125 4 -105 19 -120 25 -32 51 -15 -8 -74 8 88 -15 124 77 56 -63 97 28 -15 -16 23 -9 1 -78 47 50 37 99 -35 -34 100 -85 4 -80 10 12 103 -35 -28 127 -65 -42 -69 26 -39 20 5 43 -29 -22 75 25 4 -47 -38 8 38 -58 -6 -61 -9 76 -19 2 9 -32 120 -23 -29 -87 -25 24 -50 10 -50 -81 33 -46 -81 -40 -18 37 -20 -65 48 -1 -16 -17 3 -18 -85 -7 -11 35 -56 99 -15 -19 25 -77 22 2 -32 -29 20 -4 97 47 -58 -65 -3 26 36 -34 6 -70 12 -26 -31 -32 34 -19 98 -42 20 9 36 -24 2 -1 25 -119 27 -7 34 25 19 52 57 -40 48 45 -2 24 -73 31 15 67 25 82 -20 21 -115 9 13 28 13 -47 -91 -14 -9 -46 -19 25 -9 63 52 -12 -36 -59 -10 -125 -20 38 -3 106 -24 -92 -114 10 -61 -16 11 -30 -74 -98 -47 54 72 -58 67 -92 89 26 -28 56 46 36 -29 31 23 59 -69 -63 11 31 8 -74 -24 -42 -3 67 -45 -123 -16 17 -43 14 -14 72 -92 -82 -16 -46 -80 -81 -28 22 9 66 -49 49 -20 28 -49 110 39 52 51 34 32 43 -22 15 -33 6 24 -11 7 69 -33 69 -100 22 23 -8 -23 51 88 -128 66 9 36 -27 -13 -27 82 28 -83 -28 -63 84 22 -14 -19 65 19 -6 -4 12 -43 81 17 -27 1 56 -11 -9 35 99 -33 105 -22 31 -50 68 -70 29 -102 82 -106 34 53 15 25 12 96 5 -2 22 17 88 108 100 -34 45 -60 -107 66 10 -64 -98 56 -62 -51 -59 21 75 8 10 -39 -38 19 -27 48 28 -32 15 -2 21 17 19 -77 -74 -30 -51 -71 47 -31 -13 -1 -6 -15 9 113 6 50 47 26 -2 36 16 -73 41 43 81 55 17 -6 -8 -82 -20 12 -16 67 -52 78 8 -30 109 -48 -36 -16 31 -24 -123 -9 54 89 15 34 17 -28 -109 -37 107 11 -16 -36 39 15 -43 -33 49 -23 37 45 43 -28 -58 37 -28 -77 35 82 -21 -13 -11 39 22 0 -45 35 -40 -23 -18 11 -35 22 -5 34 1 -74 -66 -18 24 -47 2 -53 53 16 63 10 -45 -13 48 -17 7 -105 38 83 -125 53 -84 34 -19 11 -78 17 -83 57 54 -35 74 -22 40 3 81 -27 -80 46 -17 -29 -14 -17 -66 61 90 19 -2 -18 -31 31 -8 6 7 26 -29 28 95 -51 1 -23 3 37 70 -65 -4 -34 61 -44 -55 -34 -69 -92 35 -36 -5 -66 -7 32 -41 -34 23 76 36 -78 58 -22 72 -9 92 -124 -10 43 -14 24 -15 95 12 -93 -72 0 -20 -13 22 -96 -17 2 -26 1 65 6 79 118 9 -87 40 80 -3 13 76 26 38 126 110 -62 -83 -43 41 31 -45 -91 -63 127 -107 15 -59 -32 -28 -77 -23 -77 -12 79 -58 105 -120 -45 5 90 72 -70 22 29 17 -60 38 -39 -19 -90 83 123 -21 -1 124 -56 71 61 -63 -98 -36 -62 48 66 -30 72 -128 -17 83 0 -16 -22 -41 -4 -37 16 -31 -31 31 45 22 -6 30 32 -25 -71 31 -32 10 1 33 -12 -73 2 -46 -63 10 -91 5 51 0 38 92 35 -44 26 -63 27 103 44 -32 99 -104 71 122 69 -17 -89 -76 -51 -14 -36 54 -48 -27 -39 80 -21 -52 33 38 53 -34 84 98 3 -11 20 -52 -38 12 65 -122 91 49 -48 -19 1 -2 -81 15 25 12 127 28 -7 -8 -24 1 31 -2 -10 -71 35 0 -27 -5 3 53 39 9 0 -73 -30 64 31 -111 -14 -74 -7 -34 -127 28 -121 16 -13 -7 -33 47 -3 -40 -38 127 -26 32 -47 -118 39 -125 68 23 -33 94 -93 23 -50 69 -28 -128 -44 -6 41 127 30 -68 61 5 -39 -69 17 5 -16 -46 24 6 37 -8 15 -79 1 -13 96 -127 69 5 88 34 -88 -32 -55 53 10 -9 -60 -12 59 32 89 64 -5 21 -58 46 100 3 -89 -124 63 8 -28 59 -51 71 72 14 6 4 25 -22 20 22 -76 -101 39 -51 107 -69 9 11 -7 44 -5 -18 17 -71 49 -88 -14 -85 -34 11 1 8 -57 -13 -100 46 -61 -70 -50 -15 13 -70 52 11 -67 99 89 71 -16 4 -32 124 -16 -23 56 -31 -120 4 12 51 -83 52 -67 7 21 -50 -118 -56 52 9 -45 -125 44 21 48 8 55 37 71 56 -34 9 -28 -40 -38 -82 -125 -35 61 -50 -8 -56 2 -85 62 -8 -86 -71 25 -19 20 40 28 18 -128 100 -4 -4 77 -54 74 -98 -65 82 38 -3 6 -39 46 102 -3 -66 10 37 18 43 -23 119 -47 3 -24 -14 -66 -58 29 66 8 11 44 -6 -26 -13 -24 -106 -60 -23 -91 2 -86 48 5 -78 -52 -127 26 58 -62 -1 -59 37 24 27 -34 30 -125 -20 25 25 -42 -5 -34 -1 37 -86 -86 42 -116 35 26 10 -46 23 -65 38 2 0 -11 69 -102 -5 22 19 8 34 41 33 -27 62 -3 15 32 6 53 19 9 -41 70 25 99 -24 -11 -34 -5 -7 -39 -43 -45 92 -36 30 32 15 30 95 -52 -22 -35 54 -77 70 -55 -50 -49 -11 -8 -40 -14 -60 1 -47 -36 -64 92 -1 -11 21 11 0 41 45 -35 12 -11 -16 -14 106 19 0 -27 -42 -16 15 2 -26 -44 -41 24 -53 59 45 100 -5 11 -14 83 -23 -9 -126 71 43 -16 5 26 -4 -65 69 40 -25 4 -40 21 -20 82 -16 -26 -27 65 63 -26 -14 -90 62 37 23 48 97 92 -28 68 -31 10 43 -54 28 -55 -28 -7 6 -25 -77 -17 -101 -83 -12 -98 -10 -21 39 19 -88 118 -11 -45 106 -6 118 -38 -98 -108 41 4 34 56 11 -88 22 -36 -49 -124 23 -101 44 -55 -37 -48 -14 72 -65 -77 -47 100 48 84 71 31 -44 -92 100 57 -55 1 9 -36 -34 -7 -19 19 10 -64 -63 25 -14 -67 -4 -58 29 -82 -11 -51 -32 -93 20 50 15 -60 28 -39 -42 28 77 -22 -66 14 -21 62 -10 -6 18 -22 -13 9 43 10 14 -10 -86 -95 -119 -10 -61 -92 37 2 -6 -74 -74 25 8 -84 42 -23 -21 82 49 -1 58 84 -42 19 23 -5 -15 -5 51 -25 29 39 71 0 -44 -95 10 -70 -67 -16 13 -38 18 -32 -16 1 22 -8 -6 42 22 30 15 -74 39 45 -26 -15 36 -85 -33 -71 -14 63 -32 3 72 -82 5 -108 50 -20 -61 -44 -11 2 -19 0 14 13 67 17 32 60 64 -64 35 -16 -26 -75 73 2 -22 53 -2 12 63 -81 1 11 9 36 -36 39 -8 13 -61 -19 34 -15 37 -6 31 -20 -30 -51 101 -25 16 14 57 77 -24 65 -51 -47 49 -52 48 45 15 42 20 -68 0 -111 -18 12 48 3 -2 4 -33 34 39 72 1 -19 -44 -44 -73 39 32 38 28 29 30 -37 -12 -21 -56 -27 -19 -15 -43 -20 -31 -14 96 -98 69 44 -70 91 -15 78 57 -74 -126 -112 3 -1 31 -22 -125 97 64 -100 40 -31 21 10 124 -20 -6 121 16 -12 -3 86 18 78 -92 -126 4 -96 -1 -84 -103 -124 -106 -26 -10 57 21 -1 -77 -95 -20 29 -79 61 -20 53 -65 43 125 119 -23 -62 -2 56 22 -122 -66 -114 127 -102 65 -71 -65 -43 119 -13 -30 127 -53 -9 82 -77 59 -115 -121 -128 -22 55 13 40 -49 -79 58 -35 -28 29 85 58 -24 -47 3 -68 -54 33 73 -59 49 -54 -9 -32 -94 -44 -31 13 34 -63 44 5 -65 7 -26 -50 125 -10 -18 20 21 75 19 72 120 -88 40 -19 -71 -48 10 -44 -53 54 30 17 -66 41 3 13 54 23 -46 27 -24 -26 -75 -37 64 -60 22 48 -18 -127 -9 -91 -6 59 96 16 9 -47 56 87 -29 1 -69 7 -23 -30 11 -90 29 -35 17 -48 22 -37 -28 22 37 -30 -8 42 -19 -46 -15 17 -22 -11 -28 -15 -54 -20 -15 -11 -25 -64 29 22 -62 107 60 -70 49 82 17 127 -99 57 81 27 32 -85 41 -97 -15 12 59 19 -26 24 -99 67 53 22 -16 53 86 -70 23 -39 -79 38 -1 -65 -1 55 2 -56 34 38 -67 -6 51 25 -87 -18 -37 -37 -28 22 9 -89 -2 21 -2 -55 -34 19 -43 35 13 13 -56 -78 -38 -21 -54 39 -93 121 105 90 -11 29 2 12 -29 62 -48 -4 90 111 -8 -125 -33 -31 -28 -70 -51 -51 74 -97 -11 18 -40 124 1 -13 -5 62 -83 19 47 -77 70 105 117 -116 -4 -31 85 -38 31 -12 4 59 -40 -124 -6 5 28 -49 48 22 58 13 -127 4 -26 21 54 -16 4 -114 22 -46 17 -2 37 -48 -26 88 -23 -85 5 21 -42 20 -7 -69 2 -50 9 67 -68 -61 -77 -62 -48 55 43 48 -43 15 -12 41 67 -44 -20 -35 122 54 111 -81 81 116 65 -90 13 -71 -36 4 -73 -109 -6 11 5 36 -66 -33 -18 -19 -80 -33 -52 49 -28 2 -9 2 -48 18 6 19 -123 -124 77 39 104 17 26 5 38 -58 31 -46 48 86 46 -1 -26 -23 -5 27 -12 -4 -100 -72 -36 -76 -15 -125 40 -56 -41 -69 -20 -1 -62 36 -25 -67 30 -26 -27 19 -111 16 44 -127 -68 -108 -11 2 13 3 -30 -32 3 -75 126 29 31 -49 16 51 -40 -98 -18 43 -19 -21 8 18 -25 61 59 13 -12 -102 71 -75 27 -64 2 -48 -31 -110 27 61 112 44 80 -97 -3 -101 -37 84 -29 102 -19 50 61 37 -67 6 -31 -59 40 -8 48 7 12 90 -36 45 -14 -10 -38 -125 68 -43 -22 71 9 24 -57 97 124 13 3 -44 -19 127 24 25 87 -122 35 -1 59 116 -11 -124 74 -26 1 15 -22 30 8 8 -53 -15 15 -31 3 -79 11 34 -27 -14 36 -13 -19 -64 50 -9 8 -47 -62 -87 49 107 71 50 67 -53 -61 11 -68 -30 29 -123 -70 -32 -34 -75 -61 -24 -74 -31 -29 14 -47 4 96 0 91 -28 -11 17 -2 20 20 -55 -69 72 7 11 -36 114 5 -53 -22 33 -35 66 -9 -24 -30 33 -11 77 14 10 19 33 35 36 -8 8 97 -78 -59 25 36 -17 15 5 -82 88 -64 -46 108 -49 -56 14 54 7 37 -15 -53 -5 -36 -7 -25 87 10 -2 -32 15 3 37 39 -18 2 13 -16 -43 -65 -9 19 -55 12 29 45 0 11 -17 12 20 6 -11 -64 -4 63 16 105 -17 -26 -49 42 15 0 -57 -5 27 -41 31 38 -15 17 44 -62 53 -3 33 -14 34 86 0 -65 -20 -46 26 -18 -13 1 -25 -69 3 9 -28 -54 -21 -29 57 36 -22 -23 58 66 28 52 -50 18 10 72 21 9 45 37 19 -75 -69 9 45 21 5 66 31 76 -14 35 93 74 -1 -35 34 18 -29 65 -32 8 40 -7 -39 -10 -64 124 73 -34 -23 89 -103 -21 14 -11 -58 -3 -125 70 -57 -60 -17 -55 31 -46 71 125 29 -96 22 -79 -61 -5 -76 -24 53 26 58 24 -15 -29 40 -59 -52 -26 8 -48 -11 37 6 -53 13 97 -19 -121 22 10 122 -31 -17 11 -45 -1 -9 52 67 -36 37 -64 33 -37 -38 4 127 -9 11 -5 126 -7 -34 -16 4 -76 -54 45 -20 -4 43 46 47 -1 22 -35 -18 -29 -28 32 -82 25 -122 -60 31 48 10 -37 81 14 57 -33 -120 35 38 21 95 -65 -125 -58 59 10 13 8 -59 -35 -85 36 -122 -13 34 28 -8 47 -44 -13 35 -40 -105 -60 -67 54 -15 -108 14 -46 -55 0 -43 12 -125 8 -103 -75 10 -101 75 -120 -54 -51 93 7 127 -68 61 40 -8 65 -16 -68 -23 -48 -25 -9 29 21 51 -7 29 62 -15 29 4 -68 -85 103 24 -8 -124 60 76 -4 -8 -54 -17 -12 5 -49 -37 14 91 17 -52 -12 -13 -39 44 18 6 33 33 81 -88 30 2 -31 63 -9 -58 -9 -12 14 -43 24 -31 45 8 72 -30 -21 -36 41 28 -9 37 34 -74 20 -65 -57 8 -7 -68 2 89 -14 1 -48 -32 -54 29 19 76 -25 85 60 17 45 -37 18 -5 -54 20 51 54 -20 -8 33 24 -16 123 -44 47 -1 55 4 31 1 73 1 -21 -74 -2 39 -97 -11 55 -4 29 -17 12 35 67 3 -72 40 -14 127 -3 0 -19 -42 -127 -40 52 31 -46 -57 -127 -26 66 -57 -23 28 -43 -28 40 -45 -91 -93 -20 97 -73 86 -22 6 52 17 -38 -43 14 -14 -83 32 -53 65 -67 -33 42 18 46 -66 -3 -26 -25 -13 8 26 127 1 18 -51 -96 -24 -116 -7 -12 -68 -120 15 -15 42 -36 9 -5 -13 29 13 48 -30 -128 -34 -46 18 -78 -15 -22 2 7 82 60 7 5 -126 63 99 -66 -66 -74 -91 119 18 77 89 60 -42 -39 -52 47 94 21 35 8 53 -18 -69 -123 -17 -32 22 -17 -84 -3 -11 -128 -22 -128 -22 113 -97 -59 127 29 -28 125 89 -122 114 -63 99 21 -71 29 51 59 62 -105 3 9 122 25 -114 -33 77 -11 -46 -96 1 4 106 123 -113 118 44 -51 122 17 -110 25 -90 -90 46 73 -105 106 38 19 -24 55 92 -39 -123 33 83 37 54 -36 23 2 100 -10 -22 -39 -18 23 -64 52 124 122 98 30 24 20 -25 65 73 -31 47 15 -14 57 -26 -13 -28 -104 -84 -67 23 -43 57 32 -53 -80 36 -66 58 -30 -58 -39 -22 -28 48 73 79 -57 36 -52 33 3 -38 35 16 -16 13 -19 -3 46 13 -28 56 -7 49 -53 -25 -94 90 -60 -51 60 8 -32 11 60 12 23 -35 -123 -24 28 -74 112 -78 -55 -32 49 -12 -114 -38 6 -3 56 3 3 4 70 -23 -66 -37 72 88 37 -19 11 42 83 -121 59 24 44 -92 96 -104 -52 -9 9 -93 9 -80 114 61 6 24 -58 -111 127 -84 -41 99 62 -107 7 -18 -7 34 -124 -128 -33 -12 -59 -4 -14 -9 62 -66 -17 13 64 -1 -29 63 -44 -23 23 61 14 63 -58 35 -14 -33 31 23 42 -127 -52 -62 75 10 28 -6 41 -109 -59 -67 25 25 -103 -17 42 69 -59 -32 -5 40 34 -103 -33 32 -126 9 16 83 -25 31 126 -104 121 -24 117 94 51 -120 -70 57 -30 18 114 -8 70 48 -71 121 -30 117 63 122 113 9 30 15 11 47 -16 5 37 -28 -60 29 -121 67 -16 -6 21 69 10 -53 38 -31 87 -52 -128 -123 79 -117 -83 -12 123 -90 105 -8 24 -59 33 61 21 -11 58 26 -60 127 64 72 59 47 -37 96 -107 2 105 -66 35 52 -55 124 10 -119 -58 20 126 127 16 100 -27 -104 23 -55 -31 17 8 -47 72 64 27 -1 50 74 19 17 -34 13 25 13 5 1 28 40 -112 -79 12 14 -11 -90 4 56 7 126 16 -19 75 -14 -31 119 -66 59 -82 -4 17 82 -104 -47 74 54 -9 -125 122 119 30 54 49 53 34 63 -64 -36 36 55 -77 1 88 -12 -26 25 -13 -14 87 57 -51 123 23 22 93 27 -28 -53 41 -45 -64 -82 71 -94 45 -70 -11 65 10 37 13 -36 61 28 42 10 -54 -15 -14 63 -8 2 32 -98 -22 49 71 -90 -28 -94 60 -11 100 35 -19 -56 11 -29 58 -52 35 127 111 -10 -74 11 5 59 -4 105 -15 -35 84 -68 61 15 -82 -8 -52 120 76 49 -31 -11 60 -59 -37 -14 -20 -22 -37 44 -50 42 2 18 123 -57 -40 -10 -73 5 13 25 -124 -45 -31 -21 -83 47 -14 2 127 58 1 36 -58 15 -123 7 42 81 50 9 63 -85 -11 -53 -124 20 -102 12 107 -49 127 10 -24 -31 -127 -86 -89 -88 85 116 76 -57 47 -123 66 112 59 30 109 4 14 9 -40 -117 -16 -69 -41 -32 -35 -42 -24 37 -77 -100 97 32 7 65 71 -6 80 50 -97 126 -73 -23 -92 26 -6 -12 2 61 -123 -12 -127 64 -123 -109 -71 13 12 -128 -73 -40 -1 -64 89 -127 114 -36 -98 74 -3 -119 75 -115 -126 5 14 -126 124 -53 23 46 -44 43 -16 -27 -83 -9 24 8 -104 -72 -17 -9 -54 -102 -20 -128 18 -64 -106 -89 43 -3 47 -7 -83 -4 -47 21 -104 -31 115 -88 65 42 27 4 10 -11 1 -11 -77 8 -48 0 -26 -6 -73 24 -86 0 31 99 113 4 -115 -43 -110 97 -45 -19 -15 -122 -13 41 -34 23 -46 -51 -52 -12 0 9 -115 -22 -1 11 -38 11 -60 -51 10 -6 -56 -27 -80 -25 -49 65 -42 -3 97 56 125 14 -50 76 -3 -67 0 33 -36 -17 16 -51 49 8 15 20 -15 5 53 85 80 100 -58 -94 -124 120 19 11 -124 76 -127 -27 123 -66 -49 121 -52 54 4 -62 54 57 17 -126 42 12 -55 -46 40 -107 14 -15 -107 66 126 30 127 75 -9 -125 49 -79 -92 -6 -40 127 -31 102 -83 -127 -46 -46 -79 -78 -12 6 38 97 105 72 2 71 48 51 24 46 -9 -76 0 -36 33 21 -10 -79 -127 21 -40 -53 -126 -16 11 -111 -24 35 -19 107 35 127 95 83 12 93 -8 32 40 -1 91 70 52 25 23 -90 -127 22 34 22 42 -42 -42 8 -98 21 -70 123 99 24 63 -17 112 0 84 27 62 -1 47 55 23 -37 25 8 30 -2 -19 -7 122 -17 -27 52 77 -83 35 -88 52 -64 90 2 32 21 66 34 14 41 64 113 127 127 2 49 -81 7 -14 68 45 48 -1 -12 10 6 72 -23 47 71 -121 112 -82 40 9 -38 18 2 85 20 -39 -6 -32 29 -5 22 -8 1 70 81 65 -8 60 31 -24 21 64 87 -3 9 -19 -29 69 -12 1 -7 33 13 76 14 58 -17 -26 41 57 6 57 -30 -13 -12 11 -15 126 53 -41 -56 5 -16 34 -3 58 -87 16 2 -7 87 11 94 -6 8 77 -4 48 -1 -17 9 19 30 28 -43 39 20 104 47 -53 70 -12 -3 -31 -39 29 91 112 -32 -123 -29 -26 -72 45 3 38 -2 44 54 91 -32 35 -9 -15 26 38 39 -5 12 -61 -106 -5 -37 44 -114 124 -127 -101 -21 -68 40 108 -24 -93 1 56 -67 10 -51 27 61 10 -61 5 23 -6 -119 -51 34 112 66 72 38 107 67 -50 -15 -57 25 -79 52 -24 20 24 -8 19 14 -20 -86 91 25 -37 56 -11 -37 80 126 -38 -50 -14 29 11 -86 23 -30 -124 -36 10 83 -44 57 -72 -6 -57 71 -81 -9 59 -27 78 69 39 44 17 -32 45 91 -39 -128 99 88 72 15 63 -43 -45 -57 9 20 62 36 6 -54 8 -70 45 -84 0 61 27 -70 -83 -85 10 -33 -67 -40 87 -114 -22 -74 -23 -40 -30 -14 -18 115 -37 -20 -121 25 6 -39 13 -6 119 -1 -17 -116 -52 113 -17 -42 90 -53 85 -31 -111 92 -43 0 -18 15 -36 66 11 73 11 -98 -98 27 -28 29 36 -103 52 -50 46 -34 33 -98 -36 73 30 57 33 15 14 20 -31 -6 99 10 -41 14 -42 44 16 -49 23 17 -121 58 -64 -25 -41 -32 104 -25 95 10 -28 -68 54 18 12 -9 19 57 11 -52 31 4 49 -89 25 8 7 122 -11 30 15 -32 -84 28 -52 30 46 -55 -41 55 32 20 -9 -27 35 75 -10 -46 12 65 -54 -8 35 52 -45 -32 -39 29 -5 -74 -39 5 -89 -122 -18 -45 30 -69 -7 -26 19 -26 5 -45 -52 -56 38 -54 -15 20 -25 14 -17 -17 -84 24 31 3 -16 49 17 -8 66 83 112 2 -20 57 80 0 27 -27 44 -78 67 57 54 -9 66 16 14 88 -45 27 127 -61 27 20 44 68 -59 -47 49 -70 17 0 108 -14 88 43 20 -5 -46 -40 -4 -35 -9 -2 11 87 95 -35 8 63 -32 -55 -10 -19 -16 23 16 -72 -12 35 -35 -11 41 6 12 27 76 41 -5 6 -63 11 -87 -87 2 42 -11 -12 70 -21 -29 -74 50 -37 15 51 55 6 39 -44 -10 -38 -80 7 121 28 -14 -16 1 -52 107 -31 95 -45 -74 -41 -14 -41 4 86 -39 6 -29 67 31 -78 -115 -82 34 16 -26 2 -71 -36 88 6 47 32 5 -11 42 -37 -19 -20 2 17 9 -36 -3 77 51 -121 -91 -21 23 25 -72 -52 -55 -99 45 65 126 64 18 91 49 10 86 121 -120 -98 63 16 6 28 -109 29 -17 -3 -71 -52 15 -17 -3 69 -18 127 -14 -63 -90 57 64 -13 84 -62 18 80 -12 -12 -15 -19 120 2 -33 34 -9 -55 75 -13 -87 -127 -111 120 -101 43 -20 -8 -101 20 39 -93 -83 15 -19 120 56 12 -67 -21 36 -16 -12 37 33 -13 53 -48 30 91 -22 -1 -3 -7 -123 -21 37 -8 -5 -67 -44 -39 38 -34 -2 -10 41 127 1 33 -24 22 -4 44 0 -54 -121 12 -33 -6 30 -71 -33 14 -25 -37 62 -28 30 -42 -65 -24 41 25 -27 32 17 -2 44 -25 -58 -16 -19 32 65 -17 70 -66 -127 -7 -4 27 35 -48 -11 18 -103 120 47 -126 59 17 -63 58 45 -94 -39 115 -31 73 22 -86 7 -83 -30 23 31 -11 63 28 15 18 -96 43 -30 101 64 39 93 53 13 22 -29 35 -62 24 -31 -30 10 85 72 -87 -45 43 26 -60 -28 -57 -1 -10 3 -31 -119 9 -73 -19 4 -35 -76 -51 65 24 -53 10 30 -12 -35 -38 97 -12 -34 -87 -22 40 0 25 44 122 3 29 22 -24 -2 16 -93 -94 -15 62 81 -2 33 30 -9 -125 -36 -35 3 46 12 -59 41 -64 113 65 -27 -24 43 -29 95 51 -16 -112 -28 -26 -31 -11 31 -92 -125 -23 -66 -124 -2 -19 -52 20 -4 -2 -53 -128 26 -9 -103 -26 66 30 -4 -31 44 20 91 12 5 13 -4 8 0 35 48 124 -51 57 -41 -23 -83 1 -30 88 -71 51 21 -9 27 -4 -54 57 53 10 -6 -8 23 96 58 -10 -70 -24 -8 26 -21 18 24 -4 0 15 68 -112 -19 44 3 22 -67 -98 56 27 95 49 -29 15 12 -72 -89 -39 -65 27 -41 14 -26 24 42 -76 -25 -28 -69 -93 44 -46 -15 -25 -33 -47 -6 11 -17 43 -3 -70 18 71 15 -36 88 -34 -65 -56 24 -49 -61 -14 -3 -24 -45 -80 108 -37 -72 41 -27 -4 20 17 60 21 -61 32 103 -99 -35 -13 -65 -11 -5 -28 -122 62 -2 7 -43 -13 -42 21 22 -17 -44 -105 5 -13 16 42 25 -45 -32 -34 123 -56 89 -126 14 21 90 -72 127 15 -80 33 11 -22 127 68 80 92 6 -7 -126 -105 62 127 -33 -53 57 -33 -53 -112 86 -35 -27 -128 -30 28 127 6 -56 -20 75 -12 11 89 -127 -64 -87 33 -50 30 45 126 79 -128 29 12 15 -1 127 71 7 -87 60 -49 56 -29 81 40 80 -12 -84 -10 -1 29 51 3 77 36 -9 -10 74 4 -15 -112 -39 -16 -49 21 83 48 -47 47 32 32 75 -52 -9 -7 35 40 6 45 -2 41 -71 56 25 9 -32 -51 3 -26 -38 4 16 -26 -77 75 92 113 108 -20 106 -73 3 51 27 40 47 -98 -43 -9 -18 -12 -31 -3 -58 -23 11 31 14 -25 -74 15 1 33 16 11 -24 35 -47 30 -23 66 -10 103 17 48 -18 -35 31 -47 111 75 -39 39 -14 17 -14 96 -69 -4 -50 -8 51 -63 14 -33 11 30 113 29 -29 37 -19 24 -43 31 -27 55 27 -40 -30 32 -10 -60 7 27 27 37 22 -14 52 -55 47 62 55 -12 -86 4 47 -31 16 53 -19 39 15 -1 31 -21 14 32 16 30 24 -13 9 38 33 73 -9 -28 -25 15 -71 18 -13 76 -17 -54 -21 -6 33 -66 -38 -27 29 -2 53 -54 17 2 -13 96 -4 8 21 -11 4 -49 -36 -56 -16 27 3 -57 5 -96 -7 7 65 -18 66 9 5 84 78 -3 -17 -42 -2 -59 -42 2 -43 19 -54 28 -5 45 -80 127 19 35 22 -28 28 -19 69 24 18 38 -20 19 36 -47 -56 -36 73 7 -54 78 -44 38 -37 15 -42 -50 -26 24 29 7 79 29 41 12 4 -17 -11 -17 -22 60 -4 1 19 21 55 -1 -14 107 24 -38 62 47 1 -68 4 33 -17 -72 113 -13 -71 52 92 8 -25 -80 -23 -11 5 21 126 73 -57 -97 -14 -49 -19 51 -91 37 0 -9 -10 -10 -93 40 14 -11 -21 26 -59 13 -94 -13 93 46 -125 71 11 25 69 54 -71 29 47 -20 96 31 -126 -46 43 90 10 3 41 66 -37 -26 -9 -6 120 62 -31 -70 -14 58 3 69 -27 39 75 21 25 -69 -38 18 -83 53 -127 52 -39 15 -12 -87 5 0 63 -32 -67 -109 9 6 30 57 19 -34 21 -9 -61 -34 -31 -75 21 80 -12 41 -1 56 23 40 -84 -3 -127 -15 -41 65 -61 5 -60 34 8 -34 -25 -64 -39 -24 93 16 -15 16 25 46 -47 -65 9 11 44 38 2 66 73 40 43 -25 6 -86 38 -46 3 15 -47 55 24 -50 -8 32 -11 -23 5 16 -111 85 36 -4 74 74 4 37 1 58 -1 18 -86 0 -24 -53 -34 -51 -16 -88 -93 -6 53 4 -20 -13 23 57 -106 50 20 30 -25 -21 36 -29 -61 -37 -96 -24 -26 4 40 -22 -36 -17 40 -54 -60 -105 -19 -102 13 44 -3 44 19 -19 -79 -47 5 26 2 -14 -10 101 63 -57 41 39 116 4 108 18 -37 -40 18 -126 0 -37 118 4 -19 78 19 -56 119 -125 45 103 -46 -11 100 -38 55 77 -119 -122 -78 -2 7 12 11 55 -15 93 0 55 54 -81 -14 3 6 -58 -17 -18 -122 -38 -52 -51 -14 -68 14 85 57 45 -21 33 -48 79 -55 -107 73 -2 -61 33 -9 44 -44 -17 -9 59 -84 37 -20 -53 -41 41 -53 29 -61 -33 18 -72 -43 11 4 -29 109 -121 120 4 -20 -44 -41 -65 45 117 -99 -96 120 62 27 33 -29 -117 99 79 -23 0 38 -40 8 -34 29 -2 -127 -19 21 -46 -128 -19 -32 -110 -17 -13 -3 -12 -34 2 -64 29 -42 -86 -12 75 -40 -35 126 -56 -74 76 -17 -118 -67 102 9 -60 -75 -8 54 81 16 -27 -105 58 -23 -111 -124 28 -91 -25 -54 -18 26 0 30 11 -43 -39 -39 -27 -24 3 -101 -78 -37 41 4 3 -97 22 88 -20 -13 9 -74 2 7 -95 8 43 -49 13 26 -45 -56 96 -14 -115 -5 30 86 36 -8 50 63 35 88 -10 -66 -3 -3 -12 17 14 30 42 2 -20 49 -42 -28 17 -52 -10 -7 4 -42 57 -11 -5 87 -38 -2 -81 -7 -6 -21 1 18 19 47 -19 -42 71 15 127 -91 -21 -44 22 -88 -101 46 -79 26 48 99 0 33 9 -27 76 -28 28 34 24 -124 -79 2 -12 92 -9 11 -27 4 -47 108 6 23 5 -33 -3 -88 30 -6 -73 -101 51 -11 30 2 -47 -20 74 1 43 -18 14 54 -4 -24 -1 12 0 120 -81 46 -73 -41 -95 -43 61 -4 32 35 41 8 -75 94 -16 -12 -91 -31 -60 52 73 -6 51 2 14 -13 -1 50 15 2 39 12 39 -16 -44 -34 -64 9 28 -90 15 -7 -39 -56 -15 85 -54 -44 8 -32 1 -36 0 -11 -10 -58 51 3 -45 75 56 -17 60 -20 -71 -38 11 -30 14 -53 -27 -65 -5 47 33 57 63 44 -105 72 51 9 3 -35 42 43 43 75 91 -57 39 -43 -63 31 -128 -60 7 -35 -126 -39 -3 52 -2 8 -22 -21 0 122 -35 -56 -100 19 -19 62 70 -22 -43 17 116 61 -42 20 127 -3 77 102 -125 91 10 16 108 -25 -61 -31 -4 84 -56 69 -74 87 -32 98 5 -18 -6 44 4 31 -26 10 87 21 -50 67 -92 28 -26 2 -56 11 -59 6 -28 -19 3 -86 100 94 -18 -37 33 -89 -13 23 2 -39 -63 17 -10 -66 36 57 -25 -41 -7 -114 -4 18 -16 0 21 89 27 2 -18 16 -1 104 -39 -23 28 34 18 75 -33 1 29 34 38 53 -54 81 -1 79 -13 24 -32 66 -8 40 53 60 32 16 72 -84 -15 43 -58 25 -12 -89 30 63 45 -66 28 13 28 -65 -17 -62 -1 26 -34 -89 29 -53 9 55 62 3 12 -17 62 17 -3 -14 3 -67 -53 -7 84 50 -69 99 -102 -40 61 77 -61 23 -45 -65 -89 -31 -40 49 -78 57 28 45 25 -81 46 -5 -39 -93 -37 0 84 -33 -4 -1 -32 -10 17 30 25 -126 -49 32 44 115 84 41 12 -20 2 -13 60 -23 110 29 -119 72 124 -100 -35 -26 44 106 -80 85 -64 3 92 89 75 -32 30 -77 34 -14 -16 -30 51 35 -30 87 35 90 82 7 2 18 -19 -24 -37 -19 -35 20 55 1 48 28 60 8 18 -62 8 18 -34 36 -39 1 54 32 60 32 41 88 -43 50 -59 -66 -105 14 -21 -17 -38 28 -124 21 -15 -32 44 76 -117 -6 23 91 40 -19 51 -68 19 -3 -76 15 49 44 46 -67 39 -125 -55 22 -77 -122 -14 -60 -1 -19 -14 -37 -61 -6 83 -33 53 69 13 67 17 -26 29 19 37 19 23 -14 0 70 6 28 -125 110 94 73 99 -16 66 36 28 10 -34 -2 -20 77 58 -35 31 21 10 25 24 61 -7 71 -32 -56 -23 17 43 -34 -43 61 -27 -10 -49 -44 41 -109 -4 -78 -37 -53 62 61 -47 -28 -39 52 -53 -48 17 -7 42 5 35 -28 59 -33 44 8 107 42 -28 -2 68 -53 20 23 15 -53 -29 56 29 -13 -9 76 -13 17 -29 -58 -24 9 -46 36 -103 24 -19 39 -31 -55 -7 78 -1 48 32 -29 22 -8 -56 -24 -8 -19 -33 -36 -74 -18 17 -27 -11 53 11 -9 4 -4 13 -92 48 75 -65 14 126 25 3 104 6 -75 89 35 -83 57 -123 -5 23 -34 78 -89 51 25 -29 -11 31 -43 -34 53 25 -3 -41 -107 -29 -39 -9 58 6 -14 28 19 -7 -65 30 -13 -43 -58 -31 50 5 -30 56 26 9 -115 44 7 -41 86 29 48 29 38 51 50 -22 17 -31 35 -46 -46 -19 24 -3 -48 65 5 15 -7 26 63 1 -10 -27 -70 48 -51 43 24 -15 105 55 114 -24 -42 19 88 9 61 -29 116 -23 -73 -12 73 66 -4 41 -23 90 11 49 -39 -48 54 -16 124 -25 40 121 44 41 40 -32 -60 98 49 16 109 -21 123 20 67 -33 -8 -17 29 -3 53 -42 -37 46 114 100 19 -29 125 24 -41 39 -2 18 -17 34 -18 24 -1 -53 57 -36 58 126 -29 -22 -95 -104 -30 127 30 37 11 82 35 2 17 -16 -34 -118 23 -31 107 -7 -36 -38 -43 -29 64 14 -32 -37 -10 19 -2 1 39 -66 76 58 89 -23 19 2 52 -26 -25 -32 60 16 -19 -21 5 -22 -10 -22 -19 19 5 -48 -43 31 -37 46 -63 20 -17 15 -22 24 41 -18 40 -56 64 -45 -4 14 18 97 -27 7 68 69 75 26 -13 34 -35 5 5 8 27 -19 52 -18 -22 -40 -26 15 12 18 -8 55 69 -6 51 27 14 38 19 -9 -46 -25 -8 77 48 13 66 -95 -46 38 26 24 108 12 54 19 47 65 -50 -119 123 -63 -13 52 17 -2 83 18 -38 15 -17 -76 60 -122 -23 83 -59 76 21 45 10 -23 -9 -36 -8 -74 16 32 6 -58 46 70 -91 8 20 -27 68 125 57 -126 68 29 17 88 -11 1 -67 8 58 13 -3 41 -126 41 -87 8 107 54 -2 -48 5 -30 -19 30 -27 1 -10 -56 -6 -32 -47 -85 -108 6 49 104 -102 26 -12 45 41 -43 16 -29 -52 65 -74 -74 26 34 -9 -12 -58 -59 -38 -33 41 41 48 -40 107 -52 55 13 -108 56 4 -124 72 -12 -7 -12 115 74 94 -18 5 45 -64 23 -10 -83 102 64 16 29 -45 -20 112 -57 15 6 -7 -38 89 -25 -31 44 33 -33 -36 107 -56 -5 -17 5 -58 -33 -44 -57 -6 -68 89 34 106 -64 -48 -29 -11 -79 -9 -45 7 -96 -41 -35 -9 -69 -27 -80 28 -29 -8 -85 4 -43 -59 24 -25 -64 -61 -2 89 -19 36 -23 7 -50 -78 35 -24 -16 29 -25 8 -35 -33 23 45 14 -24 25 17 -1 106 -12 -18 43 -6 46 48 -72 -11 10 -54 -66 -74 -75 97 64 7 7 54 -11 13 -1 -43 -11 44 -13 -31 124 22 -29 -26 54 61 28 16 109 9 -49 -37 -39 -30 -46 29 12 37 29 6 -44 -64 20 68 8 -37 55 15 45 6 55 7 -63 85 7 -40 -16 -45 -68 -24 40 -72 -6 68 -5 -11 -26 -14 11 -34 -1 -18 126 -7 110 111 23 -95 21 -38 1 14 -74 -44 36 51 -7 48 27 -30 -45 -33 49 16 -39 -70 -39 26 -37 -12 -48 15 0 -11 100 46 -5 27 -55 119 39 -31 -26 -63 110 -26 4 19 74 36 12 -39 41 60 -28 -64 -36 -20 108 -34 20 -7 -45 2 -29 6 57 34 -77 -3 -14 34 -114 -4 -33 -64 -23 17 18 65 8 11 -18 49 -8 -18 15 -19 23 32 -62 -57 80 16 27 -77 45 25 39 -25 14 58 18 38 -27 -104 -82 9 19 -24 65 34 -7 -80 25 -52 80 127 -44 36 -50 26 -53 23 45 33 48 77 -39 33 85 56 -3 87 8 -19 33 76 -119 69 -78 36 -77 22 68 102 97 22 -52 75 -4 77 1 57 112 46 89 -25 73 56 7 -17 28 -16 -37 70 30 105 87 -3 3 61 7 70 109 -12 1 24 34 16 -21 -72 99 23 76 -19 -126 -48 -25 -13 9 127 -31 -33 -9 87 -3 -17 52 -61 7 -13 16 1 39 -17 13 63 -14 26 -5 -1 -46 48 -94 32 -16 -9 3 47 39 -15 -18 43 -40 -28 9 -9 -26 -40 57 -5 56 73 -99 101 -27 19 30 47 25 -72 -30 -32 120 -49 45 26 9 40 76 6 24 2 -1 -5 -13 -68 -16 -17 127 -2 14 76 18 -68 45 -55 18 -14 24 -1 -62 -55 -31 25 -45 -11 52 116 38 -18 53 -113 -20 -98 -23 29 67 51 -14 -35 30 -69 23 -31 -65 -95 14 75 -11 33 -12 -29 -16 -30 -119 36 52 5 37 19 2 57 -36 25 -96 11 40 71 -101 -60 -15 33 33 69 18 -39 13 21 7 12 24 20 -46 69 33 56 53 47 -87 -47 -22 -22 14 0 -52 22 -12 -38 58 -51 -68 11 -64 -30 -30 -33 -4 -47 94 -27 -19 -32 -10 -14 85 10 -91 48 43 -10 41 -66 23 76 47 20 -60 -40 -5 -54 41 45 14 61 -38 -6 -123 -98 -68 11 -111 17 22 53 -24 -2 -90 -9 -26 4 -61 38 -22 -58 -38 81 -20 -109 22 -66 -33 -56 29 -38 -50 -19 14 -4 69 10 34 26 0 -12 23 -21 2 38 45 -2 56 -18 87 -19 15 -11 30 -33 20 85 -96 -72 5 -51 54 -24 62 -49 -21 -64 20 20 6 56 104 -42 22 72 -32 46 81 75 -22 -121 -100 -72 6 4 98 -62 18 4 -43 -65 46 65 -5 -54 109 19 69 -29 -18 15 -15 9 -45 -31 -16 -107 111 31 -27 -5 -82 26 -20 6 29 1 29 47 127 47 -45 5 48 -59 25 9 60 2 39 25 12 28 -21 -59 3 33 19 -23 -20 -75 53 -65 57 -39 -18 -34 5 10 68 23 16 -5 36 55 -12 -36 72 -102 -3 -1 -15 -3 28 -42 60 -75 -53 -59 9 54 -36 -42 -75 68 -82 28 56 2 89 -28 17 -68 -30 58 29 48 8 -10 10 24 5 100 120 -56 14 -70 8 -25 0 67 121 21 105 -19 21 41 37 29 119 20 -26 5 4 51 -107 40 -66 -32 41 71 -13 6 -33 31 -36 1 1 62 65 -55 -46 9 -115 50 -31 -31 11 -106 -45 66 70 54 -25 41 -35 -70 -48 -34 15 -30 -45 119 66 87 -112 -55 -24 126 38 -40 -87 55 7 -31 81 42 -32 -66 -50 22 66 -128 32 -22 -61 11 -45 32 22 -38 86 23 -56 17 9 -31 63 75 -15 115 71 35 37 -38 40 -45 -45 -23 61 -37 -17 104 -40 31 2 -21 -63 3 124 -28 -99 73 -22 112 -30 73 -9 73 -39 -22 37 -22 122 -51 40 -51 10 3 60 106 -91 61 -106 -17 -36 -126 54 0 83 17 58 4 114 -65 89 7 52 26 -18 -62 -92 58 17 -8 46 -19 -7 88 -113 -68 -10 -61 39 96 1 10 -91 -1 -37 -18 -95 53 11 25 -35 -8 -7 21 -10 -52 77 52 24 -17 -15 114 52 -7 44 -19 -43 60 8 107 -88 66 -47 34 -20 10 82 60 -15 21 26 17 47 -21 -9 53 16 96 65 37 14 33 52 72 71 -10 12 -118 -26 17 8 28 -5 -85 -35 19 13 66 91 -11 19 -5 -60 48 60 -79 69 9 -11 -2 -83 -25 7 -8 -90 26 26 -19 -51 -9 36 -34 -2 -3 27 -66 53 58 12 -14 4 43 -26 -31 63 -58 -68 96 -76 74 -51 37 8 9 32 -24 -29 -68 -39 46 70 14 -28 7 -29 73 27 22 84 -60 37 -26 1 37 -12 24 79 -93 37 -96 -51 -17 7 -2 29 45 25 -26 10 49 -18 49 36 21 75 48 -30 25 56 15 -16 39 -26 -28 82 -74 22 38 -19 90 85 7 -49 -10 -27 -37 -30 41 66 -22 -11 -28 -2 -32 -6 -24 -32 62 -2 -15 -37 -12 65 14 76 127 23 20 26 28 -37 -88 -21 -4 -100 -21 -38 27 54 -41 -61 -55 76 64 0 -18 25 2 18 -32 8 -103 -12 -24 -87 127 -39 0 15 31 22 84 61 32 20 -74 28 -32 33 16 8 -24 -36 1 -52 45 6 -114 -84 -127 1 -58 26 -26 -60 32 -69 -47 127 63 6 85 84 71 -29 63 -10 22 30 71 83 61 37 26 8 -45 20 -70 47 -73 -1 61 69 76 56 51 -9 -25 -75 -103 85 -28 34 -40 -10 62 56 41 34 -64 51 24 -127 22 45 58 21 -23 9 -73 -28 17 53 -60 72 -57 22 -31 -26 -5 -45 -50 -35 -26 45 16 2 36 -8 39 127 71 11 -11 -6 59 -5 115 48 -17 -38 18 -37 1 72 -11 -34 -21 -38 -11 -37 0 34 -27 1 3 6 59 1 -13 -78 -11 -44 41 30 1 -32 -19 9 13 16 20 45 -64 -43 -77 -2 -24 -35 35 -5 65 -51 -18 41 3 -30 -13 1 23 35 6 -51 -62 14 -73 46 71 -46 -13 53 -22 14 93 15 -52 35 -20 29 -94 95 37 -112 -23 20 -83 12 34 -24 -18 8 24 68 -48 -68 50 -4 -5 -8 -12 28 -45 -37 -15 56 -65 -59 -117 95 8 63 5 40 40 -26 -10 -95 -57 18 -56 -111 49 74 -37 -75 37 -10 46 -2 63 -37 127 12 43 -32 -105 -34 -128 23 68 -31 53 -52 -38 4 10 36 127 -17 -46 6 61 76 -17 30 34 -117 -86 34 -17 123 7 31 11 44 -38 -10 -83 51 65 -81 44 63 -96 9 105 18 -1 79 -81 -13 48 34 -41 48 86 -40 90 19 28 127 -1 64 -62 -16 -82 42 -37 -95 53 73 81 90 -18 46 7 -99 18 73 -80 -70 -7 46 51 -27 -12 8 -3 12 19 -27 74 75 -37 89 -29 -35 39 7 41 -1 42 -4 34 41 49 -48 -70 -23 3 40 -80 29 37 46 93 110 -55 25 111 -56 -47 27 -54 -86 33 -19 33 39 -12 59 -11 54 -74 -1 20 -60 77 8 -70 70 22 -13 36 -32 -28 -44 -17 -19 57 68 3 -21 96 20 -7 -24 33 121 -8 5 -25 24 28 -50 25 -25 6 89 105 -16 36 8 6 -10 91 -61 8 28 98 42 2 41 -80 14 94 -21 -69 -27 39 17 70 -12 45 48 26 65 40 5 -13 32 -69 87 -37 42 16 11 -44 31 69 -22 14 3 -20 -40 17 14 -4 -2 -13 36 90 27 -5 4 5 -12 30 39 -5 -107 3 -22 -45 53 -44 -35 -55 5 10 -26 -59 -20 47 58 21 -19 -29 10 -30 37 -37 -37 -16 -40 22 -63 26 -28 35 -54 11 79 15 -50 -32 -24 -41 20 51 81 -52 -88 20 -41 -38 -55 -38 -44 26 36 37 -18 21 -28 75 -16 -52 56 37 -19 4 48 -12 -16 -45 100 -1 -66 -38 -30 -42 -28 -48 -3 43 29 -53 1 -26 -28 45 -45 45 -39 -22 26 73 -22 0 31 -12 17 46 18 38 -48 15 -20 32 6 45 20 -3 67 -63 -98 6 100 22 -50 21 -12 37 -17 20 75 -96 -3 7 67 51 88 12 82 65 37 14 -22 -29 68 -81 -2 2 21 -21 55 -44 -110 -39 54 77 39 76 16 41 25 33 111 -27 -3 44 -45 -73 23 -21 16 56 -60 -44 -83 -14 76 67 28 71 -5 17 122 -82 -46 55 44 52 -59 -34 17 46 12 61 32 26 -38 46 -31 60 -36 -52 12 -11 63 -47 22 -65 -21 -40 -32 1 -11 -53 21 51 -63 111 51 3 36 53 -122 6 49 -69 1 -28 -60 -39 50 -101 -45 43 -23 32 30 -49 -77 98 -15 -6 -62 -20 7 92 -24 12 58 8 4 19 -64 -105 -96 -58 12 -11 -4 -91 -51 69 28 -60 -125 -58 -12 42 67 66 3 -14 1 86 -59 85 -72 -43 8 95 22 7 -30 89 85 -49 33 15 28 33 14 -9 -8 -42 34 -32 62 -96 -34 64 6 34 49 87 62 -26 -90 -39 -55 -38 121 -17 13 -53 76 -84 22 69 105 -6 39 -66 9 69 -6 54 -54 10 -24 16 127 46 76 -43 -101 14 -17 14 -2 -3 44 6 -31 63 -18 -90 1 34 -39 -21 -55 -7 7 6 -13 55 65 -48 -44 -39 -127 -15 -78 -24 -115 -82 126 -63 47 44 5 7 -31 -37 -29 72 28 -48 14 -24 -123 48 -50 87 -10 -125 -73 23 19 -80 59 -11 -3 19 14 13 -28 -29 73 -23 -22 -56 -63 -33 -57 11 58 -23 -19 0 25 -60 -9 -38 -46 -107 -77 10 -80 -107 -38 -71 -50 -51 22 -28 -76 -47 -50 9 -37 8 59 0 -59 -27 20 67 -24 26 -8 -84 10 -66 -71 -62 -25 33 -41 -52 -83 -26 77 -25 -57 0 -52 23 -47 -52 -4 86 -72 42 -111 76 -34 -42 17 -30 -71 19 -33 -99 -77 -105 20 -39 -31 -2 50 -12 -50 -89 -2 23 28 -73 -50 -33 -74 -3 -40 -40 -53 -14 -21 -15 18 -48 -27 -26 9 50 -2 15 -96 24 7 4 75 -13 105 36 0 42 -15 -40 -77 -23 4 -29 -13 -71 62 14 23 -32 33 -15 -42 28 19 -19 -35 -64 28 -42 33 -46 -27 -11 -69 -5 4 -18 23 20 -24 10 0 -25 -27 -2 -53 -16 8 -46 -28 -14 -111 58 -44 124 20 6 41 46 36 1 -35 8 11 62 59 -23 25 -37 -13 40 29 -52 28 103 -42 -22 -9 13 33 14 -44 -33 -61 24 -5 44 7 68 -32 45 -36 2 -30 -29 -74 -34 23 20 -25 -21 -33 66 -3 -40 98 -53 -5 -68 25 -36 -12 17 58 35 19 -12 -85 3 -15 -12 -15 -21 28 -7 -12 80 8 30 -57 -55 26 -26 6 -4 3 -73 -8 -74 17 -19 -11 -25 -2 13 -7 67 10 -19 -36 -8 26 51 19 -14 -46 -7 37 8 13 6 48 74 44 -40 4 1 -14 -58 0 -11 -21 -29 6 4 -75 -35 -40 33 -31 -42 -120 -87 -4 -13 61 31 37 -37 -29 33 1 24 -27 -6 -58 14 -77 9 39 -49 -39 45 -76 -71 36 -5 45 -47 19 -18 -77 -28 -34 -66 -40 -58 57 -60 45 -2 -43 -127 -53 -66 -45 -117 -103 -25 -36 31 -123 -71 4 -49 -43 7 -117 -10 -26 127 -110 -47 -68 -41 53 -34 -69 -114 -123 -31 67 -85 -41 3 -28 -43 -34 -122 -89 -112 50 19 40 13 -90 21 25 -17 -17 -1 92 60 -12 -107 -95 124 104 -33 62 38 -62 -19 -94 -20 77 31 -1 -2 -25 -58 -31 73 62 30 -38 27 54 75 -25 23 9 -6 -68 -42 63 13 -26 7 13 38 -8 -67 -41 -11 44 -7 -24 -25 -83 -15 64 36 -48 -65 -103 19 -78 92 -69 17 -30 15 -81 -77 43 39 53 57 -54 -62 -47 54 26 9 53 -28 -63 40 -70 3 -33 -6 -92 -9 -31 -21 22 -31 -32 7 -128 -50 61 34 -26 50 50 25 -31 -17 -28 -14 23 -5 65 -62 27 -69 53 -123 -46 27 67 25 -16 -37 83 -82 39 -76 -18 10 37 5 -10 65 -40 -27 1 -19 87 -65 -53 52 6 46 59 59 59 -5 -36 126 -76 -126 -11 -31 -60 -59 -39 36 -63 54 -20 -22 19 -49 29 83 32 41 52 -42 -52 -32 65 15 6 -52 -126 -42 -40 -76 -114 -8 23 -56 60 -16 51 -20 14 -93 51 -16 21 46 79 70 36 -9 -12 -16 1 94 59 -65 55 -11 29 -60 -25 89 -6 126 22 33 -78 -23 0 62 59 73 -38 100 -37 -92 43 26 50 -20 -7 9 -19 -4 58 11 16 127 -15 82 40 17 78 4 10 -55 76 25 54 -25 69 9 -61 -81 67 22 71 -95 35 19 47 -26 39 -19 -35 27 58 7 -24 55 15 17 -65 -41 127 8 10 21 -102 -11 -11 -24 -13 82 94 2 -41 72 19 12 -43 41 127 -63 16 9 -28 69 -57 107 4 2 -9 -80 -20 -18 -27 30 7 63 12 7 -33 11 56 60 -19 49 41 99 -86 42 16 -51 -55 0 4 -28 31 -10 -26 -36 -1 -65 30 -104 69 -28 29 5 36 -17 62 33 14 52 26 -27 -5 8 115 -113 -13 34 82 -18 34 -47 1 -21 -57 66 87 -58 22 9 27 8 1 -127 -14 28 16 -27 -25 -86 -26 87 34 -48 15 -31 22 -67 -12 -6 42 18 6 124 -17 -42 -19 -5 -45 -60 97 -21 126 -37 39 74 49 31 -43 2 12 33 -60 45 -28 39 50 22 -35 -47 -55 13 34 12 3 -37 61 99 -110 -11 -25 -37 11 35 122 52 -68 -87 -22 -14 -65 -90 -71 -6 94 83 29 32 61 -15 -31 -4 63 -23 61 49 -24 30 56 -41 57 6 48 94 47 -50 -83 37 -66 31 104 -92 -20 45 -57 -90 9 48 31 -2 54 9 26 -82 -22 48 -44 -2 -90 29 27 2 -2 18 -25 17 81 5 2 -123 -39 -42 117 2 10 -5 -27 56 -21 56 92 12 55 -82 -17 -5 -6 -24 -11 -33 -15 -72 -73 2 15 100 61 -128 71 87 -56 37 127 19 16 107 62 40 -33 -126 116 56 31 -15 -62 -3 86 -65 45 -37 -25 -51 0 -67 62 -1 -2 -3 6 11 -59 127 -41 70 -43 -53 49 65 -87 82 -95 -125 -85 -51 15 -3 9 62 -47 48 5 77 -42 78 28 -15 76 -20 13 78 0 -1 -22 -61 -30 -74 -44 -46 64 36 124 -12 -107 50 -37 70 77 -99 79 -1 82 97 -71 27 98 -106 -128 -64 79 -61 -19 4 -20 30 -23 -23 -33 -21 -48 -40 -20 84 13 -114 32 -60 46 -33 -4 42 -116 -10 70 -13 -71 -17 -36 7 -102 -123 3 -37 70 15 -9 27 -106 -36 -112 76 -46 -11 -63 -42 -23 -38 -86 -127 44 66 -11 45 23 11 66 -41 -54 -62 -15 9 14 -42 -14 14 -11 105 -120 2 64 -11 38 -27 67 -17 29 55 -7 21 -16 -12 20 -14 -6 76 46 -46 -13 -68 -14 -6 57 -120 73 -60 -36 4 28 57 8 33 83 27 -19 -66 -75 -1 -11 23 -55 53 -45 45 33 74 -18 -28 87 -33 49 -69 106 43 11 10 34 40 -13 -50 -34 -18 -33 41 8 -39 -20 50 33 39 59 8 -104 -9 -27 -59 -104 38 48 38 -43 46 17 -77 -3 64 -45 -39 -43 86 13 -78 26 126 -43 21 -45 -54 -24 -65 33 -50 -2 -1 56 -92 32 -4 19 -32 -123 39 7 17 19 41 49 10 -1 12 42 -38 19 -17 -87 -27 -19 14 -43 36 -2 111 -1 -38 -31 36 -113 -93 48 14 6 60 -36 5 -3 17 13 0 -46 -30 57 6 -24 -53 7 -18 -5 20 -6 18 43 6 15 -127 -46 -9 63 -20 15 47 -8 -50 -119 -31 -108 -2 -90 49 48 -79 -11 42 18 50 12 9 -19 -49 -87 -50 8 36 -9 -4 30 4 18 26 91 -21 68 -40 71 -34 -33 13 16 51 33 -20 -35 55 -34 -22 53 46 38 -6 -49 -24 11 -25 28 -41 -17 30 -8 1 -7 -46 -44 8 5 11 -17 21 12 -91 -33 6 -27 -75 22 -26 -1 99 12 30 -9 10 -22 -24 -125 -49 -43 -9 26 6 -3 -17 41 -72 -38 -9 23 10 -10 -19 42 -23 -52 39 38 -62 -56 -8 40 1 -16 -23 57 27 -2 -33 41 -15 -10 -32 -44 44 -18 -10 -123 34 14 38 -60 22 33 -20 24 18 -103 -11 40 38 4 9 12 -13 67 -31 59 -9 9 4 15 -7 9 55 1 -41 5 22 -61 -112 23 33 -36 -14 14 30 32 7 11 18 -33 -62 -15 -18 0 -36 -24 22 -38 -9 -30 21 48 17 64 -1 57 -2 -20 15 -89 18 17 84 47 -8 25 4 0 16 9 -13 -3 -62 94 -26 -11 33 -12 -39 -40 13 35 20 22 -26 -15 126 19 -65 -20 -63 -2 -58 12 46 -3 -6 -4 49 -41 58 127 -46 64 121 24 51 -13 -21 -117 34 34 -103 -25 -38 72 -90 39 -4 -2 82 63 64 54 30 -24 78 -25 -123 103 33 48 93 -1 -8 8 -4 -21 -64 -9 -10 96 -52 -37 -36 30 78 -36 -80 -89 -23 56 48 70 25 -55 114 55 97 32 27 -32 -49 -8 34 -59 -20 -60 -70 -66 -46 -7 -110 -66 -58 -10 -37 -50 -31 10 22 -2 71 17 -26 -67 8 18 -26 55 31 40 -15 -76 9 -36 20 25 51 49 -44 36 19 -36 -2 -117 -25 -122 -25 16 14 28 12 18 -25 19 -34 30 1 -39 15 -27 33 -31 0 -14 66 1 8 -8 -32 -15 8 -36 10 52 26 2 -13 -125 -32 2 -116 -20 -50 -75 25 5 -26 -55 -22 32 -2 -56 -15 8 -37 -40 -45 12 -36 -48 21 -11 -38 -8 -35 -73 -22 -6 -122 -13 38 -45 -41 15 -84 14 80 -44 -4 -27 47 -37 35 9 -21 -60 -87 118 53 -72 4 -35 -80 17 47 -114 -30 -14 91 25 -97 16 35 -87 -19 30 -12 -12 90 -9 51 32 75 127 -13 -65 -80 -29 -51 29 -38 27 15 14 88 23 -50 -21 -11 15 -4 -41 -10 -37 -1 -27 -37 23 -76 14 -10 -16 54 -1 -52 -84 94 2 59 -67 21 -18 -3 27 61 60 2 -6 -42 -17 -125 -32 50 10 -46 -76 101 -1 9 6 57 -98 18 56 38 21 -22 -60 61 -17 -4 124 38 -29 3 -47 11 49 28 14 41 2 119 -21 -4 40 -42 126 35 69 20 82 10 24 -63 -44 23 -2 3 15 91 -71 28 63 59 40 -44 47 118 -20 -74 108 -22 52 5 -14 34 11 -58 1 -16 103 -34 -31 40 0 22 37 100 22 12 6 82 64 -107 46 -33 -111 -51 -46 -69 -53 56 -56 30 40 -44 -11 55 11 -49 39 -89 17 121 77 11 -19 61 3 -34 -21 -2 -4 -2 -5 1 81 25 -22 -88 -38 27 111 2 -4 -39 0 -16 -29 -19 -81 -57 41 -18 -4 -45 24 -55 -26 8 -4 49 -23 -67 -78 32 -37 -11 -26 58 3 18 -26 -9 17 -48 52 -38 5 73 -4 7 -51 78 35 -48 22 -30 14 -10 24 63 2 -122 -24 -4 20 -2 11 -23 50 16 -68 -10 -27 25 7 -24 -9 16 -49 2 -34 1 21 16 3 32 -57 1 56 -50 -73 -67 -69 17 10 -65 15 -34 42 -91 23 9 27 14 4 -15 6 -15 -28 -68 48 40 -62 26 0 123 -62 -47 -3 -15 11 2 18 -45 -12 -16 -38 -2 30 41 -77 -12 85 12 -7 -70 48 -20 21 -47 64 47 -1 -13 -16 -11 -74 -10 -24 65 20 10 2 31 -42 -41 -10 -52 19 102 47 9 -78 -96 11 -13 -2 -107 0 -48 -66 15 5 -22 -54 110 -50 -24 61 13 29 -11 10 57 1 -26 53 -80 -2 10 123 72 31 89 35 -11 71 -48 52 -1 -3 -44 13 51 12 -23 -8 29 17 110 81 -24 39 -17 -13 82 2 79 59 76 -56 6 77 14 -73 -53 -60 -43 -49 126 -2 84 24 82 -1 -17 5 67 -58 -56 -28 62 -4 126 127 5 90 7 39 24 49 -77 -72 -9 -37 -16 21 33 62 44 -15 -45 50 65 -17 12 85 13 122 45 -11 -32 -39 84 -42 -33 25 70 -2 44 68 7 -47 -22 34 7 14 -17 1 -6 -26 0 -36 53 86 -8 -36 -70 -88 -125 64 -77 4 51 117 4 -21 79 72 42 -62 31 -58 4 41 33 74 31 -14 32 84 -1 -21 21 -127 -49 28 -44 59 16 -106 -107 48 108 3 39 28 -30 -19 9 49 67 -37 11 -48 -51 -36 65 -25 -16 -5 14 1 -29 32 27 48 54 6 57 2 63 78 -55 -5 56 53 29 -5 97 -5 -16 -104 66 -13 43 61 -24 -46 -21 -22 -80 -65 39 5 -91 -58 -71 105 2 6 -113 -62 -30 -6 66 -18 -51 33 -109 37 -100 -78 -47 4 24 79 -53 -32 -29 -25 -14 80 -125 2 -51 -48 -24 125 71 33 -10 -21 -42 -37 -30 38 4 -56 -40 -84 8 16 81 -42 -9 31 21 119 127 -52 91 -81 -124 -121 -115 14 -8 80 -71 -21 6 64 -122 -1 -4 49 28 21 101 24 24 -72 54 -16 -45 35 46 49 17 -3 43 -76 -41 68 -31 -38 43 -57 -6 -20 -70 -17 46 -13 38 25 52 58 -55 -12 -14 13 -121 -24 -3 34 31 -20 99 -20 8 -65 -2 -102 -75 -15 -44 -69 -38 82 -89 79 12 -123 -13 114 24 -124 -22 -46 -38 -127 10 -36 -126 -1 -99 5 -43 -87 -120 61 -38 15 13 36 -71 -78 15 -1 22 -11 -28 -19 -26 -104 -72 33 -65 99 -44 42 50 73 -14 0 -60 -26 -21 15 -27 -3 32 55 -36 -93 25 36 39 5 -11 37 -38 -79 64 -19 -24 -7 21 -37 -60 -1 3 5 4 -37 74 12 9 41 119 -41 62 -20 46 29 51 72 -7 13 73 66 -7 1 -53 49 27 -34 -11 -11 -22 3 52 -80 27 -18 -57 -86 -4 -20 66 42 -3 -57 -9 -23 54 36 124 -17 -17 86 -123 27 -26 71 -52 -50 9 36 19 -16 -60 -70 -85 27 -43 41 -106 -32 -5 -22 -17 44 56 -6 -30 32 87 44 24 -79 -70 -33 101 11 1 33 57 36 -52 -29 -13 32 -52 12 37 -29 -36 -14 -17 57 38 61 -38 30 18 -31 -84 -39 -5 -74 -70 -22 -31 10 -47 -19 1 30 -47 36 -53 58 32 58 -21 -1 63 -102 46 1 42 -67 -24 -38 -12 95 -10 61 -18 -33 -27 -34 -49 -10 49 -12 33 61 24 -55 -46 -5 7 4 -19 -32 -51 -30 -19 -72 -53 -66 -32 -24 -31 22 -67 -27 -45 34 -2 3 14 76 76 -31 -74 2 -71 -23 -37 -74 23 74 -54 -11 84 41 8 -102 -66 -20 -6 77 -107 6 -34 -91 -26 61 -38 -54 -101 -4 80 -55 66 -65 62 -10 119 60 98 42 -31 31 -110 -96 89 -100 20 -39 15 -3 -54 -4 -5 -8 16 -121 112 -9 63 -67 -95 -48 127 68 12 124 23 125 -51 125 -75 12 -70 38 3 62 18 80 96 -30 -83 -2 81 54 124 118 -7 70 27 64 -7 -52 68 -12 123 78 13 2 -54 10 -78 -42 -102 19 107 26 76 -6 60 20 0 -116 58 83 43 -12 -1 5 45 99 31 -20 -71 18 63 87 29 -6 95 84 86 -66 -16 61 59 52 -17 -9 78 64 -34 83 21 -38 14 -5 2 -31 24 14 -21 62 92 -17 -15 40 -32 73 10 18 -4 -12 127 -4 35 11 -12 -73 26 24 -34 2 -33 5 14 40 7 63 66 -47 37 32 17 -125 102 24 1 -7 100 98 6 -54 108 74 46 -5 -72 -11 102 54 -47 -9 1 -104 17 38 -45 43 -3 -25 -56 -45 -5 18 -71 -2 44 -78 -41 39 -125 -46 65 47 106 -13 12 -60 -7 -65 127 -52 -119 56 5 35 20 4 -4 -55 -75 89 13 23 -27 50 -4 -127 65 -28 126 51 -90 127 -93 -115 -16 -42 10 -45 -73 123 5 -60 -6 -37 -50 -61 -56 14 37 118 -24 54 45 20 -41 33 -3 -126 -26 13 40 -39 -24 -25 -37 -23 -68 -73 0 12 32 -124 -67 31 -1 76 -127 -29 -84 81 75 -69 53 -6 45 9 -90 121 -33 75 -98 -75 -28 -41 -72 -97 -60 8 -8 -34 -32 11 -104 120 -48 11 10 46 -27 58 -21 -70 8 -31 -55 55 -125 127 -12 27 46 93 -58 -42 -54 42 -23 101 -21 29 -31 -102 41 -127 -50 78 -21 60 127 -15 -8 -30 33 68 -9 -87 -103 -120 -127 -37 12 40 -43 -39 0 -72 100 9 -5 -27 38 18 13 105 -56 -24 6 8 -61 -45 -92 -30 -23 -96 -37 37 -15 89 2 18 26 6 44 -10 -119 -35 34 30 61 16 7 -5 -19 -42 49 38 -54 -6 -4 21 110 -10 92 57 -56 1 13 2 116 -1 18 -18 -105 87 -110 -127 -98 -116 -63 80 40 -31 87 -78 33 -78 -21 -30 -126 -34 -33 -77 -30 54 -78 -125 -1 61 -32 -42 -63 -81 1 13 -72 18 -1 -63 45 -21 -1 30 72 21 -45 1 -24 -16 23 -45 30 15 24 -45 -118 -7 99 -32 73 115 -61 -48 -99 54 126 3 -123 24 -124 73 76 -51 19 80 76 51 12 -115 121 -123 -45 -79 -17 80 101 24 -65 -69 9 -114 -127 59 72 31 58 -76 120 29 -16 -127 -49 -111 -58 60 59 -33 -6 -39 4 -99 35 58 50 17 127 100 81 -57 -56 -29 47 40 -15 91 8 21 -33 77 45 -87 -20 -23 -84 47 53 96 -96 -128 -102 -50 -86 127 -24 32 -21 -18 3 1 -65 -82 -3 17 37 4 27 4 75 -38 7 -64 10 67 11 -16 -70 49 31 9 33 -21 -89 22 85 103 -8 48 18 -65 81 -1 55 43 127 22 -46 46 40 23 1 29 13 4 92 20 27 66 -53 74 -20 -21 45 -15 78 -4 99 -66 29 53 5 77 -4 61 35 49 -31 21 -117 -26 -1 -6 100 23 35 -7 3 -25 -19 27 8 -10 -79 53 -65 -11 14 -44 -1 -52 88 -71 15 -31 94 1 -24 -11 102 26 -11 11 0 22 38 -23 -84 -65 30 3 -9 -5 18 -3 -13 4 31 -26 23 2 37 52 -19 14 76 26 2 -12 22 -3 62 -9 12 -1 34 -15 24 -10 8 -7 22 -21 0 26 6 -1 -1 -30 5 69 20 52 35 38 -22 -30 -38 -40 4 18 -41 23 19 -37 -46 -82 18 -26 12 -63 25 -70 41 -66 -43 28 2 -12 -12 -7 -17 64 -53 -17 -18 4 10 24 13 41 36 -27 -25 18 -59 41 13 8 15 -9 -44 -48 -83 84 -4 78 -95 38 -26 -86 36 -31 10 7 -81 -7 -90 -122 58 -40 42 -7 -30 54 28 -33 22 -74 -9 127 73 8 -30 -14 -88 -15 47 46 9 43 7 -51 -61 -40 29 -64 124 18 -61 -3 -22 76 5 -14 15 24 9 -70 -63 21 -44 10 -51 49 -29 -13 -8 -48 -34 19 -56 24 -38 35 3 -2 -69 -78 -11 -67 -23 0 -34 21 -128 20 -33 42 -21 -74 45 70 24 118 66 35 -2 9 121 -115 52 72 68 60 27 -6 54 -73 -56 -22 -72 82 37 43 -52 20 8 4 38 110 77 95 -15 54 66 64 -2 12 33 53 -5 16 23 -2 -69 -37 59 40 -3 -87 32 82 42 51 -33 21 113 103 -43 70 -19 21 50 122 -64 -61 45 -41 61 8 -9 73 60 54 -28 24 24 -106 -26 -15 97 51 -4 -54 -7 105 -43 -61 121 -84 85 20 2 -35 -41 -41 77 -23 -13 27 -73 -13 -35 -37 4 28 122 -15 17 16 30 101 -67 28 -10 -45 18 -11 5 17 -10 -91 -28 74 -22 -26 -84 4 10 29 -18 33 21 -26 -84 14 56 -37 35 9 -73 -12 50 -18 -55 0 32 97 15 -35 -29 0 -36 -64 -45 80 16 6 22 40 -10 34 -20 -66 5 -9 -128 -37 -50 -3 -46 -24 -29 -51 44 23 123 -61 126 71 16 -1 -59 21 -69 -55 24 110 -46 -79 68 -50 -76 98 -17 79 -57 -2 46 -48 5 65 52 -38 -13 -18 -98 32 2 21 -27 -37 21 -6 33 -57 -76 -45 -24 56 -32 -62 94 20 1 46 -82 -46 -123 46 -50 127 -2 -33 110 -16 -54 -6 97 -49 18 -3 36 -2 -37 103 -5 88 49 -17 -1 -92 39 33 -27 -4 -21 -99 15 -53 25 44 51 127 24 37 -4 9 -46 16 66 -27 0 6 46 -45 -27 100 -43 30 0 11 68 -13 -122 -1 -4 56 29 64 18 29 25 39 -65 -38 37 -14 -110 40 45 -27 38 3 5 16 87 70 -2 18 -43 1 21 -47 45 -1 -11 24 -61 -93 -29 15 -33 -43 4 25 -28 99 -13 -24 -21 -65 -26 -13 -18 28 24 -74 -122 -26 -34 59 85 -62 -125 30 -20 -46 -49 -72 -9 -7 -44 -49 -60 -107 30 28 -65 -102 31 -14 -93 17 -89 -4 79 6 -44 -25 63 -7 33 69 -7 -88 69 9 4 -24 4 -38 7 30 43 -34 -19 15 24 -20 -6 68 2 -21 -62 -2 74 -41 29 55 93 -11 74 -23 34 22 3 12 -40 30 -42 -37 -8 -96 -3 -85 -35 -4 127 -24 55 -20 -33 -57 -22 100 44 6 40 -41 -7 31 15 -72 61 11 -88 44 111 -71 32 20 21 -35 -60 93 44 21 -68 27 12 47 -13 -19 -36 -44 -3 6 7 8 -5 11 -48 50 12 37 -37 10 -17 -22 1 22 36 32 -127 -16 -85 -68 43 53 15 55 -47 -29 -60 -13 57 -98 34 97 -25 27 -3 24 -85 -9 4 35 32 58 -72 47 -42 -73 10 -4 63 -64 -1 31 -47 -1 6 35 -12 71 -4 -44 -84 3 20 1 -34 2 123 -22 14 -58 -40 -41 -40 -29 14 -62 32 -18 42 18 -29 -12 16 -50 -56 -32 -21 60 -28 -23 -16 29 105 -4 29 -21 41 -14 68 -39 -34 -57 31 -4 -25 -87 -69 -3 34 10 -51 -15 14 -31 77 2 -9 1 72 76 -18 67 32 85 -11 -44 -13 -102 -89 -86 -8 11 -36 126 9 54 -4 67 38 41 10 96 118 -24 110 30 -79 79 48 -90 18 -8 -31 4 61 91 27 116 23 -11 116 38 65 64 17 7 42 0 -1 47 42 57 80 -80 88 -37 -93 38 21 63 -21 105 -13 46 53 52 72 -46 54 4 75 68 82 -49 -84 57 96 37 -69 18 37 -59 -40 49 -32 26 125 -12 -54 43 7 -27 -128 -49 64 -11 -65 -52 46 50 7 57 32 69 31 -91 127 -72 45 90 -110 -20 -5 125 112 -126 127 -88 -14 12 28 -86 -10 -66 51 -24 20 -9 -57 3 -13 41 -44 46 -53 37 -2 24 45 -41 6 15 -65 -106 23 -2 -19 -92 -40 -5 -71 -9 -94 -59 -13 -74 -62 32 -45 18 -10 -94 -5 25 52 45 3 10 -97 -100 -126 -55 -22 -64 -74 57 -126 -72 -57 -72 -24 29 119 -69 -71 -35 22 -27 -7 17 30 -22 -35 -49 7 -5 22 -10 103 -83 -88 60 74 -23 127 -1 40 -7 8 -88 33 -62 -51 45 37 -8 13 -64 -46 -62 64 126 61 -66 60 -3 -27 33 -9 14 -48 -39 21 5 79 -19 1 -53 -10 71 -15 15 -2 -42 60 -10 13 4 -6 -26 -81 -44 -13 23 33 112 65 2 56 36 17 70 -37 -26 25 -60 -50 -32 -16 -54 -108 77 40 50 32 21 6 0 40 -23 -49 -72 -45 -16 -19 81 4 84 -14 97 58 36 49 -55 -31 14 30 42 91 114 50 40 -9 -17 -25 69 -105 86 16 1 64 3 -14 65 74 31 56 -35 120 -46 -64 -5 18 18 53 -18 15 47 -11 -46 75 5 60 -14 -27 21 88 47 42 32 23 68 127 117 -47 114 1 55 -5 72 -37 3 21 53 22 -15 72 26 127 125 -10 115 81 48 77 47 -65 1 -47 -104 37 -9 -26 17 47 -12 9 0 -14 34 -50 -40 25 7 -82 -6 50 30 -2 -4 -20 58 82 -39 12 -12 3 -29 -8 10 35 44 19 -56 0 -80 -14 -28 19 -45 5 -13 12 -58 -9 -25 -26 -51 -17 -21 -106 48 -17 -41 0 7 47 -31 32 26 8 -38 17 28 -14 3 -24 -13 40 -56 -8 -21 -22 -4 -26 53 3 11 -6 -43 45 37 -32 -53 -35 11 -27 -84 -91 -11 45 -75 24 0 -50 -19 -55 -88 -12 -32 -13 -22 -22 -16 37 -25 7 -61 15 39 -26 -1 -4 -31 -8 34 31 -69 3 83 24 -28 -4 35 -21 31 1 -6 71 -38 -7 0 62 -38 4 52 -57 22 8 -4 -32 6 14 10 -11 3 -46 -8 3 -7 25 2 -5 21 36 -48 15 49 -13 -29 6 -9 5 22 -13 24 122 -27 -22 -10 24 29 -21 10 9 -21 -7 11 -37 24 -15 -14 90 -22 -92 35 -11 -10 -20 -19 36 37 67 -10 21 -23 -34 21 -4 -38 -17 4 37 1 25 98 32 53 65 24 -44 13 13 8 9 29 32 -44 -13 26 15 -51 51 -15 24 38 -22 -1 77 -29 -39 74 -8 27 -58 -5 67 -41 9 40 19 44 -30 -36 42 29 124 80 111 71 -4 121 -17 48 10 12 -2 15 17 12 -6 21 -15 86 -62 -62 -10 -2 -53 -9 39 67 66 -89 -9 -7 -16 33 -41 39 74 45 -59 76 25 -13 4 -26 -43 16 -64 30 39 4 -12 7 -90 23 -25 -37 -1 27 58 -33 -15 -5 17 -24 -22 19 49 122 -79 -44 -25 33 -11 81 1 -22 -13 -1 26 3 73 14 31 26 -58 95 -29 -65 31 13 47 26 -54 68 22 41 37 -1 -40 24 38 -18 27 61 -6 23 -90 97 9 -49 12 77 67 33 -22 56 77 -35 0 32 40 -24 16 -109 8 8 -83 3 4 38 -11 22 20 91 60 -44 3 70 48 -17 18 32 31 38 -31 -34 14 110 4 59 -47 -6 -31 62 -36 105 27 45 -128 -19 -94 58 -81 -20 -126 -47 -101 8 103 -41 -78 -10 -128 7 31 -71 76 -44 127 13 -41 -88 -20 -39 -77 127 -27 69 21 -4 -32 58 -36 53 -124 30 1 24 -117 -6 -1 -71 48 22 125 -34 83 13 -98 -43 -4 126 -9 -124 41 15 -128 -122 -60 -5 -76 86 -114 72 -10 42 -55 34 68 36 -35 72 -13 8 -30 -40 112 -13 -35 22 -8 125 -38 42 41 -51 -101 19 -51 -53 -53 28 53 -26 81 127 -2 -35 -77 -4 56 -56 -97 -123 40 5 -107 20 -54 -7 112 11 117 -98 38 -65 -72 -101 -42 -22 16 28 50 -19 21 33 -48 -34 -26 24 -22 -10 -42 7 -15 -40 24 -59 3 37 78 -36 115 76 45 0 69 -39 -128 11 -31 46 -116 1 -111 -81 -116 -38 -23 9 14 -7 -2 104 73 -25 65 -8 -69 48 81 -31 9 -62 -57 4 -3 -66 -95 -57 -19 -57 46 15 -70 14 -5 -3 24 20 -24 32 -15 33 -13 -48 -47 -1 39 -100 -54 38 -9 49 3 59 60 74 82 39 46 65 15 11 -63 -14 -34 9 -6 22 40 50 -28 38 -11 -62 -10 -35 18 40 -68 -52 -1 39 29 -96 -5 -28 -73 -52 -56 14 10 25 -9 -9 -69 -37 -5 -11 38 46 -18 -23 -36 -3 -57 16 26 24 57 30 -34 42 0 12 -47 96 31 95 55 22 -62 11 -16 62 43 -100 -5 36 44 32 -26 -116 -37 -124 -43 48 -6 16 -67 -26 73 -7 -17 16 12 21 -34 76 -15 75 -58 -9 -55 -15 -22 126 -14 25 16 3 -13 -59 9 -36 -42 12 -9 -53 -96 -56 -11 13 43 -11 -49 63 1 -70 -2 -15 60 -26 71 -44 17 -52 -126 -94 74 -65 20 24 -38 2 -62 -66 -105 -46 24 50 -16 31 15 34 66 25 23 -6 -10 1 -50 -84 65 21 -44 18 -39 -32 91 32 -35 -10 27 -15 -53 -64 -16 32 -6 -71 -67 -62 -7 13 -34 -3 85 -33 79 -45 -42 -50 -71 -60 -33 10 1 -57 25 -57 9 -15 -33 14 -41 89 2 -16 -40 -28 -72 -32 30 -59 32 31 -127 -65 -63 -46 23 18 21 -44 -17 9 -2 9 62 -50 -126 -1 -20 -128 -7 16 -64 -52 18 -25 88 15 76 92 -87 -33 53 -5 -2 41 7 5 -17 72 -31 -5 3 -128 -68 -18 23 3 -35 -39 62 -30 -59 24 30 73 -30 -30 -17 -14 89 -4 48 20 63 -29 -107 -44 -15 -37 85 -28 -49 -77 -63 -37 -40 -33 58 -121 -68 1 27 2 -42 -32 -9 -48 -26 -33 -70 10 -29 20 -44 87 -20 12 51 7 -74 43 29 53 -24 6 -127 -30 -45 -41 24 5 58 -6 24 -17 78 63 -24 24 -13 15 -41 28 -26 27 -1 86 73 7 9 -3 -31 -66 -25 -35 18 -35 -38 -13 -31 -36 20 -16 64 -121 -54 24 -33 1 23 25 -48 7 -27 70 -2 57 -10 32 26 11 -18 41 -50 -19 105 -55 8 30 71 31 -2 -94 -82 -62 125 -41 -28 -20 35 56 -31 46 -23 -34 120 0 -75 -26 -70 -3 -47 16 -30 51 66 15 -11 5 -59 -59 32 -40 28 -50 28 82 -54 -16 48 -93 -2 2 37 68 -22 22 22 11 0 -39 2 -88 61 5 54 45 -51 22 -2 -30 -119 -70 -27 -31 -6 -14 -67 -18 17 -6 -12 -34 -5 51 46 44 -90 -79 -43 111 45 -9 124 -47 105 -27 -25 -63 61 55 -95 -90 -8 -15 39 -47 -45 1 81 68 -39 -46 62 59 -81 -97 35 -27 127 2 -69 -44 40 -70 -94 -25 -128 -99 114 -70 -41 -40 66 69 35 -64 107 -121 -30 50 40 -88 42 62 -44 -7 -38 95 96 33 -83 -73 -55 -46 -117 -55 -37 -84 -40 -87 -47 44 47 -77 -105 -46 -40 10 46 -69 -112 29 56 -32 19 -39 -106 -63 -28 -70 -26 -61 -65 73 116 89 19 33 -14 16 -31 59 6 63 54 42 -59 -65 -66 -54 3 -65 -89 21 43 -3 62 124 37 66 -47 -75 28 -6 27 -50 -26 114 -51 70 -54 20 -36 -81 -31 0 40 6 40 -118 -15 56 1 -79 -27 -30 -53 47 -75 87 12 -42 31 -101 53 103 91 27 26 121 -74 -53 -42 23 -100 74 27 -23 88 -3 -80 -48 17 52 15 32 7 25 -10 -21 -2 14 67 -18 -30 -25 44 1 -76 -46 -115 -61 -23 -19 -23 34 -60 69 18 -124 -13 43 -57 106 61 -59 -63 126 14 109 105 -15 -56 36 -51 -33 -32 -47 -31 15 -21 45 -76 -125 -17 15 83 86 123 37 -33 -81 -34 -42 -31 62 -106 -100 -15 -19 -97 -64 -63 -86 71 -80 -17 -56 80 1 53 -22 -71 -9 22 39 77 14 -125 -54 0 36 -26 85 62 -36 -7 -34 82 -29 -41 -22 94 18 127 52 26 106 -9 29 127 31 7 -5 89 -63 -50 95 28 -1 -12 6 31 56 105 -38 -5 3 46 47 73 -2 -38 -116 -40 78 -27 91 62 -115 -14 -45 8 -36 36 91 123 109 51 -105 -25 27 -74 27 -12 78 -11 -10 6 20 -4 101 57 -53 30 32 -12 -71 51 120 -83 11 -99 11 -71 -32 44 42 47 46 -93 -62 -42 -22 22 -2 -83 -52 13 -128 40 -27 -23 7 92 -16 8 -52 4 11 15 2 -21 -36 -11 -3 -15 69 45 -43 91 -16 68 24 -3 22 116 79 123 -128 -78 127 -9 -8 -78 -119 -18 -48 48 -121 -56 39 -59 -86 -45 86 76 -44 125 58 -59 -109 -36 100 69 43 29 37 73 50 -24 14 41 -33 53 72 23 49 50 121 -8 -1 127 106 99 61 -3 74 34 74 127 72 -45 9 62 31 -19 -14 -60 19 -35 -27 19 7 51 86 61 0 -4 -65 31 -83 50 -23 49 -2 -3 16 13 2 -65 42 105 -7 47 -4 -59 -39 18 -37 50 81 9 -21 -7 96 -20 -92 -34 46 -7 117 42 -117 -53 -7 -81 7 -12 71 -4 -77 -44 -54 47 -38 -53 -69 -33 -92 69 -8 67 69 -89 15 -101 40 12 -46 -33 -20 -81 26 3 -13 77 12 47 -66 -72 -24 34 8 -44 -9 -11 41 16 -16 -65 -84 -84 -125 -37 9 56 -6 -82 28 -66 -13 -67 -1 -26 -49 -8 4 29 -7 29 24 -27 -31 62 96 -5 29 -28 -36 9 -29 122 7 -18 -31 -128 -124 -57 29 -10 -73 31 -12 -69 -111 75 122 -124 4 26 27 -50 -121 -127 -29 -15 -27 -26 38 -72 -33 -47 99 -29 16 63 6 -30 17 122 26 109 19 -126 -40 -57 113 45 41 65 12 -22 29 -128 -35 -123 -45 20 -101 25 -16 -10 -107 -108 -24 -66 -84 112 18 70 -19 11 51 -50 -34 74 -52 -50 63 7 -39 -56 -116 49 9 64 22 14 -127 58 -7 -106 91 -31 -12 6 -18 34 -4 -21 -125 1 -49 -45 -25 -44 11 -22 -36 28 -8 51 11 -127 72 -1 95 73 -5 -125 -33 -24 14 -74 -76 66 -63 -100 -35 70 23 63 33 -56 21 -2 37 76 41 3 -38 81 59 -48 -46 4 -119 -64 -32 -50 -31 63 14 29 122 -6 2 -32 -29 66 84 -65 117 -62 -51 23 -49 7 38 -7 4 -98 64 -81 -17 80 -16 79 35 -37 27 -19 -91 -54 -74 18 -124 -20 -24 -65 5 7 19 69 -18 -59 26 18 63 -20 -17 -5 -76 -17 21 -40 -52 24 -127 4 -14 40 -17 -8 -65 -69 4 -35 -16 0 -62 76 -17 64 -16 52 -65 -29 88 16 7 35 -44 -53 -102 -35 -2 58 78 -38 17 24 127 34 -12 -22 -13 73 54 3 -43 110 116 -40 23 93 43 -50 79 41 61 -32 101 19 -36 -86 -93 -8 31 -41 -47 60 -55 51 18 -56 -29 -111 -65 -48 44 21 6 -20 67 -97 35 16 36 -11 21 61 -50 65 43 108 23 0 -111 -19 38 0 11 -16 114 78 40 27 6 48 42 45 105 33 67 111 -59 38 96 -26 -24 49 23 37 3 26 -2 -24 90 -21 3 34 29 33 36 8 -90 26 -53 58 -13 68 -28 70 -66 -19 44 48 68 -81 -18 45 22 54 127 -36 82 -2 -32 -13 11 63 -27 12 28 126 -14 -19 -12 -9 97 -17 21 -80 -76 -68 -9 12 -27 13 124 34 86 27 6 -12 -17 -51 -19 14 12 -4 -27 17 121 -32 5 5 -38 63 30 -30 -64 -25 24 -7 -30 5 -1 38 12 -110 -39 -30 70 -12 -58 -38 -17 24 8 35 68 -52 55 -28 -126 -71 19 -23 31 69 -25 -24 70 -46 44 73 9 -33 -38 24 7 -22 -9 -40 -15 -13 28 15 -5 64 -46 -25 -98 -4 -63 3 90 -15 2 32 -31 82 30 59 -3 18 13 -38 -36 2 -1 -27 -62 -64 -26 10 -29 17 -15 -90 -10 14 71 28 2 -102 -4 -53 12 73 3 -41 124 -19 49 96 -24 9 -73 -127 -35 -116 11 -39 -11 101 15 26 61 -36 9 -24 -46 -41 124 17 40 -32 -65 15 0 118 -84 75 46 -19 -99 15 -111 14 -12 55 -32 4 17 21 50 19 8 -3 -18 2 -21 -92 22 35 49 -7 44 -55 8 46 -19 -27 -73 -126 -29 -34 -40 34 2 46 65 -48 -103 22 23 0 -3 -39 23 -17 58 -85 23 66 127 -17 34 -6 49 -26 -63 9 80 -17 -38 14 -60 118 38 -28 -16 55 -38 55 -75 -11 -79 -20 -57 62 124 -101 76 8 12 -23 -36 19 -25 11 60 108 -19 16 -16 -70 -35 20 -89 76 57 55 113 -90 58 -126 -29 -102 -11 -115 57 20 7 25 17 -42 -12 41 80 71 73 -15 82 55 66 89 11 -49 -51 7 85 34 72 127 0 -22 25 68 -6 -111 -67 13 84 12 -43 -53 -14 31 53 26 12 29 21 30 51 -48 15 37 37 13 8 -25 -23 -20 -14 5 -73 53 -24 -27 18 -10 86 25 -5 -57 -72 -22 1 -6 80 -9 -49 30 -19 -35 -25 -18 -35 59 -54 17 34 45 15 -28 -32 12 -21 -14 0 -30 7 -18 35 -5 -46 23 41 33 11 41 57 -27 14 5 -31 -5 0 -45 -33 8 -32 49 -29 25 -37 -48 17 -29 22 25 7 -18 -37 23 2 7 19 -38 32 -53 -26 -77 50 57 -38 10 -48 -35 -1 42 16 -12 -53 -25 43 -39 -46 -26 -28 -6 -11 16 42 90 14 20 -66 -85 -18 -39 0 -10 -2 -8 7 -122 1 -39 -126 -52 71 44 -67 73 35 61 -34 -26 -125 -43 37 20 51 -28 66 10 -19 -20 -24 39 55 -21 94 -10 23 -47 -94 -25 -102 -44 107 -1 75 -77 -23 -81 37 19 27 -2 -88 -43 -47 -63 29 38 -3 -40 24 -9 -30 70 28 -58 -1 20 -16 -47 43 -46 -47 -61 -15 43 34 60 61 5 -62 -9 5 -68 105 -71 -4 81 -19 11 37 -6 54 26 -3 -42 37 23 0 0 -30 6 16 121 20 39 21 -68 -4 -101 -36 -40 35 53 -103 25 -31 20 -76 -3 23 115 -52 87 30 42 -63 21 20 -17 98 -43 59 58 81 -59 -114 -5 -19 -63 79 -22 8 38 -1 1 -20 46 -26 85 26 -11 105 20 9 65 -95 7 -43 125 61 44 -61 19 31 -20 -3 39 78 -7 45 -36 9 24 -39 -1 4 66 -68 -13 31 -4 -64 23 126 -20 -28 62 25 70 24 58 68 4 7 -50 -45 123 98 10 93 28 70 97 77 -10 -54 32 4 7 59 26 -9 3 42 47 105 -9 10 30 10 -42 -8 9 12 -2 -116 -44 7 19 -7 46 21 67 -40 22 -15 15 -53 -9 -47 -15 -57 89 0 19 14 -46 -12 -58 37 40 -30 20 -9 26 -33 127 10 -13 47 -12 94 -16 17 -38 -24 121 -51 57 -46 -42 15 40 -19 -1 -37 -69 -61 3 11 66 58 -24 20 -64 4 -12 -79 -5 60 -16 29 61 25 26 -66 0 13 -25 2 -13 20 118 21 45 28 1 12 -80 68 25 -77 -59 -37 54 -46 59 21 24 -57 -80 -34 64 -23 -21 -20 -73 20 -68 101 -64 -12 -121 -35 20 99 -13 65 70 127 -42 -48 52 127 -60 13 30 -12 -12 84 54 91 17 28 48 -31 -78 105 -65 -62 -11 97 23 -23 67 46 44 -35 -128 -5 -26 0 4 44 85 -67 -75 -47 -59 -73 -29 22 8 -18 23 17 -83 -32 -8 -8 -21 18 49 -78 -58 9 9 47 -122 40 -51 -116 76 -15 13 63 10 12 -15 11 -7 77 10 -104 23 40 59 53 36 -16 -16 49 -73 -6 -64 0 15 97 -2 -18 53 28 -74 -22 -32 45 52 33 -67 26 -2 70 33 -16 -3 -69 65 -119 -50 -29 39 33 -13 18 -35 -15 24 26 57 -35 -25 16 24 69 -53 -1 -55 -92 79 -27 38 39 37 -66 -86 -5 -26 -10 19 55 101 50 -13 -5 -14 6 -32 74 62 57 123 48 37 10 -124 -26 50 -68 -42 55 23 1 29 -63 15 101 -55 61 -86 -66 -34 51 -52 -44 -17 100 -127 7 -68 34 -19 -13 -13 4 -80 4 -22 78 51 -17 82 53 -90 -23 -4 43 -17 43 102 108 42 -54 82 12 68 0 59 -98 6 68 -95 -3 86 -70 11 56 -95 -45 -88 54 17 -72 -31 70 -4 84 32 -58 -55 49 -72 20 -122 -37 -37 -125 -18 58 41 22 86 -6 123 -4 -64 28 -60 56 68 33 -51 40 7 -77 51 -11 22 56 -23 -108 21 90 95 -58 18 -49 31 -8 -5 -76 46 -124 76 82 -119 -55 -92 22 -17 38 -9 15 -112 -123 -55 -1 77 -58 -99 -21 -19 25 -28 -33 78 -18 -32 3 83 124 67 4 -10 89 21 124 -32 83 12 -34 95 23 16 -5 21 52 -30 19 104 23 -45 19 12 -12 34 -1 17 33 50 52 -47 60 -1 4 48 2 52 -64 37 -37 19 -69 -127 -15 -8 -50 -63 -33 9 6 -8 -96 33 40 -88 44 27 -11 -31 29 20 24 -38 103 -34 39 -123 79 -62 23 -79 -19 -37 -10 -60 17 10 -19 -14 -2 52 8 38 18 2 24 -5 64 -53 -9 -4 29 -14 79 94 -3 22 84 -24 29 3 21 11 -14 25 -44 -46 88 -12 36 24 -4 -30 23 -55 -48 10 -47 -11 67 -23 -43 -8 12 -28 40 92 121 58 34 -1 -62 29 -64 78 -29 -9 40 81 12 -40 8 -2 8 17 -12 35 -4 91 19 -16 15 -40 69 54 54 -43 4 -32 -43 -31 -16 39 -19 -23 -8 62 -55 13 9 -32 12 -64 -26 -41 3 -42 77 78 47 -25 60 3 7 1 6 67 -48 -1 -95 -47 46 -25 7 55 -14 -31 -16 12 4 -41 -102 -53 -43 -70 -37 -103 26 -64 -21 -3 17 15 -6 29 5 -51 48 25 17 -20 -74 45 -34 72 67 -23 -7 68 -19 23 -22 37 -93 -47 22 6 60 38 -17 1 16 10 -32 -5 73 -7 -32 49 -1 20 -23 22 -4 61 -14 14 57 126 15 80 -6 -68 -18 -12 -20 11 -17 -30 1 19 1 8 -7 19 78 -18 75 18 11 -40 -53 82 -11 25 54 -68 7 5 32 -49 80 -67 -3 -55 -51 8 51 -60 -23 -16 -24 -21 -8 -32 12 -77 -17 -37 22 59 -115 -51 -47 -44 -21 41 -24 -44 12 -70 -13 -1 -6 -74 -34 -78 0 -44 -34 -95 -81 -24 1 -73 -71 -51 -49 -19 -40 -53 -49 -72 5 -69 -30 -89 -14 -8 -74 -54 -47 -23 -79 30 -83 -66 -51 15 -63 -48 -52 -24 -14 125 -64 -12 -46 -13 13 -7 -46 -127 -12 -53 -35 -27 -59 -75 -31 -21 -13 -35 -7 -34 -1 47 14 8 -12 34 -9 -14 -24 -64 13 -22 3 25 56 -57 18 12 15 -31 -3 60 -14 -26 19 -121 -2 78 -7 -94 1 -20 -44 -9 -33 20 -15 -28 -60 20 13 46 -74 23 -3 1 32 4 7 -26 43 -39 -10 33 -59 -55 -69 32 -51 -79 41 40 33 44 -65 -20 -1 10 0 -84 -48 68 -54 36 -44 9 89 19 -9 20 22 -15 -22 -60 -36 -85 31 34 -3 22 -15 8 -55 10 -41 -28 -56 -56 -31 5 48 54 53 39 38 -27 5 34 -26 31 19 -44 -81 8 -55 3 34 127 -16 21 15 -125 35 -70 -98 -26 -26 66 43 79 33 -6 -52 18 80 -87 36 30 -24 1 -65 -70 -46 -17 44 8 44 64 2 -19 -22 -20 -26 61 33 31 24 -84 -45 -2 -52 -4 -31 72 -17 37 -20 -62 13 -25 8 -1 20 -4 12 13 64 47 5 93 -34 -83 17 -8 -20 -12 47 -26 -23 62 -50 86 54 34 38 13 0 44 83 -33 70 3 74 -36 -125 0 -32 -45 -101 59 18 -40 121 54 8 111 -120 -18 92 100 36 -32 25 -84 91 75 6 -42 28 95 31 -65 124 1 43 46 99 -6 26 20 15 -21 67 75 -16 26 84 28 -44 -35 102 41 -92 71 -88 -55 -44 15 -48 31 49 -25 74 68 27 125 -46 113 41 27 -5 45 -9 22 43 -75 120 38 81 97 18 92 -14 31 16 8 -45 -106 -22 64 21 26 -14 30 -56 -83 39 -92 -33 -65 15 -104 104 99 23 11 25 -28 67 119 -34 -21 61 -48 -83 5 23 3 -52 17 36 -17 -21 52 -31 44 -60 -90 24 -16 -71 13 -103 -69 75 46 -11 -18 -72 30 -7 -127 -77 89 21 -90 -22 -4 83 -50 17 -87 52 29 -53 -10 60 -90 45 -83 -49 75 117 -128 97 98 13 2 -68 -89 107 -90 -74 40 -15 -59 45 -12 -36 -11 -102 117 102 41 -124 8 39 22 -30 -52 48 -15 50 -38 79 14 41 109 -83 53 74 27 9 68 -37 -125 19 98 -119 90 15 46 54 -125 93 -95 13 71 -97 -13 20 -67 -14 -6 64 -52 7 -62 -36 -7 -114 -17 -41 -38 78 65 -78 39 72 126 -25 -67 122 -121 108 -87 31 48 -72 -124 -48 -86 -12 127 -126 44 -30 24 -54 3 44 24 40 59 -63 -19 3 79 4 -9 115 125 83 5 -48 77 -18 73 -22 88 -56 -36 -35 127 -93 -20 -21 -127 101 33 50 -123 -31 -5 54 -15 -40 -27 10 -36 17 -27 -87 -42 14 25 -50 127 -7 -22 -2 -94 57 13 3 -1 8 -71 -83 39 21 -34 -93 -5 11 -57 -18 -34 1 -74 -93 -127 -44 74 97 20 -52 -54 15 43 126 23 -49 71 -21 3 -71 0 -15 -91 -33 -27 70 2 13 -16 15 -81 -12 9 75 22 -30 45 -53 -47 41 0 -30 -128 -71 9 13 16 -81 127 -28 -74 39 4 14 108 -72 -42 -3 -13 -57 92 78 -79 0 23 -14 -44 92 9 -40 15 -6 48 49 -26 -24 26 100 31 14 -61 -16 4 -127 -16 13 -31 -55 -101 59 -44 -31 -20 -68 20 4 -82 56 -39 -44 56 -41 -6 -11 0 -6 20 40 -78 96 -13 -8 -91 0 46 -69 87 -32 -126 -34 16 54 29 -27 -31 -33 22 -38 -22 -46 -70 59 -71 22 -77 -43 15 -40 -18 16 7 13 44 -10 -16 -58 15 49 -30 22 118 -24 19 -35 3 -39 67 -22 93 -127 5 15 85 -16 46 -43 -38 6 10 -11 28 -25 84 42 -98 26 -22 -3 39 -8 2 -16 30 3 33 -27 23 -91 0 -117 34 -13 -12 34 -7 48 31 -36 35 -61 -31 -22 -7 22 0 7 -13 14 -6 -12 8 3 -64 24 86 42 46 48 -63 13 -6 -21 65 24 18 -44 37 -6 -20 -22 -24 4 32 10 -23 -46 2 -13 -84 -12 5 -40 13 -75 4 59 -3 -14 35 55 -84 30 -125 51 -38 47 52 28 12 -68 -16 27 -127 8 -64 -105 99 123 -6 -105 9 -23 -60 83 21 -35 -27 -40 125 100 35 46 108 -4 -23 -63 0 -49 64 -49 77 17 30 -26 7 -27 109 -48 -106 -109 -124 43 -26 -24 30 91 6 -123 -123 124 37 -75 42 -122 -28 17 93 -70 51 124 -44 82 38 -27 -29 124 14 -13 -51 -21 -16 -48 12 -70 39 -64 -33 11 -22 -54 -37 58 36 25 51 -106 120 127 -72 20 93 -4 13 122 21 -71 -43 -66 -94 -44 20 107 -14 45 0 -80 122 30 33 20 -27 -23 -99 4 3 64 -21 30 -47 122 -30 121 -1 -75 23 -67 36 126 119 -26 12 18 -107 11 51 -57 -3 -25 20 -22 105 52 32 -23 -115 13 -17 -35 -15 -96 -53 -15 -8 75 -125 92 -21 115 14 -19 -35 3 33 -34 107 -12 19 66 116 -42 -39 -94 -57 -13 5 -58 26 -2 19 -53 24 -115 45 -15 58 2 -122 78 48 12 -37 35 -128 35 40 -62 84 28 -117 4 -47 -124 20 -128 19 -56 -50 -45 -55 11 -55 74 41 -31 -52 32 -26 14 19 6 -47 -15 -31 2 -124 121 16 -22 2 -90 73 -123 -15 -78 -9 -26 -40 116 123 8 29 22 -120 -32 17 -68 -66 -28 15 -17 -13 88 5 -16 11 5 17 12 103 -119 -7 -80 90 74 -74 14 -10 44 74 42 33 -90 10 -111 44 36 -79 43 -105 9 -108 -15 81 94 58 2 28 -100 -6 -10 -54 12 67 0 99 -18 12 -76 127 1 -118 -50 -26 -53 33 -20 32 -5 57 33 23 73 8 81 22 18 -24 67 -35 -15 14 -60 -47 123 -19 8 -83 43 -55 21 -11 -122 -36 -14 101 30 -62 -76 36 110 -14 -74 41 -34 -70 1 7 -28 14 -44 -21 -39 -11 12 28 -72 -21 -74 -4 43 -6 95 -23 75 56 -38 13 -46 -21 51 72 -57 -78 -97 24 -53 -85 81 -32 92 3 -63 -34 44 0 127 -1 -73 72 127 24 -64 -1 -21 -7 -28 -74 -57 -55 8 112 -65 -36 19 20 -29 -34 12 -48 14 10 23 8 66 -45 -80 33 -23 -63 -127 65 22 -79 -65 13 20 -26 29 -125 -27 -59 -60 60 -24 14 44 -68 -44 9 -1 -41 -14 35 -49 8 30 -82 26 54 65 -18 95 -120 15 77 -29 6 -22 94 42 78 -64 -71 99 -128 53 66 54 67 62 -41 9 -67 -17 -40 -86 38 30 53 -11 16 -18 1 77 57 -13 8 -24 64 104 14 -3 10 -63 56 89 4 39 59 -57 126 -89 3 -3 -54 -36 6 -11 -20 20 58 47 17 -7 -31 57 -56 -50 -96 -8 46 -33 -97 24 -8 0 -35 -88 -74 -18 42 79 72 -26 31 -13 32 29 -17 -8 58 18 -48 -65 38 19 -46 49 8 35 -53 16 22 -2 -74 -38 69 19 -41 29 40 -73 7 -31 -30 -106 -105 -35 -9 -28 -33 -20 30 18 -18 -128 -4 -65 2 -16 -11 -31 36 -89 -125 -85 -2 40 -64 -37 -42 -7 -71 -89 -125 51 4 -6 73 4 -17 -69 0 -43 -56 17 -87 30 -48 -46 1 -74 -30 -21 -39 -26 -57 -37 -118 -127 -82 -92 108 0 32 -109 -57 21 37 -33 -50 -7 -86 14 -77 -91 -19 -57 -128 -9 -69 -47 11 -37 50 127 -25 57 -51 -16 -86 1 -80 17 -58 -14 19 22 -15 -36 36 -12 39 9 -27 -16 -14 -15 -32 -11 -18 -10 -48 25 -8 -16 -47 -126 -39 69 -53 65 -35 -50 -40 56 -7 23 23 19 -30 -9 72 -32 -46 -78 -30 -35 66 -9 13 -10 -26 9 2 -6 4 -39 -7 -24 34 -94 2 -36 -23 58 -10 12 0 79 57 7 -61 -13 38 105 23 -30 33 21 -52 26 -15 -25 56 1 -36 -17 -65 39 42 30 7 70 58 -7 -17 -67 54 1 0 -3 103 -11 -44 77 -13 10 -56 9 -32 -5 -93 61 56 -127 -44 -44 -119 -28 15 27 -27 22 -53 125 49 -3 45 56 -4 -73 -19 -5 -52 12 7 29 -27 -32 14 24 -32 11 43 0 -20 9 -32 -14 -30 -18 -43 -30 -18 -8 6 6 -14 -13 -1 13 -53 -12 75 -18 23 5 -45 -28 -29 -4 32 -48 96 -59 -18 3 -27 64 127 -67 10 12 16 4 -59 -16 -7 -44 -19 49 -23 8 14 39 -7 34 9 -123 -54 -123 39 -18 4 42 32 -29 -106 -34 3 -20 3 -29 -11 -84 37 -81 -38 -23 12 -60 -114 -45 -63 -9 -7 4 -2 41 -24 -22 -7 16 -3 -10 44 -52 40 -58 25 -29 93 47 -48 21 -15 19 -41 -25 -104 -50 -41 -21 -8 57 -39 -36 54 2 -17 -72 -67 -1 -77 7 -22 7 1 10 9 -19 -47 25 -62 -128 -126 -24 -71 -36 49 52 13 -9 -48 -2 -34 -20 -52 -13 -19 -35 -64 17 22 40 -17 17 35 -32 -55 1 -36 19 -82 -63 1 -9 -44 -52 -27 -40 58 30 9 -100 -25 81 13 108 -48 -61 -60 44 -46 43 6 32 45 -26 50 55 63 20 59 -78 77 25 -34 -34 -7 52 -32 9 36 -18 4 -15 11 -38 -51 -40 -41 -12 30 50 -1 1 47 1 -57 -71 5 93 25 -18 68 43 27 -69 -10 -14 17 26 -12 -10 -52 1 38 55 4 78 38 102 -24 61 -18 -12 -73 -18 2 38 -31 -22 49 -25 15 40 -59 24 -31 24 121 -49 9 49 -127 -1 30 49 30 124 -60 106 -31 14 43 11 70 -128 0 9 45 -9 95 44 62 -28 -123 -77 94 -53 68 -39 -31 10 -3 -116 2 21 11 -12 3 -16 -3 34 -10 47 -39 -34 -50 71 103 -13 -41 0 -43 -68 63 44 102 -25 -24 -48 -35 -25 59 125 127 -115 35 0 -1 20 -112 -47 -18 -66 -9 124 9 -84 -32 -52 -20 -77 21 -55 47 84 -34 66 48 50 -9 124 -32 9 -95 -76 18 5 -46 20 -19 67 95 -24 45 -22 -98 30 -123 41 -125 -128 5 127 48 50 -120 52 -41 -40 57 -12 -112 64 104 6 25 2 -8 11 -55 19 -87 122 -40 -12 -99 -78 73 79 55 22 -126 -91 31 -123 -47 36 -83 -31 76 121 34 37 -16 -72 84 15 115 -57 -78 -87 91 -50 48 2 -35 11 -125 29 -21 32 60 7 -41 91 56 -37 -66 -14 69 0 -62 44 -35 18 -54 5 -79 66 -4 -38 22 -125 -21 -55 -22 -23 -91 -60 111 -105 -91 6 -120 -3 -88 -61 53 -26 7 54 15 30 -17 -27 26 -126 -72 46 -15 35 -46 -73 24 -70 71 38 -51 91 -9 -26 6 6 -67 32 -82 -12 -83 -37 -94 -37 64 -55 -71 57 -22 -34 -51 -30 22 -102 81 -91 -105 -84 -101 30 8 -40 86 104 -123 -11 -3 -44 -50 -83 -27 49 19 28 3 36 10 -41 39 40 -95 -20 -76 -14 -21 58 1 -67 -22 67 96 58 14 -44 -86 46 18 -51 29 -15 127 107 -2 72 -62 -24 -57 -2 20 63 -1 82 -7 -121 -31 75 -128 -125 -23 -51 17 30 -13 18 63 -68 74 56 -6 0 -33 32 -20 100 39 12 72 -23 -76 33 -90 9 50 41 11 -43 -29 -96 100 44 44 15 45 21 -89 51 117 -54 13 -4 2 35 -35 -9 8 14 16 -29 2 63 25 -8 34 4 20 40 -46 -21 -25 36 86 34 21 15 1 -58 47 5 -5 -15 -2 -35 57 -33 4 19 6 -23 -57 43 84 -7 -23 5 -97 105 -3 53 103 -48 92 -22 -75 -24 -30 -107 -3 -11 -46 7 33 20 -40 0 33 -15 23 -42 -63 -52 12 -41 -54 -31 50 24 11 -94 3 8 -20 -50 -2 -69 87 -5 -24 -57 14 -30 -35 -32 -92 -59 -10 17 14 -13 -21 -22 2 -33 -4 -126 -38 36 -31 -18 -97 52 -62 -4 55 45 -17 33 43 16 -34 25 49 8 37 -43 -7 88 -73 -85 -9 -89 58 -13 -34 -48 -55 -38 7 -12 -6 2 10 72 -22 -37 15 -33 -97 -33 62 -48 43 21 55 3 -19 -60 71 -85 -5 -65 25 15 -54 -37 30 37 19 -13 -67 -16 -13 -10 -6 -1 10 -49 58 -27 31 14 -54 19 13 26 71 -11 -52 -2 8 -64 58 -5 30 21 -12 9 -34 -40 -48 -58 -22 -21 23 105 60 -54 -43 95 40 10 -7 39 -15 13 27 35 50 -21 90 -8 -56 -63 44 -26 29 19 8 -68 5 23 -63 -39 -28 83 -14 16 10 42 29 19 -60 -24 -47 12 -39 -128 -22 31 24 73 -14 -17 31 -51 46 71 64 -20 -14 77 7 44 -81 51 -32 -35 -3 52 21 0 -32 48 -55 -2 -8 3 82 13 15 30 18 -38 -42 -25 34 26 -8 7 17 -52 -80 64 -33 32 -23 -64 57 -68 -8 7 -28 23 39 -28 13 23 -23 -74 -26 -6 31 -87 5 19 -19 -49 -26 33 11 -43 26 23 -38 -36 -35 -123 -22 -37 -125 -49 -79 -127 106 -26 -26 49 50 -68 -40 24 77 -117 -50 33 -103 -6 -35 44 64 38 -41 12 -39 -28 -100 87 -75 -58 -106 -128 -77 49 4 -26 -67 -40 17 -111 -58 -2 21 64 39 -103 -17 18 71 -52 -92 14 14 -67 -13 -59 -24 -45 0 26 37 -16 39 82 -26 -68 21 -19 -49 -68 9 -70 41 -91 -20 -38 1 33 39 -54 -11 30 40 11 38 85 25 -28 -5 54 50 -45 -4 -96 40 -43 46 -53 -31 22 -18 -59 -38 26 -68 -41 -96 -7 -7 12 -45 46 49 -54 -105 -20 -1 -121 95 -37 33 90 -54 29 74 62 10 -18 -38 82 -67 27 -2 47 -80 -35 36 -107 13 3 -77 -59 -45 42 -98 -50 -114 53 -56 19 62 107 -22 34 -40 2 -15 49 70 -52 -30 -45 -35 -25 -72 -4 47 -41 51 27 58 80 -3 -4 58 -98 41 -3 76 -21 8 -56 -19 -55 62 -3 25 70 -19 12 65 55 13 -42 28 -56 43 -24 39 30 61 43 11 60 -72 27 -53 -43 -42 15 25 4 13 -12 -8 35 -30 23 65 8 26 -9 2 -32 82 119 -43 31 19 10 17 -53 79 -11 -54 -19 -61 57 -37 22 67 -9 14 -97 7 57 -55 -26 -109 -7 -7 -32 -9 -51 41 -23 49 37 -56 -51 60 0 28 -47 -12 -7 -50 -23 -120 -41 -81 -26 -46 69 4 17 -11 -74 46 60 74 -33 -48 -40 50 53 -125 103 -61 63 -56 105 -37 86 0 20 67 26 43 38 -26 -103 -31 -9 30 39 21 -27 -25 88 99 48 109 13 26 16 37 25 68 102 126 38 81 49 91 113 14 -17 108 -25 -29 -19 79 90 -45 0 12 68 51 -14 -4 -84 -60 53 48 124 21 -80 -4 26 0 5 23 127 95 -68 1 7 -67 120 26 127 -93 42 24 -38 -34 -18 16 89 92 48 25 -3 8 -27 -70 -84 28 -20 -128 56 -127 -13 -86 82 -37 67 -5 4 -40 74 -35 -16 47 98 -27 -36 -75 87 42 24 34 11 -12 36 41 125 50 26 82 -1 36 14 -24 -89 11 4 27 68 -82 -20 57 12 28 61 -37 26 -16 24 -64 -34 -3 -66 50 -54 60 46 11 -9 24 -54 -19 -17 -16 -25 -42 107 43 67 9 -34 21 -75 -28 13 23 -66 81 -27 -36 74 85 -125 38 -29 100 46 107 49 -71 -40 51 -13 84 49 125 66 -50 101 -39 -32 -28 -20 -18 24 -114 36 115 -71 15 103 8 44 -34 -1 -39 -63 -47 -4 83 10 80 -88 0 73 -2 64 -48 -28 -61 -57 -7 -70 -53 -76 -42 -12 87 26 28 -10 -3 -9 -43 22 -3 127 127 22 46 -4 32 93 -70 -44 29 125 -43 -1 54 -104 41 -17 91 -25 41 -14 18 -1 31 -44 0 12 36 53 49 92 -24 -59 91 2 -35 -23 14 126 35 6 -69 60 -20 -11 51 40 -8 -67 -25 61 -24 -44 52 40 33 -3 -10 55 -82 -53 24 -22 29 37 -25 10 63 3 39 55 -58 -17 23 21 -27 27 45 53 35 -18 -64 21 -37 57 24 74 -50 49 110 44 3 44 -33 11 92 -15 -112 -27 -45 -7 37 53 -3 112 28 -90 68 29 18 43 84 26 71 -58 -3 -12 -6 4 11 -13 -66 7 -25 6 -16 -19 15 92 28 -56 5 -82 7 63 33 -56 11 39 51 -29 37 -75 22 -127 -14 -94 -18 -8 127 -48 28 23 -81 -30 -5 25 23 -22 -7 51 59 70 -79 -24 -25 10 -43 -56 122 -37 -116 -41 43 -35 28 42 -28 24 -98 -44 1 -47 11 -6 -30 -112 0 20 -62 -63 32 4 24 -32 -57 -2 -20 -4 3 18 -92 16 -23 -57 -4 -8 99 -84 16 -46 -25 50 5 23 34 9 51 -1 96 12 7 21 60 -98 104 84 -22 26 45 13 -89 25 7 -3 38 8 42 67 -75 93 12 17 24 -13 -8 -60 32 -20 100 38 58 -42 24 22 -107 -40 -31 -34 56 66 85 -85 -28 49 -52 -13 -26 54 -26 -8 -56 -6 72 -37 -87 37 -52 -45 31 -2 106 -53 5 -13 -70 52 56 -19 32 -99 6 -21 27 88 52 25 9 -39 -99 -17 63 16 0 -53 -31 35 -38 -13 37 -2 57 -5 8 39 21 22 -96 -11 4 125 99 -4 4 111 89 120 -60 -30 0 -18 64 59 -5 83 -1 27 -40 79 69 -60 -12 126 24 17 127 53 -9 17 74 -27 -25 82 36 -9 3 66 44 -33 127 54 126 -4 -42 -41 -47 89 31 78 -74 28 73 6 2 40 22 2 127 75 86 26 -20 70 6 113 87 33 -70 -8 78 32 127 -49 21 4 37 -13 1 40 127 70 81 121 47 102 110 -26 -67 -10 -46 -43 -10 -34 -13 -58 51 -46 -80 -45 70 8 51 125 -10 46 -104 -13 34 11 -46 26 -101 -75 -100 -20 -7 -39 37 -10 -48 -24 -80 44 29 -103 45 -68 -60 42 15 -16 -1 26 8 49 -2 2 26 -51 -52 -22 46 -75 -26 8 -33 14 22 55 68 21 44 -12 -7 -50 -24 26 127 -87 27 2 -10 -79 -15 -56 118 53 -59 -97 47 3 -40 -47 -89 20 5 -49 22 43 44 50 36 -22 -79 -94 49 33 32 3 -1 37 50 -39 31 -19 17 -37 44 -1 -50 49 -20 -20 89 -103 31 64 -26 44 -17 -79 -44 31 -59 48 -27 45 48 28 -54 65 -48 -45 50 54 44 -20 -78 0 23 -68 -32 69 -47 -15 -74 20 6 27 -53 69 42 11 -30 100 -93 -95 67 80 9 13 -28 -39 62 50 -16 16 -18 -35 -31 -47 26 37 47 -12 78 17 -127 -30 -22 -7 90 10 -43 2 -44 1 3 40 -27 74 -13 1 71 -13 63 127 39 69 127 -19 -2 15 -36 110 5 42 105 -3 36 42 -31 100 122 92 8 -89 -60 80 -8 -27 7 12 70 -13 18 92 56 112 39 114 2 -33 6 31 59 30 -13 41 -65 -37 -45 13 -126 31 -66 -50 8 20 -19 -14 -71 -62 8 13 -28 -75 50 56 27 11 40 -80 71 -64 -21 63 -11 48 109 12 49 17 53 -60 18 -116 9 27 -3 10 -116 60 44 -83 47 26 0 -56 -5 20 -66 45 127 28 117 -9 -54 -35 13 -42 -34 -16 21 -41 80 -75 10 -60 -58 -63 -19 -10 -35 27 -55 -70 -83 -49 -22 -33 -52 -16 29 5 4 -36 -15 -32 35 16 -73 118 -30 8 -42 -19 22 54 35 43 -51 -18 -47 25 -6 -37 -15 -3 37 62 20 -10 27 -18 83 -69 40 40 -42 -69 -3 -6 -1 29 -7 -46 -54 14 -67 10 -74 51 -73 23 -8 80 34 -33 -25 5 94 41 28 70 24 102 -9 -40 25 -53 13 -17 -125 38 -5 -84 -12 -9 88 -24 50 -92 22 125 -59 45 -38 24 3 26 -44 38 44 -82 3 79 35 18 -74 19 -31 -79 -47 22 36 12 77 -31 4 64 -6 17 -67 6 -66 48 -30 44 34 9 -36 19 -37 25 16 -3 22 -53 -43 73 48 96 -47 -55 18 8 -77 48 65 45 -70 -26 -10 91 -8 74 71 -2 6 -85 -127 -93 -50 59 -118 13 -23 -15 -38 -104 24 86 -20 124 -25 -119 -110 119 -18 -83 -51 -105 -19 -90 -51 36 -62 -115 -66 17 -44 -56 29 -37 47 -27 -107 -27 0 -68 -60 -128 -112 -9 19 -19 -51 51 93 -127 84 -120 5 102 8 -4 -15 68 -120 -80 3 66 -2 99 29 12 -8 -29 -20 44 -112 -44 -126 84 -91 49 -36 5 57 50 -25 -6 6 27 89 46 -40 73 112 -103 63 124 22 42 76 -73 -5 -15 38 -67 0 -37 29 -56 21 15 87 127 -41 84 9 -13 -8 16 52 -96 42 -52 8 43 -101 -80 -48 -12 23 5 -11 -24 58 34 -2 29 31 -30 9 9 -104 -8 8 -65 -69 76 -21 33 127 -109 103 36 49 94 104 71 33 69 29 16 11 -48 31 4 1 -14 107 35 -28 -13 -58 55 0 -39 27 1 -30 -25 77 108 -75 -48 67 -19 -28 -26 -12 -67 -71 -38 86 49 -56 29 71 -35 -104 20 -43 -81 -38 43 28 74 -82 -121 -19 16 126 59 124 -108 39 24 98 -17 125 -48 -92 78 98 -126 121 37 -6 31 -102 102 -126 -22 -55 -54 62 125 -17 -40 82 -127 -39 -95 -46 96 8 -74 -63 6 37 53 85 76 -42 123 -65 -18 -109 51 -77 79 58 -41 62 91 -100 112 -61 -36 127 -108 102 63 -48 123 42 44 10 -60 -22 113 -24 68 40 21 -22 -38 23 108 37 -18 23 50 -38 -123 -55 -78 -79 -88 116 -54 22 15 -14 40 -1 -58 -128 18 -21 49 24 -56 21 35 97 -23 37 -19 15 -36 3 -29 -64 64 -64 21 -57 -55 -21 8 -12 33 -11 29 38 2 48 -65 1 39 5 -25 -120 -63 -38 15 66 -123 33 29 -61 46 -5 -9 -13 94 -105 1 -113 -67 -54 -19 37 -108 -63 8 72 -25 5 3 -20 29 -53 -81 113 20 -70 -88 -34 -87 45 -27 47 15 -6 -83 28 -14 -8 -28 -28 -46 -6 61 -89 -66 -51 30 22 61 24 -2 -73 -59 -4 -36 1 30 37 -55 -20 29 33 -98 -12 -23 43 -6 -61 32 -63 -39 -32 16 23 104 41 36 -27 29 35 -26 -7 45 -58 -47 3 -56 -19 34 -23 -6 93 18 -27 -54 -22 66 -13 16 2 70 3 -33 15 23 22 -95 17 75 -23 65 -26 -14 15 51 -17 45 -6 -47 -47 -27 -102 17 -70 35 94 -45 -26 32 -20 -10 -64 -52 20 -26 70 -69 11 127 73 11 -49 15 -27 -38 -18 24 -58 15 26 8 12 -32 37 -54 106 -75 -62 16 24 -74 115 -94 90 56 -36 24 -72 28 3 -34 37 65 -33 51 45 -78 -119 -46 -42 -29 8 -26 -8 -96 15 11 22 -26 -79 20 30 37 23 0 -18 -6 2 36 24 -40 -44 19 -35 64 42 -117 -39 -96 -1 -32 45 52 17 22 -35 -80 -35 -41 -13 27 18 21 39 -16 0 21 46 10 -11 8 54 11 -50 -113 5 -57 74 25 -2 -102 -65 18 6 11 78 -5 99 -4 47 17 51 84 45 12 88 12 -3 82 102 81 1 70 53 -101 -37 81 39 -32 -60 76 95 -22 -15 1 71 71 53 23 -53 0 -19 41 86 -49 21 16 44 12 68 -22 -51 33 13 0 14 -19 40 80 -13 -3 19 120 -11 24 77 39 27 66 83 23 83 -53 -58 -29 0 -57 44 -7 19 4 55 18 -65 15 46 89 -18 24 7 13 -68 22 53 -38 -93 -49 -60 -84 11 61 -4 58 -17 -17 -26 -88 31 36 -59 8 55 -17 58 -108 -36 -9 22 31 23 -22 -68 5 32 -39 -26 58 -58 -12 -8 -52 66 22 -3 37 -45 69 -13 -39 -4 -37 -68 -41 -38 1 -102 -25 -21 -3 -42 23 -60 -36 -12 -11 55 4 10 3 -42 -114 -8 47 -127 -16 4 2 -26 -20 -95 -21 -7 36 -39 39 -125 -11 -48 -97 -9 -37 54 108 -19 -37 42 26 69 -85 57 100 5 84 -45 69 -50 -37 -9 -31 -44 -69 -35 32 29 -12 7 68 99 -45 46 -54 -20 92 29 3 25 -23 -12 10 39 9 3 76 56 -80 21 -74 -4 19 -11 -38 -22 43 -52 90 16 0 -54 40 8 -23 -33 49 -60 74 -49 1 71 1 2 -41 -74 -83 7 61 -47 -13 -41 2 98 59 24 12 71 -33 -48 26 67 -6 -54 23 61 59 -92 69 86 -31 -27 19 31 -6 -19 -52 52 125 -57 -1 -3 -84 25 -64 59 -26 -83 -112 -128 15 -41 7 -55 24 114 18 -115 -74 20 -31 69 -65 -69 -106 -19 28 24 -115 18 11 6 21 -125 -111 -107 23 -83 -74 -104 -107 127 51 90 -127 -118 -94 -72 -86 -127 -26 -106 -6 -3 -47 -51 -9 -2 24 -31 108 -69 52 -94 -61 96 -8 -124 -54 11 -82 -65 54 10 9 115 28 14 104 -89 2 -85 -123 -8 37 7 47 -47 -25 -113 122 37 -95 20 35 -9 -1 -7 30 54 5 23 -15 -51 -36 6 95 31 27 -33 -36 41 -7 -18 -118 -90 78 24 -42 -128 44 82 -71 -66 1 47 25 35 -7 83 -103 -117 22 80 -65 -17 -76 13 -47 2 82 18 -42 -69 55 20 -29 -14 -20 3 -44 23 42 17 43 -11 -21 -46 -52 -69 21 -63 33 -24 -48 -97 -31 41 -64 3 23 74 37 -80 54 127 98 -8 -1 -17 78 42 -28 18 -49 3 27 -3 42 -61 12 -127 9 -90 -126 -41 64 -74 38 -27 0 75 -122 127 75 -90 53 54 1 -41 69 40 31 22 11 111 -68 -34 33 -48 16 -72 9 12 50 -67 -106 -99 -72 18 97 53 16 -34 12 8 -128 -24 -52 -70 -72 -4 87 -18 -45 10 51 21 33 16 -53 52 -10 20 -45 8 -33 36 -28 43 91 -60 -75 -128 59 16 16 41 -126 -9 -7 14 36 -4 -36 76 64 -19 125 17 -42 -6 -7 26 70 -7 -15 -26 38 39 -13 6 41 -16 -28 87 74 32 14 127 56 32 26 17 85 34 -43 -3 -35 -52 18 -17 -9 -88 -52 54 5 -125 60 84 29 27 8 10 52 3 -92 4 1 59 -5 -26 -28 65 54 12 -36 19 -12 -17 -4 -15 106 64 127 7 -14 -23 -67 45 62 68 24 20 50 -65 40 38 36 0 41 46 23 13 43 28 82 25 -20 1 8 20 -18 48 -22 37 -14 -1 89 25 8 -51 -26 -21 -20 -19 86 12 17 -19 18 43 26 -5 64 3 -52 14 19 -51 -28 5 -28 -39 -26 -127 4 6 6 52 -26 3 11 30 46 21 15 0 -35 59 28 20 -16 -30 23 60 0 56 32 55 97 17 85 -20 29 35 -44 44 -5 30 -67 57 17 20 66 -54 -7 -26 48 -21 -23 3 -35 -3 -36 43 -12 -1 -96 34 -29 36 -49 109 36 -7 -35 38 -55 40 -41 39 22 96 13 33 -17 11 14 -51 -6 -43 -11 51 32 12 17 -55 123 6 -22 -25 26 -1 63 37 -17 -66 34 -11 -17 30 -66 -18 -80 -1 27 -48 -13 -46 2 -27 5 -18 6 15 3 -22 20 10 34 -7 -7 -40 12 -19 -19 -36 -56 59 -4 21 75 5 75 2 81 -23 -38 -20 23 26 -5 -70 -61 -5 -39 57 -21 -51 121 -12 17 -64 -28 -33 -9 -21 -14 63 6 41 -55 -8 2 6 17 47 21 12 -8 35 -9 -29 16 -25 -128 80 127 35 -26 -101 -31 3 -1 -67 20 28 18 -44 -59 -1 -25 -42 -39 61 47 113 -21 -18 121 28 82 70 72 123 38 97 10 49 36 125 -94 -106 8 -15 66 91 -79 94 29 17 106 -42 23 88 -27 121 102 76 -50 -7 11 44 47 90 11 32 46 87 -64 -50 70 12 -21 23 -49 -9 60 83 55 126 32 85 -33 -32 -81 25 51 -40 -27 83 56 43 -68 -58 -8 -8 29 100 81 5 -35 83 -6 74 -35 -24 57 -15 -50 -107 52 -50 -5 16 -112 45 -3 34 -40 -114 9 18 108 122 105 111 51 50 -81 33 -13 56 40 81 -73 116 45 9 57 -31 -17 -24 -81 3 16 -1 -37 -98 66 -7 -38 66 1 -40 27 12 127 61 1 12 -5 -46 -46 48 -13 98 53 -39 29 -6 37 -126 -21 16 82 125 22 18 -28 -68 -14 54 -26 60 66 106 -121 25 37 -30 -15 -8 -37 30 0 -1 -11 6 -64 -16 -5 8 -101 -23 110 -24 0 -41 1 -80 127 7 -76 -1 53 -2 59 -60 -80 -1 -30 65 -15 -108 95 -42 0 -98 3 -51 -59 12 -49 45 72 116 22 -48 -44 -65 -24 1 7 19 -53 -42 33 31 37 -20 23 -60 -77 -35 -56 28 -92 -41 46 -25 16 -103 24 -51 -24 -71 -36 -34 -68 -56 104 41 64 -109 -73 54 -47 4 -12 -41 4 63 -24 80 69 6 -21 103 -22 34 20 15 -54 -79 -16 -50 -23 94 -11 -23 -13 4 -46 -10 36 -4 21 21 -41 16 40 -21 33 91 34 65 53 24 7 31 55 -13 -15 3 -57 112 70 80 28 3 34 -42 -27 -19 -30 33 126 37 -96 46 -13 -15 36 34 -53 25 -46 -66 29 46 92 3 -5 36 -39 27 -62 -60 10 36 -115 -10 -24 25 30 8 -1 3 42 -87 86 17 -44 43 23 8 -17 -104 1 100 -5 -124 38 41 14 53 11 42 12 -17 23 -65 -85 28 -16 -62 18 52 42 46 -3 18 58 23 32 10 -11 2 -11 29 20 -12 4 -37 -87 -9 29 100 66 90 -13 6 -2 38 -3 -4 -77 17 46 14 -36 -32 23 -4 -73 -78 -50 -15 -66 -9 -2 -28 -69 -32 31 13 54 9 -25 -73 -26 8 -17 37 -14 -1 37 -89 -18 -15 -13 73 -75 -75 70 12 -101 -45 -36 -8 -8 -33 25 -12 -95 27 58 4 -18 -31 -12 46 22 -14 32 -7 49 25 83 54 -4 0 4 32 -29 75 -25 -51 57 -57 -11 -18 28 -18 32 -14 44 10 57 -54 -41 -4 -40 84 -5 16 -16 -41 124 -8 -38 29 -54 34 2 -34 16 41 23 18 -51 53 45 -44 33 -36 -46 29 23 62 21 7 44 -91 -5 -48 -11 5 -44 29 -73 36 -40 15 -31 -14 -18 2 20 66 -70 31 17 -62 44 46 -15 -79 7 13 13 -10 1 41 38 -38 -7 1 92 -63 17 2 19 36 -8 64 -67 -14 53 -23 -44 -6 105 -46 43 -27 -22 -46 61 -8 -25 106 51 65 52 76 43 106 -23 4 -20 90 98 58 14 -91 -111 -7 -32 -83 -84 75 7 77 -30 -8 -18 -108 84 51 -41 92 15 97 1 -14 19 40 23 -15 94 -20 52 42 29 3 77 61 107 78 -101 -41 92 -83 79 -14 40 -8 5 43 23 0 -32 22 -44 99 -79 26 68 -40 1 -10 -2 -16 59 11 19 1 -27 57 -21 37 -58 -65 -23 -19 33 35 55 -36 -96 99 6 -70 35 -56 5 54 19 127 10 39 -13 26 -50 -29 -7 18 49 1 66 4 69 25 82 -44 -36 52 11 -82 -14 -7 60 -41 27 -55 -26 60 27 -89 23 -1 -32 58 29 22 -34 -6 -50 7 -45 32 29 -42 42 44 21 -6 -17 39 24 56 16 -78 -37 18 49 18 -27 29 -27 67 -50 -72 -31 23 54 -31 74 -13 17 19 -23 -18 -18 -26 -5 -38 -24 6 72 34 51 -24 10 7 53 41 -36 59 46 -13 31 -51 -27 8 33 -32 65 25 -36 0 -22 -16 -52 -12 14 27 39 1 44 15 -15 -39 17 -51 -26 -42 9 -2 -76 71 -21 59 30 56 9 13 -19 22 42 14 -1 77 -14 -32 -42 -3 49 33 -29 2 -51 13 37 -47 -49 57 15 -64 41 -10 -8 -61 -16 20 -56 -13 10 -10 8 -2 -8 46 5 -84 79 -92 32 -16 67 -110 15 -4 -72 122 123 82 -66 -29 -128 -47 8 -125 57 14 -31 9 -14 -118 -45 21 81 -125 7 -21 -84 -51 -21 -9 25 -21 35 122 22 -8 -72 67 3 -53 -12 -58 20 11 42 69 4 -62 56 -2 2 -126 47 -116 59 84 -5 -97 -115 42 16 122 2 73 -78 -83 -100 73 28 -22 -124 48 90 58 -3 -2 -124 125 -116 52 63 114 -23 93 -8 -94 105 2 69 127 -8 59 -6 -113 28 70 77 -14 111 87 -12 28 41 16 4 -14 -38 13 -74 -1 -2 15 -41 17 7 -127 75 27 -63 -80 0 -24 8 20 42 12 27 24 4 102 37 50 -29 -71 -20 124 -18 11 36 -50 -26 -47 109 7 -79 9 -106 120 -79 111 -36 64 -39 9 17 -21 8 45 72 -4 69 -64 -20 -16 41 -9 -28 5 -47 127 -32 8 -34 110 6 92 -65 -23 68 78 -58 -125 86 59 -3 -21 42 32 -18 -9 14 29 11 102 47 78 18 -14 -123 -48 46 -33 -128 53 -54 -124 -19 55 15 105 12 61 23 -125 49 -80 -75 19 -74 -105 30 -73 22 39 -13 124 -82 25 -30 26 -38 -78 -66 -60 40 -4 56 41 64 -26 29 -100 52 52 -96 -65 5 66 62 88 2 -58 9 127 67 80 -8 -57 -31 75 -14 -15 -43 120 -48 -33 21 9 -47 108 9 -41 38 -35 -52 26 -73 -18 -108 62 -55 1 -30 75 -26 -30 -87 18 27 91 49 35 75 -110 -38 98 47 39 53 -86 -26 73 -109 51 -55 -12 -7 91 82 -118 -10 44 18 25 17 68 -16 8 79 -76 66 -32 -19 68 -2 -94 41 53 -16 44 0 91 -79 -3 -41 -25 -39 32 -24 127 48 56 -5 -25 -109 12 90 59 54 -34 121 -12 48 -52 58 18 -89 -88 -2 -106 15 -31 -85 4 -31 -74 49 82 6 -3 -128 81 7 -112 61 -17 -12 91 10 85 24 -66 6 23 24 -42 -9 -49 -32 -122 5 -11 64 35 14 29 -25 31 -35 -39 -22 -63 -23 48 2 -21 3 51 51 16 -66 71 41 -18 98 15 80 47 41 15 22 -65 -65 23 -21 -22 -43 -2 -36 15 60 -52 19 34 21 -33 12 -12 -9 -18 -85 -37 31 -47 -53 21 -49 -45 91 10 -12 13 27 -96 -16 75 45 22 68 -12 -6 -15 -14 -16 37 -5 -49 16 4 -67 64 -23 23 67 37 -58 18 -48 12 3 -42 -31 -72 -32 -52 -126 100 23 -74 -22 9 -71 60 93 -17 -19 111 -10 51 -66 -35 22 -22 2 40 -3 53 -21 29 23 -35 -57 -20 -19 31 66 37 21 48 71 -12 32 -55 -23 -60 -35 -37 -26 1 43 -42 42 -28 14 2 42 -46 84 29 68 -12 -28 -52 -50 -9 64 14 23 -28 -36 -30 -20 35 37 7 -2 35 -13 66 -16 -77 60 -43 15 41 -78 14 -5 50 6 23 -98 18 56 -83 -28 -13 -36 -56 -118 -7 -73 -39 -41 60 90 -46 127 -3 -13 52 7 -32 11 -111 -9 -15 -124 42 -124 -51 -21 4 -83 -120 -76 -9 -66 -16 -79 -52 -1 -83 44 7 -14 94 -89 63 -34 82 -95 -63 12 73 -111 21 -3 64 26 -28 -55 -95 15 -20 -117 -8 -88 -73 -93 20 70 -14 -36 70 16 -57 24 -78 26 8 38 3 32 -67 52 -54 -56 127 -30 5 13 -91 94 -7 -11 105 -78 52 46 -42 33 -46 -104 -7 18 19 -4 39 15 -57 11 70 29 73 -10 2 127 84 -16 -50 -82 15 -36 -126 -21 33 -76 -56 82 -22 -10 6 48 -12 -33 7 -55 -8 34 81 -52 98 55 6 -91 98 33 0 -12 -11 -5 -74 -29 30 -7 -43 -5 -68 20 51 33 44 -37 41 -59 -99 73 53 30 16 16 -34 -3 -74 -123 -78 77 -127 -32 48 -59 14 -51 17 -37 39 40 124 -19 0 3 -79 -13 21 -1 33 -125 -9 20 -24 26 115 -33 -37 12 14 -5 -73 57 1 -47 32 39 -62 44 -104 42 23 15 -16 -1 8 93 36 -34 2 -6 24 127 -21 -11 1 32 -12 25 -94 -25 -32 36 16 29 -15 37 10 -53 -10 -26 25 -26 -55 -95 -51 110 -19 -28 9 -57 25 46 14 64 -40 35 -25 117 -1 -127 -61 66 -48 -51 -1 44 1 -61 -17 -3 37 -100 21 51 72 12 -23 -30 -25 -125 22 8 59 -2 0 31 15 33 41 43 22 -5 34 32 10 -6 31 -11 11 13 4 22 -3 60 1 42 14 31 -28 -7 11 49 22 -14 -20 62 -8 44 50 4 29 1 1 -14 20 43 19 32 30 61 19 3 22 16 -5 -5 -23 -6 17 95 82 14 4 -17 13 41 51 -51 51 25 25 27 48 -18 16 33 55 9 17 -22 40 32 -21 1 8 22 -18 51 -11 -1 31 -5 -6 19 -4 28 35 -22 10 15 20 -15 -4 -4 -13 -47 27 34 -22 50 -7 -12 -10 10 5 -6 -6 13 32 -9 -16 23 -4 33 -5 -17 2 -13 25 47 -28 -5 -18 1 33 -11 -2 -21 37 -11 14 -8 19 14 -15 -12 51 8 36 2 18 -17 17 -15 1 1 -54 32 35 3 -9 -23 -9 -4 -6 8 -3 -31 -10 44 -48 -7 12 13 -13 -31 3 30 46 11 2 1 6 -4 -16 14 0 12 18 5 14 3 -40 -38 11 0 -6 -6 19 -2 3 -82 -4 -44 33 17 -4 -15 3 6 -3 -8 8 8 -1 45 -34 -16 -2 36 -4 9 -1 -11 4 5 13 -10 5 19 2 1 22 8 13 27 2 11 -23 -1 4 2 -35 -7 35 32 16 13 15 12 -1 -22 27 -33 -6 -11 24 -4 10 -36 1 40 -1 8 51 -36 11 -19 20 28 -23 -12 0 -20 -1 -18 18 -14 9 13 3 17 -33 7 -14 -37 6 -11 13 -10 96 22 1 49 63 47 40 25 26 23 8 2 11 17 29 19 6 -7 3 19 28 28 33 13 41 5 -23 -33 -45 -36 -24 -25 -20 -18 -19 -10 -18 -18 -24 -23 -21 -22 -16 -7 -18 0 7 3 8 -3 -8 -12 -16 -16 -10 -9 -14 -19 -13 -18 -18 -12 -20 -34 -69 -63 -42 -43 -67 11 12 20 14 16 28 29 25 26 29 28 36 35 31 28 29 14 -7 -46 -72 -70 -51 -62 -89 -59 -39 -7 9 9 0 -6 10 12 14 16 27 47 45 43 44 15 11 11 35 63 64 83 62 53 56 40 41 54 64 65 65 54 40 24 -3 -33 -69 -73 -63 -16 -44 -17 25 33 2 -14 -5 1 -3 -1 7 3 11 -7 -21 -36 -43 -47 -31 30 37 -1 -20 -7 -48 -40 -7 30 51 64 38 -6 -42 -50 -38 -31 -50 -88 -121 -126 -125 -99 -123 -98 -75 -68 -106 -97 -76 -57 -59 -68 -56 -38 -21 -5 -5 5 17 24 30 34 30 5 0 -16 -60 -28 -53 -87 -97 -119 -81 -51 -54 -45 -37 -23 -43 -56 -51 -25 -18 -19 -14 -7 25 31 -6 37 33 66 79 73 72 63 74 118 125 125 123 114 102 104 94 79 65 80 60 47 42 -4 26 35 43 29 14 4 -4 -2 -3 5 2 12 17 14 9 3 10 13 12 5 -13 36 19 21 5 6 14 15 8 2 -4 -5 -19 -23 -49 -68 -59 -41 -14 14 3 -17 -16 20 -29 -72 -28 1 -7 -27 -30 -21 -13 -21 -26 -39 -47 -45 -34 -36 -30 -17 -44 -66 -33 18 24 41 21 11 15 31 26 7 9 27 36 36 40 50 67 81 92 62 27 -75 -63 -25 -15 -40 -96 -112 -121 -116 -125 -127 -127 -127 -127 -118 -106 -86 -84 -78 -52 -23 -33 -22 23 37 36 45 42 36 51 49 42 34 40 37 29 37 38 33 36 32 24 44 66 79 31 -42 -47 50 126 87 27 31 30 27 28 43 48 53 46 32 22 16 -5 -27 -9 16 -10 -10 -8 1 7 3 -19 -20 -10 -23 -37 -31 -45 -41 -37 -34 -42 -44 -42 -44 -45 -39 -58 -18 -12 -23 -24 -15 -7 8 4 -22 -32 -30 -33 -31 -30 -30 -21 -23 -31 -15 -23 -30 0 6 40 95 110 110 118 123 123 113 83 72 61 63 58 58 60 61 60 29 25 21 28 56 35 -29 -45 -61 -86 -96 -110 -88 -104 -126 -125 -127 -128 -128 -126 -125 -84 -33 -41 -58 -28 17 30 52 62 68 53 52 53 57 47 59 72 78 61 59 73 76 69 76 75 77 85 29 3 -31 -68 -69 -73 -69 -72 -73 -72 -70 -78 -84 -88 -81 -71 -60 -78 -109 -86 -49 -65 -26 -40 -55 -50 -73 -87 -96 -90 -71 -65 -47 -31 -25 -24 -21 -19 -23 -30 -9 -58 -82 -8 55 61 53 62 62 53 53 63 69 72 78 66 68 70 66 53 48 38 46 41 27 -20 -30 -72 -85 -98 -97 -83 -73 -68 -78 -62 -59 -40 -20 -4 -4 -9 -16 -16 -1 8 42 7 9 6 24 33 35 34 33 35 49 73 88 107 120 123 123 113 99 66 22 45 70 72 -75 -60 -55 -80 -82 -80 -93 -82 -83 -59 -38 -34 -19 1 7 8 9 19 45 22 -14 -31 -33 -36 -32 -24 -22 -9 -19 -19 4 17 32 45 42 23 10 8 4 2 0 12 27 39 30 56 57 40 38 29 29 27 34 50 65 60 64 62 39 27 20 21 19 -32 -73 -113 30 30 22 31 45 47 39 31 26 20 13 14 15 17 6 4 15 20 -11 -31 -72 -23 -18 23 40 0 -30 -11 -9 -34 -47 -33 -14 -10 -8 -26 -45 -59 -58 -41 -60 -75 -93 -46 -8 5 16 33 39 49 48 40 37 46 28 33 38 37 32 25 42 60 62 45 5 -16 -41 -13 1 6 7 2 1 8 18 23 30 25 15 7 3 -17 -20 36 111 80 37 68 -13 15 12 4 -1 -18 -32 -42 -44 -48 -45 -55 -64 -75 -98 -123 -125 -120 -82 -71 -36 -3 -44 -90 -84 -84 -72 -48 -31 -12 3 14 11 5 16 21 39 55 56 41 22 13 7 18 -98 -121 -101 -89 -65 -52 -40 -33 -26 -33 -46 -39 -36 -22 -4 4 -2 -12 -17 2 9 5 23 4 -8 -8 11 17 6 -6 -11 -10 -20 -5 12 17 16 13 7 -9 2 4 13 -14 47 52 65 39 22 40 59 60 56 52 43 23 20 10 -12 -14 -6 -1 -4 -12 -21 11 19 39 44 38 30 24 21 20 12 12 20 24 20 20 21 17 15 24 34 29 16 6 -4 16 54 100 123 125 119 75 26 -1 -9 -11 -1 -8 -16 -18 -10 -4 17 27 42 15 46 28 6 10 17 27 34 41 44 45 39 26 15 2 -5 3 1 -10 -14 -13 -8 35 -39 -32 -25 -28 -18 -9 -4 -19 -35 -39 -50 -62 -68 -63 -37 -23 -31 -70 -127 -127 -123 -68 -8 -21 -25 -12 -15 -18 -19 -32 -29 -16 -8 -13 -18 -10 -2 1 5 6 4 5 19 27 109 72 43 36 29 35 30 22 33 27 12 16 9 3 6 16 5 15 19 28 40 112 -127 -127 -126 -65 -21 -7 -7 5 -3 -18 -27 -23 -18 -21 -28 -27 -20 -27 -43 -28 -25 -7 -126 -125 -69 -68 -59 -65 -71 -54 -43 -61 -57 -61 -65 -63 -63 -62 -70 -63 -52 -39 -42 -23 -10 2 9 12 10 22 7 10 13 6 -16 -22 -19 -10 10 13 2 4 4 -3 -7 16 -40 -30 -26 -19 -14 -16 -13 -14 -1 -2 -15 -4 -10 -12 -19 -23 -20 -2 -6 -14 -14 8 -68 -36 2 20 28 38 45 31 -1 -32 -51 -57 -44 -48 -62 -61 -53 -1 64 57 52 56 56 30 -4 13 39 34 35 40 19 9 0 4 5 8 15 24 39 76 75 30 -42 -98 36 38 19 10 2 5 7 -2 -6 -5 9 24 22 18 21 21 6 -3 -15 -26 -24 -28 50 58 41 33 12 16 30 15 24 34 36 47 57 69 83 96 98 97 107 89 75 33 -89 -120 -59 -50 -26 18 -15 -53 -50 -29 -24 -25 -27 -32 -30 -36 -33 -22 1 -21 -50 -37 -4 -22 -12 -2 -12 -21 3 48 94 118 117 99 86 71 58 39 18 1 0 5 10 18 -33 -18 -8 8 2 -10 -2 12 32 45 53 63 61 64 64 56 42 29 23 14 -42 -50 13 -8 -23 -28 -19 -12 0 10 22 35 26 14 -6 -30 -63 -91 -114 -112 -66 -58 7 123 -45 -68 -57 -46 -38 -57 -76 -70 -75 -79 -70 -67 -62 -45 -45 -51 -59 -73 -54 -20 -30 -43 -12 0 8 -3 -21 -28 -35 -36 -26 -20 -28 -26 -26 -28 -41 -50 -49 -62 -29 -19 8 14 5 -11 -6 0 27 31 37 35 24 14 6 3 -2 -8 -12 8 26 81 120 124 124 125 47 20 30 42 45 63 82 121 127 126 97 65 51 33 -4 -12 1 9 -6 3 18 -4 11 6 -5 -14 -49 -60 -68 -61 -37 -11 -4 -15 -19 -35 -57 -63 -61 -38 -10 -43 -102 -85 0 -4 26 51 70 71 67 65 61 44 46 38 41 39 30 31 35 43 24 14 -4 -11 32 8 5 -4 3 8 22 24 18 31 39 38 52 56 55 67 72 55 46 82 69 50 -80 -91 -42 -33 -74 -127 -125 -92 -97 -113 -114 -113 -120 -121 -124 -123 -125 -117 -92 -65 -61 -72 9 1 -18 -12 -1 -7 -18 -16 7 18 10 17 0 -8 -24 -53 -78 -124 -128 -128 -119 -85 77 58 42 29 28 19 -16 -38 -67 -79 -86 -61 -55 -53 -43 -25 -12 3 23 17 28 62 34 69 89 75 89 76 55 40 22 19 26 24 38 38 32 20 14 5 4 9 -3 24 21 30 35 25 12 18 33 29 16 8 -4 5 8 3 -2 -10 -9 -17 -42 -36 -42 -18 33 77 98 83 41 26 30 29 36 40 35 17 12 3 -11 -11 -6 10 50 36 35 -8 -2 1 -18 -28 -35 -37 -46 -44 -38 -39 -54 -53 -57 -59 -53 -56 -55 -38 -17 -34 -57 -50 -85 -43 -28 -23 -37 -41 -31 -22 -20 -34 -44 -31 -24 -17 -20 -12 -10 4 18 16 34 41 -3 11 5 12 2 0 -13 -8 -1 -1 9 3 7 4 7 5 6 6 -2 -24 -53 -53 88 34 -12 -43 -31 -31 -35 -31 -24 -21 -24 -24 -17 -6 14 22 36 65 82 101 71 127 -7 -13 -19 -21 -32 -21 -10 -3 -26 -43 -45 -54 -61 -74 -77 -74 -71 -79 -95 -101 -95 -33 47 52 44 39 39 30 19 9 21 19 1 -7 -1 13 17 10 2 12 16 4 -15 39 73 55 49 55 48 45 48 52 44 50 59 56 47 52 55 63 57 44 67 79 74 58 -44 -66 -63 -53 -54 -44 -40 -42 -38 -50 -69 -68 -61 -60 -54 -58 -62 -67 -64 -39 -30 -76 -40 -41 -55 -48 -40 -44 -43 -22 -19 -28 -17 -19 -21 -18 -9 -4 5 -7 -45 -51 -81 -93 -27 -27 -36 -47 -51 -57 -54 -59 -58 -54 -49 -44 -52 -59 -50 -47 -44 -31 -29 -29 -19 61 -1 9 51 71 69 87 114 117 90 77 75 60 63 59 43 32 25 16 11 -1 2 9 -11 -26 -27 -29 -28 -29 -26 -23 -29 -36 -47 -72 -81 -72 -45 -27 -12 -1 -8 4 4 -16 -9 -62 -66 -56 -51 -53 -54 -53 -66 -77 -75 -79 -81 -81 -66 -55 -54 -41 -62 -82 -89 -83 -32 -65 -68 -65 -71 -70 -66 -40 -35 -48 -38 -43 -46 -43 -17 -4 -3 -6 -23 -30 -28 -17 53 28 19 4 -16 -8 -17 -20 0 12 14 30 28 25 9 15 32 98 111 95 80 54 -23 -30 -28 -31 -35 -36 -40 -39 -52 -52 -43 -54 -52 -51 -49 -51 -47 -32 4 -21 -40 -37 -49 -54 -31 -29 -22 -12 -5 -14 -28 -31 -34 -26 -19 -23 -31 -19 -13 -20 -43 -30 -8 5 59 101 113 85 51 46 43 43 34 20 25 30 33 32 23 16 12 9 1 8 18 1 46 63 43 32 24 25 22 27 28 44 61 68 56 60 69 71 51 45 57 80 125 127 48 47 43 66 54 33 3 21 29 43 48 48 49 59 55 46 37 19 22 36 59 51 -119 -91 -57 -52 -48 -52 -37 -22 -14 -19 -22 -34 -45 -47 -48 -49 -47 -39 -10 -8 -24 -24 23 37 30 38 27 30 24 27 30 30 33 35 30 24 31 31 28 32 27 25 0 -5 75 31 11 32 58 63 58 33 34 41 22 37 22 6 2 15 20 5 0 8 36 54 -5 1 4 -4 5 23 34 24 19 29 30 31 27 21 3 3 3 0 -35 -37 -23 10 -24 -7 14 29 39 19 11 9 3 6 9 -9 -19 -18 -5 -5 -5 -3 -2 -7 -9 6 4 52 43 17 -14 -8 -8 11 21 19 20 16 34 43 8 -11 2 26 33 16 24 5 24 1 1 -128 -128 127 -128 -128 -128 -128 127 -128 127 -128 -128 127 127 -128 127 -128 127 127 127 -128 35 -128 127 104 boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/mp.rnnn000066400000000000000000011036351516712004000273030ustar00rootroot00000000000000rnnoise-nu model file version 1 42 24 0 15 4 -1 3 -7 4 1 18 25 21 3 8 -62 -1 -10 7 -5 -5 -2 -15 2 -9 5 7 29 19 31 9 -18 -25 27 -30 20 -19 50 -20 -16 -23 -30 -24 -2 16 -3 -21 10 7 35 -3 16 50 -9 -29 -16 -25 -32 -22 -16 -18 49 -25 -45 24 -21 -25 -30 4 -6 -45 29 19 43 24 36 38 -32 16 -18 -21 0 46 36 62 -9 -4 -28 -42 28 -11 -20 -34 12 -11 7 27 -66 30 -75 4 -7 -13 12 11 18 -12 20 -43 55 7 11 23 -21 19 29 -59 -2 -5 -35 63 -83 -1 -21 -11 63 15 -6 23 -32 17 2 37 -4 -26 40 -56 -21 -47 -45 -6 -6 -18 -60 23 -48 -50 -13 -41 -101 -71 9 79 -121 110 72 -44 -125 -28 32 18 45 -77 -30 -114 -93 -104 -74 107 -55 -29 -128 34 -13 -51 17 -7 121 126 55 11 -85 126 127 -128 127 -19 40 -80 46 22 61 52 96 96 -67 -37 -24 -112 6 46 10 -67 -62 63 -35 67 -23 64 44 3 48 -128 -11 0 -7 121 -126 -51 -25 -34 -15 27 -29 35 -77 -47 45 -20 -106 -1 19 -126 13 -17 -11 -127 56 5 -62 42 -127 -75 -71 -15 -116 -103 -24 -9 83 -70 -128 -38 -31 105 36 28 -7 -37 40 -81 -19 -32 -44 85 -62 13 -10 -32 90 -57 102 -77 30 62 -45 -36 -21 -1 55 -128 116 90 8 11 72 36 9 -127 43 -116 -95 0 48 -124 -124 -8 -59 21 -4 -35 74 5 -96 -10 -123 8 42 29 123 -124 -125 40 -18 19 3 -2 63 91 -104 69 -10 114 38 9 62 -40 50 -80 -77 -8 122 127 38 -87 -96 123 50 91 5 6 127 -128 -46 -3 -43 29 -124 71 16 70 32 -63 52 88 22 40 58 16 -120 74 -94 71 125 126 6 -47 -76 -96 79 -11 -38 100 26 98 -36 -127 10 62 3 -101 -31 -121 -98 66 -5 127 26 68 76 -70 -100 -25 76 -37 41 94 -94 92 -79 97 -51 -93 113 -74 -64 -111 -8 124 127 125 -53 40 96 120 27 87 -36 126 127 -44 -42 -128 -15 33 -81 -3 -109 -115 72 -117 -125 127 18 126 -60 12 99 -19 -20 24 -53 -21 6 57 -111 -69 -30 -22 -100 -23 21 27 -44 -126 -122 74 -60 58 73 -24 -57 -20 6 18 -65 -50 113 121 -26 50 72 62 94 -33 52 -128 -116 -36 -38 28 9 85 -50 92 -2 14 -84 9 124 3 -21 -26 120 -77 -1 0 -46 -47 79 82 41 -7 111 93 -46 -125 -51 104 123 -10 -27 -16 47 37 -19 -20 42 127 49 -29 26 -32 59 40 -26 -17 95 -72 -47 100 25 127 -103 57 -55 125 86 112 127 -82 113 19 -11 -112 65 127 -58 -75 -11 65 -128 50 27 -95 93 119 -125 -106 83 97 93 27 97 121 12 8 52 -3 -123 -84 21 77 -15 -37 115 -72 127 -40 33 120 -112 38 30 -60 102 124 -113 -127 110 -36 -72 -54 -127 -128 -126 -76 42 42 17 55 15 -2 92 27 -48 -21 71 67 -99 -40 49 77 -95 36 19 21 -54 103 -37 -113 -14 7 -23 -3 -123 63 123 -53 -28 18 16 -115 115 -122 -97 33 90 52 -28 1 -41 -87 -78 -70 -22 11 34 35 50 53 127 10 120 -31 102 81 -126 66 -103 -40 -76 -10 -10 9 21 65 -29 63 -48 -88 -93 97 42 -17 -14 20 100 98 51 72 95 44 46 -51 50 49 -10 -83 -75 -100 45 -67 26 127 79 -33 -50 -127 -92 -12 13 -57 -76 62 79 -124 19 55 34 -34 -90 -20 -46 -1 -7 45 -8 85 -84 81 83 -90 -128 44 127 54 71 -84 66 11 -45 25 -17 -5 -24 -79 -2 -120 35 -20 27 17 30 71 -21 5 69 114 -26 52 -5 12 -12 110 123 -20 -57 11 -20 29 34 -92 14 -5 -89 -30 -27 104 80 101 11 58 -3 -52 43 52 -8 114 -90 -69 14 32 41 -6 7 12 26 -126 -20 12 -35 97 -101 -123 -22 0 -80 0 -32 -31 12 -64 -2 -28 -10 7 94 -18 -44 -7 -18 23 -31 100 -7 -29 -69 -69 125 127 121 25 -125 -21 124 127 63 -128 99 -58 40 -101 -46 99 -126 -12 127 123 -126 44 98 -69 91 123 56 40 -127 94 107 127 63 -95 121 119 -60 83 35 52 -121 -28 127 127 -121 120 1 -40 -106 -111 -109 29 -3 14 -63 62 -49 37 69 63 -72 -33 14 27 76 -121 -83 125 20 -2 -117 74 85 -54 -42 47 3 27 32 70 -56 -15 95 -81 -46 -38 -61 66 -36 45 -76 88 52 -14 9 82 120 14 -17 -11 -121 -126 -24 48 -22 32 13 17 -67 59 -121 -52 3 77 -88 -25 124 -113 46 86 78 -97 -118 11 107 12 22 8 63 43 -14 -109 24 15 -21 80 4 -75 -76 -18 -5 -103 -19 -95 -13 -34 -23 31 -41 51 -39 1 -26 34 -36 36 75 10 56 -22 16 18 33 -2 11 50 2 -1 62 -19 62 28 -38 92 -40 13 3 8 -24 -5 -51 16 -37 -13 42 14 34 50 -26 11 -20 126 -69 -7 -38 74 127 -1 19 -5 -39 4 27 -127 115 -126 125 3 -29 120 10 94 74 -35 -16 3 24 24 0 25 -122 41 -91 6 -9 2 72 -100 -46 -102 -101 31 54 -48 -47 -80 -107 -5 -31 -121 -5 -26 -38 -16 -11 36 -40 -19 89 -25 105 -5 -107 -3 -9 40 28 2 15 -54 -105 2 24 -83 -86 -6 59 1 -63 -2 -28 36 -47 21 29 -28 4 -14 36 25 -30 -27 6 -50 33 -4 -50 3 -69 58 4 -19 -69 -45 2 -41 110 48 -42 -12 -100 15 127 61 64 65 51 -74 24 4 -8 -61 -127 14 -126 -113 -81 -81 31 -18 -11 110 -5 37 -126 -90 -44 26 -57 -45 127 -22 36 0 -103 5 24 62 -117 -18 -126 99 127 34 -44 77 62 -42 12 -101 -103 103 -59 66 -40 9 127 10 -1 -13 74 106 117 104 126 17 -127 88 -126 55 -127 -125 44 119 -9 -68 -122 115 108 123 -79 19 18 -32 -86 13 31 68 -3 11 -16 27 -61 -34 -69 -44 -93 -43 -26 -128 -86 59 -10 96 -36 10 68 -9 48 66 85 69 -5 28 -13 39 30 58 24 49 -9 -65 -42 -40 -21 32 29 -24 66 -14 -69 10 -19 -8 1 -47 -57 5 -106 14 -32 -77 126 -41 -69 16 -44 -43 9 -125 -63 -37 -128 50 -1 113 78 67 -29 98 40 -14 -12 7 -19 -20 43 -85 -33 53 -38 -53 45 -23 9 69 -9 69 -128 42 48 -3 80 85 -116 2 -13 52 33 53 -18 -45 63 -22 -25 49 32 93 -102 -119 125 72 8 57 6 9 3 -6 -98 14 25 5 117 0 12 13 -13 -119 -91 45 58 -58 -10 126 -54 14 95 120 123 6 40 4 -35 125 17 23 48 57 94 2 120 121 51 76 29 -108 -42 -65 -5 62 -20 24 -15 -17 87 3 -24 25 9 8 24 -43 -38 -6 -32 -48 13 -9 -51 5 17 29 39 -34 5 25 86 -32 -54 -19 79 26 127 -9 52 -45 19 -50 -58 -64 -45 -11 42 40 -72 -11 85 23 -55 -103 28 -19 -46 91 87 -54 -125 -38 -11 -19 62 -4 84 18 8 -16 107 40 63 80 -35 -49 -27 19 -59 -28 4 67 -77 55 22 1 -8 -22 11 -74 66 -38 -15 22 52 123 -94 -53 -3 -32 -128 -60 -58 2 105 44 6 -9 -37 -42 -70 -44 -1 -62 29 38 14 78 122 -94 -46 45 -32 52 -35 14 24 37 -47 52 -59 68 21 -18 29 -5 40 -52 -18 27 -49 -33 30 55 106 61 119 74 -70 -24 -8 112 120 101 -79 62 96 85 -60 16 -11 -32 -53 -80 -15 -46 -56 74 -42 -3 49 -64 7 30 42 105 53 -79 34 -29 20 40 -59 -73 42 -19 -118 -10 -10 82 62 79 -84 1 51 37 -34 -46 29 -36 16 -38 58 -83 -36 40 1 -23 29 -6 101 -118 -71 36 10 -41 67 9 44 -49 -95 -15 -12 -100 -18 30 30 28 45 -20 -76 -22 11 -64 13 14 -38 -13 10 73 5 20 20 67 10 88 17 75 28 -24 53 4 -31 -21 -22 -30 74 -35 -93 16 -16 -83 127 -11 -17 7 34 -12 5 -107 2 -4 -40 67 65 -24 -71 -61 25 -12 70 7 23 -36 1 6 5 -8 22 -57 -89 72 -30 -90 -34 -7 -2 6 -83 4 53 3 41 -62 -25 26 17 58 -20 21 0 69 -3 -4 -43 -12 -4 6 8 14 44 115 59 41 124 65 19 107 -43 -29 41 15 -32 32 94 77 -52 -34 94 69 -18 -89 36 -31 8 -16 14 -72 34 33 58 -36 41 67 11 -17 41 13 19 21 22 -75 58 -33 27 -107 25 -67 -40 -6 -25 -22 -49 -23 -60 -32 -65 55 -24 -49 -43 -37 -4 7 -44 -43 10 -2 -17 -36 -25 2 -56 -42 -67 52 -128 24 5 31 68 -3 -88 -8 -10 34 -29 117 56 49 -68 91 111 5 32 14 -124 -56 -36 -93 -73 60 81 -3 21 -40 -31 -96 -107 -45 -8 -1 101 -31 50 37 -103 -25 67 -4 5 -5 -103 -14 69 91 -21 26 11 6 50 -38 32 53 43 126 -88 -71 50 30 -52 49 -80 42 -16 90 127 99 79 -102 -98 24 -63 -33 115 126 86 -46 -19 99 -30 127 123 97 39 -125 -126 27 20 39 41 -46 -53 27 -42 13 -7 11 55 -42 -93 -1 -23 74 36 86 -21 45 -5 -119 -76 8 -15 43 6 -53 10 -30 -19 76 -3 -1 -83 -10 -38 76 -17 -13 20 -38 75 9 -18 32 -81 52 -63 -47 -58 -48 17 -14 37 56 87 5 38 -65 92 34 61 -51 3 -13 -76 10 -13 89 6 -60 -45 70 -37 50 48 20 -62 93 -33 70 6 28 -54 -19 50 -23 14 75 -39 2 -85 59 -5 7 69 -26 12 48 -10 -5 42 -46 -4 62 -15 4 10 27 -64 -27 79 16 35 -11 60 -40 37 -33 5 127 -5 -35 54 -113 95 44 -39 86 45 21 88 45 24 45 83 90 127 105 50 -121 42 62 61 -123 47 34 0 -36 63 119 -43 39 -67 -60 127 110 -1 -17 22 21 25 -64 111 -78 -63 105 -84 -87 16 -61 -10 2 -7 9 8 -27 -36 -32 117 -15 -31 -127 58 127 -55 74 69 -25 10 -17 -82 -128 -69 -54 75 2 34 -48 40 46 -52 -107 0 -83 14 -94 -54 -54 8 -66 -102 79 127 -127 -28 3 -39 -61 25 -23 -24 81 -80 40 73 68 -42 -25 -72 27 34 -10 -88 -85 -89 127 34 -49 -5 -40 60 -13 36 3 -10 24 -5 76 -62 -49 65 28 42 -102 80 -21 -28 -61 60 27 80 12 -19 -126 69 39 11 -55 -80 -20 -13 -51 -80 -61 -6 -22 -15 -61 -26 -54 100 -95 109 44 -30 29 10 -31 44 -71 -127 -36 -94 69 77 -3 116 -60 56 15 68 -16 -21 20 -49 -69 -22 22 -55 -6 16 67 1 -12 5 101 -85 53 37 -19 93 -68 -60 106 51 40 -3 -57 -8 -49 14 33 2 -21 45 -61 -59 -16 -18 -93 34 52 -51 -45 59 -5 -53 -104 -121 -50 57 -42 -66 -31 -39 -27 -36 106 125 48 -14 37 -15 71 -108 47 45 23 -5 -47 43 121 123 54 -118 9 31 48 71 72 -20 6 -83 11 39 27 -124 -43 15 -99 -42 60 -49 75 47 -95 8 -55 32 60 -65 -1 45 -122 18 -21 29 -125 -126 -117 -127 31 118 -50 115 91 125 -125 -125 33 107 -38 -55 -103 -114 -32 -6 125 121 -86 2 41 44 17 35 79 17 93 -58 19 -61 126 -23 -124 -30 41 -8 -77 -67 -19 124 124 -1 62 27 -38 28 -41 1 -31 4 27 41 0 4 -19 82 -67 -125 -19 -32 56 -100 66 58 1 8 39 22 -116 -50 59 -39 85 -127 -128 -19 -113 -111 -119 17 -77 -128 -126 -127 -4 -127 -120 -123 126 -65 -37 -14 -11 52 -7 100 79 -89 13 -127 -99 -40 -93 -60 -27 -127 76 -73 126 42 -128 125 55 85 -42 -125 -19 -19 -19 30 1 -82 51 14 -13 16 -2 17 -91 -11 54 -25 11 74 25 42 -97 -22 23 82 -128 -81 38 126 -34 11 -28 94 29 -93 -128 20 -19 -66 -128 -112 -119 7 -13 -125 126 75 -110 27 -16 -38 29 -28 82 -39 60 3 -24 46 23 -21 74 96 -11 -83 7 -44 -38 -34 31 -17 36 5 66 -78 -31 -27 5 41 60 7 -43 -6 -7 -76 -71 41 11 -30 0 47 -60 0 6 -7 70 51 106 21 39 -70 -85 127 91 73 61 102 46 -52 -88 125 -44 34 121 36 69 5 115 66 6 -55 -23 61 76 32 -11 117 -25 -5 65 78 19 12 -60 -20 -66 -4 -128 23 -6 -13 -3 -19 -10 115 31 24 -16 -37 76 71 6 -57 104 -97 60 17 -49 -99 -29 -42 -103 -8 -18 -36 -36 17 -2 -40 59 18 -75 -32 39 70 -127 41 127 -65 93 56 78 69 -38 -126 -116 67 -2 15 -79 63 52 106 -49 -125 73 124 11 -71 89 -124 -4 -9 31 10 118 -69 -51 35 54 95 23 6 -52 48 8 -102 -32 55 18 19 -67 -30 -46 24 3 39 12 53 3 -20 -9 9 71 -29 20 90 -17 21 -61 -2 58 126 95 -78 -46 17 58 -84 -29 127 86 4 93 0 118 86 -62 62 65 -31 -117 -75 -39 -81 -41 93 -55 -128 -66 65 -69 38 23 6 -48 -8 -65 4 2 -39 -7 31 31 -113 -101 31 -19 30 48 6 43 -6 -25 1 -8 -22 -60 -9 -82 -77 -20 -78 67 -19 38 41 10 -67 11 -20 30 50 -57 -74 74 32 126 39 80 -44 -118 109 65 -63 0 -86 -64 -49 -128 62 9 -63 -118 41 48 127 -17 76 4 -41 -32 56 -49 21 -25 -86 -91 -61 11 -46 87 71 119 55 110 18 -91 72 29 -68 35 74 41 -12 9 54 75 -60 -14 42 15 50 14 11 -20 -87 -2 -1 41 -25 123 -1 -37 -54 66 64 124 41 -73 -78 53 38 -54 79 106 -53 -24 110 65 98 3 -92 -49 11 -34 80 84 76 -7 -49 47 -3 -9 10 21 33 -56 -15 68 29 9 9 30 -8 35 13 -34 25 34 71 65 118 31 -127 80 -3 86 -45 75 97 -87 21 28 -38 56 35 124 -82 -23 122 39 -84 63 -24 21 -66 -39 -65 -117 -22 62 -42 -49 57 10 -56 -60 17 -8 30 -85 -118 -33 78 -10 -61 29 -33 -121 -84 -23 49 -93 -87 -21 -20 34 -18 44 24 -69 -32 -88 -66 -50 -39 -86 9 -8 -47 -15 -78 -14 1 55 70 15 -42 -7 6 -38 19 -48 -20 -35 44 71 -40 59 -40 -46 -33 -73 26 -14 96 -3 13 80 77 72 43 -94 65 98 -26 -27 63 106 52 56 44 127 112 43 89 12 57 -33 -56 116 -38 5 -73 82 80 -97 42 105 54 -20 50 53 -15 11 -14 -20 7 -128 -23 12 -16 11 87 -13 34 62 -74 46 55 28 -104 8 66 -48 25 -5 -22 42 49 91 9 -13 -15 -70 -52 -16 46 28 -13 -23 -3 -21 -34 -109 5 0 -98 37 -109 127 -3 -60 -110 22 -24 -80 106 -91 -114 44 -20 -93 -6 -17 -63 32 -30 -74 83 53 -91 -64 28 86 -8 -9 -45 -76 11 94 -57 -117 -37 3 -8 120 49 103 -43 58 55 81 -126 46 8 -128 74 -93 -34 98 68 126 -56 -98 59 -78 -15 -73 64 126 -9 80 -2 126 61 -2 17 118 11 -124 124 37 1 48 -31 97 30 74 1 85 -3 72 28 102 9 5 44 127 16 -36 28 -22 -10 7 96 45 69 81 16 -8 -54 -9 -15 -66 118 18 8 47 -1 -115 6 -69 -124 51 29 -63 24 -14 -43 97 77 -25 63 -49 108 41 -44 -14 81 22 -127 -53 -57 -42 -127 32 14 62 21 127 -3 -51 -42 -32 22 59 24 -19 127 -22 29 117 33 -45 -50 -22 -96 -33 68 48 -6 43 14 8 94 -10 -4 27 22 15 23 30 -31 -50 -111 -5 -127 -16 -58 -36 100 -23 73 -128 -62 18 40 12 -61 54 -47 35 112 -103 -91 -115 81 101 3 126 42 37 -18 -69 -41 40 110 57 14 -82 -94 28 -105 -15 34 89 43 -5 -121 126 125 84 126 -105 69 -3 -67 27 3 -27 61 22 103 -22 37 80 -9 -50 -7 13 -12 58 -106 1 28 22 49 -26 1 32 75 51 -27 78 -125 119 57 5 -89 82 38 -17 115 -88 -62 58 19 127 -91 10 115 -16 -16 -36 -19 103 26 70 106 47 -118 -62 -18 -128 78 33 33 -7 -82 -85 -122 124 -94 25 -95 -128 69 102 75 -38 60 -62 -39 27 -127 -60 -48 -127 -40 -38 -78 -31 -29 -43 -104 -6 -31 -27 -65 -7 120 -6 -22 -35 -102 42 -47 90 104 35 -57 75 87 -80 83 -104 -84 47 127 101 -115 -127 80 -127 -87 -28 45 -11 84 -50 -122 -42 41 23 -12 70 42 -41 2 -23 5 -7 31 -126 127 31 29 123 -13 111 59 35 22 28 69 33 117 42 7 72 17 1 49 -24 -67 30 31 6 -53 67 -124 57 -126 34 53 36 -46 -81 118 -19 -61 -27 44 -90 26 69 -59 78 65 -8 -53 -128 82 74 -68 -29 90 57 47 -82 -25 -2 -19 89 19 -44 3 93 -28 -122 127 120 -128 -61 -53 0 -28 -98 -95 17 -86 120 50 26 37 16 36 -84 -36 -47 35 13 5 -66 2 -20 28 69 30 7 -51 67 39 -92 56 60 32 -51 -50 21 -72 110 22 21 -128 -5 63 -66 23 -43 -125 114 58 123 -69 -28 127 24 -66 3 29 52 35 -70 -41 -72 -10 85 14 -103 43 -12 5 -127 -12 6 33 -84 -123 -124 -37 93 -86 -19 -80 -44 -48 47 35 -89 6 62 17 -34 37 -1 -79 -32 -87 -30 45 -15 -12 -28 -30 25 45 13 -73 -9 39 -83 126 -49 -56 -52 51 -94 -126 9 -46 41 92 -50 -74 -63 33 29 -126 115 86 -8 -3 -127 39 6 -127 -70 -78 17 52 -45 70 -10 -25 43 -66 -31 1 -128 24 -57 4 122 -17 35 -30 -107 1 25 29 0 79 91 -15 3 29 8 -60 -34 21 23 -6 -14 -17 47 33 10 -96 91 -35 28 -8 -43 39 -126 -35 -59 0 -6 -27 47 -57 70 37 -49 -59 -107 92 23 -57 -31 -11 44 -19 -27 35 10 0 59 16 -122 -25 3 -117 -17 0 99 17 -26 34 125 -118 22 -16 -71 80 29 -44 -40 -41 1 -12 -50 -13 -29 -62 51 29 -28 6 -28 -4 13 -23 -63 -33 -53 -86 -96 29 -25 -52 -13 44 87 -124 34 9 103 -74 38 71 -106 70 -49 -47 13 28 127 -83 -105 61 -39 -46 -105 59 79 -19 16 76 43 95 20 -27 -77 -128 -51 46 -44 -63 -8 88 96 -32 24 -1 37 46 -74 127 117 124 -3 55 27 -47 -87 16 -102 -13 -71 -23 -47 -37 -75 -86 38 -60 -2 -1 -19 99 0 51 -72 -7 60 -87 84 0 -7 -56 -11 85 -47 39 -39 -50 78 -2 127 -49 -22 77 -62 -52 -60 -48 84 58 68 63 59 13 -27 -87 80 -46 -75 26 60 -9 -12 -53 109 59 30 -23 -29 30 -4 79 111 98 45 -8 89 48 -16 -29 37 -28 -65 12 -1 62 65 11 64 -7 62 -7 -66 97 -36 33 10 5 14 -22 -43 -26 117 -60 -29 47 56 -20 -24 -45 18 63 31 -79 27 24 -48 16 69 -59 -40 15 -25 61 -120 29 73 116 35 22 41 -46 -63 34 61 -4 -35 -110 33 124 5 63 -70 -90 -43 -24 -53 -7 11 17 11 -49 -11 63 -19 15 16 19 61 60 -78 -55 -14 -33 1 -16 -27 -57 4 -48 -50 125 -60 20 -40 52 -99 36 -19 -41 -8 41 -36 17 -128 56 98 -128 115 31 -48 12 -47 36 -13 -22 -69 33 25 95 34 -61 61 -76 -101 127 126 -104 14 51 -77 125 54 5 -60 -112 -7 -89 -34 52 19 -59 99 -20 -18 -59 39 -27 1 16 15 13 33 16 21 -1 75 -40 -12 -24 30 -119 -127 127 -55 -18 -122 100 -21 -18 66 -58 44 48 -48 -88 -127 127 73 -128 59 44 -62 100 -81 33 63 64 109 58 27 44 109 -112 30 123 56 -35 20 -14 104 119 24 126 81 98 -41 -9 119 55 -43 -15 32 -27 -11 -47 -8 -71 -23 -42 -55 -43 -10 -76 7 -47 42 -7 -3 -16 -12 27 -40 -11 -48 7 119 0 4 -22 -3 72 4 -24 -7 -6 -23 114 54 -27 -2 83 -81 16 6 -18 26 -68 73 127 -102 -17 127 -40 38 -86 79 -85 33 127 38 -128 126 125 127 125 -127 116 -125 -101 105 -55 62 7 20 -9 -5 5 92 -85 -72 -35 66 11 -20 13 37 100 38 -14 -41 31 -36 -91 42 -73 -70 73 -8 0 -5 36 -9 -60 -7 16 16 101 -54 -122 -101 127 95 -128 127 39 -96 -31 -34 -1 -127 -125 -61 -58 -52 38 -21 116 45 -98 -21 -56 -4 -26 -123 -117 -58 -62 3 -48 52 -87 -125 -61 -62 -25 3 -54 64 -3 19 -39 1 -68 -97 -6 -9 17 -92 -36 -53 -54 -43 -101 44 1 -58 -61 -66 125 -44 -68 -112 -6 -76 26 32 38 45 5 -24 -120 -7 127 32 -116 127 61 -112 -16 -24 31 -113 -127 97 -27 127 -42 -63 -77 -126 59 -98 -57 -23 30 -127 -73 -128 -59 124 -119 127 70 -34 54 -80 -12 27 -40 51 -69 58 -98 -18 -26 27 73 104 -65 28 123 14 32 6 127 -50 -121 -49 -128 -127 127 -127 -118 80 71 -126 -14 127 -91 127 127 -50 -88 -128 127 127 -127 109 127 19 58 -126 -19 37 -125 66 115 -75 126 102 127 101 93 125 -91 3 127 -50 -98 -85 26 77 -118 121 -116 -82 -37 101 -25 65 27 12 119 74 76 -52 41 -15 51 27 127 -72 127 77 56 47 -64 34 -58 95 27 127 -74 79 99 29 -68 88 126 -77 37 -32 -77 89 70 116 -71 -103 41 -127 -47 -2 47 13 -3 60 32 104 -14 -65 25 112 -50 3 18 99 71 65 -124 93 123 63 15 -96 13 -65 -29 66 9 -70 -44 57 38 -46 -12 19 30 -19 -27 28 -8 49 -15 -24 -11 -58 -2 -47 48 76 36 42 -93 -40 -119 -6 -62 -36 30 74 69 -56 16 -34 -3 50 -52 2 -7 103 17 -44 85 5 -29 83 -51 -116 -128 76 -100 29 -20 -18 94 -20 -4 114 -6 -29 77 -128 -90 -85 -128 -19 -87 127 41 -20 127 124 -2 65 -49 -36 6 43 49 -53 -30 36 13 48 30 70 67 127 55 -2 49 125 44 39 -11 50 -127 92 65 51 -96 34 124 -9 40 -127 -39 76 34 59 -47 -87 124 -70 -125 89 -14 126 19 -128 -127 24 -84 28 81 -106 121 -53 -34 -73 -128 -59 31 -127 -123 -127 -125 97 -127 123 126 -125 -11 36 -8 32 85 37 52 24 79 63 66 40 22 39 8 2 15 75 -24 54 -38 17 49 22 58 6 -59 5 5 38 -26 -4 -36 -10 11 -12 -19 8 5 78 -53 -54 42 -120 -45 59 33 -7 5 90 48 2 0 27 12 8 -81 27 -43 -13 21 40 -6 36 -10 -75 -50 -1 12 20 43 -54 -26 12 -69 18 -69 36 -11 8 -31 -54 -46 -21 -29 5 11 84 90 -4 25 -18 -91 41 15 -6 -36 -22 -68 -3 25 -13 -15 14 22 -14 33 10 1 -4 72 -9 -25 -46 -37 -84 7 -49 9 -45 0 -16 1 -28 -36 -23 28 4 -62 2 32 -60 34 -17 -3 23 -22 -16 -33 -31 -57 1 -20 66 46 59 -68 31 51 -64 -6 16 36 -13 -43 -15 27 4 -36 7 17 11 -11 -5 -79 1 28 9 -27 35 -49 23 -12 -7 31 -10 15 -40 -9 -46 36 -3 17 -7 19 -73 -6 24 8 -21 52 -4 -14 -5 -14 15 17 53 -1 36 -9 -7 12 -69 23 -16 2 -52 17 -57 38 -80 23 -30 39 -46 24 42 107 5 -125 -43 -122 51 -7 -125 67 -43 104 35 -2 25 -21 -71 -15 1 -20 -88 -93 26 12 76 -96 -8 10 -108 52 -16 44 18 107 6 16 19 56 20 30 -57 79 -17 -19 4 -14 -85 79 -11 28 -26 -40 10 0 9 -40 -46 -36 -80 28 53 -16 -10 -40 -16 -46 19 2 -45 14 45 14 17 74 -21 42 -34 4 -69 111 -36 36 -44 12 63 24 13 0 36 46 -34 -77 -32 -9 38 -96 -45 29 -41 41 -12 -49 67 -19 -19 -6 16 -70 15 -31 -15 38 -91 -3 -63 -44 -29 25 43 -43 -76 20 -24 -13 -31 -16 62 -43 -39 39 -84 8 -51 57 -44 32 -98 32 -26 29 -43 -78 57 25 -65 -5 -10 -43 60 -32 -96 -12 8 -2 -24 16 -15 -100 -28 -18 -7 -38 -41 -4 16 -34 -11 -39 -74 -114 21 -42 25 51 100 33 45 -47 -5 -4 12 15 46 40 55 -7 -51 31 -41 -34 14 -30 -36 -43 -22 21 -25 9 -2 -55 1 -47 23 99 43 15 57 33 -31 -22 46 17 -36 -18 -15 9 72 -36 -2 -6 -47 -81 16 49 -60 -94 -23 19 -9 -20 -29 -11 -74 16 -38 15 -48 43 13 33 9 6 6 23 -1 -26 43 23 -4 -9 28 35 -39 59 45 83 -2 -44 -28 -50 -50 44 -14 -2 -76 22 12 -13 69 -61 52 -19 5 81 32 -1 -103 33 -48 85 -78 -22 -18 15 -43 20 -5 7 -57 -40 3 -76 7 64 21 33 -40 -23 -59 22 -3 -15 -57 -20 52 90 -15 15 16 -5 -17 -5 -66 31 70 -1 50 11 9 45 4 6 -23 52 68 49 47 69 27 -21 15 -10 -47 39 -5 7 -27 -62 43 36 -22 105 11 -73 -16 -30 -33 -46 -12 -72 -61 -37 28 -10 -23 -17 8 25 -19 -8 35 23 37 -55 -78 -53 -34 31 -16 -22 -12 21 -3 -15 31 40 44 -20 -20 -55 -24 -42 20 15 -23 9 9 6 3 -21 7 1 -48 -8 36 44 69 -7 5 -38 -26 -5 -47 39 12 45 -3 -46 22 -29 8 38 -18 -15 -39 78 -51 44 29 -14 16 -41 -21 -25 -35 46 27 -12 70 -38 -8 -6 31 -8 -3 43 2 50 48 13 36 10 -59 15 -7 64 5 57 91 29 25 22 41 5 -6 -32 27 82 -58 3 16 37 -43 3 -59 -81 -4 -19 -2 -9 -33 -3 -33 -14 -51 -7 17 -19 -18 13 22 27 14 40 -19 -37 -20 1 -6 26 -47 -47 -4 4 -27 52 22 3 13 31 -12 25 16 -76 28 -5 -16 -48 6 -29 -1 11 25 22 38 -33 9 3 -38 -10 3 -21 12 20 -28 2 -6 14 -30 2 7 34 8 5 -40 -14 24 -28 10 23 -27 4 -72 17 -1 -5 4 6 -20 0 23 20 13 -36 -22 -116 33 2 11 -54 56 11 32 -20 -1 -91 -57 -40 -127 4 -52 -6 -82 -36 -80 42 -23 123 2 -72 6 -26 -39 -35 18 60 102 -36 -125 -39 -26 -26 -85 -12 28 -109 56 30 24 64 -102 -79 59 -79 -96 40 -33 -7 34 7 -2 23 -71 47 -38 -9 -58 56 18 -70 -26 -72 84 68 -3 -30 45 84 41 -85 10 13 58 9 -66 74 42 9 -67 -49 -12 -76 22 10 70 -69 -44 11 11 18 31 57 -36 32 108 -38 57 -3 17 48 77 -13 -27 -28 24 74 17 19 9 8 55 28 -9 -18 -22 7 -12 -34 12 -10 46 -1 61 64 -21 -49 15 35 37 35 -15 -36 -5 48 81 11 12 13 -12 -43 -3 -36 -29 -65 17 34 -33 32 -59 0 -51 30 -26 -38 -28 30 26 36 18 -28 -31 58 3 -65 -3 -9 36 41 -43 -32 -29 -10 -66 -26 69 -24 -12 -5 -23 -6 -36 31 64 -49 -43 17 -46 4 42 56 41 -28 -14 51 3 9 19 35 -10 16 -51 72 82 -37 -50 73 -28 44 24 -58 -27 3 -85 113 1 30 -22 33 21 58 -26 -36 20 -12 19 23 -12 -45 -7 -32 -49 3 -22 -18 51 30 -67 -20 7 -7 -16 -43 53 -22 -7 -43 -5 0 -3 -1 26 -22 -7 19 -30 -40 -32 -38 -38 31 41 -16 15 -34 -39 23 -12 18 -74 40 -2 14 25 -2 -55 13 24 18 -3 -35 -10 29 -13 -26 0 40 -54 -39 82 18 30 26 -11 65 35 -28 -7 3 60 -12 -23 39 16 24 -11 56 63 -31 17 20 -67 -1 55 38 -57 34 20 -41 81 65 57 30 48 -26 44 -48 -10 -22 -29 -17 17 21 -16 17 0 19 9 29 59 -16 -9 -10 44 7 -76 12 -39 29 -12 5 -49 46 -12 39 11 -3 -19 -41 -20 -15 8 54 26 2 43 -6 7 -6 -27 -34 46 35 35 49 -11 -76 -54 -20 -30 13 -12 27 -37 -52 3 3 25 -7 40 -30 0 14 11 -9 20 29 12 23 -48 2 32 48 -24 38 -47 -19 33 8 -26 57 13 76 -17 5 27 43 -5 -32 -9 -13 7 2 -54 -72 54 54 -26 -68 17 2 -22 -75 64 -32 -75 99 11 5 24 -28 -21 -56 2 -61 -21 34 -7 -21 8 -23 10 -61 41 9 5 -10 5 -41 -38 -32 -4 27 -7 101 -38 40 17 -120 40 -25 1 -35 -6 -8 26 -10 -21 -5 11 -28 34 -26 -21 21 46 -5 -14 33 -3 -22 -14 8 9 27 4 -39 -20 -59 -35 -29 5 54 -1 -35 -51 14 69 64 65 9 23 7 -17 -27 39 7 4 28 -22 18 1 23 49 21 -9 -12 13 23 33 24 -26 4 23 6 -62 35 -23 23 -28 -23 44 -24 42 -26 -2 13 1 14 27 14 -8 -9 -16 15 27 61 7 -10 -40 -13 -36 -31 24 -41 -73 2 -19 -31 -2 8 9 18 -18 -63 -12 -32 51 -46 -37 -38 -8 59 -36 -3 13 -9 32 -8 58 -67 -2 -42 -11 -127 13 68 -22 88 2 -44 12 25 -52 58 26 12 10 12 -12 51 18 15 -45 51 20 -108 -26 -22 -29 39 3 25 -33 -36 54 -46 48 23 7 8 -24 -20 -93 8 -38 8 69 4 -55 -53 -27 25 30 41 43 -20 -3 -18 -11 -11 55 77 35 -57 20 -3 -35 -30 6 -8 19 36 23 -72 -55 -21 1 40 -66 2 -12 21 -23 -4 36 -9 -34 34 -34 -51 -55 -27 8 8 17 -31 -8 -9 41 -10 -38 14 53 28 -18 18 -36 -10 -16 19 -19 15 -19 -31 37 15 -2 70 10 33 -19 -19 -20 59 -21 -30 -24 -66 22 -63 -47 -7 -4 52 -43 -14 -55 103 -100 26 -24 49 -22 6 -20 -24 -41 34 -68 -126 29 -53 6 42 -70 -32 -25 -1 -28 -20 -13 28 9 30 65 -7 -20 -10 72 -47 19 -61 20 -28 -5 25 73 38 -30 28 58 96 -36 21 13 12 -31 15 -16 -41 -58 -38 7 66 13 -41 -50 -46 -12 49 -28 -43 -23 -40 13 27 57 19 -49 -24 32 0 -30 -52 -49 -34 -67 100 27 36 -62 45 -34 -16 -4 49 -61 -71 8 17 46 26 54 -4 -38 11 33 -30 -58 12 54 17 -46 -20 -5 34 -27 -47 45 -52 18 -12 5 23 -20 27 -10 44 -63 -28 11 5 -35 27 73 61 -23 6 3 40 -42 92 6 30 51 -65 -3 44 40 -27 -2 74 45 -43 43 -41 -5 15 -5 12 70 -28 99 -41 -3 -33 40 -79 -60 43 9 29 16 -20 33 -22 13 34 -51 -84 12 29 -45 -19 -43 1 -10 59 42 -23 -23 -52 14 -15 -16 -64 -9 32 -42 17 -9 54 28 -19 -26 -22 -25 11 -14 63 21 -5 -43 -58 12 33 -28 71 13 25 86 6 -49 31 4 33 15 -19 65 -64 80 -36 -53 -41 55 -49 -7 50 20 8 -1 5 -21 13 41 -7 55 3 28 -29 -32 23 -7 4 49 16 13 18 33 -20 -24 30 -31 34 42 18 -24 -17 14 -36 44 28 -18 13 17 17 -37 -5 -24 -38 -5 0 -38 -1 90 -45 -2 5 0 4 29 -17 -17 -38 45 -41 17 45 59 30 14 0 -28 -2 -22 -21 -37 53 -41 78 8 -60 -33 -33 -37 -4 -7 35 60 -59 -9 -69 -54 110 47 18 75 -14 71 40 46 15 -14 -48 -10 -5 -20 69 16 30 -12 -35 17 14 44 32 34 2 -27 14 81 18 -35 -20 21 35 30 -47 7 43 11 -3 -34 -31 -22 44 -24 8 14 -29 4 3 -39 7 -21 15 19 12 35 -24 44 17 -38 37 -9 -2 -15 25 21 -49 4 62 14 -47 40 37 -21 -36 13 2 -35 19 25 19 12 -45 -22 -9 4 -2 32 23 -47 57 -31 33 57 57 -19 -10 46 -39 25 43 18 -30 4 21 -94 50 -7 -36 4 -9 -82 -13 51 70 12 -36 66 -4 -6 2 92 -18 63 0 -121 58 -42 53 4 -53 -18 46 30 41 9 -6 -19 35 79 -78 -5 14 19 -16 -25 8 31 62 33 -91 -29 2 -72 11 -9 -22 -28 -74 20 44 -36 49 -12 -46 54 -92 -101 -43 -48 3 32 -38 -46 50 -27 -7 -41 -76 4 36 9 -20 -40 -15 7 -1 -5 8 -1 35 -10 32 27 -52 -48 -31 -99 -60 -18 28 12 10 -39 49 60 75 15 48 -22 -1 -9 -20 -27 35 7 53 -32 21 25 -2 66 8 31 -40 14 8 -25 30 -61 5 -36 -40 18 -43 8 25 -38 5 -21 1 7 -2 -51 3 -20 -8 18 13 -25 2 -63 -3 17 -86 1 2 26 21 -7 16 1 46 -19 39 23 12 55 -24 -8 18 22 38 -51 -45 16 -11 28 51 35 -13 62 30 11 3 32 -35 -47 1 11 -3 -3 15 18 -21 -18 34 60 47 15 -27 -6 -32 38 -66 -36 -46 7 2 -87 38 14 -34 25 9 13 -36 -18 12 53 20 39 13 -10 2 64 -12 -16 -31 6 0 7 7 28 -9 -74 -17 3 3 -14 14 -17 62 -55 -45 39 -14 51 18 28 65 43 -33 1 -19 25 -13 -6 -7 -2 -54 -10 -26 -6 -15 -33 -3 -6 -14 -1 -15 -14 -15 -22 -12 14 -14 28 -3 -56 3 32 -14 -25 23 42 -40 -24 0 44 44 -17 -95 127 -6 -124 -40 114 19 20 98 3 -43 -62 0 -30 49 0 -9 -85 14 -4 -28 -42 31 77 -47 -10 43 -52 13 41 -11 -7 -65 -2 74 -9 -23 -7 79 52 3 47 15 93 5 39 53 -30 -17 -71 82 13 -50 21 46 -12 122 -29 38 36 30 -115 21 27 -95 -41 -21 -2 39 -9 19 -6 -39 52 51 -27 21 13 -51 5 -20 44 -11 -47 -128 23 47 17 -60 13 -43 33 6 -8 2 21 -22 -16 39 -30 -49 8 -17 -30 -21 84 -19 -21 -17 7 25 90 -22 -24 -8 21 -33 8 51 -25 -12 -59 -38 41 -30 -26 38 -21 86 24 31 19 -50 -35 10 -11 -41 -36 27 17 -49 12 37 -5 44 33 -4 47 1 -22 17 -29 4 6 107 65 -6 2 8 -62 22 71 3 45 -19 -3 7 -15 16 -58 -28 30 21 95 -8 39 -7 3 -44 39 -79 48 0 -87 10 -17 7 41 42 -96 -67 -94 27 -3 -35 -30 -73 -8 9 -43 -11 -5 -32 12 1 21 -91 -11 45 -28 -59 80 18 59 -14 49 37 9 -2 38 18 -29 46 63 -1 28 17 7 53 -73 19 13 84 -23 -1 6 -63 -25 -3 -59 -38 -22 -67 24 -25 4 -26 -4 49 -32 -27 -31 -52 34 2 -36 32 20 20 -47 48 37 -28 59 97 41 0 -85 14 -51 -10 70 26 -20 -7 -35 36 -4 82 -7 -21 -13 -4 71 31 22 9 -9 26 34 4 17 -55 -42 -13 -52 -64 -21 43 48 36 11 57 4 74 33 27 -21 30 22 6 -82 74 -84 59 -4 28 120 65 42 62 5 13 -15 -39 1 -64 15 91 -37 80 -11 18 -14 93 55 32 -49 -34 21 -41 -37 -5 127 23 -67 -9 -34 -3 -8 -2 74 -39 -14 28 -5 -30 65 -32 30 26 55 45 40 1 38 -13 -36 -27 -86 74 101 78 -22 20 22 -9 -74 -23 7 23 115 36 7 45 50 -52 52 6 12 -5 -1 -14 -58 16 -20 47 -20 9 -36 -78 -4 -27 18 -6 39 -48 15 0 -32 -45 43 -30 -10 -19 -18 -23 -5 26 -36 -8 -15 -71 -36 30 -16 33 7 -20 -52 -31 47 -26 14 -27 10 23 -91 50 -122 37 43 -38 -57 109 70 4 -112 -17 -39 52 -40 40 -35 -13 -63 48 78 -20 -109 -31 -68 32 22 -26 -12 42 -106 -12 -25 3 -104 -29 64 -26 -8 -34 60 -5 5 13 6 9 56 32 38 -6 -32 -4 52 -42 123 26 2 65 20 7 -90 -55 -32 11 -92 35 0 1 -86 -25 19 -12 -69 -22 106 -34 -2 -10 71 -43 73 12 7 -2 62 16 -5 12 42 30 -48 -38 13 30 -32 -31 20 -11 -23 0 -41 -8 -9 -7 15 6 -2 -22 -39 -18 35 40 -96 -5 -3 -40 24 26 108 -47 -14 -64 42 13 41 12 31 1 61 23 26 11 -97 -21 33 -3 16 -2 -73 -93 -36 -7 -48 -9 -14 -13 80 -2 -10 -72 19 53 -86 44 -16 43 -79 -6 10 34 32 5 -56 -30 10 2 46 1 25 -34 54 -3 64 -71 7 -24 4 -2 2 81 29 5 -47 -18 -7 12 71 15 55 73 60 3 -13 30 17 -2 2 38 85 20 -18 43 20 -15 8 -57 79 26 26 23 19 -11 2 38 23 -12 -7 -16 9 -92 -48 -7 3 6 4 -11 -13 -12 47 -32 24 38 -24 12 -26 40 88 35 1 -54 52 69 -35 -14 12 -47 27 -13 19 -23 12 -2 6 -42 -4 28 -26 6 17 -21 -9 -32 63 0 -29 56 -10 13 -14 49 -3 -8 6 -8 -5 24 33 14 19 -52 44 -12 -12 69 -43 -26 53 0 2 8 26 -74 25 6 89 -15 50 95 -23 -11 103 36 97 11 21 15 -35 122 -43 -74 40 -11 -8 28 48 28 2 -6 59 60 -12 -127 15 102 34 43 8 27 -39 -7 -41 52 -45 -5 -62 7 -51 -30 72 -61 -21 39 -27 -21 -68 -41 14 66 -32 -47 7 0 28 -19 -3 -12 -31 24 44 -35 -61 45 -18 5 23 -19 8 50 -13 32 -24 -10 28 10 -43 -31 61 -43 -57 -31 -21 -48 -88 -15 -1 45 35 -14 -62 -2 -1 -27 -13 -82 9 -27 5 -44 26 -5 -52 -65 2 -12 -9 -4 -70 -10 -26 -77 43 -36 12 21 -97 22 -20 -5 -85 -16 -17 38 32 25 -91 -27 61 12 19 53 6 43 21 -28 -33 6 -22 -10 -12 -45 -31 10 20 -45 30 -46 26 -75 53 2 -44 11 -73 -19 -42 -19 -26 24 -19 -26 18 -44 -8 36 59 35 -84 3 -45 -40 14 12 -61 -31 18 51 36 -4 -20 38 59 -29 -43 -5 -6 -5 -15 10 33 19 12 55 77 -19 15 26 10 -2 17 18 -24 -39 -17 -5 -17 -87 -31 -41 -30 -25 -123 -1 -30 -97 -51 37 23 13 41 2 19 14 -41 10 4 22 23 0 -9 52 -16 -21 -26 27 11 -24 31 28 -6 15 -19 14 20 -30 -44 1 -18 -17 -42 21 18 27 4 49 -30 18 13 -55 6 10 10 7 21 -13 -44 -1 10 -11 37 12 53 -6 -29 23 -8 -20 10 -36 -77 -3 -78 -17 17 -36 -22 -65 14 -30 -80 -44 -16 -62 -54 45 14 -10 -3 -51 -8 100 55 -21 22 39 -48 -29 -12 15 56 97 37 27 19 -30 38 32 46 -32 29 -38 -73 -1 66 -19 40 53 46 -28 -38 -45 54 10 -82 62 9 -15 -48 -34 28 11 -30 -39 -53 44 -30 -19 44 -85 25 63 12 45 -31 11 47 -37 36 28 88 18 -15 4 -54 9 24 -36 -62 -4 -61 -15 -47 26 37 -33 -31 -8 4 -14 44 47 -2 -3 8 15 -25 5 49 -58 50 -50 -17 -31 -2 11 33 -22 10 20 -24 37 -27 47 -10 46 -19 -52 8 -24 -10 4 -9 33 -14 -2 -18 -16 -19 18 48 8 10 -67 -42 71 16 46 16 -48 92 -42 -23 -6 -26 -32 -31 15 -33 -4 41 -10 -26 -17 -24 30 -24 6 -34 -39 46 -29 61 -27 3 -18 31 -67 -15 19 3 -17 -15 -28 -36 -28 -16 -2 -81 -24 52 -68 68 -80 0 -12 40 -60 -26 -29 -44 36 -28 41 10 -47 16 -3 -30 60 -13 -31 22 6 56 -39 -61 6 -2 -40 38 17 -12 117 -49 -49 2 -3 72 -96 -95 -66 27 -18 45 -44 15 -1 -1 -17 -16 10 -2 -23 -9 3 -6 33 42 9 43 21 -35 -14 -6 63 16 15 35 -35 6 -10 -2 21 -16 -29 18 -16 19 15 -7 26 51 5 -35 58 -33 -18 -33 -12 5 -70 53 -18 3 -3 38 10 28 -1 30 62 -27 -8 -8 21 30 33 23 -30 -2 -13 -9 17 7 -66 -4 20 -11 -11 8 -7 23 -9 5 4 8 12 -22 -12 4 10 -12 55 38 -30 5 -1 -48 -27 -12 12 -10 -12 12 -6 -41 33 -32 63 -1 -22 7 7 -25 19 -62 3 -48 17 27 -1 -35 -9 -5 -5 28 -4 -17 -39 0 21 5 37 -10 -3 20 20 46 -6 -33 -34 -4 0 10 -14 22 7 -23 -15 35 4 5 22 -31 -9 -21 -39 2 37 27 -6 -16 -28 -17 -22 41 -6 -10 27 -1 -27 -9 25 22 -15 25 24 -1 25 31 -23 -23 10 -1 42 15 -11 39 -38 17 -25 -31 -32 26 48 -10 40 -8 33 10 6 -13 7 -3 6 48 -42 -15 17 37 -6 -46 -32 -1 -76 2 59 -49 16 8 13 -24 5 21 25 -29 -78 -19 12 -7 -7 -14 6 -36 10 18 0 18 13 8 25 23 -2 -47 0 -1 -39 1 -9 -23 21 49 -1 62 25 -49 -13 -11 -21 11 22 1 5 -7 29 32 59 42 -17 14 -12 22 4 -13 -29 26 60 -20 44 25 34 -5 45 -32 24 -6 -18 6 3 0 -10 38 9 43 1 -15 16 -5 -20 25 -31 18 28 -21 21 19 36 -9 32 -10 42 -50 3 25 -5 11 24 -36 -30 -15 11 16 17 -46 3 33 7 1 15 22 -14 33 8 -24 27 -34 19 -9 -50 0 -15 -2 25 -31 -17 -3 -6 29 -16 -48 -3 -15 50 -44 -3 -28 -3 -20 -26 71 -14 39 -61 13 9 -4 -26 15 19 31 12 0 -44 15 74 -6 -92 -25 23 2 -25 -56 -55 2 -29 21 44 18 -35 31 18 -26 28 -39 18 -13 49 -15 10 33 73 -64 13 -13 -25 3 35 -16 -11 2 25 -5 17 10 44 -3 -43 72 -57 -48 30 33 -64 -24 -22 0 6 -32 -54 -83 9 35 5 54 54 -29 -31 -3 -1 -41 41 12 -32 11 -15 -4 -47 21 36 2 36 17 21 9 26 23 -18 15 18 8 15 9 -37 -13 13 -24 7 9 -33 -11 -58 12 6 -7 33 -6 30 50 77 24 26 -11 32 60 -23 -42 43 -7 6 17 -5 -28 7 -33 -12 -2 6 -37 -23 -74 -23 -18 -1 16 26 -17 -78 -46 -7 8 -7 -49 35 -60 29 -20 -18 -58 -33 29 -58 -59 13 21 -6 -14 -20 1 4 -84 25 27 58 29 34 22 65 -13 54 27 58 -15 2 -9 13 -8 28 0 -37 -75 -14 -52 33 27 -36 -5 11 15 -16 24 -13 -11 8 -45 -48 19 15 -1 0 -71 -14 -30 1 -12 11 44 102 -22 -6 -66 -7 -43 -2 -19 5 -54 -6 27 -3 19 -34 8 19 28 -9 -3 5 14 2 -1 19 -45 -7 -15 18 59 -72 25 -25 32 29 2 30 -33 13 16 -44 -9 -23 11 16 44 -56 31 -39 -37 6 73 25 -35 -29 37 19 -50 58 18 75 1 61 -23 -17 9 47 51 21 -23 28 -31 32 -32 -6 14 -54 34 36 15 -99 -31 60 -15 21 -38 23 52 15 -25 51 18 -41 -1 -66 42 -19 2 -14 60 8 56 42 -32 -12 -17 18 -45 -6 -45 -9 -14 -17 -42 -14 -49 2 20 -11 -29 -34 -6 -15 -74 23 30 -27 31 25 3 -8 -61 7 65 -26 26 -3 1 1 -1 -22 32 41 -77 -19 -11 -16 -12 22 -51 -23 -34 -92 26 -22 -37 -44 11 8 11 -26 30 24 14 -36 34 3 56 -14 7 -39 49 -47 -42 -40 -25 3 -12 48 -44 62 -26 -50 1 -53 10 -39 -57 4 22 38 -13 56 -15 -8 33 68 -11 -12 39 77 32 -30 -31 -24 51 -31 -8 -13 6 0 49 35 1 35 -1 -45 15 -16 -45 -5 -23 31 -39 -9 -46 26 -65 19 15 43 41 -20 -35 -7 59 16 -35 8 19 -71 54 15 -17 16 4 70 -56 40 -30 -44 29 -39 -3 10 -54 -27 -56 32 2 -39 -4 -7 -36 17 -5 14 17 0 2 6 20 1 -15 -2 -17 -16 45 31 14 -24 -29 -44 -14 -30 17 40 15 5 -18 3 35 -11 22 30 -61 -55 -11 38 -10 -32 -17 -37 36 -37 24 19 -2 5 15 21 52 -27 23 9 29 5 -31 14 -1 -6 10 19 -36 -26 -20 -17 -39 6 -10 32 -18 21 -14 -57 7 27 17 19 -17 0 26 -15 -24 42 29 21 10 11 19 11 20 -17 10 -24 -12 25 27 5 18 25 -23 37 40 -3 -12 -2 11 -45 -11 -20 -42 13 -3 18 -9 0 33 28 -19 43 -3 14 26 -26 -7 -15 18 -16 -13 -24 21 4 -13 -60 28 45 -33 -28 -9 32 -66 -44 -34 -10 -3 60 -24 -3 -39 -52 -56 -4 32 28 10 -27 -35 24 -19 -4 -1 21 -1 7 -73 -8 30 67 19 -4 -29 21 6 -33 -25 -18 -53 23 -20 -19 -33 -20 -20 -58 -12 24 43 22 -28 -47 -8 20 1 -16 34 14 -4 -18 -29 -2 4 -28 -9 7 -36 27 -29 -20 44 -22 39 12 -44 -26 37 -31 -11 -5 14 -1 -6 -22 13 -49 -5 74 -1 -40 -36 -3 -43 34 30 18 7 -44 -38 -63 46 -54 43 -23 -30 76 -37 49 -41 -74 34 -5 20 -14 51 -26 22 -2 -45 -44 -70 -50 -6 29 -44 27 54 -32 5 70 -24 -68 44 -37 1 -16 6 -25 29 -11 43 -24 68 -19 -16 17 67 3 -72 -40 -30 11 5 -2 29 -13 55 -21 29 -27 38 30 -41 -26 -59 -15 -38 -41 28 -64 33 62 0 45 48 -16 13 94 40 36 26 48 -26 -33 20 -4 -41 -19 -7 -35 -20 -24 12 15 -29 3 -2 28 -28 83 -43 45 72 -6 9 6 -30 80 -19 16 35 11 -12 11 -22 44 20 35 28 6 5 -18 1 -9 -6 23 -2 4 14 -1 -10 4 18 25 -12 -32 11 -2 -15 12 -24 -5 50 27 -2 56 60 66 21 -46 -2 36 -60 -23 -48 -42 -53 17 1 65 72 -47 84 37 -7 2 -31 47 15 20 58 -60 4 5 41 56 -12 1 -15 20 -33 -24 44 -4 -4 23 63 -42 -22 -46 0 4 -7 -40 29 -24 -28 -4 -29 -15 -15 20 22 -1 -9 -22 -4 2 41 53 3 8 -25 15 5 -47 -48 -59 32 41 -16 -12 -5 -14 4 -22 3 -28 -7 -62 18 8 -10 25 -14 24 13 -4 25 5 -29 -7 -3 -5 -10 -42 19 -18 15 -25 0 -3 30 -17 -18 -8 10 2 -15 1 22 -12 8 -39 10 20 6 21 -20 -1 -29 -37 -23 16 -26 1 90 -2 23 21 -6 5 8 23 36 18 -17 -57 -1 7 61 25 37 -33 -22 -60 63 33 14 55 -11 -67 -39 -10 -34 1 -54 -48 10 30 18 -20 64 75 36 2 53 -38 17 15 9 0 6 15 -25 21 -68 36 -13 -9 -9 50 49 0 -10 13 3 -1 0 -31 33 -32 -41 21 4 15 -21 -7 23 -6 27 -25 -2 7 -59 13 52 8 -53 15 28 -14 -28 53 35 -5 25 41 -1 -21 30 18 -25 -48 -42 40 -23 30 -8 -16 -23 15 -23 2 -34 39 1 -20 -20 28 44 -4 -37 -33 -20 13 28 35 28 52 -15 -27 -4 7 6 -36 -29 -13 9 5 4 -27 -26 -37 44 -1 -70 33 20 -53 -24 -34 35 -57 6 -42 51 -81 51 34 49 -1 11 49 -25 -8 7 -45 65 46 -4 -23 30 -57 52 33 -11 -42 -21 4 -56 39 -10 -6 -13 -68 -32 -12 10 6 -75 57 3 -3 5 -24 -52 -29 -1 -42 -19 19 -5 -38 -21 -73 -38 -32 -33 12 44 5 -2 -54 0 -22 16 8 -2 -2 -7 8 11 35 -5 -65 -25 8 1 22 7 25 11 -12 15 15 8 -21 2 10 -3 -2 -1 -14 -19 -21 47 -39 18 -37 -31 -17 -9 -16 3 9 -23 -9 30 -40 2 -15 11 -26 -27 -3 36 -3 27 -30 14 -16 27 -22 6 -19 -20 -30 -37 25 -13 -39 -26 -33 -43 -24 -15 22 -14 -2 -41 0 27 19 -28 -14 -16 -2 26 -39 -31 15 -17 0 16 -8 0 72 10 38 -38 -36 36 -15 -58 34 10 54 21 60 0 -23 33 0 45 10 -43 -46 -5 6 40 20 -32 13 6 -38 1 10 -67 7 -41 0 -18 -16 27 19 -28 -42 42 -66 -33 -17 -9 5 50 -18 76 -28 -41 12 -34 53 13 -13 -14 -18 -16 -35 -21 42 -2 -15 28 -5 18 -7 28 0 8 -25 -21 37 -14 -3 -27 11 -48 -30 -21 -22 37 -31 31 -10 -8 -14 -33 5 -11 -17 -8 -49 -33 -20 32 -20 -14 -39 29 -7 14 -25 -29 0 37 -8 -6 -19 -46 -42 -22 12 -35 4 7 10 1 20 -31 -37 19 8 -22 -62 65 -4 -17 63 -2 10 -7 40 34 -25 11 45 100 4 19 -46 -26 -50 -14 -16 48 -50 -24 27 -54 -18 103 19 7 23 -50 33 -63 -26 -51 17 -36 48 30 -61 -5 -3 30 -54 48 -31 -23 3 18 -26 -16 16 8 -5 -43 -6 5 -26 -9 65 61 -6 -7 32 -47 27 -1 -41 25 37 -15 2 -6 -30 40 18 3 16 28 -22 -11 33 -58 -34 -11 -7 -29 36 -18 46 5 27 35 -34 13 -36 -23 -15 -30 8 13 -26 -7 35 -17 32 -26 -33 -28 13 -10 11 10 5 -36 13 4 26 -6 -40 -15 -14 -2 -6 25 9 12 27 2 30 1 -14 -2 -4 15 -42 -16 0 -9 39 -12 12 9 27 -15 39 -109 71 -46 3 -41 -12 8 50 -48 -6 52 -19 13 -5 -29 16 65 -41 -26 -64 30 -25 -34 6 4 -59 14 -23 -3 -21 3 -14 -26 29 -49 93 -14 -28 1 -29 0 -2 7 14 39 8 -15 -42 28 18 25 31 -8 1 29 7 -3 25 16 36 -13 -28 -27 41 -10 -43 35 35 63 19 30 -45 -32 14 -16 15 1 -1 -58 -2 23 7 0 28 -33 35 -7 40 51 6 12 -57 57 12 12 -29 11 -33 -42 -19 2 -16 1 24 -30 6 -51 31 -4 41 30 -18 -28 25 32 -6 44 36 29 -35 13 -27 7 -38 -16 -23 -19 -39 23 16 20 10 17 43 1 14 16 -57 23 -42 11 -33 31 6 4 -30 -26 37 -59 -13 27 33 26 74 21 -12 -37 3 -21 -35 -26 56 30 -4 33 -2 -17 -1 -2 31 22 -3 8 8 -62 0 -15 26 27 52 4 18 -9 2 20 -19 -8 0 -27 12 52 -15 -26 36 -8 37 -11 35 17 5 -45 49 20 -16 -11 -34 10 13 -33 42 -44 15 -41 -14 37 26 -19 5 7 0 7 -7 2 -3 37 6 -11 47 -8 -29 9 -16 37 35 -34 0 -25 -11 18 15 -23 -20 -32 3 23 -14 -22 -2 -8 55 -36 -24 1 21 -32 -3 7 -6 -13 13 -32 -2 33 12 -40 10 -6 5 55 18 -13 10 4 -39 -14 38 19 -22 24 -20 -26 -12 4 -8 18 45 16 -12 -70 -30 -29 -18 -40 29 -15 20 -7 -22 6 4 28 6 27 -9 35 -24 0 -16 44 -16 29 -7 67 -20 -32 -34 37 -29 -44 40 32 3 25 3 3 28 21 0 26 -27 7 32 -41 -40 -49 -14 -1 25 -25 48 22 43 -4 -11 16 -15 7 -37 -11 1 -6 -25 2 -51 -28 19 9 -3 -11 11 -43 23 -22 14 24 -40 36 11 6 -12 -7 20 -6 -10 -10 -22 -40 0 53 -13 32 -22 -14 -54 -26 -5 -23 -4 -15 -10 16 9 17 -21 -6 -40 -29 5 -22 30 24 56 -6 -9 -10 5 -18 -22 -7 6 17 24 2 21 44 -22 -16 -17 39 -8 -4 16 3 37 20 -7 -29 -17 -30 20 -40 4 -6 1 -62 36 -51 -18 -16 -41 9 13 12 39 -17 -43 15 -22 -2 -51 -7 24 24 -1 -26 9 39 0 13 29 -52 -79 12 11 24 -50 46 0 -86 -39 -30 -28 -35 7 24 18 -7 -40 -27 9 -27 -14 -4 -7 -19 -41 28 -54 3 11 23 -13 -32 -35 61 18 -10 -56 -25 -6 24 12 -29 -9 -18 31 8 -19 -57 6 -22 23 -48 33 -22 44 3 52 9 -33 -63 26 -14 -27 24 37 20 16 16 48 -11 15 25 -25 -5 22 -58 -20 3 -12 23 30 -8 0 18 2 17 29 9 -5 -10 5 -9 -8 -2 22 -23 -12 15 22 -26 -11 -8 12 -30 3 20 26 -6 51 7 -6 -3 66 17 -13 -55 45 -36 18 -28 19 47 -2 -57 51 47 54 -3 -15 -7 8 -25 -7 1 -11 -27 12 16 15 11 -16 -15 -13 -11 58 18 6 35 -58 21 -24 -6 111 -38 -39 -19 4 -2 -5 -30 41 34 11 -16 29 44 11 -31 -34 -19 -2 -4 -5 11 -35 -10 -7 -52 13 -10 5 -16 34 -2 -59 -61 -24 8 17 -3 -36 -10 -9 -65 6 -40 -51 -31 23 32 29 -7 12 14 -15 -40 -48 -40 30 -36 -54 -1 10 -45 -33 -17 -21 -3 11 13 12 -8 -31 17 -8 -19 -3 -36 17 21 6 28 23 -8 -38 22 6 16 14 -35 5 0 -2 -35 -2 -41 -16 12 40 -28 25 -6 12 -19 19 7 18 -22 33 57 -67 -16 12 11 14 -23 -11 -4 16 2 29 18 14 -47 -23 18 59 6 -18 -3 -35 -4 -11 -27 -6 5 30 50 -1 -112 17 73 -37 -21 53 -24 -96 43 -13 28 39 -23 -45 27 0 -100 26 -35 0 34 -19 -49 -21 -38 1 -43 -19 36 -66 75 13 93 -28 -12 15 -17 21 -17 -20 -12 -12 -14 -49 -43 1 41 17 79 30 -8 -15 22 18 13 16 16 -40 8 44 79 -21 10 -35 -21 67 -3 73 13 -32 -3 55 -3 -13 -45 -4 34 -17 -10 -10 -14 -11 -27 -31 8 57 48 -53 40 11 -15 6 13 43 -32 -2 47 -43 13 -14 -10 37 27 -36 -6 26 -11 -14 57 -18 23 32 32 -2 -66 13 -9 23 -18 -27 -3 8 -18 26 64 38 2 7 33 19 47 -12 -33 -37 -42 23 -6 51 109 5 38 51 -65 -14 16 -29 19 -76 -25 -29 -5 114 -84 -25 47 6 2 -15 64 45 32 23 -8 8 -51 21 13 -14 -4 -14 89 -23 8 14 -30 16 7 43 52 35 27 13 22 -17 44 23 13 51 22 9 -39 -90 -18 49 30 62 -9 -50 6 27 -27 1 16 -35 12 21 -62 -8 -4 -8 24 0 11 -34 -8 11 -8 7 32 12 -17 -23 -17 23 -19 -6 17 3 -7 50 -15 29 31 31 25 -27 1 -41 -6 -50 27 -24 3 -18 24 46 -53 49 -32 -56 -18 -48 29 -11 32 -6 21 -39 -42 29 48 -45 -44 -11 47 -7 105 31 -13 21 48 3 81 81 72 125 40 -38 -10 83 -11 -106 26 66 -17 -17 12 22 -5 -14 -54 13 90 47 -71 -18 19 25 -19 12 44 55 119 -61 78 -90 -28 -52 -34 -26 37 14 24 30 58 -39 -20 62 38 34 -53 3 -14 -23 -9 -16 -16 -1 -38 114 5 47 -31 43 -21 21 37 -16 43 -34 -21 13 0 -63 28 8 38 -16 -12 -21 -104 78 -21 24 -21 -5 8 -63 -7 16 -29 49 -10 -2 -68 -60 47 -50 -38 -17 25 -5 13 7 -43 18 50 -31 -17 -16 6 16 32 47 3 -51 -72 -17 -36 -66 15 -30 4 39 17 33 16 -16 25 -28 18 -32 -35 -1 6 -12 57 -19 14 -74 3 -39 -34 -43 20 2 62 -5 5 -37 -51 42 -23 -5 -34 11 11 6 -17 9 48 -8 -18 16 34 65 -5 -12 1 -1 49 44 -55 37 30 -31 31 -20 23 49 3 -22 -49 -22 19 -7 -37 -22 24 -6 24 4 56 82 -29 53 -1 9 12 67 56 -5 31 11 7 -10 -28 -44 -7 -74 -16 -18 -23 81 1 -75 -45 -9 -47 4 -37 -60 2 -3 -2 -86 4 1 -2 6 -8 62 10 -4 -36 19 37 10 -22 -68 -7 11 -42 -31 -41 35 -61 52 -17 0 -51 -48 19 -22 -15 -23 2 -27 37 -39 -74 22 -23 18 3 -27 -21 18 41 18 55 -2 -28 -1 -4 37 64 51 37 56 -20 8 26 -17 34 -16 11 20 -48 29 -9 -21 0 37 -9 11 12 5 42 -6 -14 -1 33 -27 18 37 44 28 24 0 -22 -36 11 18 56 17 -24 -16 -34 -29 -28 -9 -14 19 8 0 2 -1 -33 -59 -23 43 -41 -1 0 2 -44 24 5 -38 -28 53 2 -30 -17 -56 -13 43 21 -36 15 -19 -4 33 -44 0 3 23 -12 -22 -1 2 16 16 -18 -15 -40 -36 21 7 -13 -14 10 1 -11 -22 30 -35 19 19 18 -24 22 38 4 -32 16 -22 -14 -13 -19 -6 -32 17 32 -12 -40 13 -7 -29 -31 2 -21 0 -22 19 -34 -21 0 9 11 27 -5 1 19 -19 -6 -18 45 21 -3 12 79 17 -27 23 5 -43 -54 73 -42 -15 -28 -24 52 -27 -77 -73 -106 -32 -48 -20 -75 31 -30 47 -43 -123 3 3 8 19 29 -49 -11 46 14 -6 90 116 7 -77 58 -43 69 34 24 -2 28 40 -10 24 -26 37 8 2 -7 46 58 81 58 14 -38 19 -74 1 16 -26 -14 -18 32 40 38 -19 32 20 46 70 5 -61 -8 -40 14 -44 -64 19 33 -27 9 29 25 69 -20 37 5 23 32 -76 -55 -9 -94 13 16 15 15 -35 -2 20 41 17 -24 -41 -6 11 24 10 7 -19 -65 -26 -8 33 -9 0 96 45 32 -16 3 21 14 44 7 -37 13 13 31 7 -29 -14 70 22 21 4 54 24 -11 -41 -31 34 -3 -24 -41 -6 7 -3 -9 -8 10 -16 8 -34 -15 10 3 4 -1 3 9 -11 -17 15 15 -32 -40 19 -13 -16 -16 -3 -10 6 5 3 17 -41 13 22 -1 -22 7 14 40 4 -15 1 54 5 -30 -7 -27 0 7 -5 10 -13 12 -32 -25 -28 5 2 -55 50 -10 6 -20 -18 -13 18 -18 -18 36 6 34 14 -5 25 -23 8 -24 -29 26 -55 -13 21 -41 10 16 1 6 -15 4 14 -6 5 3 -8 -26 -10 5 -5 -3 9 -19 25 -11 20 -23 5 20 -5 -17 -17 5 16 5 8 10 -18 -10 19 -13 21 12 8 -12 -8 14 -25 26 0 4 -24 -11 41 49 -5 77 42 29 42 14 10 -22 -39 -20 14 -34 26 -3 -3 -3 34 -27 -21 -16 -30 15 13 -38 34 14 68 70 26 -5 -5 11 13 -41 15 3 -1 44 -3 -50 -6 48 -9 -29 18 63 -14 6 18 16 38 33 -13 -70 27 50 -48 -47 -32 54 -45 -31 -12 29 -32 57 13 -10 -6 -25 1 -1 41 46 -33 -4 -4 17 29 -15 27 30 48 23 21 -13 21 -32 -11 -3 67 -3 44 -11 -14 -30 24 10 11 0 -3 27 43 3 -36 -34 -8 6 -41 2 -4 -1 11 3 25 11 -23 37 -25 -20 11 28 -41 25 -24 -29 -23 20 14 17 12 12 -31 5 33 -5 -4 -12 -28 -32 2 -12 55 27 -70 -3 -12 45 -56 -44 -26 -11 -30 25 -30 -28 9 -1 25 31 17 -44 23 17 -40 -16 -75 -35 -53 5 -20 -65 25 11 -2 57 -47 22 -22 -40 -21 -27 -1 -64 -21 0 34 82 9 124 -35 -78 44 14 59 -11 -8 52 0 -4 15 -44 -1 -22 -56 -17 14 -6 5 1 27 -103 -11 -3 6 4 -63 -30 -67 37 5 27 58 53 -26 32 -32 24 -22 2 -51 17 25 -30 26 -68 10 -44 40 -25 -24 -23 25 -10 33 35 41 5 19 16 42 5 -8 -23 2 -37 -11 -2 20 37 42 22 6 -15 -33 39 -46 40 -53 33 15 62 -37 -27 6 -42 -5 -20 20 -9 5 -41 60 -61 35 -9 13 -45 60 25 1 41 6 -17 39 7 21 65 -66 -22 28 3 -27 44 11 -51 -1 -17 4 19 -52 -87 -24 -23 -84 -45 29 29 -25 -13 -33 10 38 -30 50 40 13 16 -9 18 -31 5 15 -99 39 9 -45 22 89 -24 6 13 -57 79 -21 -62 -61 -57 35 -57 60 29 -4 -51 22 -25 32 12 -56 -48 40 -13 33 23 -89 -39 -31 -54 -24 -8 29 57 35 -4 -27 -13 93 58 -38 17 -43 -1 15 -46 -37 -7 -65 16 -27 12 11 11 -6 10 -54 13 29 -13 3 -41 29 -19 29 10 27 13 20 -20 -7 30 5 31 -27 -49 11 23 -43 26 -35 -21 44 9 -8 -16 34 10 -42 -48 17 -34 32 58 28 22 -33 32 48 68 -5 -27 38 -4 28 57 6 -9 33 -27 -3 -7 7 -53 10 15 28 -2 -40 -5 -29 -38 -28 -26 -3 -33 -21 -51 92 -47 21 20 -49 -3 -13 21 -7 -70 8 56 23 4 46 36 -9 38 -2 -37 55 -50 59 19 -46 74 3 -34 55 24 22 26 -47 15 84 -9 -27 62 -20 -44 -54 53 -62 9 12 -9 -75 -27 74 -34 0 -2 41 -18 68 29 -6 -32 -30 38 2 -68 -12 39 19 21 62 34 36 -7 -3 -2 14 1 -12 -36 -34 9 -11 -33 -31 0 -12 -23 17 -9 -37 -14 -47 -27 38 71 10 -27 -45 7 -42 37 -4 23 -66 -11 2 -37 55 44 29 -61 41 -54 19 -7 44 -18 -60 -15 -29 -49 28 36 -106 -33 12 -11 -49 37 23 -23 10 -34 -58 -2 23 -26 73 -48 49 -49 -68 44 78 41 41 40 82 5 -25 -45 -19 -53 34 26 40 36 8 -40 -26 -13 -28 -9 65 63 9 24 -61 -43 -37 -14 96 5 1 9 37 -49 40 -32 33 60 -58 -20 47 56 7 2 41 -9 -67 -101 -32 12 38 36 68 -45 17 51 -67 -86 -41 -2 -34 23 -12 37 3 30 69 61 -1 11 -10 -35 1 -26 29 19 68 -5 1 -10 33 -1 -15 22 -15 -26 7 -54 11 10 55 -35 49 37 45 -47 -35 36 17 21 -61 17 -55 24 -110 -31 15 -45 -23 48 25 54 -127 -8 48 89 33 -71 73 105 -45 127 66 52 -126 -127 -56 -50 77 44 -38 -33 -86 44 5 -16 -10 -81 13 -8 -54 61 63 -21 48 -37 38 51 12 -19 -114 -49 -43 67 -72 -15 -33 -127 -59 57 -24 6 -125 -2 -105 28 -13 -126 38 -43 36 -128 -79 77 -38 -71 15 64 -72 85 20 17 18 -127 36 -19 -101 -23 37 104 73 28 63 -83 -54 -27 80 52 -71 102 92 -35 -7 -57 69 56 -68 34 -81 37 127 127 -24 -71 98 -67 80 -66 73 54 -80 86 70 -6 52 52 6 -19 -99 23 -85 73 88 71 29 -68 17 -14 55 74 57 -71 -7 31 -71 8 71 65 -40 99 52 -70 76 55 -23 96 -88 -22 91 -126 10 19 -40 -124 -22 78 -21 -63 -39 -100 56 13 -111 78 -72 -2 -123 127 73 -41 -26 -7 -69 -40 46 -37 -103 21 45 -107 12 76 68 -29 73 -111 -32 4 -75 8 -22 28 35 -78 -92 35 -128 -47 -128 17 22 57 -119 94 -89 -49 -7 -39 127 54 -24 -33 -30 49 38 64 65 -61 5 115 0 127 52 -2 55 106 -83 63 30 32 -42 16 15 15 21 35 5 -30 31 -66 -100 -61 38 29 17 -45 2 -41 -74 68 1 0 -14 -48 123 -36 11 72 98 102 -2 -72 2 -127 127 51 44 56 -43 -54 -85 -63 9 -32 -47 41 -105 -32 -20 100 68 21 1 55 24 17 -55 -24 -38 -40 -59 -65 27 66 121 -11 -35 -92 6 120 93 25 -127 -24 43 -51 33 22 13 35 -81 4 8 -45 -122 -37 -33 47 -122 -127 83 64 11 37 -79 22 -49 -81 -66 -128 -57 -2 -111 -34 -18 -111 -109 62 56 -16 -20 -94 -128 9 -41 -126 -26 61 -127 32 -12 92 -33 -59 -54 -78 -67 -1 -16 103 66 -52 -97 74 18 61 73 -14 -30 -1 122 -98 -15 -126 -21 31 52 -96 20 -19 -51 70 66 54 -97 -128 -21 -32 -128 -76 -37 -45 14 14 67 -38 -15 -18 -76 121 33 42 90 9 -9 -18 26 30 -21 35 105 16 106 -2 75 -5 79 -55 18 6 2 -127 -58 81 -123 65 123 -32 25 -7 -76 -63 63 -127 -65 -16 -33 -96 -84 99 -64 -40 -59 44 98 85 45 -30 21 56 -127 -78 38 -79 -4 123 -101 -2 -127 -126 -32 95 -93 -127 -17 -128 65 -77 -112 -96 -48 -71 100 -128 -35 124 -103 -126 91 -65 -117 -56 68 98 -81 127 26 31 -82 12 -80 83 -10 -78 127 53 -77 -8 -59 -62 40 -25 -128 45 0 25 -17 2 123 -87 59 -29 125 127 67 9 -105 -45 -52 2 6 48 45 -21 -8 39 21 48 -2 15 -46 50 45 -47 -54 108 127 -37 -19 -42 63 0 118 58 -11 90 -73 48 -47 65 -23 -31 -104 -29 116 96 117 13 126 -41 -6 127 -125 127 14 -71 -43 21 -59 97 13 -56 44 -126 69 -32 -19 -128 -23 -127 6 -36 -67 126 -47 -54 69 126 -126 -115 -7 6 -48 84 -113 34 -62 79 -102 54 -77 -98 -40 83 -94 114 121 -80 127 101 79 -72 -65 -34 -68 -6 -15 8 67 4 5 53 9 19 -33 -112 65 -2 48 -1 -100 -73 31 -43 -46 -123 -127 -43 -106 11 -17 -71 -36 -59 36 7 -48 -126 9 6 -43 26 -80 7 127 -14 81 -116 -46 -72 40 -128 32 -108 -80 37 -43 -35 -128 49 1 -128 104 127 -40 -125 69 -24 23 108 -74 -55 -72 -59 -61 -2 -28 10 98 -36 42 15 28 -26 -50 59 -24 58 -41 0 5 -59 18 29 -97 -126 -71 -114 102 -55 -118 114 -64 127 -58 125 -34 -3 29 -35 -41 -115 125 127 -60 -50 112 54 -43 -65 -90 -22 -30 -17 -127 30 -31 -4 -127 1 -52 101 -125 108 -15 -79 43 47 -126 126 72 23 99 127 -127 -38 -55 -46 -104 27 -51 -12 -35 -126 -21 -128 -123 -76 41 -127 127 -10 124 -18 -90 -8 -34 -84 -6 73 -82 53 -91 -34 -100 -75 -111 57 41 -127 -24 -127 -93 -38 3 -84 -128 -19 2 -3 127 120 115 6 -71 -25 48 -24 20 -42 -25 44 59 81 41 56 127 18 -128 -6 79 28 -126 -26 -31 27 -11 64 -69 -77 54 -101 101 72 -58 -85 -45 -59 107 127 -128 60 46 -127 19 -72 -103 37 -128 127 127 -26 47 20 20 -39 52 125 -68 -57 4 -13 47 40 113 -59 121 -1 -79 -41 13 -127 0 -124 -34 -16 68 21 38 125 -96 -13 -30 -127 42 89 -73 33 93 22 -112 -125 10 127 -71 -28 -29 -27 -66 68 127 76 -49 -124 40 -127 16 -89 -22 -79 -115 -83 -54 -98 25 -78 17 -109 104 -83 90 -28 -46 45 -128 79 -88 -16 -61 -12 -30 127 33 -114 -72 -7 89 -69 5 4 -128 -20 -6 -38 -80 82 -126 -25 28 7 24 -98 -7 -95 -86 -8 -3 -52 -22 -9 -68 7 -29 85 127 58 -44 -11 -12 127 -87 -48 -23 -23 126 -109 91 4 67 95 -61 -7 -23 -65 59 -63 -14 42 53 -23 30 22 -67 -118 -97 27 -103 -20 -73 -8 9 127 22 -36 -101 -14 -62 -51 -73 -1 77 -52 -23 127 -124 -20 -2 -41 6 3 -27 30 -2 58 15 -52 123 -5 127 -128 104 -87 -125 -57 -127 -126 -12 127 -42 -124 -40 -56 -80 38 37 127 -12 -63 -128 -128 85 15 -74 -23 -109 -46 -104 -124 -15 33 -72 126 74 -115 96 -23 -101 -31 -127 101 -18 -76 -116 -127 -7 117 -126 46 86 90 51 8 60 -127 52 20 -71 67 -53 79 12 91 -62 -5 -34 -10 -127 108 -89 -19 14 98 89 -82 72 -124 -13 86 112 124 48 0 38 -64 -39 -50 -12 16 63 -44 77 -1 124 -59 -2 -78 124 73 -39 6 1 -27 20 117 -117 -81 -5 -33 45 43 -50 120 -63 -68 127 127 -70 122 20 80 -4 -64 -3 16 -92 -95 124 98 23 127 49 11 -17 127 72 -41 105 -4 92 119 101 -39 -63 83 73 -1 -28 78 5 120 109 52 -65 -21 -118 -87 58 34 0 29 115 13 30 -90 -44 -36 -128 39 -62 114 112 -105 9 127 124 -33 97 -10 -117 -66 0 105 -128 61 17 -14 -35 -86 101 81 66 -22 1 120 -57 36 -71 -53 -62 -62 38 120 -113 122 -4 -45 86 122 127 81 -19 42 -6 34 43 -10 124 -128 102 36 -20 125 127 32 106 10 -126 98 -36 -64 -127 -92 33 -127 -30 -99 23 -77 42 -45 118 -28 -62 -2 111 116 -82 -36 -6 -52 27 54 -31 -47 3 68 -127 -78 -11 102 -74 106 73 -94 14 -127 -4 105 -35 124 33 -51 109 40 127 77 81 97 65 -64 33 126 -64 59 21 52 19 127 -9 -28 39 125 -27 -19 -33 20 96 127 -19 41 -74 31 -17 5 -89 -38 41 -127 -122 -45 -128 39 17 21 124 -88 -25 -7 127 -109 -123 85 -28 25 -121 -1 -125 -69 28 -58 -112 -104 -23 -83 -15 -61 5 127 -11 81 63 99 -88 20 93 27 17 -74 119 125 56 44 89 20 -94 0 55 -2 127 124 6 -126 -101 62 12 -34 126 -121 126 127 -70 -127 -106 10 -117 -18 127 -128 127 11 93 -126 -20 -97 -122 118 123 -40 127 18 68 -86 61 1 5 -71 12 -57 -32 123 19 -61 -108 12 -18 93 85 -81 -119 -105 26 126 -100 89 89 -127 115 -101 -31 -44 -127 102 81 -78 -127 -110 -38 127 -20 -41 -103 91 -71 116 -47 79 -109 34 -66 -74 53 -65 -7 111 -14 37 -94 127 -128 3 -88 -128 -54 -110 -128 -5 -121 -106 109 -123 7 102 127 -46 115 -62 -50 90 -33 -51 85 -56 7 125 -36 -123 59 -23 31 4 75 -64 -82 52 -11 92 75 54 29 -42 61 103 -16 116 -19 -28 126 -44 -90 -107 -4 106 -1 8 119 -4 63 16 -104 57 -37 90 127 -119 -127 -122 127 -128 -60 -5 -13 -52 -48 -69 127 -39 -102 -109 -24 -76 -107 16 118 -20 27 -39 18 -63 -63 113 -11 -127 -30 -75 19 7 111 82 -10 31 106 52 31 4 28 -34 -33 9 -6 -109 51 -117 -19 -72 60 85 127 -76 -123 14 -56 97 127 8 115 32 -5 -64 31 1 -127 70 115 -31 67 10 26 -28 -3 56 -127 127 -127 64 123 -128 -37 -12 62 35 22 75 127 -128 -114 -17 -9 -46 64 72 119 -26 -127 105 -34 15 32 23 -85 -85 14 127 30 21 103 122 98 -78 127 -127 -98 126 -6 -27 -103 -72 102 -31 -77 -56 126 124 58 -56 38 -33 12 -82 -17 -125 75 -20 13 65 113 127 -2 10 -30 -120 85 36 -102 -65 26 86 115 24 71 -5 -125 -127 -24 70 123 -35 127 -10 28 -10 -125 -126 -70 48 127 70 15 79 62 127 -29 127 102 35 2 -123 -66 -99 11 80 64 -128 -104 -101 -40 -30 111 -109 61 -124 121 122 -7 123 60 116 56 126 -71 -43 11 85 -2 44 11 -117 -32 -123 69 -11 81 -62 -65 -84 -111 52 -106 65 -29 -128 -102 -43 33 -63 -44 38 -127 5 19 25 -91 -27 -83 92 -6 9 -79 52 -55 -64 -98 -117 -64 -126 33 -126 -41 -99 70 125 -69 -3 69 -58 -53 19 20 -121 -99 -84 80 -73 -30 10 10 113 38 -91 25 -67 58 -78 -46 -33 -126 0 47 -98 -37 -15 127 -38 -44 8 -15 13 -1 -24 18 5 -33 21 6 -42 -58 -123 27 -17 -26 10 47 100 41 43 -21 -24 59 77 30 16 -39 126 19 -128 30 111 121 -101 64 -7 -77 -127 52 -91 82 114 76 -38 -121 12 -125 10 32 37 91 117 10 30 -43 64 127 122 36 51 -118 8 -127 19 0 -127 -109 -50 40 -38 107 -12 -12 25 -122 102 -121 98 -74 52 22 -125 -115 -120 -54 -75 -114 -99 26 40 -2 81 -127 64 85 -5 -12 8 -118 -56 -8 127 -92 45 -26 -85 -25 48 22 -11 -43 77 14 1 -2 -36 33 25 38 41 -22 -90 -80 -20 -29 77 48 -67 41 20 -21 60 0 -26 -125 2 -47 -127 -92 -77 127 -55 4 120 113 -128 21 -75 -86 127 -104 -80 127 -128 94 -38 67 111 -56 -82 127 106 82 -94 -87 72 -54 76 53 -24 18 -122 -126 -49 10 116 -58 113 114 -77 119 76 -91 -102 -13 76 -103 -69 -123 -30 -72 -23 -19 -92 -39 -102 -128 124 -80 85 2 -69 16 58 50 104 -126 -117 117 19 -124 -50 52 -126 92 112 -63 57 21 -60 51 106 127 91 -51 -44 -42 47 -55 -34 127 59 -125 -46 -18 123 -113 93 126 115 -89 59 -63 37 -127 71 -88 124 -29 61 -116 -67 4 -42 68 115 14 124 -22 113 117 -8 56 -114 -91 70 -128 -56 -74 85 65 30 -21 125 75 77 -9 115 21 -57 -65 -127 -97 32 -100 14 78 87 15 -14 -126 -109 89 -48 127 127 29 -49 127 27 106 64 -45 105 127 95 125 -84 8 -36 -1 -121 127 -108 -116 127 127 121 20 127 -108 84 126 75 -71 -50 107 -124 43 50 -21 -22 -72 -67 -112 17 23 -55 -112 112 41 -6 -102 -19 -32 116 -127 -104 -50 77 56 124 69 85 80 -127 23 -60 -7 127 -37 60 -97 14 -115 -57 30 -66 90 -81 -7 85 112 -3 99 70 127 20 -24 -69 127 -69 97 126 -15 -11 127 -68 -23 -14 3 -121 109 113 -70 -97 83 -128 -28 23 -97 -128 -5 -31 -128 -103 -70 37 44 -65 -49 -69 36 -127 26 126 -46 50 -54 72 -19 127 125 -39 -15 127 126 28 -94 -33 119 16 -30 33 36 -102 -96 -83 -86 -90 30 55 -106 -39 -69 -106 -31 -64 -71 -127 -75 45 -119 -44 99 122 -127 73 -34 5 100 56 -43 127 127 -123 -54 -2 -110 -128 66 127 -127 56 -25 -33 14 -30 -26 60 45 -24 -98 19 19 20 -67 -55 5 -44 85 -19 -41 -17 123 40 -47 54 -5 47 -12 3 -25 45 -75 3 -69 53 3 -69 47 2 -53 38 -10 33 28 -9 -20 -78 -42 28 59 15 -17 -55 127 5 13 -41 6 -49 -34 36 67 89 12 71 -12 32 -6 -27 -43 19 10 48 59 -24 -81 -15 20 -28 -10 23 79 40 37 -83 -36 -18 -94 -23 94 60 55 -17 127 3 10 -30 56 20 33 115 -85 -28 103 83 47 16 21 80 22 -7 -95 31 -35 48 -74 28 -37 8 -49 -74 -17 16 -16 72 73 -61 14 14 -65 49 32 -3 -23 61 -18 102 -65 1 14 -35 50 19 -96 23 24 -58 47 -1 -25 16 -24 -90 -124 43 21 -78 -20 -45 15 -84 29 -66 31 -8 63 8 -44 -12 -34 -8 -5 2 26 95 7 -48 -45 11 47 -71 2 29 49 -49 84 -39 -32 -1 127 -127 52 -122 74 19 105 -49 127 -16 48 -127 11 -65 60 19 51 38 -85 126 6 -23 -67 64 -55 -126 63 -58 7 61 -37 106 -25 -66 -4 -95 127 -42 122 -61 4 -32 83 -7 -73 -107 -2 -1 87 1 64 -55 -38 27 -29 30 127 39 -8 16 56 6 -10 126 -13 -17 -46 20 -38 -42 26 108 -127 -9 27 -19 -25 16 -5 44 70 -49 38 8 14 -4 64 -48 -127 52 7 -61 35 43 -7 22 60 -71 89 -4 -33 -2 51 30 36 -51 2 20 -112 4 -30 -3 80 83 -115 -39 20 -63 83 -94 15 -25 -26 118 -127 121 46 55 20 -10 -33 100 6 18 -37 60 -10 12 49 -18 -50 -76 12 -63 55 124 52 -44 37 22 115 127 -57 127 36 62 -36 32 -65 125 125 -80 88 -45 27 51 62 -65 113 20 -13 11 -13 -57 -61 -105 -9 126 13 5 -66 -15 34 127 14 -11 4 65 44 -27 3 77 -125 -121 28 -44 -10 -98 -11 -128 20 66 -1 -2 55 -3 27 42 -55 26 127 -19 48 -52 -33 22 -17 -17 7 -59 15 48 55 6 -75 27 -62 26 -5 21 -13 27 -45 -4 -7 -124 11 3 55 -106 -14 -32 43 119 -75 84 -104 46 8 44 7 114 -122 -128 -120 25 63 18 -44 63 -12 81 52 39 42 11 -14 125 50 109 -65 -64 -5 -58 80 77 109 -68 56 88 9 74 -125 -23 13 74 -22 -79 -8 -64 2 52 -20 40 57 116 106 -37 -78 125 -125 1 -30 114 40 -82 -78 4 -17 -51 108 -124 97 75 54 -48 -42 80 3 5 -65 -2 -83 -22 -127 25 -15 -50 30 -82 -127 33 -6 83 -109 -114 -127 -125 -35 -83 -79 -128 -3 49 -27 123 3 90 27 60 -102 -7 8 -39 -54 56 21 -24 -8 -70 112 74 73 -116 -13 68 -121 38 -126 -102 -17 43 -123 125 -54 33 127 126 -13 -1 -19 112 -47 -29 -20 -46 30 -31 36 -56 -126 75 -128 127 49 78 -25 -21 -58 0 8 -36 18 127 -41 -35 117 87 -52 -99 -11 125 -115 123 -25 -2 79 -47 46 46 -124 29 98 126 -21 21 -94 13 21 -120 -7 -127 -89 13 -14 -26 -46 -73 16 64 -42 15 81 83 47 -7 -63 117 -44 -71 -123 -25 -65 -2 52 -128 68 -50 -109 -12 -77 30 8 23 -19 75 127 -24 -128 -6 -14 -12 15 -123 6 21 -6 106 123 37 -128 74 35 8 -1 16 17 127 18 1 -20 53 87 48 7 -77 -15 -35 -57 74 -51 -94 -10 35 -106 -4 -33 -61 54 38 -98 -94 60 127 20 -44 -30 -62 -92 -31 -17 -101 44 -60 64 106 57 81 -42 -72 -57 3 -69 -65 69 -5 -9 -30 110 -42 -61 24 -90 -5 -31 -16 -62 -93 -41 -36 -87 112 32 -3 -128 -19 -34 123 -44 -40 124 -36 124 0 -125 -64 29 117 127 -26 -113 -5 69 3 7 -14 -81 55 -19 48 -80 74 6 -50 93 -38 -54 -52 -128 -49 55 91 -88 64 127 -49 34 45 42 -60 112 125 48 -48 9 -54 47 -5 102 -112 -94 25 -7 54 -35 38 -19 -81 -35 109 30 -63 -99 43 -124 80 49 43 -41 -28 -24 97 -27 48 20 -7 52 -68 50 26 -7 33 36 -73 66 79 5 -109 126 84 41 127 -65 45 -2 72 121 0 -41 26 14 74 -12 -78 -114 127 -49 7 126 3 -74 124 -94 117 14 -46 45 -28 65 -47 13 47 48 -9 -5 54 1 -58 -39 68 -16 14 -61 -18 2 110 28 -53 52 26 67 57 -19 -78 -6 -7 -2 -25 -89 -15 17 122 -47 12 -32 -1 -24 -95 -48 55 -59 -5 6 -29 8 23 -17 -57 55 71 24 -22 126 27 39 -17 -32 70 21 -127 -39 -7 101 2 46 54 -20 -116 -40 -24 -127 -24 33 22 -58 40 31 -65 -10 -124 20 123 125 -49 25 -58 -17 -22 -66 17 -63 -11 8 -1 -79 -124 114 23 27 11 -1 26 -1 -29 11 19 -63 -19 -64 48 64 46 -21 -20 49 79 56 -5 -95 10 9 -19 -37 58 -86 -19 53 10 76 32 -109 -64 -10 -37 10 -28 -70 42 -62 38 118 -13 -20 -6 -21 37 -32 -39 127 -11 -26 -57 -16 -123 -27 -5 54 -29 -84 30 0 -49 58 37 54 -57 35 -98 77 78 -58 -107 -119 -51 70 -83 -45 -14 42 -39 79 -35 -20 56 11 -12 23 -29 -26 32 1 -18 29 -119 114 -62 -19 -22 1 -55 -36 127 64 1 -62 3 40 -48 -57 54 -26 -19 77 22 -51 6 61 27 101 -128 -33 -48 14 36 77 -18 103 125 -13 53 95 2 -19 -104 111 48 7 62 -65 -7 -77 -34 35 24 -31 -20 32 42 -40 -68 114 69 64 72 -49 50 -6 -61 127 101 2 -102 114 73 -24 -37 70 53 -50 41 -74 39 -82 -18 45 115 124 84 -5 21 -32 -76 -40 43 -128 -21 51 -52 10 20 11 -60 74 -2 127 -56 -56 -20 -19 -32 -59 70 -101 65 -18 -5 7 48 122 80 -14 -5 -73 45 -7 51 -10 19 -10 -126 64 -64 72 -127 9 -62 6 75 -26 -63 -45 74 -5 -100 32 115 -65 3 -59 54 22 -41 -17 -3 18 90 8 125 37 -67 8 -53 -1 -82 16 71 -3 68 115 35 38 85 -15 4 95 56 -39 -24 17 11 -115 26 12 24 31 -63 -127 -105 120 51 3 -19 119 82 32 115 22 -55 50 39 27 127 -98 -34 -83 50 -20 -112 -15 114 -15 -78 94 -127 0 78 0 -12 -30 3 -14 -33 81 -14 53 -14 118 15 35 113 -110 14 40 -9 -10 33 33 -40 55 -16 2 -76 -28 -4 7 67 42 -96 -49 -87 30 -54 96 -72 26 40 -16 122 -2 13 10 -15 -100 82 -50 -50 -30 19 21 35 -27 59 43 30 -73 -17 50 42 52 -43 24 -95 58 8 -23 84 -45 -20 0 71 114 10 73 -122 106 34 -2 15 -15 35 127 47 -68 31 -119 -10 27 36 -65 4 11 -47 -58 -122 98 -19 -40 -79 -18 2 88 -18 -15 -42 -64 -66 -55 35 -113 -53 -87 28 -127 -95 -28 -70 107 42 -3 -52 -34 -63 18 85 -8 69 -48 -75 20 51 123 22 13 13 -21 36 42 -109 42 23 10 4 -48 -12 -53 24 90 -26 77 -105 -17 -9 -24 -55 57 13 -89 -88 -39 41 -122 45 -20 -63 81 30 -58 98 34 70 -33 5 62 -79 83 87 86 -97 66 -73 6 -52 -111 -65 54 -62 -63 -5 102 -1 -49 -37 44 -39 -20 63 2 78 65 -44 -82 -19 -15 43 18 -38 127 -124 81 49 88 -41 -54 -13 122 -7 87 -43 125 -65 5 22 -52 -35 27 113 67 1 127 -89 -65 -82 54 49 -68 34 49 68 -14 102 -8 -75 64 13 63 86 34 114 80 -33 -25 15 -35 -64 -95 -118 -22 -98 73 -50 -28 56 -46 -112 -49 2 71 -101 -20 -27 -51 64 -2 -18 60 66 -77 127 -27 13 -41 31 8 -75 81 -52 -49 -97 -84 8 72 -3 -99 -111 -41 -14 91 -36 -6 122 26 -122 -67 46 -79 5 -69 31 73 44 3 -13 40 78 -57 -87 102 -27 -39 125 4 52 -31 105 -115 -32 113 -24 72 10 -127 51 68 -60 -30 11 -119 41 113 14 36 -102 38 -86 38 20 -97 -25 70 45 -6 -54 -9 -27 -112 -23 42 -11 113 -9 -39 -20 -111 -55 -27 76 42 -103 -36 52 -10 -89 -52 -115 104 46 -126 -91 -73 -96 -63 34 127 109 -6 -67 -37 31 -9 -54 34 -68 -41 116 -5 120 34 -70 54 -6 -71 -74 -124 -69 38 126 5 123 85 92 127 64 21 -4 -62 56 -60 -10 4 10 57 111 45 19 -2 -9 -46 121 64 105 -2 -105 127 -30 -39 -39 68 -58 108 127 -88 -33 108 64 -23 -7 -43 -7 -97 -63 -52 -69 -72 -51 1 -65 93 -128 -77 -47 46 -119 6 -100 -6 -105 -41 -128 -4 -17 -125 -33 6 40 -10 -127 -46 -105 -37 -52 22 18 76 -70 -33 -82 -46 83 127 42 -70 -19 -22 -99 5 66 10 -20 58 94 -19 122 112 -50 127 105 125 122 15 27 127 126 -24 -127 -67 -27 116 -27 103 -9 -53 -72 64 120 61 -122 -34 9 12 50 -100 90 -122 40 -44 127 13 -29 74 -55 94 71 39 -57 126 -54 98 -126 77 37 -67 -65 -27 121 -106 12 41 -21 -127 125 9 -127 -6 127 -25 -81 16 -92 52 30 41 127 26 -123 126 -45 -19 -15 21 78 9 -32 -65 -67 85 -9 97 -10 39 -12 14 -115 30 -59 -43 -3 73 -39 41 11 87 8 -91 -6 123 -107 -3 -121 127 -127 -102 -107 -38 -90 -21 26 75 44 60 -124 -69 -82 47 -109 -24 -62 118 -104 -23 34 -25 64 73 3 82 13 30 7 -2 118 -24 39 -18 90 126 125 112 -11 119 43 113 108 8 -68 112 127 7 -52 -33 30 103 -53 126 -12 35 -61 -100 88 38 -80 -60 52 -56 6 45 113 -39 21 -58 127 80 -26 76 15 -74 2 23 60 103 53 42 -31 -61 52 62 -81 -60 122 59 78 0 -57 6 69 -63 -27 -20 127 29 -125 36 30 -59 -1 -8 127 -49 -57 99 62 11 31 -2 127 49 5 26 34 80 -46 -86 77 -70 77 2 34 45 67 -70 37 110 63 -46 126 61 127 25 120 23 -90 -7 93 -44 -65 37 -79 -38 -65 22 -17 38 67 126 127 -35 -26 19 5 -39 -48 17 75 75 29 -37 37 -82 -126 16 -32 34 -13 -11 122 -46 -20 -84 -127 127 79 -70 70 -74 -125 27 18 -116 -127 80 36 -29 59 58 -29 8 0 117 5 -57 22 -121 3 -21 75 -83 -48 -51 -95 11 -6 70 -16 -93 -14 56 -45 -84 106 3 -90 -85 76 26 7 -61 109 -72 -65 58 -111 -51 76 9 -112 -44 -34 88 -19 55 127 25 29 35 -26 110 121 -127 -82 -55 -74 -35 54 -128 -108 1 93 -28 125 89 40 21 33 -4 1 -24 127 12 25 -32 -20 42 59 -59 -7 92 -29 -87 78 52 123 30 75 -45 -9 110 92 -112 35 20 -126 -22 -127 -85 -27 -98 12 -95 100 -76 70 -58 -52 -55 -102 49 22 58 -23 -127 -2 42 -10 74 -127 42 -18 -40 123 60 100 -55 -26 53 -43 -8 -24 -54 -20 9 4 19 -41 -61 116 -57 -15 73 -12 -32 41 -60 76 -42 -66 4 48 15 90 -100 108 50 -49 -21 -45 -45 -30 12 -92 73 -48 7 3 35 17 -82 42 -13 -27 91 40 -81 -45 -94 -60 -33 30 -81 -22 -88 117 -51 22 -36 127 -52 -16 10 105 27 8 7 42 103 -82 0 -6 21 62 4 44 -92 20 71 21 126 -5 -14 95 44 20 75 86 67 -31 50 57 -72 -69 -14 -73 -10 -53 90 -26 -125 60 30 40 59 -26 48 -127 -43 -29 -127 -61 15 48 33 -38 28 -2 10 46 -120 -108 -58 -7 -114 -12 -26 -22 14 -59 5 -32 -4 -62 -50 0 -47 80 -30 89 63 98 -10 -36 -15 -43 -37 -58 -56 66 -91 -26 -44 127 -98 -43 40 127 -24 57 3 35 -35 8 -88 33 101 40 -22 91 68 -61 8 23 -42 -71 7 -122 43 -6 72 -116 -39 -33 -35 105 -49 36 47 35 23 -122 -52 6 -38 87 11 -29 17 23 17 39 -25 27 1 -46 70 24 44 50 14 -19 67 -74 -35 81 17 42 -41 -110 42 51 100 -36 -6 15 6 -56 2 -71 -27 38 95 -49 47 5 -42 -92 -21 6 57 -29 -26 -68 -115 115 -126 41 -110 20 -74 -44 22 8 -61 75 -35 -38 -62 35 78 29 -50 -45 -123 -76 56 2 15 120 12 8 -122 -62 63 -121 -95 27 -1 -88 -49 20 -33 126 118 -80 39 62 -35 -85 95 -55 -109 -58 -85 16 -58 -1 -124 119 3 40 -7 121 -2 -49 -114 38 -126 113 -2 36 -17 -21 26 -40 11 60 -7 -106 28 51 32 1 -30 -120 -123 125 -79 94 -34 127 97 77 -75 -64 91 -78 -72 81 31 13 47 -67 -27 126 -53 125 108 -20 33 -77 50 90 2 101 41 -39 59 -6 -10 5 -125 15 -45 0 44 -72 -1 -17 -117 -14 -9 -79 44 112 28 2 -27 -2 -10 107 43 -20 -123 45 0 -48 60 -25 -68 -16 0 121 69 80 45 86 115 -9 63 -43 73 27 -7 -40 -11 27 46 8 19 31 55 96 -46 9 24 15 -115 -64 -28 -50 -39 -44 26 -11 11 90 -41 -127 32 -6 7 95 -27 42 -53 19 -12 70 34 -89 -24 25 12 113 29 71 8 27 103 1 2 63 -16 67 -2 34 7 53 -14 -3 77 -48 21 -42 12 23 83 11 54 56 -11 53 21 31 -9 -23 -66 -16 2 -29 -31 74 -3 -15 -6 63 11 -127 -1 49 26 14 93 7 30 -44 3 7 43 -15 -50 -66 -22 -18 -34 -88 -125 34 -38 9 -28 -2 -22 15 -68 50 6 0 -28 -71 -36 -5 -17 -51 -29 6 -90 -69 18 41 21 -16 36 13 -75 -50 16 7 -14 21 62 -63 -3 -12 7 50 -2 49 37 -67 -24 34 35 -41 48 30 -72 -118 -20 25 15 -44 55 102 22 2 -55 72 -31 -80 -50 -10 12 14 3 -11 -47 -17 26 -71 -35 -11 65 -13 17 -67 38 -61 -24 12 -71 65 7 -60 -44 -49 19 -8 -51 -50 -45 12 27 -24 10 -35 31 -17 10 30 -52 41 4 8 -2 15 -14 -30 26 -15 -70 -10 -96 -66 21 -19 -17 40 -125 4 30 -15 50 8 -1 -60 -36 -18 47 9 24 29 -68 -10 10 -7 -42 84 34 -10 45 32 43 -26 -26 0 -124 11 97 -14 59 -36 5 -90 -26 -18 -10 70 11 -2 -69 -34 93 -62 -3 23 -12 -9 -16 62 -5 -66 15 -76 124 -18 -75 -25 56 -13 70 -5 -25 -96 -29 -27 -9 20 3 -56 68 101 60 4 -33 -27 85 -21 26 96 -51 108 -9 26 -45 96 0 -20 -13 -41 -37 34 7 20 -45 -36 -41 67 2 83 46 -43 -4 -77 11 19 38 -86 12 37 5 1 -32 -23 -26 -64 33 126 18 23 41 47 -95 20 -42 7 -33 -10 57 -97 -61 4 -5 -58 41 68 -38 40 -116 37 -17 10 120 8 -34 -9 -119 49 -28 -40 14 57 -68 -122 17 -14 -13 17 -11 -100 25 -42 -65 -106 -63 10 -34 15 2 -61 28 -79 -5 -42 6 56 13 -128 -114 -83 -16 -64 -34 33 -52 77 42 -7 50 35 45 -6 90 -71 -46 -62 106 -17 33 -6 26 33 2 -8 -57 21 10 2 42 -27 90 -45 28 28 1 31 -31 72 -68 -41 27 -2 69 -40 1 2 50 25 9 48 67 -36 35 14 -30 -45 -53 -38 59 -63 105 -95 -59 -45 -51 -35 -76 -43 -75 76 12 30 0 51 -44 -27 48 -15 -122 -23 76 -36 7 15 -14 13 -26 -4 9 -51 21 6 62 -34 -52 21 31 16 28 -12 -43 -44 -40 -51 -34 -3 -48 -43 -109 -42 11 36 -8 -73 35 -13 -17 8 -14 -7 20 -45 0 38 -40 59 -127 -15 -6 -51 2 28 -20 0 59 -66 37 2 -2 20 45 -1 46 -29 9 -5 15 -17 47 -2 31 22 -6 -16 24 21 -29 -38 -73 0 27 34 48 22 10 -45 19 77 -37 -15 -71 94 4 -76 55 -27 -1 -52 33 11 -22 -15 -13 40 37 -27 125 -50 -20 4 -22 41 -47 -13 109 52 124 -46 67 8 -24 1 -10 41 16 30 17 37 5 25 32 -15 -60 -6 34 18 0 -30 -3 -6 33 38 9 -26 100 63 10 -61 -63 42 1 3 -55 -11 -10 80 59 71 -14 -43 47 -83 60 -37 -51 4 -13 20 -67 44 71 36 -5 28 16 -2 -12 -41 23 61 -59 -23 -14 -61 25 -42 -74 -45 -43 8 -24 -64 24 -14 -27 -53 -36 39 27 -17 -106 -15 -11 -69 -10 -126 42 -71 27 -27 5 -56 -18 27 30 13 59 8 75 0 1 8 53 -24 44 -23 -22 52 -73 -40 23 57 124 -64 -54 -1 -23 78 39 -19 57 -34 -14 37 42 10 -43 -11 30 -24 18 13 127 -41 -8 62 -29 9 98 18 -42 -58 -11 -38 -7 -37 -6 28 23 33 81 85 9 0 -52 69 40 -109 70 60 3 64 -8 46 29 -16 32 -57 -2 15 22 -10 -71 81 -23 -26 -31 17 42 40 77 80 17 -52 -7 -8 0 -16 -17 -126 -37 -40 -38 38 -51 -41 -76 -8 -6 -9 -51 53 -29 52 19 -116 54 73 2 35 -21 33 44 -61 49 -42 32 -26 -19 45 -19 65 -69 15 -19 -67 16 -35 -1 -37 -8 45 -52 39 2 -38 3 -4 96 48 -56 -55 34 42 -19 34 -29 -90 116 -61 -18 -39 20 30 36 -20 3 2 127 -35 -126 34 7 -42 90 40 7 58 97 46 -11 15 -29 -21 -9 -23 16 -39 -62 -47 -7 6 -47 12 -19 7 -32 7 -15 1 33 127 -12 12 -23 -5 -45 -48 10 -19 -15 0 5 -17 -30 -48 14 65 -4 -68 -69 27 -16 16 0 17 -19 37 -22 -18 -26 -114 74 -13 20 -12 -11 84 8 -23 -55 -16 57 37 -53 7 67 23 4 -29 -58 5 111 2 58 -12 -3 -40 20 27 7 -115 -29 -29 -100 26 21 -8 -24 29 -81 -26 29 3 66 -37 40 -19 -60 -47 23 17 -44 15 -22 -49 42 40 39 5 2 92 126 -11 8 11 -57 -30 41 -32 -46 2 35 -30 81 9 -94 -5 82 12 36 4 -30 -54 16 -31 -53 -4 -11 -92 -16 13 70 -67 27 -28 123 5 108 95 41 79 3 45 -22 22 14 6 12 56 10 -14 -27 94 110 -5 -20 16 36 2 30 -70 23 -43 60 60 -1 -61 -65 23 4 27 14 -92 62 -39 -18 23 -43 -13 -53 26 -15 -32 -8 123 27 -78 24 55 55 -38 39 47 7 28 -63 -11 -28 62 39 72 -66 -50 22 49 -4 -36 48 43 20 -43 -18 2 76 -6 -96 60 -59 -37 -23 29 24 76 9 15 32 -8 -6 -36 44 48 -13 16 -16 -64 -36 -35 33 49 -72 2 -47 -89 77 -33 -21 -94 7 -127 -53 85 21 22 -7 -43 54 -110 -30 34 -72 30 45 -29 94 -35 -1 34 15 23 -70 2 27 113 35 49 -21 -90 103 -27 -12 86 37 -9 -12 19 23 -103 -10 126 16 24 -6 107 48 -37 -63 40 -18 -91 6 90 106 -47 -21 85 -19 56 -2 -24 39 -23 87 35 14 28 -46 -6 51 -10 -44 113 15 -36 -7 -78 66 18 49 -27 -25 -12 72 -56 2 -44 19 27 -36 -5 -18 39 -78 -40 -34 -29 -47 13 41 42 11 39 -19 79 -65 26 -29 -23 42 64 -49 33 -4 -12 4 -8 -118 -53 -75 -40 -36 -22 -36 85 38 17 75 -33 15 62 -38 40 73 -5 0 -71 10 -127 -11 15 22 -1 -49 -36 39 -50 12 35 56 -51 125 -31 -66 -3 45 -11 53 -11 16 -19 -29 -37 49 -13 10 79 -63 75 75 127 -24 12 47 8 -10 48 57 -61 31 18 -1 -60 -18 6 -36 48 -45 33 66 -33 4 61 -29 -28 43 11 -48 37 45 59 -6 -62 64 85 -47 65 -25 -43 34 28 -109 17 -22 17 -60 47 -42 -89 36 1 -9 -52 75 -8 1 -38 64 25 -26 -43 86 -34 7 -6 14 37 35 39 -74 -34 30 -69 5 36 -100 15 24 -72 18 36 7 74 -16 -16 21 4 116 17 63 6 -29 29 -20 -32 76 -30 24 -64 53 -10 -6 -61 62 -73 92 -128 1 -56 24 -61 15 2 6 24 20 86 13 19 57 44 -1 64 0 71 -30 48 32 78 117 49 -13 -70 56 -29 63 49 -105 36 39 18 27 58 68 19 61 -2 -91 61 125 12 80 11 24 -28 -21 -19 71 -44 -19 -9 26 -8 9 24 17 -85 9 43 25 -32 -32 -18 16 69 -17 18 -5 38 -9 57 -5 -18 -34 -28 48 -83 11 -58 -52 93 -60 -24 120 55 -21 52 -2 8 13 23 -36 -96 -33 37 -37 -105 -46 33 81 -2 -13 -23 84 18 -4 -38 -30 81 11 -7 18 -1 -17 53 -112 63 9 53 -72 4 21 -74 17 94 -33 -9 25 23 15 2 -75 35 -23 -36 -1 -114 26 -19 -3 76 -13 31 -65 -50 4 6 -79 67 122 13 29 -24 -38 16 28 -27 -52 5 -18 14 83 -10 4 82 -25 -52 -1 22 -28 -34 -100 3 77 11 12 -77 -80 41 28 28 32 -10 116 -9 36 40 21 -61 -33 64 41 -24 43 -55 4 -2 44 1 -37 -12 -10 -4 -21 42 14 12 -39 40 -31 -22 -73 58 -4 44 -33 31 28 48 29 67 8 -21 6 -6 -12 23 54 -46 27 23 -13 20 -38 -17 87 117 -61 38 10 -20 -99 32 -125 12 40 59 90 -16 0 27 22 28 57 39 5 6 29 51 25 -37 -42 6 -9 20 -51 -19 31 39 14 44 -41 37 66 73 -6 1 -22 15 -49 22 34 -51 -29 -31 83 18 -118 -29 -20 14 -21 65 70 -47 11 31 -73 50 25 13 43 -33 97 39 44 -66 -42 -20 25 -19 81 5 -3 3 58 7 -49 -29 106 -21 51 67 -36 -5 -39 55 66 -15 70 -31 99 -7 -84 15 -9 36 12 -33 54 3 27 10 -18 -67 -63 13 -21 57 3 12 -59 57 28 24 11 39 10 -28 -80 49 7 39 -66 -65 -45 -8 -16 -2 46 -98 -37 5 -2 50 -6 14 42 25 8 -7 -14 33 114 62 26 -35 80 60 59 7 -26 2 12 21 -21 45 -19 -53 99 12 37 -10 -77 53 -29 -1 -27 46 -61 -4 -20 15 48 20 -72 82 33 -10 -9 -117 3 5 -2 26 21 -5 -61 -37 67 -50 0 -22 78 7 57 2 127 -13 -4 47 36 4 -40 -1 9 8 -93 30 -90 -40 -52 -2 58 -5 9 -21 -46 -64 108 13 -1 4 86 -3 -37 17 -16 -8 -17 21 55 -55 29 49 84 -18 2 15 5 89 -45 -30 11 42 118 -36 1 -29 -18 37 -11 15 15 -18 -42 -21 -28 -38 12 48 59 -1 -47 -55 57 -5 -12 11 2 -20 -44 0 11 -95 -27 -62 57 76 53 -74 -4 -5 82 79 -31 -24 -3 45 -46 -10 11 -80 -35 23 -39 33 -7 -23 -14 38 -21 -72 -76 -30 27 -13 60 -7 10 -29 -37 62 36 -4 -30 18 -39 -11 40 -20 32 -66 -20 -21 8 17 -25 -12 -19 -5 -34 -16 71 30 53 -55 -20 -7 -63 -124 15 -56 14 45 18 28 -58 47 -1 -4 124 -92 -69 1 15 30 21 -17 20 84 -28 -13 -42 22 37 44 -127 -2 46 28 19 -22 -74 25 -101 -39 48 -46 -31 -35 -12 35 9 -30 9 -4 -14 68 -26 19 -6 81 34 -53 22 -20 -77 -41 7 -3 -12 11 -5 -22 -126 1 -1 19 38 126 -19 -40 3 30 -47 95 33 -20 -33 98 -49 -40 68 -40 87 -30 -46 -5 -94 75 20 -2 3 38 80 58 46 -45 18 17 5 38 35 -25 -57 4 91 20 14 -84 -48 52 6 -65 59 1 -6 39 18 -26 -46 54 9 -59 -2 26 2 -11 21 6 -80 -16 81 -67 -21 86 -86 -68 22 -28 -4 26 -61 57 -25 -45 41 -19 -57 12 12 -67 -43 26 48 -17 0 11 -42 43 -31 -22 -8 1 -40 -21 61 -87 38 17 -18 -72 -32 -13 -6 -38 56 -16 34 39 48 66 -71 -45 41 16 -2 31 9 -3 73 -6 -42 -30 -53 1 7 49 16 -96 -31 -40 70 64 47 59 -27 -14 42 97 29 34 42 -11 28 20 56 -107 -14 1 6 27 -28 32 0 51 -17 50 44 -28 55 -4 -8 -10 40 -18 26 7 47 37 -10 -24 40 -71 119 60 -33 23 -35 30 44 -32 39 84 34 -35 69 19 16 14 -28 7 44 22 29 -79 13 -29 11 -16 55 8 20 -34 -75 -86 32 15 -6 -37 -22 -64 -81 -5 100 -7 -78 53 108 -5 0 -25 -9 -19 3 -60 -39 -30 -8 45 -11 -15 -9 44 -55 -51 48 -28 -63 -56 -19 31 29 -18 90 12 20 -1 71 -7 -13 -3 3 -15 80 -73 37 -34 3 -41 10 85 18 -7 10 80 -3 43 -6 -10 -66 -39 -45 11 -2 -47 115 -32 16 1 -3 38 73 -23 -29 -45 18 -34 -46 -113 34 -26 -29 -53 32 33 -25 8 1 3 47 -63 -13 1 -8 20 23 16 17 -21 -30 52 43 1 -74 17 -35 -60 -44 33 -37 51 70 -30 15 -5 63 -107 -43 6 -18 -69 -70 35 32 -27 -22 4 -45 11 -23 42 -24 51 -41 -40 -42 -8 -8 14 -29 -54 -43 -4 8 -25 -105 -10 24 17 -72 11 25 2 7 -3 -58 9 46 53 15 35 65 67 -55 -69 -116 -16 22 75 -16 7 -52 43 42 38 -29 2 -26 -22 -67 44 -34 -12 -53 59 77 -17 31 -13 61 18 44 22 36 127 22 -1 40 -80 4 7 -99 44 -119 -96 -11 6 45 -44 -17 -37 -29 6 51 3 55 3 -69 -74 127 -82 -19 68 -13 -43 -20 22 -64 7 22 -10 -4 38 17 -31 -11 63 52 -78 78 13 -5 -9 78 -39 -2 -54 7 72 -34 27 -75 -82 -60 35 18 -95 13 113 3 -128 12 8 -51 22 -114 -15 33 25 21 -38 -27 -3 58 -41 12 -66 16 18 14 28 -89 50 -36 50 -52 -71 -52 -76 -6 -21 -34 46 4 11 -2 4 8 -41 19 -98 31 51 -19 1 25 -4 73 55 25 -31 17 -26 55 -45 -54 10 -95 -30 86 -41 -39 -28 45 27 11 36 10 -30 69 41 -51 20 -26 -26 66 -35 39 44 17 -34 43 34 -63 9 -31 18 40 -53 30 -94 -13 12 -25 -25 9 14 -82 73 25 -31 20 -45 27 -84 7 -32 -69 -102 43 41 -38 -7 -16 62 5 -10 -89 9 -58 -15 81 -62 25 -18 -52 7 -6 -11 -118 -87 -11 -26 34 -88 -39 -15 6 32 -3 52 -2 34 19 -47 -74 -19 32 11 -55 10 -126 -85 -27 -14 -61 67 -18 -20 -56 92 -29 37 -18 -3 21 -32 -21 9 -57 77 -18 -127 -69 22 19 -65 2 85 -21 -28 28 6 -30 -10 5 17 -62 1 9 -75 22 -85 63 -51 -55 -2 26 -76 56 12 68 -59 17 -10 80 -32 11 14 -30 13 -3 44 -68 44 23 15 47 -43 -51 56 -46 14 -13 56 20 24 74 -21 3 -4 -24 -22 -34 6 -35 -30 47 31 36 38 -18 25 -3 54 -25 -9 -58 23 55 -39 -34 34 -7 -69 17 -17 -22 -34 -38 79 -33 -14 28 27 16 20 -22 127 -36 20 -36 5 25 19 21 37 -24 27 22 -12 -23 -99 -12 56 5 8 61 3 -38 -83 -57 -58 -18 -30 -74 -38 -26 -23 -50 -43 -42 -45 -42 25 71 47 -50 66 -5 24 38 -34 -20 -48 -12 36 -3 -80 -70 30 -8 48 28 -4 51 93 -41 37 45 11 99 43 79 33 127 100 1 60 1 -11 -4 16 33 -11 -23 65 57 -35 14 -48 -89 90 -22 -12 -1 -34 41 32 -21 -39 12 -33 -21 61 62 -9 17 23 55 34 -8 12 10 -19 -52 -55 -27 3 29 -69 34 -8 -4 -39 19 32 5 24 75 -10 -8 -14 -12 6 17 24 -16 73 -53 5 100 31 -1 25 20 -27 -27 10 -50 -10 40 26 16 -39 -12 -38 -52 -22 47 1 50 -39 -4 -5 -67 -40 -4 26 -2 -67 -16 51 -30 -41 28 83 36 -50 -27 -21 3 -17 -14 13 -4 23 -50 -23 -44 -2 -116 26 18 -70 27 56 -1 -64 -20 -20 -51 44 -12 -15 -75 16 43 44 -55 -4 58 -14 18 23 -2 -23 14 -27 27 -59 -92 -56 -24 -17 -15 91 -56 10 2 81 -24 -21 34 -3 -54 83 26 37 8 9 27 18 60 10 39 25 -59 0 -53 34 -4 -10 55 -34 108 70 -3 17 27 11 -15 18 -3 23 -21 37 25 21 -61 77 25 -14 -79 31 85 66 -10 16 -18 -39 -15 64 -37 -10 -57 77 7 -7 -33 0 72 32 94 12 29 -4 39 -28 -3 65 12 -27 -5 30 12 31 -26 88 40 -14 -28 6 -24 27 3 -29 81 21 -22 -10 -59 23 -46 -18 4 27 47 -2 24 -17 6 0 67 12 -26 -67 -23 -48 56 12 -15 29 19 -25 -39 -29 -47 -15 -21 -8 54 1 91 8 27 -17 -25 58 0 34 0 -21 10 -33 -116 65 91 -56 6 22 -14 16 28 31 -51 127 -48 -64 -1 -23 -25 -44 -8 -96 -3 29 -33 -25 53 50 68 33 -26 15 115 35 40 54 -12 -47 -26 125 -59 2 67 -33 -27 25 32 -3 -11 -51 -25 3 68 -2 -8 -25 42 -11 -19 3 -13 -4 -18 57 49 20 12 24 -56 -9 37 3 5 -14 27 -84 50 -31 7 -1 -39 -48 -55 10 39 39 3 12 127 -101 34 5 28 -21 8 2 -70 18 23 -16 44 -56 -5 16 -9 -81 -8 -8 33 -31 -87 17 13 -33 -31 -40 -18 37 27 3 56 21 48 36 82 -15 -20 -127 1 16 -18 12 64 15 21 -23 -21 -42 6 -13 103 -1 18 25 -2 -54 54 -8 -52 -33 -25 -25 -38 -15 74 -40 -34 52 -37 11 3 44 9 37 -19 7 41 5 -36 3 91 25 -21 16 36 -9 22 -50 -17 12 -34 16 29 -8 -33 -65 -53 -16 -54 -11 15 11 -47 13 44 7 14 -79 -38 -65 -65 40 56 -94 60 74 -54 12 -32 -47 44 -3 -7 -103 53 127 26 21 40 26 33 -21 7 48 33 -6 -19 29 12 79 28 -54 -25 -59 83 1 -1 -41 28 0 40 -28 12 -28 50 48 50 -5 -17 5 -35 -8 -62 -12 -90 -45 -16 -117 -122 -10 -118 55 -2 -128 -11 -18 16 30 15 13 -8 14 62 -45 -8 41 -28 30 40 10 18 -60 -54 -43 43 16 2 -5 127 -37 -72 83 48 -24 71 25 -4 -37 32 6 -30 22 45 8 62 9 -9 -67 55 -9 -21 -8 6 83 -18 36 30 48 -17 46 -68 -30 -4 -29 -15 -28 -47 7 5 -65 -2 -125 62 20 68 -41 -3 30 -16 75 -27 -9 -65 15 -24 -19 -58 38 -24 5 44 -10 -46 47 51 19 -61 -27 18 -43 -21 34 -37 -63 -44 -54 -48 -49 60 2 -1 20 -20 46 6 -22 29 -23 -4 -16 -2 49 -47 -9 0 2 73 -72 -30 70 34 74 -60 -37 29 -19 -2 72 -77 21 -14 13 -124 -125 -15 23 24 -2 -2 -59 -36 92 59 -8 -18 97 -36 -17 -26 19 74 51 6 -69 -56 -72 -42 -42 55 -58 -5 -55 54 -24 -60 5 -113 3 -1 -8 55 -17 0 25 -28 4 5 -61 -11 54 65 52 -102 -10 57 9 -49 4 -14 7 -23 -4 -22 6 -44 -34 -5 -50 22 -62 -42 31 -7 -5 -26 -57 21 34 21 -7 29 1 -53 0 26 -99 61 36 9 -62 -43 62 30 27 -78 66 -30 40 21 59 -57 -43 31 -32 34 12 60 -41 -9 45 20 39 -93 107 11 -19 42 -12 15 -12 -40 -59 52 -45 -44 12 5 20 40 -92 22 -20 35 -62 26 -62 -36 39 -25 8 -11 -68 -42 22 3 -42 -11 56 -80 40 3 1 -77 -17 87 49 94 80 -35 -64 52 -25 -125 51 57 40 -36 -27 69 -19 32 -3 -8 9 31 8 -46 15 6 16 21 -37 3 12 23 -4 74 -25 25 -62 127 42 39 60 -9 -33 -15 -23 82 -1 12 -79 96 -111 47 69 1 -37 9 -41 -36 32 10 -56 30 8 35 -33 47 -85 -23 14 111 62 1 1 -18 -6 -78 -56 -34 -20 -6 -44 -59 27 38 -17 -25 26 37 -30 25 -14 -45 -9 84 24 68 38 2 -61 35 -14 16 76 60 6 30 22 -93 28 36 24 2 -41 13 38 25 -95 59 12 -89 -73 2 -78 37 -32 -37 6 10 2 -48 -22 18 -90 -22 -13 -68 -18 -25 79 49 -45 -5 -99 -16 94 49 -22 -116 -9 -62 -60 23 -5 -1 34 4 -7 -15 59 -56 12 13 29 -14 69 17 -17 36 -3 44 -85 46 -14 20 -41 -82 9 50 -60 18 -3 -70 -47 73 -16 -10 14 -84 -30 -6 85 56 32 -9 1 61 -30 36 -58 0 15 -13 11 8 -41 -3 0 -21 20 -33 -69 1 -32 43 29 51 37 -77 42 -33 -11 19 -17 -60 71 18 -21 -8 -10 -15 39 58 105 -88 -16 -27 -15 -26 79 56 -53 17 16 14 -50 -48 -29 4 -8 -26 19 -7 41 33 -22 37 -73 27 -10 -27 -20 -6 30 20 -34 16 -17 77 23 -19 -36 63 -80 27 0 -61 -36 -71 -20 -78 8 -68 -89 -49 39 10 8 -78 2 -57 -23 86 -22 -74 25 37 -3 -38 17 -18 -97 -8 -40 -30 51 59 5 10 16 23 -4 -9 -35 10 -44 40 7 34 -5 -46 3 -25 -31 14 -52 109 -10 48 -27 42 25 -35 38 37 29 61 -56 61 -29 -9 -7 88 -23 -44 74 -6 36 -26 23 33 47 -51 -74 -12 17 95 -4 24 6 -41 10 43 -37 -37 25 -32 4 -52 28 80 -38 25 3 -16 6 30 -75 105 -34 -35 51 31 54 23 92 -19 -31 76 20 15 -32 113 28 -11 -29 82 2 5 97 69 92 -77 -9 -7 3 -53 11 15 29 -57 -125 -28 -17 34 14 2 12 7 -75 -84 -37 -37 -29 -49 -32 -97 -63 -19 -3 43 8 -27 10 3 -14 21 -46 -57 123 86 -29 54 -38 77 6 35 -5 -19 16 -47 -33 72 -53 -43 -73 -57 -41 -25 11 45 -51 -38 26 20 -48 -75 28 86 41 -17 32 -47 -36 70 -1 -36 -30 59 -14 67 18 -37 22 -21 13 6 16 -49 31 26 -13 35 36 2 -67 49 19 6 6 28 -82 -3 -9 4 -73 -30 13 -111 37 -8 14 -23 -33 -31 66 -32 14 56 115 -16 -3 -25 40 -34 39 45 -54 39 30 56 -3 -14 -93 9 -84 30 42 -2 -20 -39 -46 -26 -22 30 22 15 -24 88 -10 18 1 -15 -76 15 15 16 -23 -62 2 -80 -49 39 8 5 48 -18 34 27 50 20 -14 -45 -38 19 23 -53 -83 -13 -55 -61 36 -22 19 57 20 20 48 -33 -4 -1 46 -36 -77 43 51 -56 -93 35 -24 63 -6 27 15 -27 -11 -62 19 -11 -68 -10 -13 114 -77 47 36 -43 -60 22 13 -73 104 46 -34 57 6 30 90 -5 8 -17 -52 -49 -34 -10 10 -66 -30 -40 43 -11 -5 69 -20 34 93 59 -40 -51 -83 -10 68 -60 -43 -17 41 10 14 -4 -9 126 -67 -46 -35 -66 11 62 50 33 -56 -33 -37 -42 77 80 -13 37 20 -54 -16 -43 33 -25 18 47 -67 34 -26 59 -88 11 4 -15 -2 54 3 -43 67 27 41 -12 -16 -45 -30 26 51 14 -40 -60 54 -13 24 -9 36 35 57 35 58 50 -24 -70 48 -58 -56 3 -13 -41 -7 -27 57 -90 65 66 8 -7 88 -16 21 21 -38 -48 -7 92 88 16 -84 -23 -46 4 5 -24 24 -2 -50 42 -15 26 -52 11 -26 -12 -77 89 5 -5 2 12 3 119 0 10 -70 -72 -34 41 74 73 -16 -49 -50 -24 0 -18 16 -4 25 -36 65 -19 38 9 -36 50 -59 -40 -47 -5 47 16 -8 24 6 -49 35 3 -45 44 -38 5 92 24 -41 66 -9 -55 100 -19 -19 33 26 13 -75 3 -12 -7 -2 36 28 1 -67 -51 -32 -33 -2 -5 -10 -49 23 40 4 -56 -8 -110 -16 -51 1 -56 -30 10 -16 -20 -66 58 -93 56 -87 -12 -6 -22 14 -16 57 -22 40 -4 -5 -39 -33 -34 86 -4 21 12 2 39 95 124 -29 59 22 22 -6 -17 16 81 26 18 -39 -88 55 -12 37 -25 59 -29 -9 -31 40 -81 0 85 126 -32 1 12 30 -29 0 56 -6 27 -37 2 6 38 -24 -20 42 19 7 27 -55 59 -13 11 -13 49 71 35 67 -89 -15 -42 -30 -18 -9 -14 10 -18 13 22 -12 45 -11 -19 57 8 -8 43 -10 25 41 -18 42 26 80 90 -10 -12 -34 3 64 -5 26 -22 -4 -7 -76 48 2 -35 -13 72 -35 -36 50 -34 -17 -77 50 22 -19 0 102 -3 -103 8 -57 13 -67 -51 20 52 -29 -11 -39 -61 20 107 -51 20 -3 25 26 -53 -60 -42 0 -9 61 87 -27 -68 -9 -30 15 40 57 -25 -4 14 -77 12 37 0 -56 26 -37 32 57 -5 -43 -12 12 7 -4 41 -90 107 29 -45 22 -87 -61 93 -81 33 -51 5 -76 -20 -66 12 -17 54 14 -23 -47 -30 26 6 -36 -15 34 101 28 41 48 36 -1 14 79 26 40 -11 -51 -17 -101 -30 -41 35 -73 -47 -18 16 15 94 20 -18 -38 27 -27 -23 -10 -22 51 -9 17 -17 29 45 -18 21 -56 14 -34 84 -25 -79 -40 86 -94 -15 -37 1 -3 80 -37 36 -35 5 61 -26 -4 31 65 20 1 -37 10 -126 33 -47 19 -1 -10 -23 53 74 65 32 -48 7 -49 -35 120 12 16 80 -42 -41 88 100 62 -61 101 22 -62 17 57 1 3 -101 91 28 15 -18 68 -6 50 2 58 31 59 111 9 -22 -16 59 -46 44 53 -45 -42 31 -116 -18 19 38 -56 61 -28 -36 -29 -61 68 33 -57 53 -93 -34 56 81 124 -54 30 8 -71 -13 -59 109 -14 52 -92 -44 22 -81 -69 -48 -26 -93 43 -76 -70 22 4 -40 -46 -18 -17 -17 -22 9 55 -60 -74 -79 -20 -12 50 10 -2 -28 -45 45 -82 20 -45 -67 3 63 -114 -33 -37 20 -33 -52 -88 -50 -33 -29 67 25 -85 19 43 -4 63 -12 3 -47 -37 -24 52 21 74 40 -50 -7 -7 121 -14 122 124 38 21 4 -21 73 55 13 -56 75 86 5 -17 -2 -6 -3 -60 -5 24 -9 51 -24 0 13 -68 29 -34 -45 14 -46 -29 88 -36 -36 -20 39 23 23 3 -17 -12 -49 -47 115 50 -87 -77 -53 69 33 21 -26 4 27 17 60 42 -14 30 4 46 22 -51 97 -47 -10 -22 -64 97 7 -38 3 -21 33 10 -28 -14 -60 26 66 -30 -55 40 2 29 -9 -24 -31 58 -13 -87 20 -19 47 -50 -91 -14 -72 -7 -17 86 -34 -38 19 36 -70 -33 10 12 -5 -28 79 -32 -53 91 102 74 -96 47 66 -79 62 24 13 -27 56 -12 34 47 -28 50 -78 -12 -28 -92 44 28 -10 89 47 -16 47 35 -82 38 74 -48 -16 22 -52 -17 22 -96 -7 46 48 35 69 -22 15 109 47 -7 7 49 1 63 44 8 2 -24 91 -102 -20 65 10 -48 -1 127 59 35 -38 85 -117 -16 77 103 -12 -10 -55 110 -9 44 10 -34 -29 17 16 -58 84 33 -42 41 10 -50 110 10 15 -95 11 -27 -31 11 75 -21 25 -18 52 -4 -127 -43 -16 -19 11 -81 -36 50 62 -64 -47 25 30 -26 -7 -121 -52 45 -7 76 18 -23 -41 3 -52 68 48 63 12 -70 24 -56 -76 16 20 10 0 7 -44 -24 -22 23 -80 -12 -21 -16 16 -28 17 -90 41 63 12 -36 -6 42 -17 21 23 30 70 4 19 -16 -111 -42 -44 22 -54 -25 22 20 61 -14 -45 2 -28 -43 74 -46 14 -17 19 -29 42 32 11 12 -43 -78 76 4 93 15 75 -29 79 -7 19 98 -51 -4 44 54 49 30 -16 -4 57 15 103 -8 61 -13 82 32 -30 -30 -15 3 15 -1 -50 50 52 3 -79 -35 -12 -46 14 126 88 -60 -127 7 -6 2 -23 -27 92 -45 61 87 -38 -43 -40 51 18 4 22 -34 -26 -26 49 -13 -63 49 -127 55 -20 -37 -32 78 -92 -73 -30 -15 -34 58 94 47 12 2 -14 54 92 -37 -14 91 15 48 -33 20 -8 -83 19 -10 -90 -103 -106 70 5 38 35 -114 -44 -64 -22 13 12 -8 13 16 39 -14 -47 34 -33 -23 24 19 5 -47 -18 -21 -72 51 49 33 82 -45 -42 4 40 68 -60 -16 -1 1 4 47 -27 -9 49 -7 -13 47 22 -5 -5 -77 36 45 12 72 20 -38 -15 -49 40 58 17 16 -64 44 -81 -21 31 -61 -22 -35 -9 -117 -23 44 -61 29 -1 -39 -65 -17 116 44 -49 12 36 -95 -127 -7 -24 38 110 23 -7 -51 41 48 97 -28 35 -52 -13 29 42 25 15 -31 42 -41 -58 44 -15 -47 109 5 -35 -58 19 2 15 -11 -22 101 -29 -41 63 17 -2 33 7 -45 61 69 -49 -9 -64 -10 0 -45 -29 -37 19 -31 -64 -38 -50 26 19 17 33 10 -35 9 4 17 -29 43 25 -21 24 -86 -53 -57 10 37 -56 -8 -54 19 -27 -25 -10 13 -2 -19 23 -1 -41 24 41 -47 63 -55 102 9 5 -5 23 -34 -48 -11 40 -42 59 28 -58 -25 -21 100 52 3 56 -92 -5 120 -10 53 30 39 -44 8 40 -32 -45 28 1 -28 20 -67 28 -23 -120 -15 -128 13 44 42 33 -11 -22 33 -18 88 -26 -47 -4 -35 44 19 -60 25 -35 127 29 -31 36 -21 25 -12 61 60 3 32 -6 0 5 -54 39 32 17 -11 23 46 45 -121 23 -12 36 54 19 13 -27 9 -21 107 19 5 -7 18 50 -30 16 -18 40 -19 -11 -1 -29 -33 84 -13 61 61 -17 19 -1 -7 31 26 0 20 12 -9 44 33 3 -7 -43 -35 -41 11 -5 -39 0 -57 -33 -6 -29 17 -48 -72 -50 -57 45 -93 14 74 -55 27 -38 3 -109 57 -128 40 -58 22 -2 -6 -127 -69 -4 42 106 -26 75 -17 82 -11 -25 -54 83 -15 -69 -29 10 -21 40 0 -53 26 90 64 39 -9 -74 -37 118 98 66 33 30 2 19 -55 -16 40 -14 88 35 2 20 -10 -51 -63 29 -49 33 -8 62 24 103 91 -16 -22 0 -96 -56 71 9 -77 25 43 -1 -8 17 48 -27 41 -12 125 -5 -36 -49 1 23 55 33 -45 28 -9 83 69 -56 -21 23 -7 -37 -25 18 8 -42 -39 38 -70 43 8 -50 -65 -11 -48 37 20 -28 35 -35 11 38 17 -27 25 -10 20 -93 2 45 -65 -112 8 -13 -48 3 -19 26 -20 42 -5 -5 13 50 -20 -12 -36 -29 -113 46 -15 -83 24 -15 -8 -8 11 -14 40 52 -33 -97 16 -14 61 41 23 -23 -56 67 -35 13 -67 13 -102 55 43 -8 3 45 110 -37 -15 98 10 -14 -7 88 -36 73 126 7 31 -44 96 -63 31 40 37 3 -125 -28 -9 20 9 -45 50 -65 -31 32 -4 54 45 15 27 42 16 22 64 6 -7 -15 -17 -1 31 -39 -67 -14 24 -20 12 -60 -23 7 -2 -21 44 -15 -126 61 -2 88 84 19 32 -32 16 31 -96 43 34 29 26 -81 -96 2 -3 55 -40 56 24 -84 -60 36 -68 -26 -29 -7 28 -66 -21 6 -62 1 -35 -37 26 18 26 -31 18 -14 24 -49 -33 -15 73 -17 -6 27 -9 -68 59 -8 -41 68 -46 110 38 -3 50 -24 -65 -14 -13 -58 6 -43 54 -90 -6 15 -36 -93 4 58 7 37 40 98 -66 72 -22 -6 29 -31 35 47 -7 -127 74 22 47 -13 5 -5 47 -30 30 3 -22 -64 40 59 -14 43 66 11 -1 -41 -17 42 4 13 13 28 26 41 -49 3 16 -111 -120 67 -13 30 1 5 36 -64 89 -29 20 71 55 29 27 -50 36 18 -15 90 122 51 -26 81 2 -6 -5 -29 -67 -36 -17 31 78 18 -57 19 9 57 8 27 -32 -32 16 -19 12 68 -6 32 40 -28 -51 -24 13 -20 51 43 -10 -36 5 -10 48 -8 55 62 -17 -41 -19 -49 1 5 -57 45 -67 42 -55 27 45 -117 125 -55 -2 -55 -11 64 -15 -1 5 28 12 26 7 28 -20 -70 -13 1 -32 37 -92 -28 -3 42 -3 -4 93 40 3 -8 54 -22 -38 -16 12 60 -25 61 -10 16 -95 18 7 -32 26 -47 -22 7 -23 47 9 -64 43 -38 17 -32 32 26 -14 22 -43 21 21 23 -15 -16 62 -7 57 32 -64 62 -21 -91 25 13 37 16 -45 44 -15 -11 10 -45 -12 -6 -34 -55 40 15 51 -7 2 20 13 -113 27 44 4 -76 5 -21 -60 -48 24 51 20 26 12 90 -77 0 37 11 -64 7 -18 17 2 3 -31 -13 32 74 -16 -12 11 12 22 33 4 73 6 -6 21 -25 61 -68 36 -113 -54 10 -28 -75 -1 58 27 -54 24 6 -33 25 6 44 35 11 -27 -36 -67 50 -57 -26 15 54 47 -24 18 -10 22 69 22 -8 -6 -16 42 -115 4 -78 27 54 -17 -16 35 -47 -13 -53 -15 -5 9 27 28 37 81 -63 27 34 -29 -24 -19 -20 -25 13 5 -53 -9 -39 -43 -38 43 -30 10 -12 8 -38 3 11 47 -35 -36 -19 50 -16 4 70 6 19 30 -37 -25 -52 -10 1 35 -22 5 -10 -10 17 8 -58 -49 7 -3 -10 -32 -105 -51 1 60 14 -21 -18 -33 19 -31 -9 34 -21 -79 -35 -21 -23 57 32 15 -49 11 -39 -9 111 9 16 -20 -15 49 -30 17 21 -21 -41 -44 -31 7 -26 -5 -24 -9 40 25 15 8 0 20 36 -114 -43 29 36 12 110 -78 66 41 -2 -41 68 3 -127 -89 57 -8 21 48 60 2 -18 13 2 12 -21 42 -93 3 -38 -26 48 -64 -24 -50 38 13 24 76 67 51 15 100 -72 9 -93 -84 -52 14 10 -12 -46 21 26 -25 -8 -44 60 -25 -19 -42 -19 32 -36 11 -13 -49 -60 -22 -23 68 -45 52 34 -57 12 -13 30 -57 4 76 -36 -57 -11 11 -55 25 56 20 30 71 -84 -21 -27 -15 35 -12 -1 12 3 -2 -36 80 5 125 -60 -85 -10 6 0 18 -20 -3 -28 58 11 69 12 -11 -23 -14 82 13 1 -46 10 -53 -91 38 -19 48 83 -56 -73 15 -28 47 2 1 -62 91 51 -21 34 -39 -11 -3 -8 37 73 -15 -34 -102 45 48 -2 -126 68 -18 -53 57 5 -5 -1 97 -47 -87 -17 -11 39 108 107 68 34 68 46 58 -41 32 37 -119 -45 -50 -81 93 -23 51 45 -44 -52 56 1 11 -47 72 8 29 -19 63 48 -15 44 -105 7 -55 38 35 -65 -3 25 -28 -19 -21 -33 73 -27 71 -13 37 -62 -59 -26 80 26 -102 -35 -86 -48 -5 -6 16 18 -45 -57 3 74 -122 2 30 70 10 -34 19 21 5 28 -12 -74 -60 43 32 -22 10 22 29 43 -34 10 -12 42 17 29 -56 61 65 -25 -39 0 16 56 43 47 -18 -22 -7 -59 -9 1 -12 17 19 -50 114 72 62 40 48 -34 -68 5 22 1 -40 86 29 -46 35 39 26 -28 79 -24 -45 73 20 1 -92 106 -23 49 3 -10 21 -69 9 -12 -3 -32 -23 -65 -43 100 94 74 -64 -62 -14 9 127 5 43 -30 -54 14 81 -28 -12 32 38 -11 -1 4 -50 12 12 -21 54 0 15 19 23 10 8 22 23 26 35 -36 39 -34 -29 79 36 -22 70 31 -91 -22 -20 2 -91 -43 -10 20 -14 -25 -56 24 -68 61 -12 68 -9 -27 -124 -71 0 -44 12 34 -27 -26 -46 -44 -51 -60 -46 -8 37 -49 -12 37 75 5 -19 6 -73 20 -8 -3 -62 6 -32 33 48 67 9 -53 -75 -23 2 -80 -25 64 41 -107 25 119 26 23 -54 5 0 24 49 2 -59 -43 -30 14 -24 56 -34 -63 -76 -7 8 93 5 -95 70 43 32 63 -16 -16 76 -6 -44 -44 3 73 13 60 -12 23 -23 -26 -35 21 12 37 9 62 -18 -31 -9 62 14 -16 16 -13 -33 -9 -63 11 3 -10 13 32 64 -19 72 -69 -36 -79 45 -5 -36 48 0 31 31 36 -45 28 -21 44 41 -76 2 -36 -24 -7 -5 -18 0 69 35 -21 17 -66 -2 6 28 -7 5 -43 -2 14 -56 -31 -7 16 -78 -6 -61 -42 1 -53 -127 -36 7 -53 43 18 67 -17 -25 48 -27 46 -34 0 32 -3 57 -50 -15 -52 25 -8 -51 99 -35 -93 -12 55 7 -91 -21 51 9 -96 -28 -1 -124 -37 -60 9 0 -69 -7 -18 -46 -26 99 -40 43 73 5 -45 22 -83 -55 -15 2 -89 -23 -7 -18 33 33 -30 -70 -41 127 58 33 74 -26 -110 5 -120 73 16 6 14 30 59 82 13 32 60 -5 1 8 75 3 -83 29 -36 23 -120 -9 13 -94 48 11 19 -67 100 9 30 -5 -39 9 -12 -38 -110 126 -51 -11 -76 72 57 33 61 -22 -87 -7 91 78 26 9 1 42 -84 33 22 58 28 17 -2 0 -61 -40 -52 -72 -23 -22 -35 120 -24 23 -41 -2 17 18 105 35 2 -9 127 -29 52 57 44 -22 -15 30 -14 -85 65 -32 -43 -22 41 -1 -4 -19 -13 6 -31 45 38 -13 6 6 -20 -20 -2 7 2 18 67 4 16 12 -43 9 36 -13 9 -8 26 18 4 16 11 19 41 -42 61 58 33 -28 20 -1 57 -7 26 41 41 -2 -13 18 -15 8 22 -3 -7 52 15 -5 4 17 0 -38 3 3 50 7 18 3 -4 -14 -23 15 13 -7 14 2 15 4 22 -9 -21 -23 -15 13 -15 -6 -31 -9 -16 5 6 3 32 -13 46 -49 23 34 -19 -31 7 -13 14 20 3 -15 7 -18 7 -42 -14 22 21 -6 -6 8 -8 -22 7 -41 -3 -19 -23 7 -16 -30 -11 -9 -6 -6 6 -31 -33 -6 -27 17 18 -4 -19 -6 -4 26 -22 19 114 96 0 -18 -3 82 -51 1 -42 27 8 -35 27 -8 -7 -16 -33 24 -2 15 8 -29 -9 -7 -9 39 10 2 -18 -19 -10 -50 -3 -38 -101 -28 -16 5 -27 24 -66 -9 0 41 13 4 -54 3 34 -48 9 -5 12 -25 -40 6 7 -34 -47 -22 -30 47 3 12 -26 2 15 4 -12 -20 -16 -3 -9 6 39 -15 -7 -48 -17 5 -23 -26 -28 -22 -20 37 -49 3 -4 -4 27 -21 -22 -15 -1 -35 -35 -33 -42 12 -25 -39 52 55 -11 -6 6 -10 6 -9 -6 1 -14 23 4 -63 44 -69 18 41 6 -38 -42 -17 -10 8 -8 4 -5 -28 -17 -29 -20 -19 2 -7 21 -13 13 21 -13 -22 7 13 -8 -11 37 -19 -33 28 -36 -25 -9 19 -9 -17 50 -54 33 18 -6 27 40 48 1 -6 11 -31 24 26 -24 17 -7 -23 -7 -1 18 -11 -12 8 -12 21 0 5 -10 -27 -8 -23 11 -39 14 29 11 15 24 -19 -23 -43 -18 32 -21 10 -15 -34 -8 -14 24 7 28 21 26 -12 2 16 11 29 20 -39 -10 -28 34 3 -2 30 10 -3 -4 23 27 32 28 -17 22 -10 -23 5 -4 22 3 -17 2 -36 16 57 -7 -29 -23 24 -26 -1 8 8 -4 10 -36 27 25 26 -18 -38 13 -12 22 -12 -11 20 4 -7 22 -15 -39 2 4 -6 -12 -37 1 -1 19 18 12 49 -19 -9 -35 -43 -30 -5 -21 -8 -22 -8 -2 46 -10 -15 -2 -43 4 -27 0 -13 25 -14 16 0 -18 14 -19 -26 -8 2 27 2 11 3 20 -45 -3 -66 22 44 20 -25 -13 -27 -21 -1 11 3 -10 -4 41 -11 -17 8 8 30 -35 11 18 39 -12 -20 21 -30 21 -23 -1 -4 -53 15 1 -4 -12 39 26 10 -5 -31 19 6 -29 -61 -14 3 6 -20 4 -11 9 13 31 -34 -17 36 9 -4 32 -21 -37 -32 9 37 -4 -47 -32 57 26 -3 12 -2 29 24 -3 -18 -57 0 -24 0 3 -12 18 33 26 5 -18 -5 -17 -29 25 -33 21 -21 16 -23 3 10 2 11 12 -3 -52 1 31 -15 -12 -6 3 5 9 57 27 13 -38 -25 8 19 29 34 -5 15 -25 -8 23 -5 -7 32 3 15 12 -20 -10 24 22 52 28 0 22 25 35 68 -47 39 -18 -15 -14 -13 4 6 6 16 -38 8 3 0 -21 16 25 -38 -8 14 34 32 24 -15 1 12 13 -18 -11 -4 0 36 22 -5 9 10 -34 -27 8 -35 5 -20 -9 -26 -11 -2 29 -10 32 19 2 -7 -16 19 6 9 -6 -24 -2 10 17 18 24 4 -9 -7 37 38 -2 -14 -6 20 -34 -13 24 10 6 9 -12 -11 17 -7 10 -30 4 5 -23 -16 -11 -4 1 8 -42 25 -15 -17 19 7 -13 -13 -31 -25 4 -8 -10 -25 11 15 8 9 3 21 10 0 13 22 -5 -5 2 61 86 -39 -22 -45 -16 -14 -4 9 -93 14 12 -38 27 -1 -7 22 -23 -1 74 -17 3 -11 -70 -58 -52 5 -13 49 34 -71 -73 57 -62 41 7 7 4 -43 -63 9 69 -22 44 0 13 -7 30 -28 24 -21 -13 -39 9 -22 58 44 1 -24 -5 -39 9 28 -28 -25 -45 -6 62 11 -8 11 15 16 -19 -12 -1 11 4 1 2 57 1 -39 -28 -33 -3 28 -19 15 -2 2 26 -14 41 -16 14 -20 -8 35 16 -1 -22 1 33 -21 -21 40 26 6 54 -31 11 -24 -44 45 -8 14 -40 -28 -8 46 17 3 2 5 -23 8 -10 5 -29 15 -48 -15 38 20 41 -58 1 19 21 28 -23 -2 -4 -11 -5 42 6 -52 -4 -3 -5 -21 26 33 -30 0 -24 22 19 7 -18 -2 -2 19 46 27 1 18 73 9 2 -36 16 8 24 -16 9 8 -12 25 68 -10 6 2 -16 23 64 -6 -10 18 4 -28 -33 2 -28 6 1 -2 -3 19 -11 13 7 36 -21 8 12 26 14 -13 -39 -5 -2 -25 -8 6 15 -3 19 9 6 3 57 8 -1 -3 7 -12 35 15 14 15 -9 20 26 23 -24 3 -17 -28 16 36 19 -28 -12 -31 12 44 -37 3 42 11 13 12 60 38 30 7 -16 -4 3 24 22 9 11 -25 14 -15 14 -5 -13 -27 1 12 -6 27 49 -19 19 -26 -2 -3 38 31 -14 10 -53 32 61 -81 51 6 0 -8 6 16 -46 -9 -17 -35 22 53 -13 -33 -34 12 15 2 -41 23 34 -16 -47 20 25 -33 3 32 -16 -13 -50 5 -28 -44 -52 -15 6 50 -32 -3 14 -8 -27 6 -1 -9 -58 -3 26 4 -28 65 56 -4 21 5 20 -4 -36 -72 -39 -10 -3 22 48 -58 -48 -13 37 -34 10 -98 -35 -78 6 -9 45 76 -21 -30 -40 -4 -20 3 -18 16 -3 5 -81 20 3 -53 41 15 34 14 -18 -9 55 -40 2 21 -45 -19 -10 27 -44 6 66 -7 -10 30 -31 -32 -34 -1 -13 46 -57 -13 -1 12 -37 -10 29 26 -55 33 -4 12 41 -29 -9 -29 13 6 -24 42 6 34 -13 2 2 16 34 1 -24 -3 12 -56 22 18 25 -37 1 -25 59 -40 -2 -14 -9 18 8 -42 18 11 37 -4 -12 -9 -24 -40 33 -33 -18 17 3 -20 1 56 -65 18 -5 -7 -35 6 -74 21 9 7 12 -5 -5 11 -5 13 11 -42 21 -9 10 -11 28 40 3 30 30 3 -8 14 -22 0 17 16 1 -14 19 2 12 -24 -19 -26 -5 30 -10 -13 -48 47 -5 -23 -3 34 -19 -47 -30 36 -12 -34 36 -5 -30 24 -2 49 12 40 21 -40 6 -30 4 11 4 61 31 -14 -15 -12 -2 -12 -45 12 10 -14 53 13 -4 3 -34 -10 -33 4 65 9 21 14 9 17 29 13 -25 -55 -56 -40 18 -15 7 41 -6 51 -6 12 -28 19 21 8 49 61 24 30 22 31 40 69 13 13 1 7 48 48 -67 -37 15 30 65 41 5 35 -26 9 12 30 -15 29 3 12 20 47 -25 26 -33 -35 42 -18 -29 56 1 -17 15 5 29 37 -4 26 -33 3 14 51 1 -12 51 -27 -13 -51 41 -21 44 -12 3 -9 6 74 -10 -45 13 -42 25 80 57 80 -18 48 -5 4 -57 12 -55 26 -64 10 1 -14 1 11 49 26 -8 12 44 -30 6 -1 9 -19 1 -34 11 -4 -45 11 5 -39 -10 -20 -5 -2 -2 11 -2 -7 -16 5 -16 31 0 -13 -17 28 -10 -3 26 -62 -36 15 9 -12 16 6 51 22 6 -19 -21 29 63 -36 53 40 -2 -46 13 -48 52 -11 46 -34 -42 -41 -78 -35 0 -25 8 -19 44 -18 14 -50 7 13 -11 -18 -40 11 6 2 58 -11 70 -12 -8 -37 -11 24 5 -24 30 30 -27 -4 -25 6 -2 6 5 18 -17 23 -30 -15 7 34 -16 -34 10 -22 34 -18 -9 24 12 -3 -30 17 -11 17 -3 14 27 17 21 -21 1 4 42 -51 -3 -1 7 1 -9 -5 4 -18 25 25 1 11 12 1 5 -18 21 -11 -13 19 -33 24 -24 36 -16 -23 -4 -12 32 -45 65 -5 0 -8 23 -42 -4 -22 36 -6 35 -20 6 -13 -4 9 17 -2 23 12 6 -9 17 10 -14 -70 35 -20 45 -6 7 22 -8 26 7 29 -95 -58 57 24 -15 9 20 25 -14 59 13 24 19 36 -12 21 -66 -5 -7 -11 -22 7 -18 63 4 9 11 33 7 -14 14 31 19 12 15 35 30 48 7 11 -5 -11 -18 23 25 -36 -37 52 20 8 -15 -30 28 -16 11 -16 -7 40 -2 -13 5 11 32 36 -36 27 -13 12 27 -14 74 -52 22 -20 -8 13 23 49 -22 2 -14 -6 -23 14 -42 4 -51 1 10 8 -3 -5 13 20 7 12 -11 23 3 32 5 9 -31 -37 3 30 -1 -5 -24 -38 -46 -5 -36 2 -18 -23 -39 18 -30 -21 -18 -23 -6 20 48 29 7 9 5 3 -11 -24 19 -1 26 4 -27 -40 -32 29 -39 16 -16 17 -20 -21 27 4 -5 9 -39 7 23 -11 -59 -7 -2 43 -57 -65 67 -22 -21 17 -24 -16 -48 5 3 15 -44 -45 55 18 9 19 -26 -15 -11 -41 5 -7 -8 2 11 31 -29 -30 -10 25 13 11 40 -9 -16 13 20 -12 21 -3 11 -1 12 -24 30 -16 5 30 4 -11 11 -31 -22 -46 26 0 13 0 -7 13 58 -9 -46 -14 -1 10 -20 -44 -5 16 -13 35 7 26 -53 8 -16 8 -31 12 -30 1 -13 8 -1 -28 -3 3 -17 33 1 -14 1 -11 -9 2 10 38 -32 25 7 5 -25 21 23 29 17 22 24 13 -10 -28 -20 -31 -8 33 6 -6 -7 -54 21 -9 -13 42 -19 -17 29 48 0 -39 18 -22 -10 28 -41 -37 23 52 -37 -3 -20 -26 24 -32 -27 8 -47 11 -16 3 -12 -15 -24 -12 -2 44 2 7 35 26 -32 5 -37 -9 30 -40 22 12 -3 -21 18 -83 30 19 9 -17 10 9 -24 -25 -13 2 -41 13 50 -20 -14 -5 14 25 -52 -32 3 39 -7 -3 -26 29 25 -75 12 -4 -13 -18 40 -26 -21 23 4 -18 -67 5 -49 -1 18 9 21 19 -10 3 43 -9 34 -19 55 -35 -15 41 -18 -27 19 7 -25 -19 -44 -15 1 -21 -46 16 -28 19 37 -55 -20 -45 -5 27 -7 1 -38 -13 5 -11 26 -6 26 -18 30 -12 2 46 -3 -28 -17 -18 24 42 35 17 15 -14 -1 -1 28 14 -1 -4 12 17 35 -35 0 -23 -10 -1 20 -56 4 -13 -13 -10 2 -8 16 -7 -11 -31 26 -11 16 43 2 -16 -11 -12 -20 -6 4 14 -31 28 13 1 -16 -2 28 -1 -6 -11 -2 -50 3 -5 19 -3 9 -8 11 -16 1 -14 42 9 -18 25 20 -5 -10 -14 -4 20 -30 2 -36 -25 -1 -15 -23 -6 -40 -19 20 -12 -15 7 18 34 -21 0 -13 10 -12 34 21 10 1 -42 27 14 27 -11 20 -2 -16 5 1 -22 5 8 -30 -18 31 11 23 -6 -2 -13 -31 31 -27 18 12 35 -3 -20 -15 -10 0 6 29 9 -8 8 -10 32 8 50 25 12 2 -56 16 -18 9 4 11 -22 61 -77 2 45 -55 53 19 -51 0 -8 -23 8 15 18 123 13 65 29 74 -11 2 -67 -40 27 20 33 -33 -4 -37 -1 -44 20 -20 33 51 20 25 -15 0 -40 14 1 -15 56 -5 8 38 56 40 -27 -11 58 3 -22 -15 -44 -18 1 -68 24 77 -71 1 26 -15 -52 -12 -60 16 48 28 18 -13 44 41 28 8 -60 1 -18 114 13 -18 48 24 30 -42 26 -12 -9 -26 10 -49 22 -31 28 -30 -58 -1 12 3 30 -43 -13 74 38 47 24 16 -21 20 -14 41 20 -14 29 25 -40 15 25 36 -30 11 24 8 33 101 -13 29 35 77 30 -52 -21 22 -3 56 3 24 1 17 -28 0 66 -28 -29 90 -9 23 17 73 65 15 33 21 -15 21 49 -38 7 -22 -39 28 -22 18 15 -9 -11 -18 49 7 -61 -33 -53 15 -19 -26 -39 -35 32 1 -18 -9 27 35 19 0 0 2 -38 30 20 -7 -13 -59 1 -19 -13 -26 -16 -6 46 3 -9 -15 2 29 -21 -5 -9 -11 -2 8 -15 -5 48 -6 18 1 -22 16 -8 -36 33 -17 18 -22 -11 39 9 -12 14 27 2 -10 -13 38 -3 22 21 -40 -35 -46 2 28 -38 2 -19 3 5 -37 -12 18 -9 0 -65 -9 -4 -6 -40 8 -6 -20 2 -16 -10 37 11 -7 1 -4 9 -20 -5 -14 -26 -7 -1 35 -1 -4 64 -39 52 9 14 40 49 5 14 -51 41 -14 -37 -60 28 -43 32 -11 49 54 15 -48 -8 -21 21 -95 -7 7 85 -19 -13 14 -26 20 35 -6 46 42 28 -13 37 -35 -21 27 -22 18 27 -7 -1 37 17 -24 -36 -11 57 3 -37 -36 19 30 -16 26 53 0 -40 19 40 74 10 -11 24 -31 -1 -19 -4 9 -85 -3 -9 11 11 -27 8 19 -50 -25 21 -38 -33 23 2 23 -35 -77 19 -52 -39 -30 42 5 31 -23 15 -18 -14 -52 -15 -34 15 2 -8 -17 -24 -10 1 -28 5 12 -17 -36 -4 36 -3 -22 -26 -22 -3 -22 52 55 -25 1 39 -10 -22 32 8 22 -37 31 21 -68 -18 15 7 20 34 6 -6 -15 -33 2 8 -60 10 -12 40 20 -21 45 30 30 -16 -51 -45 37 -32 4 0 -8 -32 -7 33 45 8 -19 -52 20 -15 50 -10 -3 -9 11 -3 10 4 -38 21 2 -16 -14 -25 -11 15 -11 36 2 -38 3 -21 12 12 7 -32 -10 3 40 -21 0 23 3 48 -15 -23 1 -20 -16 -22 7 -10 -1 34 -30 19 -15 -35 24 -39 5 -25 24 -9 -29 -38 -7 -19 -11 -74 11 22 -11 3 35 -15 9 -13 -36 7 7 11 -8 -5 -5 -9 -5 8 28 -33 -3 9 17 -24 13 -12 6 -4 17 -3 21 -12 -11 15 -7 -17 6 -26 44 -16 12 -25 -4 5 -1 47 34 -35 -26 -61 18 50 -17 6 -43 13 99 -7 -9 6 24 -67 11 23 -41 18 -5 -94 30 -13 5 46 19 -16 39 33 -3 -37 -13 0 19 -23 13 -71 -12 56 27 33 0 -1 -5 15 -74 12 -53 -90 0 -44 -50 -24 -11 -42 25 -62 -11 -39 -2 -62 32 -80 -23 -31 18 -27 -14 -41 -40 -7 -14 -29 6 27 28 52 -9 -59 -60 9 4 -66 34 34 38 -39 -30 34 -71 4 -6 -26 53 22 -20 -27 -19 62 -33 -56 -48 0 -9 10 -45 17 31 -8 4 -34 22 12 3 24 10 20 -25 -10 -42 -32 45 32 53 29 -2 -25 -3 10 -3 2 8 49 -1 39 51 -9 -16 -12 -42 11 -28 0 18 53 21 -19 0 -10 -18 -19 5 6 12 20 -29 -5 -24 61 -8 0 -77 6 -42 33 26 -27 1 -2 45 29 -3 54 12 53 -5 25 10 19 -26 -8 10 30 4 48 -6 17 34 14 3 0 0 8 -10 -24 19 8 -4 -1 26 -48 -13 51 18 -1 -34 -8 -20 4 -22 -9 -4 -4 -3 -24 45 -7 -38 33 9 22 -27 19 0 13 16 52 -29 10 36 54 -8 -8 -8 -43 -17 -15 29 41 -45 -35 -12 8 -59 9 -18 25 -11 -20 -24 7 16 13 10 38 -32 -33 12 21 9 -12 -30 -44 0 -62 5 -33 13 -12 19 15 -47 -20 4 -37 -7 23 -13 -29 -10 0 -24 -13 -18 -1 -35 68 -50 63 26 -10 4 2 7 4 20 21 -20 -5 18 -47 40 -30 -22 1 11 -3 14 -43 -83 6 4 -104 9 -39 24 42 -16 18 16 5 38 43 -8 27 58 -16 -19 -6 4 -17 -7 -50 -4 44 33 19 -34 -13 29 -18 44 -13 -43 32 43 27 30 16 -40 39 54 39 -4 21 12 19 6 86 -8 -35 38 47 18 -3 -5 17 17 45 -49 30 18 5 -12 54 -9 -2 17 -10 26 -23 -19 31 -18 -23 3 -19 -27 24 11 -16 21 -63 5 -5 0 -20 -39 51 -6 -53 -32 -5 14 -5 21 11 35 29 -19 -34 -9 -21 -29 -36 47 16 13 -13 8 -2 -15 16 10 9 -7 2 -4 -27 31 -5 -27 -2 9 40 -11 3 -16 51 -54 17 -16 2 37 6 -28 -20 -28 -29 -24 11 -10 2 -16 52 -22 10 -7 -7 3 -42 11 -22 3 45 -13 25 -23 41 0 -20 40 -77 38 23 -20 -32 -33 -12 -2 -7 -8 -4 -19 -22 -35 23 -25 -7 3 -8 16 36 2 3 12 -29 -7 10 23 6 25 0 3 -16 26 3 -12 26 14 -11 -10 33 -32 1 34 15 -1 9 -37 16 10 6 36 -6 11 -18 -19 29 13 31 2 1 -6 -6 -28 14 1 6 -27 7 -67 -19 4 -18 2 -32 4 -12 34 29 -28 12 1 -19 -8 18 14 -6 2 -12 -9 10 -37 -31 -24 -28 26 -2 12 2 30 25 -15 7 -11 23 -7 4 -21 -11 9 -1 23 -29 63 27 50 9 -2 -35 15 20 6 -3 16 -64 9 7 16 -22 12 -4 35 -4 -12 64 12 21 -31 -3 -19 17 -30 27 31 -14 -68 -8 54 53 34 37 -31 22 -20 -37 -38 23 -61 -58 -67 32 2 -60 -6 -24 8 -49 -24 -28 -38 -7 -4 26 25 8 -16 45 14 39 21 15 3 -45 -22 -9 22 -21 -17 14 -12 -35 -13 64 3 -21 -37 16 7 -12 -17 -4 6 -2 -32 0 23 43 -25 -21 -36 -34 6 7 14 5 10 7 25 10 22 -55 46 -28 -2 -4 10 10 16 -27 -12 14 -18 38 -41 -2 -29 -27 22 6 -32 3 11 -18 -17 26 4 -27 9 20 9 -21 -40 -49 -49 -20 3 -44 -34 22 -29 34 19 -5 17 9 -30 14 38 -36 20 -24 3 -28 22 22 -27 -12 -47 12 11 -30 23 6 41 -22 -7 11 -7 28 -12 -14 -36 -37 10 14 -19 7 -1 1 -9 9 -2 10 -11 -18 -10 48 -3 -12 13 15 38 8 -15 -30 -2 -7 -3 -9 21 6 -18 -1 22 -30 -8 19 15 37 12 -25 -20 -12 10 -18 38 -26 8 -11 8 5 -19 12 12 6 24 -7 29 -7 39 5 -13 21 -26 25 6 -16 -10 -24 18 -26 3 25 22 5 -8 -15 17 -17 23 -35 18 4 -25 -15 22 18 15 -34 14 -22 2 -1 7 17 13 20 6 2 -5 -31 -1 -19 4 46 30 -6 -15 30 -110 22 -16 38 -13 27 -37 66 69 -21 -9 -37 -17 42 -4 -21 -8 -14 33 64 45 -18 33 -51 79 -36 63 59 -27 -20 35 -38 -11 -19 23 10 -24 0 -8 -11 6 14 21 0 71 34 30 6 35 -48 -10 -4 6 96 19 21 -20 -5 12 -20 23 5 18 -3 -30 -6 -25 32 19 11 42 3 18 62 15 -13 -1 24 -20 3 25 -28 17 4 -17 26 35 -4 4 -28 22 36 21 -54 13 -12 4 -16 10 -22 35 4 13 9 -6 33 -27 10 -15 -17 -32 28 13 40 0 -8 11 -20 0 5 -27 22 30 -9 -5 30 -6 -36 9 -15 20 39 -2 -1 12 27 32 9 -17 9 30 13 30 53 -4 24 30 12 29 -3 5 32 -1 18 -62 5 -44 7 29 -19 36 12 -12 -23 -6 10 24 -19 9 30 -2 31 -30 16 -46 3 -10 1 -12 -20 -22 -11 22 40 -11 10 17 17 -31 3 9 5 25 -7 21 -8 25 13 21 -50 -1 -26 -43 -26 6 13 16 -37 26 10 0 -7 17 1 -10 -14 8 -20 20 -13 -38 -13 24 1 8 -19 9 -40 -2 40 -28 2 4 2 16 -4 4 -31 -16 -13 7 -35 1 13 4 2 -12 -7 -8 15 2 -1 14 -11 -13 -32 5 -20 -19 -21 -32 7 -2 16 14 25 -6 -24 38 -12 -46 32 1 -27 -18 -35 -15 -13 -37 44 36 -9 -9 -31 42 37 -33 -1 5 13 5 47 -25 1 67 -20 40 21 -16 -27 48 12 -1 -10 59 -24 45 58 71 -9 17 64 72 -12 5 9 8 -40 7 -19 32 -15 58 60 20 8 38 30 3 -17 -14 73 12 15 27 -16 -43 16 47 -29 28 40 21 39 26 22 -26 2 -32 -8 -73 37 54 10 -25 18 28 42 -31 -5 18 69 -14 -58 -30 37 7 -10 58 59 38 26 36 11 -49 12 56 -48 44 8 15 -42 1 -14 -15 21 21 27 31 40 0 -3 25 18 3 29 16 36 -17 -2 -18 63 4 0 -50 13 -11 5 26 16 37 5 -11 52 -11 -21 -16 -8 -4 2 -7 -17 -9 -17 13 -22 -15 34 22 50 34 -14 31 -23 15 -8 -7 11 7 -23 -20 -24 -25 -10 -66 16 -20 -23 43 -26 6 52 2 6 -33 8 47 -15 -46 24 -12 -4 61 21 6 -26 -25 -4 20 -19 -23 -19 2 10 8 25 10 0 23 -7 -14 -54 -9 -27 -13 11 19 -28 12 -4 25 -3 -26 27 -8 -22 -19 0 14 12 -24 21 -4 28 -16 -11 11 13 14 9 0 17 26 -25 10 18 -8 -1 -12 24 -32 2 39 -9 -30 -28 19 -1 -8 29 -2 5 -25 0 19 -7 -23 23 -24 25 1 18 -61 3 19 19 -27 35 54 10 43 31 50 -14 7 -2 6 -39 -11 -26 -9 -8 -27 25 29 -15 -4 12 -9 -4 -23 41 -16 -27 -3 -29 12 -18 -36 20 16 16 14 20 -1 6 -58 0 -22 -38 46 -12 -25 -33 9 -26 -50 16 -19 29 64 -15 9 16 -3 -12 23 10 -26 -9 -3 11 -12 26 -11 6 -3 -15 12 12 -18 -46 -29 29 10 20 24 -2 7 -8 -2 2 20 1 28 7 42 -26 -8 -63 -17 17 34 41 -36 25 16 12 17 24 28 2 -27 -16 -30 10 -36 -30 6 8 5 -14 -17 -24 10 20 42 -19 4 35 -9 8 -13 -11 25 24 -9 -26 10 -9 -32 -14 -5 2 -23 -20 -34 35 -23 -28 -11 -19 46 -14 -8 5 -38 1 5 -14 -1 -5 1 -2 10 -50 -18 -4 33 6 -20 35 9 -14 16 10 38 -26 20 -26 23 17 5 21 -1 -3 11 -29 14 -37 21 -6 18 4 15 -13 37 -24 9 -23 -42 5 -26 23 3 7 51 -1 17 -11 56 -34 -19 -2 -13 -23 -1 -15 -5 30 23 -7 18 -4 -1 -29 3 17 -41 -7 -27 -32 -18 -5 12 24 -10 17 -2 -33 4 0 6 -1 7 18 1 -14 2 -23 -8 -6 43 -27 -4 -5 5 -23 -34 -29 12 26 -3 -12 18 38 -14 6 18 3 -15 -7 -11 9 -8 15 -25 14 26 29 -30 -22 -33 18 -13 10 28 -38 2 14 21 14 4 -12 0 -12 -12 -23 12 0 -25 22 14 34 3 4 17 -6 16 2 40 -24 47 -4 33 -31 -27 31 18 37 -33 0 -35 -16 -10 -18 -2 -37 1 20 27 46 12 -5 -40 1 -34 9 29 -10 -13 27 36 -35 11 -12 -6 -12 -20 -56 -4 17 4 3 2 1 13 -10 -37 -36 -33 11 -5 -13 -8 35 -26 -35 45 26 26 -47 -4 -29 4 -13 -28 69 31 48 35 -13 5 58 -31 13 -29 42 -17 20 18 22 7 -31 46 -16 15 -17 -5 -27 2 12 -32 5 -20 9 5 -1 11 18 -26 16 -45 10 9 31 6 37 19 -11 0 -25 -12 1 -51 33 -13 19 -2 9 11 -16 23 -7 34 2 -18 8 9 -3 -11 31 6 35 5 -29 2 -27 -12 -38 -14 5 25 -3 1 -12 -27 21 -37 -13 12 -15 14 8 2 -18 23 -25 -50 -42 0 22 2 -37 17 -10 -12 -16 -28 23 -5 -8 -24 20 -23 -7 -27 -48 35 -19 28 -1 -27 -25 -14 4 0 27 -27 -7 5 -42 0 13 2 6 -22 9 -17 9 -18 19 4 3 -16 9 -27 8 21 -10 17 -4 -6 21 8 9 34 -6 -12 -23 2 4 -3 5 18 -4 11 13 -2 -37 8 -8 47 40 -23 30 -6 15 -5 -6 -5 -23 22 5 -16 -33 -7 17 -8 5 -8 -29 16 -21 16 -10 -10 -11 -18 -24 6 -13 -16 14 12 -48 -18 20 40 1 6 9 -6 34 -22 41 20 -15 -6 21 14 3 -18 -2 -5 7 23 2 -11 -1 13 -30 5 -39 14 -2 -5 14 -17 10 -20 -27 37 -45 95 5 31 61 20 -3 13 3 37 -11 -18 -16 52 -9 -21 4 -14 22 56 -17 -22 -24 53 -45 24 100 -3 9 -33 4 -20 32 -16 1 11 25 -18 -23 -44 -2 -34 37 -53 55 60 -16 6 -22 5 -21 5 52 58 -28 -7 -4 5 45 -35 11 -22 -5 63 -72 -9 17 17 -30 -1 -110 43 11 -4 -13 -31 11 -32 -21 -10 75 -5 -34 18 56 -12 -4 49 -13 23 -3 -16 11 4 9 -24 -15 8 -6 -2 30 -17 50 -3 0 20 -4 36 -22 34 -29 -17 -19 23 1 -25 32 5 29 0 -48 -6 -1 -22 -1 0 28 9 -10 -5 11 -40 30 -31 -7 37 -11 -49 16 25 30 -10 8 -23 -16 -14 29 -23 -30 -1 45 -11 -31 -37 -5 3 2 -27 38 -18 22 -10 28 -4 -11 17 11 -36 -2 -2 14 -47 -15 14 30 27 -27 -19 4 36 8 -18 18 -8 -8 15 13 31 -15 -34 -3 -4 -21 21 -4 23 -1 21 10 -6 -8 -13 7 -16 11 10 -18 5 -14 14 -31 -15 -12 -7 6 -12 -5 -9 0 7 1 16 -10 -9 -14 -27 22 22 -32 -33 18 7 7 -10 15 41 -44 8 -35 7 -1 -20 -8 1 26 11 22 -28 2 7 -18 -11 22 13 -8 -2 -27 16 -33 4 1 26 1 25 -13 14 7 23 -20 1 24 -21 -11 13 -32 -23 -11 -53 -3 23 14 40 10 -7 17 23 41 1 -11 54 25 16 -32 10 -24 -55 55 -1 23 30 -49 12 37 -45 29 -19 6 23 -5 22 62 41 -33 0 55 45 2 -24 0 32 -16 -30 -8 27 -5 29 -19 0 18 -31 18 26 10 34 2 -22 5 -3 -42 -6 18 -5 78 75 18 -19 23 -9 -10 55 24 -29 28 -6 -20 -21 14 -21 -20 46 -6 7 22 -41 18 9 25 20 49 15 -12 -26 -12 17 12 -29 1 52 -7 -17 -1 18 -26 -6 -12 23 -12 -34 7 24 -18 -16 32 -23 -1 23 -9 -45 -14 -22 13 -9 -19 -10 -40 -10 2 5 -35 21 -24 -23 23 46 34 17 -12 -15 9 -23 -4 24 -9 -42 -9 5 -8 11 1 48 40 4 -12 -9 -28 1 19 -36 23 -24 -1 -7 12 -10 -12 -37 -4 19 -24 -48 -15 8 -24 -32 4 11 -14 -5 -3 -9 21 52 -11 -22 -8 31 -15 1 -7 10 23 -5 6 25 1 -36 13 -2 29 6 26 -23 16 28 5 -12 11 5 4 45 7 6 -22 2 -14 32 -39 -3 -33 7 -19 5 1 4 4 0 43 10 8 0 -6 27 28 -8 -35 -22 -53 6 43 22 -5 28 30 15 -14 8 -19 15 -27 13 20 31 18 -33 -25 -11 7 -10 22 -29 -9 18 -2 -7 -27 21 11 5 24 -5 -8 14 -7 0 -24 -7 8 33 10 17 13 -16 14 26 -5 11 -43 39 68 38 4 -26 47 2 -55 -28 -37 28 71 -44 13 17 -31 26 11 -67 -7 16 12 -18 -27 -54 -70 10 18 -41 -37 -55 -40 59 5 81 5 19 -18 27 -7 -18 -53 19 73 1 11 -57 -12 12 -34 21 -6 22 -1 -20 16 5 -17 -34 -58 -18 32 -39 0 -14 24 -43 33 11 9 -12 19 -2 8 6 -15 2 -17 13 -27 21 65 -23 -27 -20 -21 3 55 -1 -31 36 13 22 -18 -12 65 7 -33 15 -3 -11 15 30 -13 10 8 44 14 29 7 -16 -5 -18 -9 -5 -3 6 11 2 68 -2 20 25 -2 39 35 -18 3 10 -71 -47 -26 17 -23 15 -14 -16 -9 -18 23 -65 -18 -27 -14 -31 -56 9 -2 -25 17 -97 -28 -34 32 -3 91 26 -49 3 -28 -25 -105 4 -1 36 -1 -20 -60 21 57 16 -13 30 -16 -74 -6 -59 -15 30 9 -41 -17 -33 54 -18 -14 -17 -47 -78 -28 -5 0 13 -24 12 -6 23 5 42 -24 8 -19 36 -13 44 15 2 -10 -5 -15 -8 7 -11 -11 24 -22 -15 4 11 -15 -13 1 -23 39 -25 19 9 0 -13 -18 -23 -36 6 -25 -14 -3 23 -12 19 16 -11 26 -32 37 2 -25 -12 -1 -3 9 2 -47 25 -3 -3 15 -5 37 28 -7 -5 -22 3 -37 -20 32 -25 42 17 -15 -4 17 -16 36 6 -21 63 -3 -6 -61 -27 5 7 -43 24 -42 20 35 65 -53 -10 8 37 56 -4 14 -20 4 -36 -27 34 12 -44 25 -42 -11 -34 -22 14 -32 25 -26 -32 45 31 -47 32 -9 38 45 -39 -8 -49 -29 -61 -1 7 61 6 0 -10 1 41 5 -11 13 -80 -47 -30 -12 -12 17 62 -10 16 6 37 -49 13 -39 -13 -63 8 -30 -28 20 -36 28 22 -64 -25 -10 -11 -51 7 -8 22 42 -25 -56 -13 43 -4 -8 -10 -21 -32 53 -25 -11 -38 -10 9 11 -48 20 -50 -9 -13 -33 -53 19 -28 1 2 -44 -27 47 -12 -13 6 -17 10 -15 63 1 29 -16 -8 4 13 -2 -5 19 6 -21 -65 -17 54 41 3 13 17 -17 24 19 1 -28 40 -11 -37 -6 -10 -11 -9 25 -40 33 -7 2 2 1 -36 26 13 -10 -8 24 26 11 -21 45 36 -39 -16 76 -30 -26 -11 14 -33 -13 4 24 21 -36 -27 3 10 -44 9 11 50 13 26 4 -6 -16 -8 -5 1 29 10 20 22 -14 -2 -38 -30 23 -40 -4 -35 -18 1 49 16 -17 8 -10 2 18 -21 -9 5 -11 49 17 -18 -2 -13 7 20 -2 24 10 -36 23 22 14 0 26 11 16 -15 -3 10 -19 -11 -25 1 -21 11 44 27 6 32 31 15 3 -17 10 5 3 34 -13 -3 44 9 -8 33 9 -20 -38 -17 -8 15 -7 2 6 -20 12 22 -5 28 6 -28 8 -6 3 -21 16 20 -6 52 -37 55 -12 -1 38 -15 -44 52 -6 26 -3 -48 46 -55 49 -12 -26 32 17 56 65 -10 27 -2 -15 -35 -114 -5 -71 -109 24 52 -16 88 46 0 -40 -23 31 -16 36 -31 21 -6 49 -47 -47 -15 74 -6 26 -3 -45 9 63 -20 -8 -81 127 -18 53 -4 45 62 75 -5 -15 15 34 96 -3 72 34 -49 -31 5 71 41 48 10 -35 48 16 -6 78 30 23 98 -6 12 96 -10 81 33 23 4 -6 -14 -9 44 37 -75 23 26 12 45 -54 -33 -17 6 -46 3 35 61 15 -28 15 -7 18 -5 -18 20 -81 -4 18 -21 16 -16 -56 22 -13 -5 28 -26 12 -26 38 -24 63 -30 13 1 -11 62 -18 -9 19 31 -59 32 -15 -15 22 -25 -29 -58 -57 -11 32 -3 -48 -51 -1 96 -12 11 -4 -15 -6 -40 -34 20 -27 -38 44 72 -34 -42 57 49 -62 36 32 -13 1 27 31 -29 -3 3 -68 -16 20 4 4 -18 -50 21 10 -27 12 -37 -41 -11 -63 41 29 -15 5 31 -50 73 6 -11 17 30 4 1 -5 -32 -19 -8 4 -26 37 -10 18 -35 -52 2 -21 -13 -22 0 -2 19 -3 64 -8 -16 2 -1 -24 -57 -9 27 -36 16 -19 -1 -4 -7 18 9 -9 -15 -46 -4 7 23 -13 64 -14 24 26 -43 -46 40 16 -7 13 21 1 -7 -20 31 38 -47 26 43 -23 -56 -5 53 33 30 48 62 20 41 10 27 27 35 38 3 52 18 26 -67 -18 24 82 14 67 23 62 47 -18 -58 -52 31 39 -23 -16 -14 -3 64 10 10 47 -16 -37 28 12 16 -38 -60 33 -24 -10 58 -29 48 26 50 1 17 41 14 -26 72 -2 78 19 19 -2 -13 21 -57 3 -19 -13 27 -29 -69 -3 -43 -22 -27 66 -31 -1 26 7 15 -7 16 5 -13 89 14 69 -40 -11 -52 4 32 10 15 -34 15 -30 27 24 -54 74 -27 -18 -14 78 -43 -13 14 43 -30 -36 -50 5 -17 -6 -1 -35 31 4 40 -59 -11 29 6 -13 15 -14 2 10 54 -13 1 17 27 -26 2 22 45 -39 -3 0 11 -53 30 -15 5 -57 20 14 -7 44 33 28 28 -2 -47 12 4 -16 -19 -55 4 -7 12 -14 9 15 13 8 19 32 -10 -36 -6 -5 -68 -15 -7 11 -17 -33 47 10 -27 3 -74 -63 35 -42 -60 44 5 -17 0 14 -10 20 14 21 -15 -17 34 -10 2 21 0 -15 -40 27 8 1 39 -4 -50 9 45 -23 -17 16 23 -15 1 5 -17 7 3 -53 -12 -8 -21 -8 -5 10 4 69 51 -22 55 25 -4 41 -27 -16 -31 13 51 -4 24 -21 0 21 5 1 42 19 -13 38 -21 19 -4 -10 3 44 -57 -8 11 -13 -3 -47 2 27 -9 -26 46 -2 22 23 -18 -38 3 16 15 3 -17 -20 35 -14 -2 -1 5 -32 -31 54 -13 23 6 -22 -5 22 -6 6 3 -26 25 -4 7 -3 2 -19 -31 -30 -36 -23 26 -28 -22 14 -32 19 -42 61 -32 8 -16 -28 -42 29 -13 32 0 19 15 -13 -53 -29 -17 -10 10 -30 6 19 -13 -25 32 12 -19 21 16 4 -5 1 -3 41 -7 -39 -33 0 14 29 33 1 33 -56 -37 0 19 15 23 18 -16 -43 -14 -30 5 -60 5 -14 19 37 -1 -3 -31 -3 22 18 -22 12 29 9 12 16 -12 31 7 3 26 17 9 45 12 7 -5 16 -14 9 0 13 -11 -24 6 28 5 17 2 -24 -26 -24 23 37 10 -45 24 -25 -2 1 -10 -18 -8 -4 -17 12 -3 45 16 -36 -10 10 -1 -9 -17 -4 -18 11 13 -28 32 -22 -12 2 9 -39 25 -28 -22 19 32 2 -26 -55 6 -14 -15 9 10 44 -61 -30 3 -15 6 -41 -11 4 22 -5 14 14 -2 -7 -19 -50 12 -6 5 18 -10 -27 -12 11 -1 7 -34 9 4 -7 5 7 -16 9 18 -18 22 5 17 -5 16 5 8 -12 -33 -35 -19 -40 -34 -46 -37 -9 -17 -11 -28 -19 -11 2 27 14 6 8 5 -19 -11 7 -18 -7 -23 10 -11 32 26 -13 -1 -25 33 21 3 11 -7 11 20 -4 -4 -24 3 -11 -21 2 -5 10 15 -9 15 17 -18 -3 -31 -1 -14 17 15 -17 -8 7 15 -31 28 4 17 -59 -30 21 44 -23 -79 27 -4 -59 -4 -125 -57 -74 100 33 44 38 -37 -5 -56 1 -76 87 -47 -40 2 -40 -41 -17 17 -73 -80 -118 46 52 -38 -26 4 -27 -56 -52 -1 -3 -11 33 31 -3 -30 8 21 -1 -37 3 34 -43 -91 -62 -47 14 61 -61 -12 43 -25 -33 -13 -89 -33 -32 -43 85 -29 -61 -85 -62 -105 -37 -17 -83 5 39 -27 -6 -45 -95 -56 -54 6 15 -51 9 -41 -33 -67 -41 -33 79 71 -1 -8 78 -76 45 -27 -42 -36 -36 -34 -46 -10 31 -74 30 -16 -4 -68 34 18 27 -8 55 17 -39 -52 -11 55 -10 -4 -36 -15 -46 23 44 27 -19 42 2 1 31 32 -7 56 -40 -30 -2 -39 -52 -94 78 28 34 -38 -27 27 -19 15 -4 -3 5 68 12 -20 49 97 71 -43 -8 13 -11 -31 -15 -14 -68 -14 -23 -8 28 55 -6 24 23 -2 -49 -21 -60 27 -16 -27 -42 -45 -16 4 18 -24 -8 22 -47 -43 -14 9 23 -11 -53 13 10 -30 -29 -51 4 -19 24 23 -7 -5 -9 0 11 -20 15 3 20 -23 53 17 -52 -3 -25 -9 -10 13 -3 -46 -30 22 12 56 31 9 10 -21 16 21 19 36 12 37 -32 1 55 9 55 -20 4 32 54 -14 -23 18 -38 5 52 4 17 38 -29 -27 -35 -7 -72 7 15 -6 29 25 15 -78 -5 -70 -7 46 27 -10 4 5 -14 -19 55 -25 -28 -28 -14 15 45 27 -26 26 -22 1 39 1 -6 32 6 50 -70 13 15 102 15 26 81 58 81 -78 -2 11 -22 -3 21 -86 2 -55 -30 -102 20 36 -8 91 21 -30 -16 82 49 6 -1 21 -13 -10 76 3 33 7 -26 -5 -7 2 34 18 -42 -39 15 0 40 82 56 -24 29 50 43 30 92 44 17 47 52 9 100 85 34 18 -42 -10 30 28 74 61 -19 -13 -27 32 -32 22 -10 -1 38 -23 -6 83 -84 -44 -82 -23 -27 10 -64 14 -28 -45 57 8 17 57 -36 16 -8 -29 35 34 78 76 -58 -34 -5 33 -15 87 -24 36 16 15 -17 13 33 14 31 -43 -52 1 -5 36 -3 22 -31 -28 41 -30 -3 41 15 -11 32 -1 55 -51 -26 -11 -17 -62 -8 -44 0 9 23 41 -60 39 -39 -6 -8 51 63 -61 48 -55 65 -58 -9 -3 -16 -42 -64 22 -42 -29 -28 -47 -36 30 47 30 -51 26 46 23 36 -45 31 -20 26 -27 4 -1 9 20 -27 -16 -22 -4 3 -17 12 -27 -36 3 29 15 0 -35 -9 39 14 0 34 36 1 1 1 6 -36 82 -16 -33 5 39 -30 27 -66 31 -19 14 -13 6 24 -47 1 0 -16 6 25 0 -30 -12 -5 1 0 -21 24 -5 11 -2 -28 -10 3 -18 -25 -50 18 12 -9 -3 -22 15 -2 -15 19 -7 70 10 -13 29 -41 0 -32 16 21 -17 28 12 -96 -36 -33 62 15 40 21 -10 13 -2 -10 9 24 13 13 -32 24 41 23 -18 -18 -15 41 48 53 76 69 -65 -17 -50 -2 2 16 -28 0 22 -8 -18 63 -69 32 70 -13 23 126 7 25 15 79 -68 3 12 -45 -45 -21 -41 -35 -5 94 64 59 51 32 -42 76 5 40 29 24 -34 -30 26 -10 -25 117 9 -17 57 37 31 23 25 47 10 40 33 43 39 58 28 -22 14 22 -7 -26 71 -88 14 -12 45 5 -57 -8 -40 54 20 -13 26 4 27 -23 2 -23 39 72 38 -37 67 -12 7 -25 52 -50 94 33 16 66 -22 20 105 -10 29 -36 -76 24 51 16 21 29 -31 -35 10 1 71 -43 34 -12 6 2 -34 -127 -14 6 -35 39 28 3 -5 127 -7 18 30 80 -24 34 -1 60 23 34 3 -20 94 -44 -21 7 3 20 -36 -15 33 -24 4 26 47 30 49 12 33 9 -8 7 9 18 12 16 43 44 -5 -50 8 -27 34 4 -13 -3 -32 12 10 -47 -4 -33 7 -50 1 28 23 31 43 29 20 9 -1 -8 14 -40 -5 9 -5 19 44 -67 -30 17 24 -9 -16 -12 -5 17 1 37 -3 -50 -18 1 -10 -37 9 47 -37 1 -14 -22 2 25 -12 -23 10 13 -1 -48 -19 45 41 -35 -10 33 -2 21 20 -43 -9 29 -18 -14 -20 50 -12 -5 40 -3 9 15 -40 5 37 56 33 -14 -12 -35 3 56 -19 -63 54 -33 69 47 -38 58 20 78 -4 -125 -51 -31 6 24 -9 3 -66 -8 88 38 -1 25 -41 -16 62 -15 -86 9 61 21 -17 -9 -51 35 -44 57 32 8 22 -26 -44 -32 -37 47 65 -84 30 -7 -3 -34 64 -6 -52 41 90 -71 -48 -39 28 -12 25 13 9 58 35 -18 -24 -4 14 43 8 66 9 -45 25 4 17 13 34 36 1 101 -42 -13 -85 67 -15 -10 38 0 65 -47 24 24 -32 28 -54 85 -30 -25 18 2 -2 -3 15 -61 7 -33 20 20 7 25 42 -43 -20 20 20 27 13 -14 95 45 -11 9 -9 9 75 7 127 8 -13 49 -37 -19 66 -9 15 -23 -86 19 29 -22 -4 11 -42 -46 20 24 78 38 36 -106 18 77 30 23 -77 -55 -25 -7 -1 -39 -13 -8 32 53 -7 -1 -7 50 -40 5 11 -16 51 -9 -1 42 62 83 -37 12 -34 -22 20 -31 11 -28 -27 -40 -1 31 -10 -49 18 -40 -15 -5 0 -26 36 -59 -34 -29 -13 -24 16 6 18 20 -3 -9 0 24 -23 16 -68 27 1 -14 12 -19 -9 3 16 -37 25 63 31 -46 16 5 -14 2 -30 -32 -17 -7 27 27 5 29 27 9 -14 -2 15 26 -29 53 16 34 30 26 -7 63 -15 -40 2 -44 -9 19 -22 -37 -5 7 9 -37 -13 27 17 -20 53 27 3 16 12 11 19 24 97 -17 -61 -39 -80 -38 0 -10 33 -12 63 40 38 72 30 -13 57 -17 -2 21 -32 8 -68 -5 32 -6 15 97 25 -15 -5 -10 98 14 -6 26 36 -60 46 39 59 37 58 32 5 61 14 22 52 -48 -15 46 25 33 21 25 -21 -24 -13 79 32 1 22 -10 35 84 -64 95 46 -19 48 0 68 31 4 39 -42 2 -15 36 41 -19 -19 65 -31 51 35 -16 -41 -47 31 -46 -12 30 49 -1 37 -122 -1 -65 -6 35 -44 5 32 -3 57 -13 -66 -5 3 6 19 -6 51 91 -5 -13 2 -38 -7 -44 -52 10 15 39 7 -7 -14 -13 -5 79 -55 -16 2 -8 -44 -127 -47 -14 -4 39 -4 52 -7 12 -14 19 -23 77 -50 -35 42 19 -40 63 -20 65 -27 -19 -57 44 4 -17 -13 27 -32 19 36 -75 -7 -15 20 42 30 8 13 52 36 -43 -46 12 -34 -54 -49 16 32 9 -23 0 -19 -22 -19 -9 -4 -27 24 -36 -18 42 -38 1 26 11 35 -17 -8 2 51 -5 -41 -6 9 -9 -18 12 11 13 -21 37 -15 23 -21 -13 55 -4 21 -39 6 5 -20 22 -17 -13 37 5 -21 -6 -16 -26 -13 -12 -11 17 -28 13 12 8 -11 -49 -20 -41 -17 13 62 7 5 3 0 47 -8 64 3 24 -2 -8 19 14 -54 8 34 17 4 -1 -36 4 -31 39 -59 17 -12 4 -15 32 1 -1 -11 82 -64 -20 13 -51 5 -35 -17 24 22 71 24 -12 17 56 -24 41 47 125 87 -12 56 -8 78 -14 -23 20 -19 5 -8 13 47 -9 -3 -22 -43 14 -21 -88 8 -19 -48 2 37 0 7 -50 78 -57 26 -63 -11 -45 37 -35 -68 65 25 17 121 10 -14 -68 29 14 -26 13 0 11 87 1 16 -47 30 65 -10 -34 12 81 63 -11 5 -56 12 -4 31 -24 104 35 -82 66 15 -60 -42 10 7 -39 -13 -11 100 60 -6 37 -35 30 63 74 24 22 82 -23 -22 66 78 -26 -16 -51 -46 9 56 11 31 -28 -19 -44 -20 -105 -2 -14 -11 18 -23 68 27 11 38 -9 55 3 4 -46 27 -28 9 -68 -35 -50 0 43 -25 -14 3 35 -9 -31 -17 41 -9 1 -19 37 72 -8 -61 -68 -25 -5 49 -34 -50 1 24 33 18 26 49 10 -58 20 37 0 27 20 -14 14 -27 32 -9 34 1 -41 -16 30 40 -5 -24 -1 -17 68 16 -51 3 52 -31 -17 13 -34 18 -8 -7 8 -22 0 -21 11 -5 -53 1 29 -43 34 14 5 39 -2 -16 -26 -2 -41 -16 -13 22 8 21 9 -37 4 12 -18 -9 5 -18 -6 12 -2 3 -16 -61 -6 -4 -12 52 10 -1 12 -37 24 18 -35 -9 48 -31 28 -13 20 14 50 -2 -20 12 -27 13 6 37 1 -3 37 -13 10 -13 -6 -34 -76 -4 -2 -31 -21 32 -3 -91 127 38 90 -1 28 -10 -123 68 75 26 33 -36 66 6 81 -33 10 88 -7 42 -31 53 63 -85 2 66 -1 46 36 -42 -23 70 4 -113 -12 -36 -81 22 -1 -8 39 54 37 53 -51 1 -22 -55 -38 50 -19 34 65 -64 -39 -40 -32 61 -60 20 127 36 127 64 14 -52 -90 44 -7 -19 93 17 -24 5 -8 -23 -4 2 71 11 -44 65 -41 77 1 -51 35 96 -4 7 2 -10 121 -18 21 6 -61 32 -35 1 -5 9 -50 -10 100 22 35 37 0 -7 9 15 -9 56 85 14 -10 -15 50 50 -4 -82 23 34 -2 52 25 10 -43 60 -41 -32 -35 88 93 22 -10 -1 57 -72 -10 -22 -44 -34 14 45 -5 27 -73 33 61 -61 15 21 23 52 26 98 104 -66 45 55 7 -65 55 -16 34 23 1 -20 13 26 97 30 -13 19 3 -35 27 43 -8 10 -18 83 13 54 -3 -13 23 -36 -11 14 -25 -22 18 1 -2 1 59 -1 5 -25 -35 7 2 -55 39 -21 -27 2 -19 56 15 7 4 10 41 22 -21 -7 10 -5 -19 -15 17 -25 -51 -4 15 -37 -20 26 61 34 18 11 23 8 0 -1 25 -10 31 -19 17 7 10 -2 12 11 -8 18 12 -14 7 43 36 23 -6 -30 -15 -18 -62 0 12 -1 -36 29 -17 -28 -34 25 -10 -23 8 -48 -33 5 16 4 -26 -9 14 -16 62 -23 -28 47 65 36 54 75 32 2 43 98 -20 64 -17 24 -126 15 -45 71 -23 -15 6 35 22 62 55 -4 -4 -3 -81 50 126 69 17 65 0 83 116 27 -24 77 -50 24 -58 118 84 -22 37 45 43 100 41 20 45 39 22 116 13 53 33 96 37 60 63 114 61 102 -13 49 62 75 24 -30 66 52 -7 -34 90 88 19 47 83 -16 28 -52 19 -25 -49 10 -94 19 -78 24 25 -38 19 -3 -73 42 10 51 58 26 -28 1 91 16 93 -7 -5 63 -33 -48 11 -34 72 106 -11 95 32 -12 34 -23 28 8 39 9 50 -86 30 3 -65 43 -24 -60 -37 48 19 0 -34 -60 38 7 55 31 20 14 5 42 68 34 18 2 57 -87 26 0 71 -8 14 -63 59 -1 -4 -58 -8 4 97 -52 11 -34 -15 25 34 78 55 -34 11 -11 -13 -9 -16 4 -14 20 39 6 16 21 -16 -48 1 -15 15 20 -17 24 7 -12 -78 -54 -57 -30 15 -22 -9 13 1 -119 6 81 -50 4 -27 -50 -25 23 -20 -11 -1 -9 -54 0 2 -8 -20 23 13 2 22 -44 12 -40 21 22 -24 -32 -6 -33 32 -35 -39 -11 -41 -1 -19 -7 -2 10 -71 9 -2 -75 -28 -18 -18 2 27 10 110 -30 -51 17 -6 -11 -19 -16 -32 -7 -5 3 -16 19 -21 -25 -13 -16 -33 52 -3 18 -31 31 -20 -30 28 0 -8 -23 -4 18 -53 0 5 -15 9 26 -65 36 40 105 -15 -2 95 -3 95 -5 -71 64 55 -53 62 -31 -29 42 41 16 82 27 19 -28 13 37 34 26 -109 -31 -72 16 64 22 -16 81 -4 -13 64 -69 81 124 96 -38 26 2 -16 29 -17 -40 10 -69 67 10 87 28 6 -16 58 27 -19 15 4 -22 19 94 44 34 98 -19 19 -44 61 9 -82 85 2 113 6 -31 66 111 42 -2 69 -4 -93 -12 3 19 3 -6 28 5 19 -12 67 72 81 -17 -97 54 -26 4 -44 14 -36 67 25 -15 0 29 -16 47 18 44 -4 -8 -84 -25 42 -26 36 52 -19 -15 -27 -20 23 63 62 36 10 -60 44 25 -29 -5 -17 -22 -27 -3 -46 46 3 4 20 37 40 -11 49 43 2 31 4 18 28 5 37 -4 -18 -35 46 -17 29 46 12 -55 16 30 -8 -24 -33 -87 36 -10 42 -30 51 -64 -15 -5 43 7 19 -28 4 19 13 -16 -19 -14 16 21 30 -12 -36 19 -36 7 -11 -18 16 -6 2 0 -12 -35 -8 -5 -16 6 -7 -6 -9 43 19 -27 -8 6 6 5 23 -10 -23 -31 -4 -3 37 -38 -7 15 10 17 5 -27 5 0 14 21 -34 10 -49 11 8 59 56 39 -29 6 -29 26 -4 9 12 22 -34 49 7 -33 49 23 33 11 11 -16 21 -4 -17 -7 60 24 16 -73 -54 24 13 2 -24 -9 54 -9 60 85 -28 4 10 48 -20 -13 59 6 3 64 63 23 -11 45 -23 112 1 126 33 -14 73 -16 -39 22 53 39 30 -6 -53 70 -20 -12 20 -16 10 3 -27 17 20 61 -13 2 -88 29 -19 73 -21 56 34 29 -14 0 32 -26 7 -2 -17 27 -10 -42 5 23 30 -11 30 -7 9 26 27 -33 45 7 71 -29 37 56 -5 87 45 -26 36 10 21 36 12 61 84 30 7 53 -21 35 -35 -1 -26 63 -78 -9 -6 -24 16 59 39 32 -33 21 9 31 -21 10 -42 -16 27 -49 25 -47 -21 -65 27 34 19 -23 -29 69 25 16 -13 42 -37 71 -2 -1 -22 -4 -19 -39 -36 -52 -54 -35 -52 20 9 3 -10 38 -73 -10 2 -25 -10 6 -16 -68 64 34 -22 -4 -33 -5 40 -10 26 27 38 34 -27 28 38 28 -12 29 21 -69 8 -44 18 21 -28 -15 51 -42 49 -26 30 2 -41 48 5 2 22 15 18 -29 -25 -41 25 24 6 10 -40 36 50 3 -30 -42 -1 2 14 50 -45 -25 -7 18 -15 -35 -8 -4 -13 -10 21 -45 25 38 39 26 -3 33 -39 -33 -10 -7 15 -14 -3 10 -8 6 9 -29 -22 17 -17 -26 -20 -3 4 -29 -8 25 -32 -19 -20 -19 -16 -11 27 -12 4 37 -32 11 33 12 8 -9 -18 22 1 32 -15 -18 45 -36 52 -33 -13 12 11 35 -7 -15 3 3 -36 -30 -74 -8 -12 -7 -58 -25 -109 29 -44 25 7 -101 7 56 18 24 -74 -74 -12 -3 13 30 -61 -33 -6 -59 -22 1 -5 -76 -101 36 6 -95 15 -11 0 -19 40 58 24 28 31 -57 27 5 -55 -3 -22 50 -16 64 -17 -32 -53 -57 -8 60 -78 8 -11 -39 12 -39 -57 -34 -49 26 -77 -44 67 -24 -4 -12 -5 24 10 16 40 -15 -32 -47 12 19 45 94 -1 2 121 23 -22 -99 121 -22 20 23 35 -38 38 -10 90 60 -15 -18 5 53 -21 46 8 71 -3 46 -80 -83 66 -14 9 43 -4 -13 30 2 0 86 -2 24 -18 22 2 -24 -7 -26 39 5 106 9 -58 -4 3 -25 68 10 -19 -44 14 -8 16 -31 -64 -2 16 10 -17 90 -12 9 27 79 -73 -8 24 91 1 -27 -11 -5 14 72 -111 6 -13 18 41 33 24 20 -1 -8 14 19 -20 -8 54 -26 31 54 27 4 21 53 28 20 30 19 -14 44 31 7 -3 14 -19 1 -37 -4 -60 36 5 -41 35 -26 19 30 27 -4 27 -51 -33 -20 20 41 16 -9 17 -7 -23 10 -26 11 -15 -54 -44 20 -2 59 13 23 -6 -26 23 28 -45 -17 24 -35 -15 -49 64 -16 22 -27 -39 -44 5 -60 -16 9 -3 25 54 35 -6 -39 8 -32 -9 -32 18 -11 -24 -54 -27 -7 -6 -45 -10 22 25 15 -3 13 -24 27 -23 29 28 -62 23 48 1 21 -8 51 -11 55 11 36 8 31 35 16 19 10 93 2 53 2 47 -76 45 -79 -21 57 37 79 45 78 17 72 36 56 9 18 26 12 -3 -19 -23 63 -5 -10 38 -18 -27 1 70 -35 -20 -11 37 65 39 65 24 -48 -5 22 -28 51 64 20 -47 12 62 -54 58 -48 25 7 -6 55 13 17 67 -19 -17 31 -3 18 23 10 4 70 7 -24 13 73 -1 41 46 14 33 76 -35 -9 4 2 24 -38 12 -38 11 47 7 -22 19 -11 2 -15 -28 2 -33 20 -12 6 -6 -35 -15 -18 -31 -3 2 -23 -48 22 -33 -21 28 -29 -18 -73 24 -29 -12 17 22 -8 -23 -8 2 -10 50 -33 4 24 -4 -22 32 -4 -36 -12 -17 2 12 51 -22 55 -37 -26 -10 15 -37 -14 21 -3 -44 3 56 62 -50 64 -22 -36 29 -71 73 -10 -53 -37 -71 35 -73 22 -45 0 -14 -12 -17 -18 20 12 -17 -1 -30 5 51 -9 -5 11 9 -9 12 -26 14 -25 16 41 -21 -15 -15 -19 -17 17 -19 -18 6 18 -18 -20 -9 -4 6 -11 -8 -4 11 -26 6 -12 -6 -10 19 -23 -34 -17 26 -4 -39 3 13 26 1 20 -6 14 2 15 -49 20 31 6 36 -53 5 6 -30 46 -26 -22 45 20 -28 -14 28 28 -23 19 6 -3 -11 16 3 16 -17 19 9 1 22 -19 11 -14 15 -11 29 2 87 42 65 50 -12 33 62 37 52 48 122 23 -3 -41 -27 70 27 33 23 83 -15 48 6 11 23 27 45 98 28 -1 -58 11 -29 5 46 -8 54 -1 7 61 40 42 19 29 -13 20 46 68 65 54 0 30 -41 76 26 -33 -44 -49 32 -11 -57 -21 7 52 7 -50 -45 26 9 13 -3 -8 70 -36 98 17 85 12 7 -54 -37 -38 37 -3 17 59 20 18 24 -80 67 5 48 -12 67 63 -12 -19 -11 -18 12 -13 -15 9 -6 -18 -36 44 54 -2 -58 -16 5 10 -24 -83 21 -19 36 -77 -5 20 -26 -33 0 22 1 -54 -2 -13 -6 75 15 39 -17 13 39 -43 48 61 -22 29 42 35 68 -35 10 5 38 11 1 12 -22 82 39 -16 41 13 -12 39 -19 -5 9 11 1 40 -21 -14 11 -34 -2 35 -50 43 -27 -12 -26 -44 46 54 3 -85 13 8 0 18 7 3 -9 -9 -40 4 25 30 -11 -16 -24 -16 -29 15 -3 23 32 51 37 -10 7 -41 52 -22 -1 12 3 -56 0 18 -37 -44 -6 45 53 -34 23 26 -15 39 1 8 7 9 10 -13 29 -9 37 -1 32 19 33 -18 21 11 12 17 23 16 -13 -22 16 22 17 43 12 35 35 50 40 48 22 24 12 26 51 -16 9 -3 -46 -9 -10 -6 7 -8 -47 -7 -23 -11 21 30 -2 40 20 -51 12 -4 16 -31 10 3 4 27 -44 28 22 45 26 23 76 -2 36 -14 84 -41 100 -3 -28 29 103 -38 -39 52 46 -8 47 -30 41 -20 43 48 30 -21 77 70 7 21 21 50 36 -14 7 -40 3 -39 6 -40 45 65 55 54 -18 -28 -50 50 -48 23 55 42 16 82 39 124 18 0 20 72 -29 -7 -11 -25 33 -18 88 -12 -43 14 -2 69 5 25 -55 13 10 35 46 34 59 33 -8 -7 55 2 63 26 -6 39 10 -30 4 75 32 -3 -67 31 12 -16 45 19 -20 49 -89 74 8 30 -50 51 -27 -52 -2 30 27 -4 39 13 -56 19 -51 10 -35 34 -7 -83 34 -13 8 35 14 12 -44 11 -7 24 15 14 -48 -21 28 77 84 59 11 -10 12 32 -1 -12 79 -30 43 -17 -57 72 49 -12 13 30 -16 -31 -32 -12 2 5 26 -16 50 -24 -83 -105 -16 39 4 22 -52 -25 67 -39 2 -19 -43 49 39 24 -52 -59 9 -12 -2 -57 0 16 -66 12 28 9 7 41 -20 0 -19 5 -27 -42 15 13 -34 26 9 -47 24 -2 -10 -12 -30 -30 -14 14 -31 -22 -4 -10 -20 -7 -7 -22 -3 -28 21 17 -15 14 -10 -10 -9 18 -18 50 -11 80 7 31 1 -79 2 -6 9 -42 -30 27 15 -30 41 1 5 18 -10 -6 24 25 31 19 0 -61 33 -44 -20 23 -23 -1 18 -2 -1 6 2 22 6 -1 -26 -3 -52 68 -25 -82 56 22 -43 -8 14 83 30 117 -24 5 -49 9 9 60 44 63 34 -26 -16 13 15 53 11 -16 125 -49 21 37 27 31 19 -35 49 102 -13 -48 83 17 -18 -6 71 -72 32 -39 -35 0 80 56 -40 -10 37 64 35 7 24 2 118 29 -9 82 31 71 -16 7 20 -16 -29 -8 81 -2 81 78 14 35 4 126 40 -20 19 31 -11 24 20 114 -55 -23 68 20 -1 1 122 127 1 -20 -41 -21 15 37 16 25 30 64 -17 5 -27 15 -86 88 -65 25 13 -31 20 47 16 36 -35 16 11 -70 7 -27 0 19 -2 20 10 72 -61 -42 0 -25 38 -26 -12 -46 36 0 16 77 11 -24 -24 -6 -33 -8 -23 -19 -12 2 31 23 11 34 72 17 10 2 6 23 -17 -113 -21 -15 -20 8 -8 -18 -23 -31 -54 42 35 -33 91 4 15 -21 -24 -23 14 61 -31 -11 -58 -9 4 -2 21 -15 -9 40 15 12 9 -2 -34 -27 -32 -11 1 1 8 4 78 -7 -24 -5 -18 -24 -18 47 5 17 -56 -58 -26 3 17 -71 -44 -21 35 0 22 -30 -4 -58 -13 0 9 -11 -34 -15 -20 1 -21 -33 -29 -43 -6 -20 3 -15 17 4 -7 42 27 -6 -48 64 -3 4 16 15 3 -51 -28 3 -16 -44 27 14 -2 -17 0 -13 25 22 29 46 -25 -27 25 -12 -6 15 -6 -41 34 -7 -4 14 46 48 18 -11 27 -35 54 16 4 25 88 -67 4 72 7 44 50 -58 -110 30 36 14 62 9 25 -2 -22 16 3 11 20 38 85 -10 -46 -25 -18 -45 -25 28 0 15 4 23 -22 29 -36 6 -37 -40 -16 -16 -61 96 18 -116 -30 59 7 89 -15 -8 -52 49 11 10 24 3 81 32 -5 32 -28 -4 -18 10 51 29 -9 -51 -5 49 -21 23 -19 -15 -22 3 -41 14 63 8 100 20 51 3 -8 -66 3 43 -17 8 -8 26 4 25 -34 -34 1 69 -39 -31 -43 42 3 -27 -69 44 -21 6 -22 3 29 67 -57 5 -28 -26 47 62 -76 57 -15 60 -45 105 14 89 -27 -74 -10 64 -7 13 56 31 32 74 -13 -26 40 -45 6 -3 14 -38 -14 6 -77 -19 -23 -6 -35 -65 -65 -23 -53 56 34 -22 -1 41 -32 48 -36 18 71 -6 40 38 -29 69 -33 25 -29 -12 -4 -9 -7 -32 37 -56 30 -9 9 -5 -5 42 31 27 0 11 30 48 6 2 -34 -1 -9 -9 10 17 41 -37 10 20 -15 5 -9 22 3 -25 -50 23 40 5 -18 6 -1 -8 -2 12 6 11 20 -23 -1 2 -15 -11 30 -3 -31 -8 -15 -27 11 -10 -1 -18 32 6 -2 27 4 -36 6 15 -9 17 11 -11 -2 -41 -15 3 -65 -7 18 17 35 -12 -24 -9 2 -13 29 -6 -84 24 -15 5 -23 32 15 -28 19 6 -14 -47 6 -29 -44 102 16 34 -62 42 62 11 -40 20 37 50 17 -5 47 -37 -8 -70 -20 -11 83 45 -6 11 -14 -43 -55 25 34 37 61 -29 -14 -47 52 -77 -53 -21 5 -22 11 38 -17 7 21 -1 62 -27 -14 -9 10 69 2 -61 116 5 -56 -17 -69 53 -33 -53 -33 44 -41 76 45 -37 64 27 82 -15 -11 12 22 0 61 -18 9 -15 1 54 13 15 7 47 14 48 -28 5 101 20 -56 66 12 -9 -13 14 62 79 4 -33 58 49 -47 6 45 51 1 -11 -73 30 33 85 88 -56 -64 19 -24 32 45 65 9 -27 -28 -36 46 -73 8 -3 62 -14 -10 17 20 46 -20 7 67 38 56 42 -14 7 -5 8 -33 70 46 21 68 39 -13 -50 -15 32 -9 -14 10 9 -27 29 46 72 33 -28 -21 75 -3 -11 21 7 63 42 34 35 44 10 35 42 -65 54 78 64 23 39 -42 24 26 3 -16 -11 -4 13 35 10 19 49 51 4 -26 7 -22 -12 -29 -22 -5 4 48 5 25 -30 9 44 73 -36 22 -26 -7 8 16 -20 4 5 -15 10 -31 9 9 -2 22 -11 56 19 -38 -9 -8 35 -27 -6 -35 11 20 -13 -38 -51 42 -14 24 26 6 -28 23 16 -46 3 -12 8 20 -50 -11 -29 -3 -49 -25 1 8 -33 -25 -22 -7 -13 14 -18 -27 4 35 -18 -55 47 22 -4 -27 2 -22 -48 -16 -56 -74 -71 51 18 -92 32 19 -35 10 -32 -30 19 -50 -18 17 36 -17 2 76 -62 -37 -15 -9 -39 83 19 -94 -43 -44 37 -32 -43 59 12 -11 -64 -31 -3 1 -14 -2 -15 -54 -7 -14 -45 -39 30 -5 36 -73 -122 18 22 39 0 69 -64 48 39 -33 -9 68 -11 -37 -103 20 121 2 -19 15 17 44 61 -20 126 59 -18 24 17 -102 -127 -2 -13 69 -19 -37 -13 -22 1 -8 -2 -43 -23 -25 8 -22 -18 52 -53 -13 34 -33 -1 -52 20 25 -18 -46 38 -2 66 -6 -90 10 -29 79 -30 -51 123 -92 12 -20 93 -16 -49 20 -54 76 54 42 55 -27 52 -44 100 -31 -77 41 -16 -13 -38 -30 39 -16 -2 -31 -10 -62 35 115 -15 3 22 -1 -38 49 16 127 7 62 -46 41 -45 -23 -58 -4 58 46 16 -55 -56 83 94 2 0 -6 59 -69 -5 67 -18 -7 22 -59 -7 22 21 -51 6 15 36 54 9 -39 8 -14 5 127 -31 -34 -6 -18 -14 20 -31 3 8 26 23 -20 11 -2 42 0 11 2 -19 10 31 2 2 -5 -15 -3 0 -16 43 -6 -40 7 -8 -9 -9 22 6 -5 -25 5 5 0 67 1 14 -23 0 19 -23 -67 -3 37 -2 14 32 -24 19 33 -23 -30 16 25 24 9 -13 7 -3 13 -35 -20 61 1 1 -18 3 -15 -15 66 58 38 7 0 23 -18 47 4 87 39 48 31 21 53 -21 47 13 89 -28 -20 -39 10 17 9 -30 15 74 25 -96 40 40 27 -5 -33 53 70 -73 8 12 14 52 32 14 -8 53 25 33 -6 26 11 17 -15 -53 115 33 53 74 18 18 28 -13 -17 86 3 12 -112 58 30 74 6 16 6 4 7 52 -8 -12 9 -27 -5 -10 -19 15 63 -12 43 -40 -10 9 36 21 83 -15 39 15 72 -128 14 33 -45 22 22 49 19 -5 -33 1 34 0 8 25 -22 -14 -26 21 5 -51 11 9 6 -23 -2 1 -80 -31 -35 -22 -21 -33 31 -21 -78 -17 -37 -5 1 1 6 27 -54 5 -11 3 -23 11 -4 -69 64 68 92 17 -22 25 4 2 7 30 15 -75 -13 41 -45 34 13 -16 3 22 14 -24 -14 35 -9 34 29 -9 59 6 1 14 -2 7 -28 65 34 50 31 -6 1 4 -10 -29 -17 -34 -11 -38 20 5 -78 9 6 -17 7 -5 4 7 -35 -12 2 2 19 5 2 -37 23 -10 34 33 -16 -3 0 30 51 9 9 10 -19 22 -5 36 -20 23 -17 25 -9 -4 16 10 38 32 26 38 29 1 -20 29 -5 -17 13 22 38 6 30 -45 8 -2 30 -22 -5 -39 34 -13 -34 3 -29 5 1 13 6 -5 -5 9 25 18 -13 18 -15 -40 -6 -17 -3 -5 -20 14 -1 20 3 -2 5 4 7 -26 3 -56 -22 -4 -33 -10 -47 -31 32 8 29 19 16 1 -5 38 38 -17 71 54 -37 20 -31 18 -26 16 9 -28 3 27 16 -29 -45 -7 -2 -18 2 49 -18 -48 76 35 -18 6 -3 58 22 -17 10 -22 -16 0 30 -14 9 12 45 -42 -36 -9 21 -40 -24 -59 75 56 25 27 -4 14 7 -14 27 18 36 37 24 51 -37 26 2 90 -12 35 23 18 -60 23 -18 -8 61 36 -25 86 36 14 -17 -1 -20 33 -38 -56 -6 5 -37 -34 -30 10 2 11 -12 55 -39 -35 3 27 -27 -28 13 -7 20 -71 -19 5 15 -48 -23 -21 -64 -9 -2 42 9 41 16 -27 -19 28 2 -43 20 -68 21 8 11 4 -27 -6 -1 20 4 11 -5 -17 31 -17 8 -6 -8 33 -80 -4 46 -55 38 -4 -5 32 50 -24 66 11 -82 17 -18 -31 -3 16 -12 -50 46 -7 25 -60 23 -3 -44 -75 23 11 104 -37 18 59 -8 61 -1 -71 8 19 14 -11 -18 15 -50 -16 3 -1 -2 -13 -17 63 23 -17 -31 26 -36 -4 5 -39 19 71 2 -21 -12 16 -27 -44 29 -28 11 3 7 -8 -18 28 6 -8 -38 -25 -19 -20 10 26 -2 -30 -1 11 -9 -33 -5 31 -18 -12 -20 -17 16 20 -19 16 22 -6 -35 -24 25 34 -69 19 20 26 50 -13 -18 -6 -20 -13 43 -5 -1 20 1 -26 7 1 18 1 -1 -9 -4 10 -31 -25 33 -10 17 48 -42 -25 94 -4 -83 16 99 -58 -16 56 22 35 10 37 -52 64 -45 41 -4 25 55 8 21 -32 -52 52 72 59 -20 39 -21 44 -34 44 62 11 -18 -119 -17 -20 -10 -15 -19 -47 -42 -43 -50 55 -42 -38 21 35 -29 -20 125 70 28 8 4 60 25 42 21 21 11 20 13 21 1 0 51 -66 16 41 47 96 -24 -64 56 -10 -70 24 -10 82 -13 20 93 1 74 -32 -16 -69 3 67 -1 29 -40 -41 -39 36 20 -15 -18 -72 -8 17 28 19 37 29 -35 -57 -16 58 4 21 -23 -22 -13 -3 13 27 -56 1 -11 26 42 -15 88 9 18 41 -12 -5 72 2 31 57 23 -19 -12 13 45 18 6 15 12 -22 -2 31 -33 3 15 1 -5 4 18 35 44 -21 38 9 -45 33 16 74 -39 27 11 -16 -26 -5 -6 9 -20 -3 39 -26 -25 53 11 -26 -29 48 -2 13 -20 -59 -26 29 5 -21 -33 15 -1 65 -17 3 -22 -23 -42 3 -32 -22 68 12 7 -21 48 40 -21 -2 -13 1 -24 5 6 -40 -47 43 14 12 -35 27 -28 -7 -6 -2 -79 10 -25 16 62 13 4 -50 42 43 -24 35 34 18 6 16 30 -10 -48 -14 -9 18 24 -2 13 -29 -41 2 48 -15 58 14 -29 24 -14 1 -1 42 40 -20 12 -30 -12 -54 39 17 32 9 5 -38 -37 35 6 18 -17 -21 -5 26 -1 11 -10 83 9 34 2 11 -32 96 -37 -13 11 -9 4 46 53 -6 -1 0 12 52 -1 22 20 0 -54 47 -81 -35 -18 35 11 -8 15 0 -41 83 41 33 -15 3 67 -3 14 28 13 23 25 16 14 48 12 45 -58 -3 10 19 80 -25 -18 -32 5 -19 -5 34 -43 -21 29 93 60 29 14 20 -52 -3 -49 72 -34 -7 14 42 -10 -45 42 55 -22 5 1 19 17 -4 12 -31 23 -19 24 53 -9 -52 -52 24 12 -25 -39 -43 -7 -15 -53 38 -52 30 21 26 -48 12 -61 -29 -44 -5 -37 52 -33 -35 -6 25 -33 72 52 -18 -10 -19 43 -32 -18 23 0 0 -5 -7 77 -69 51 -37 28 20 35 -1 20 -36 18 -43 58 -27 -12 0 7 -67 -28 15 9 36 -24 -2 -49 -15 -68 -56 -53 19 18 35 -14 -26 17 24 6 0 -27 -10 -6 -5 5 7 64 -28 -18 34 21 -39 -28 16 -4 23 7 1 -35 -23 -13 -22 -40 -32 -2 -19 -7 14 1 9 13 -5 -17 46 -35 -3 27 22 -7 -52 -30 1 11 -16 -2 -7 29 -4 3 -13 -19 30 -23 -29 -30 11 -36 5 37 51 -29 -63 4 -19 -36 -23 2 18 7 -14 -4 -33 11 23 25 -28 -34 12 -28 -36 8 53 -33 16 -32 -43 -21 -1 -16 10 5 -23 38 -35 21 -10 -38 -48 -35 -28 -27 -2 -16 -19 -14 49 -15 27 24 4 -72 -50 1 66 23 11 13 24 -40 53 64 62 36 -22 63 20 12 10 -25 -33 92 -19 -26 73 5 -52 4 -40 -72 -43 44 -31 62 25 -11 21 31 55 45 -1 10 1 -7 -14 11 -37 93 76 44 -4 -39 23 -69 1 13 -35 -77 13 54 63 -37 20 -5 106 63 25 8 12 -48 21 24 -28 16 5 0 46 -43 46 -59 21 -38 66 -12 2 77 78 24 -26 34 28 76 -79 -41 43 45 -31 39 21 15 10 -63 18 70 32 41 2 -26 31 -77 -49 32 47 -38 -29 -32 -60 -19 -45 54 -53 -17 -26 -11 -16 -30 33 -11 -8 20 24 -52 -46 25 -1 25 -62 -11 25 16 -40 47 13 -5 -41 48 -17 20 -81 39 -6 -9 -69 -11 -32 2 3 63 -21 42 -14 28 -116 -43 -71 42 -26 -2 -8 8 -29 17 -19 -48 -26 52 -22 -39 14 -16 -7 1 -38 -22 9 9 23 -34 -21 34 -74 11 -10 4 21 6 -18 7 -5 3 17 22 -15 -27 37 40 -11 -23 -15 -38 22 -16 -10 15 9 -35 -32 -9 21 -23 18 22 -34 25 -1 -26 -15 -10 -49 29 33 20 16 -60 -54 -33 10 22 19 -48 4 8 -8 -24 -29 -11 57 50 -2 -27 15 -45 -56 14 -13 -30 27 -5 -11 -6 -26 0 7 6 1 -7 15 -5 -38 37 -21 5 32 1 26 -18 -13 60 22 -23 22 -23 9 6 56 -32 34 -66 -68 -117 45 67 -63 -31 5 101 6 -107 -1 -47 -54 14 86 -18 115 10 40 1 -16 -33 -82 -10 -59 74 -47 -12 7 94 67 16 63 60 42 -10 -25 -8 -3 63 -44 6 40 -16 7 60 24 89 7 -26 39 63 82 18 42 2 -67 100 10 14 -64 54 35 33 58 15 -10 -122 -14 -115 -46 50 64 -84 8 29 127 -63 100 68 -63 -65 57 14 -10 116 115 0 43 65 -36 -47 53 95 11 -49 72 39 -55 26 -47 -21 50 -10 84 -11 -12 -16 -11 -1 -10 32 -31 -3 27 -12 16 70 -56 37 -22 -60 65 45 26 -127 1 17 6 -60 -48 -106 58 84 -18 55 29 -78 53 -10 -37 28 75 18 72 51 -1 -51 -1 -83 57 -53 -15 71 -3 74 -34 65 40 -73 18 11 28 -14 -14 18 -3 37 -86 -12 55 42 11 0 -9 112 87 -8 -6 91 -46 -72 1 -8 -29 32 -53 -39 -42 7 16 3 -11 27 40 -13 -7 51 12 25 -16 -30 0 -17 -11 3 -56 -23 -16 -15 -33 11 -24 -19 -7 -32 28 -65 41 -1 -26 -4 -13 -48 -35 3 -23 48 -10 1 9 55 -23 33 -5 11 34 -14 -2 -9 -63 35 -27 -65 -48 -42 -35 -41 -7 -10 13 -36 21 -5 16 -26 -26 44 3 0 -40 -4 25 -9 7 13 -28 10 -6 13 -43 -2 -15 11 32 3 29 56 16 -13 10 -17 -37 -40 -44 4 31 12 -35 18 21 -11 42 37 -15 -54 12 -13 68 34 46 41 26 -17 30 -33 20 32 33 49 40 -9 -56 -5 46 -20 -51 9 8 15 -13 97 -28 -29 45 21 16 44 -25 -77 23 53 11 40 -32 30 31 -40 6 53 40 -33 63 -17 -28 13 -14 120 37 21 10 -29 -34 71 -35 79 11 -19 36 68 12 35 48 80 9 -66 -4 0 62 19 14 19 -32 36 -6 97 -2 101 34 3 0 100 6 11 -50 25 13 -29 -21 13 9 -61 -30 -5 -10 29 12 -31 -32 -58 44 -40 1 8 21 -5 26 -76 -29 11 39 43 -36 -28 -77 -6 -21 60 61 18 5 31 22 2 -14 62 -6 47 20 66 -43 39 -13 8 32 3 -16 66 -3 42 -19 -1 -6 27 41 9 21 45 -28 -12 -4 -11 -27 -38 -9 -4 5 5 126 -11 3 25 1 17 35 17 -13 23 4 41 -13 -25 13 8 -2 61 45 26 -10 6 -6 5 12 31 -19 -8 -28 -4 -12 -15 2 -7 11 -30 21 -14 3 2 14 -44 -7 -24 -30 71 -8 12 21 43 -1 -10 -1 -10 31 -24 35 22 17 -15 -36 -18 -21 8 -9 8 21 25 -3 -28 -8 20 29 18 -22 11 45 -16 -16 -44 -19 2 -42 -13 53 -4 -8 -19 19 30 13 -21 22 -26 4 -19 -13 4 -13 0 -11 -8 15 -39 20 -31 -7 3 13 -22 11 -21 -7 -16 9 -5 -6 39 -38 -30 -15 32 43 19 43 -29 77 45 31 31 -8 12 55 -2 4 -115 8 39 50 85 5 12 49 -29 22 41 36 47 -16 15 25 11 111 27 48 24 17 59 -41 85 42 -15 -15 -25 -15 -6 95 11 -65 -29 -6 55 -2 8 43 -25 32 6 93 45 18 -76 32 -14 -5 -20 27 12 -45 64 -14 4 -39 4 17 19 -43 67 -58 -60 -2 -53 -26 29 37 52 109 14 69 69 36 29 67 -33 11 -45 72 -38 40 -4 20 32 10 77 -15 -35 15 -11 4 -2 26 -29 29 -5 2 41 -19 55 34 99 52 26 -70 8 42 15 70 -4 19 6 22 21 52 -24 27 -14 -11 -45 -52 -26 50 -63 -23 -18 14 50 -25 24 -15 21 4 -29 -73 -35 -2 49 -15 9 -20 26 -81 17 -24 -6 -15 39 47 -11 -6 44 -65 -17 30 24 -12 73 -34 -31 109 5 -1 -20 -67 31 -1 -64 12 85 7 -14 40 -2 11 32 12 7 29 38 9 -10 -6 30 31 -25 -27 17 3 -7 -9 29 -8 24 6 6 23 23 -7 27 5 5 14 27 1 25 -10 -13 -2 -50 -33 30 17 -24 -21 20 33 -5 -59 43 -2 0 -3 19 -13 -2 -15 27 1 15 -24 -9 76 -25 0 25 8 42 25 35 25 -28 -20 22 -8 25 -2 35 -38 -32 13 20 42 6 -18 26 -11 17 15 -12 -10 21 -2 -41 12 -4 0 -34 -12 -49 5 23 -78 81 -85 -29 -2 2 18 -33 -21 34 -39 -8 88 26 41 -7 1 32 -91 -44 -8 11 17 -45 -76 -30 -60 -1 33 -44 -64 -19 -84 -45 37 18 12 -12 -37 3 -70 1 32 -58 5 -34 -54 -26 -21 -15 -104 -81 -85 10 5 28 36 -39 31 -17 0 -19 0 8 -62 -17 16 41 -74 -40 18 3 18 -98 63 21 -38 35 -20 -89 -13 21 31 -19 -94 -24 -7 -40 -65 71 -2 -24 18 18 45 -53 -34 25 34 -54 31 18 -27 11 3 16 30 -5 -74 39 47 -4 -9 -21 -46 -16 17 -14 -57 -17 -118 -98 -94 -21 -35 75 32 -35 -41 15 10 -40 -46 -30 -24 5 31 10 -20 -17 -58 -19 -52 2 -3 3 -36 13 82 21 -11 -45 13 -59 -25 23 -21 -26 -51 -13 -50 0 3 -35 -13 -22 -3 -12 -12 38 -65 6 2 -15 61 0 -57 1 32 5 26 -26 -7 51 -1 -23 37 -22 -28 67 26 23 1 -14 7 -27 -14 65 -35 41 -8 -44 -7 0 12 10 -19 4 7 35 -4 -14 56 -7 -3 -3 -15 -6 -40 -13 32 -29 -7 48 -34 4 64 -25 15 15 -43 -32 18 14 37 4 -42 60 1 8 22 -3 7 -20 11 -36 -12 65 -31 -7 6 -28 -16 8 12 -12 41 -32 7 -20 27 29 21 0 -32 -20 65 24 -2 -8 21 -8 14 83 -13 -26 -4 25 20 23 -9 28 -9 58 -26 9 4 35 47 -59 72 -3 -32 113 -44 -33 -82 48 5 44 -21 38 -20 92 124 -8 -14 -11 -2 -55 3 -14 -2 48 57 53 41 -25 -54 -31 11 32 -5 -26 -2 49 13 -28 37 -1 27 -62 -11 -34 -23 -16 58 -26 -13 56 127 91 46 -72 46 20 -37 -66 -55 33 1 42 47 41 -7 -18 25 8 -27 -24 25 127 -48 41 9 10 3 0 44 -22 94 12 59 52 -19 5 -31 51 -7 -90 -14 25 53 -36 5 29 -18 49 -56 18 -17 -29 -23 -30 -20 -2 -13 -4 -11 -6 51 31 13 96 -15 38 -2 9 -6 -47 -21 25 48 -17 47 37 -34 -4 67 -3 19 6 -22 -44 0 34 52 -76 -7 -57 78 29 24 81 -2 54 7 -4 38 -57 0 55 -25 -19 5 -50 -46 41 14 -32 8 -13 -3 21 -5 -46 -3 15 -14 29 -3 107 4 17 60 -22 -55 56 26 -14 18 -46 55 35 -3 22 42 -28 18 11 9 16 8 -12 51 -23 73 -14 35 -12 -11 -7 11 34 33 35 35 19 4 -26 -61 -3 -4 -5 12 -4 18 9 -18 -20 -5 -23 -10 11 32 37 22 0 36 8 21 -4 25 16 1 2 -4 37 46 -35 11 -9 -16 -4 -21 30 13 4 14 2 7 -25 -5 -50 -6 24 -17 -5 32 -26 1 -3 -34 -6 -45 -24 -10 4 -32 41 -19 0 -44 12 20 9 -4 -7 25 26 -3 62 -53 -116 5 38 21 8 -50 7 -83 -3 -60 42 -69 49 -34 -33 34 -120 27 23 53 -42 86 -22 -16 32 18 -116 -28 31 -121 -97 71 -37 -17 -56 40 -5 25 35 -61 43 -6 -22 -6 -80 13 -17 -120 -54 20 -97 64 37 -2 -8 9 113 -41 22 -77 55 -53 -118 12 -50 28 6 -20 127 -54 -22 46 -33 -81 0 -38 27 -28 32 -29 23 -9 -79 -87 -21 104 46 95 39 -73 110 -65 90 -40 -60 -35 -20 25 -69 18 8 48 -50 -6 96 -42 -31 -45 101 9 22 26 20 5 21 -17 35 37 -40 8 -8 35 -38 59 22 9 -78 -39 2 -13 2 -52 86 12 35 16 -40 24 -39 -109 50 116 69 -116 -7 -45 -40 6 -109 -48 -8 -18 3 -5 52 -1 -5 -58 3 -16 14 -78 0 41 -9 3 -60 18 60 34 46 23 34 84 12 -23 28 -44 102 52 -25 14 26 -51 35 -64 38 -8 -23 -31 -31 -4 1 -12 15 38 21 33 47 -28 -9 -5 -29 24 -127 49 43 -14 25 -1 26 32 7 7 -24 13 54 1 24 -13 -14 60 34 22 40 45 -65 60 -66 18 -9 -34 -77 46 39 22 -39 -11 48 23 15 27 78 -62 60 14 64 -6 -52 5 -46 46 -51 21 42 9 -43 16 31 22 5 -16 -38 5 32 -31 2 14 37 -28 23 30 8 -81 52 86 -16 -2 -24 -56 3 44 20 57 -92 -36 -24 46 -3 -58 -20 -71 42 22 61 3 49 33 46 29 -25 17 3 10 23 -31 16 13 51 -3 24 -16 -5 50 76 40 -67 1 -30 90 -14 13 -21 10 -38 -8 -39 34 -14 44 63 -18 0 32 -22 -22 75 35 21 5 35 7 -30 17 20 65 54 13 71 6 -47 29 37 0 -23 52 8 49 91 17 -33 -26 -6 -2 68 74 56 3 9 12 -26 -6 54 17 -20 31 -8 -61 -51 -4 -28 25 25 19 34 26 38 -34 88 -80 -15 33 30 83 -8 -2 -1 -22 67 -51 -18 71 43 -37 29 -29 11 -77 44 94 -13 45 -26 -3 20 51 -6 10 15 61 -51 10 17 -40 39 62 16 -53 -23 27 -72 31 -17 24 -46 -8 2 38 -2 -23 11 -41 10 -37 26 28 81 -1 -17 -73 64 -2 103 -22 30 -93 -5 2 3 -55 14 -44 -9 23 -6 9 -4 -11 23 -11 30 79 -31 -12 11 -5 -40 25 33 55 42 12 9 6 5 12 1 -15 37 -23 1 24 -50 24 27 -18 -23 -2 -9 25 -31 2 -20 2 22 1 4 1 -6 5 -8 -54 1 -16 -13 -3 9 12 -35 -37 -2 -34 12 10 -7 14 -48 -5 -2 -14 16 58 6 61 -21 0 20 5 -40 20 28 -38 -37 26 3 -9 3 9 0 33 19 14 -17 -8 15 -19 -47 67 -24 22 -16 24 -2 -30 -42 15 -40 -3 7 14 14 14 -63 33 29 90 22 -47 -26 -78 -11 49 -53 44 5 35 12 -32 38 -26 83 43 4 31 8 -56 -16 -17 -26 86 -31 14 7 13 -34 37 58 45 5 -37 16 -37 3 -5 -30 86 19 38 -2 -15 12 40 83 60 60 -48 -53 -41 -31 -27 -10 -78 -21 79 30 61 1 100 -2 42 64 31 30 -2 11 -9 -1 -8 -15 11 34 17 -50 59 80 94 -5 -14 2 10 -48 -11 2 6 -11 60 -35 42 35 -18 14 21 -29 -8 74 -48 11 1 -42 77 -37 24 -3 12 -69 -32 62 -35 -11 -51 1 -26 34 -4 -45 -56 47 -74 -6 -24 -3 -17 -9 20 4 61 -20 -28 -5 25 6 -10 -50 -56 22 8 42 40 -11 -45 29 -32 -1 -33 21 20 -71 29 -23 88 20 34 9 4 121 57 -59 -7 -2 16 35 -5 -29 -32 -111 12 34 48 -28 -13 -8 -51 76 9 10 6 9 -13 -5 0 -66 -20 28 -5 1 -6 61 12 -17 23 5 -16 -18 -4 31 -21 -4 15 -20 -40 38 5 -11 6 -13 -78 -30 -53 0 5 34 41 21 -22 -37 23 3 -27 -23 0 2 -7 4 2 21 24 -7 -6 26 -27 14 14 -5 23 -2 -15 52 6 12 7 -24 2 -10 18 -30 34 30 -4 12 -18 -13 5 -36 19 -24 -1 32 -22 -3 13 3 6 -77 -20 4 -17 -26 50 21 3 -14 -39 45 18 -15 -7 -4 -33 -11 -39 29 1 -15 56 -51 19 80 29 57 4 107 34 103 -4 -49 46 -74 -4 5 35 -86 -41 -23 4 62 -20 13 -93 -5 16 -74 -3 -17 -116 -14 51 2 -98 85 32 95 -34 55 27 45 -3 -20 45 9 -11 -32 -27 -21 3 97 92 44 19 -51 -17 8 -38 -30 -87 0 18 -68 34 -49 73 -27 19 34 -65 -3 9 -28 -22 61 5 15 -35 63 18 -37 -125 -35 26 -7 110 -69 -26 103 -1 -49 -34 1 -25 22 92 9 49 -42 53 105 103 8 -47 12 -9 -31 -13 -20 -18 13 20 -12 42 45 12 -28 36 -48 79 13 -70 106 -7 -29 46 -35 47 58 66 23 -96 20 120 5 -4 6 40 40 -5 -20 -52 28 30 0 -117 49 44 6 96 -6 -25 -43 46 21 78 37 42 29 36 -2 14 46 -50 -41 -33 -21 -37 -65 -40 19 34 -17 -19 -52 -87 4 -71 63 55 37 -2 -28 -31 2 3 42 54 -34 66 -48 -31 18 -7 -15 19 15 -13 -21 -14 9 -1 14 -11 -19 -54 -18 40 -59 -8 19 5 -17 9 27 29 43 -23 -48 5 -42 -47 24 -29 21 -66 26 -9 27 -48 -44 6 3 51 25 -3 -20 -35 -21 -13 15 -17 -45 -18 -3 18 -20 37 -31 9 -34 33 16 24 -45 -12 95 -22 -15 21 -30 -29 37 -17 -17 14 8 -12 -40 -46 44 64 -38 55 -40 -34 17 -78 6 9 -111 -42 5 -2 -70 27 87 7 4 -46 -14 -59 11 32 17 31 -9 14 91 18 -40 19 1 76 9 50 15 -51 -56 -7 -23 2 -53 -23 -29 -6 -26 59 122 50 85 74 67 24 -35 119 7 29 54 97 95 -4 31 107 47 -20 64 43 -28 -13 -19 -41 33 1 -47 55 59 58 26 80 -62 12 44 -15 72 -56 -35 32 38 65 -67 24 35 16 17 35 -61 4 -39 -23 24 7 -53 -64 -4 -20 95 25 -124 -64 69 13 23 2 -22 89 -22 -30 63 15 51 87 17 46 -3 -8 8 -102 -36 1 42 38 -126 -38 19 52 -51 100 -51 11 48 -34 12 37 82 -11 -16 11 22 28 -70 -28 23 23 33 -9 12 -49 39 72 6 -46 -7 31 37 16 -1 -24 -45 42 16 -19 11 33 -14 -66 40 14 -28 -5 84 46 2 -111 -9 -18 -29 20 -62 100 20 15 -35 51 42 2 -20 62 19 7 -41 16 -8 -64 7 -91 -50 52 -27 -24 3 -41 -9 -38 -38 -50 -42 -6 50 25 -10 -69 89 31 -62 -41 19 -16 -32 9 -13 -29 -12 -52 2 54 -29 -12 3 13 -11 -30 20 -7 -63 -41 15 28 2 -5 -82 17 -2 -29 9 37 25 -17 -19 23 -4 0 -3 55 7 47 13 34 20 -24 45 -5 -27 21 34 9 12 -49 -27 87 81 18 -13 40 -31 0 -29 20 43 10 -15 39 -32 -24 -12 -11 -48 15 34 -1 44 44 -8 43 8 28 54 -47 10 77 -30 -55 -27 35 -36 32 54 26 40 90 72 51 -8 -24 -2 -86 33 34 -26 23 -67 -41 -42 31 -75 56 -19 -1 79 50 63 -27 22 54 39 50 63 12 -66 51 -34 108 5 -41 82 -29 0 21 -12 25 4 -38 -9 -29 7 44 39 63 34 57 -21 -4 -10 -43 103 23 -33 -9 -72 -38 123 59 -1 -5 49 51 -5 39 53 -5 43 70 -3 -40 24 5 74 -31 52 -38 39 -20 -29 -28 92 63 -9 6 28 4 33 -85 2 -11 -10 -67 46 -46 -16 49 75 35 48 55 -25 -30 -21 -65 -42 17 12 80 -82 -27 42 58 14 10 20 -22 38 17 0 -2 -44 20 28 20 26 -19 32 4 -49 -5 9 45 -34 -32 -28 -32 3 16 -3 84 -84 -2 -36 -37 -19 20 7 -3 29 12 -17 -71 -46 -26 -21 49 -62 -96 8 29 26 23 29 -18 -36 -58 81 -9 -88 -13 -24 -63 33 47 -34 -13 13 15 -7 1 21 2 -19 17 6 -18 -17 -14 13 4 -45 23 14 -4 -1 29 -29 8 19 -1 -6 -2 -16 13 6 20 -22 0 -9 25 -4 8 -49 -14 17 1 9 20 32 34 22 -1 -21 -28 8 -16 -1 -43 -1 4 14 40 62 -6 35 40 57 -13 6 22 -6 -8 -54 26 -5 -21 -20 7 -34 -20 29 -4 -50 -23 -7 13 -15 19 -20 -10 11 -55 14 -5 5 6 35 -14 57 48 -24 -41 9 68 -74 26 29 3 -54 10 25 -50 76 57 61 4 16 19 29 7 40 -43 -42 71 28 24 -6 36 1 31 43 20 29 54 78 -34 75 -18 11 5 -19 35 -65 -54 -6 15 35 3 73 11 -1 74 -48 8 -28 -37 71 -23 -7 -30 -34 -23 21 56 111 22 40 -60 21 -58 -16 11 -12 -33 -26 52 17 16 122 -26 -31 68 48 36 -10 -8 112 -30 25 17 11 -46 10 19 45 49 -45 24 22 24 -37 -4 19 5 8 -37 -26 -5 75 -43 -13 20 -42 -1 -22 -16 -19 25 9 43 -1 16 15 36 -16 35 -28 61 12 19 -13 31 36 -3 2 -7 -31 -55 22 -11 25 -2 -3 -21 -53 2 -24 17 -4 65 0 -45 44 -55 2 -25 -4 -44 11 32 -88 -66 -23 34 -19 -10 15 -32 -54 107 -53 -14 30 -97 -35 11 -18 44 12 -5 47 23 25 26 6 -35 -6 10 -46 8 5 -30 14 6 -12 -29 -10 39 29 26 -6 -12 34 0 17 26 -21 53 -21 19 22 17 -12 28 29 23 -6 -8 -9 -2 37 -14 33 31 18 9 -3 3 12 17 -26 22 18 -13 6 -36 -17 19 9 3 40 30 0 10 -17 -10 -19 6 4 23 30 54 24 8 39 20 27 -16 -1 -10 4 -47 2 11 -34 34 -4 2 16 -57 9 -12 -13 29 -25 10 -60 13 22 -6 -15 0 3 -5 27 5 -44 -82 -1 -45 19 64 48 36 38 25 0 45 29 50 -4 74 45 43 -54 -16 29 -48 -8 -82 0 -44 23 59 81 -1 -25 -2 4 -34 43 -30 87 16 51 -1 6 44 83 4 -4 44 -32 59 35 -6 127 9 92 7 3 -95 92 -10 107 0 100 80 59 -38 31 62 71 53 52 15 -11 63 33 -1 -1 80 73 58 -21 82 -5 8 -55 -70 -45 34 28 71 69 36 35 4 -30 -21 83 33 -19 41 21 -36 -32 0 -68 32 66 35 40 -29 -10 -25 63 -5 24 15 23 45 -33 0 9 -27 37 26 23 -78 44 -56 -44 -13 38 29 10 39 -17 -41 -21 12 -16 27 -16 -26 48 -5 23 -22 47 5 83 -79 -28 -11 33 -39 -49 30 57 -29 -62 -3 -39 42 -32 16 -20 -28 -49 4 -27 -52 4 50 20 62 26 -17 21 -10 18 12 -34 -17 -23 -10 -23 11 52 12 -90 11 62 -25 -11 34 -28 2 65 15 24 -5 -3 -30 -10 5 1 -16 -43 7 -2 4 -33 44 -4 -10 12 4 -28 22 -16 8 38 -5 -48 13 -19 -27 -39 11 3 13 3 5 2 3 -62 28 -17 -7 30 -25 12 33 -29 -27 8 -9 -9 0 18 39 -4 9 9 -32 2 -45 18 -3 -21 -28 10 -37 -12 -14 5 14 33 1 -1 21 20 28 1 12 45 39 25 51 -19 18 14 13 42 31 16 -18 -4 29 -70 34 -19 -2 17 -69 -27 -8 -17 50 4 -15 -44 74 3 4 24 26 -16 -8 -23 -2 -21 -68 24 54 50 21 32 -41 16 32 67 -45 -69 52 12 -71 -3 15 -38 7 78 -28 5 -32 -9 -3 25 28 -15 17 1 24 -21 -12 -6 -3 9 11 -17 11 -46 8 -57 44 65 77 -13 2 -67 -40 12 -17 55 -61 18 17 -30 -2 23 -13 23 -18 -43 -7 29 -17 -16 -31 21 -57 14 0 45 -41 110 -26 -16 6 54 57 -23 17 -9 24 -24 7 -15 25 30 -11 33 30 -91 -14 17 10 -8 -23 2 8 -5 -42 -34 2 -17 80 15 -5 15 32 27 -4 34 -45 63 -13 12 2 2 -39 33 -11 -46 36 33 42 4 -26 9 -26 -26 21 -9 4 -39 29 0 -9 41 49 -14 10 125 -24 -3 61 -1 31 5 28 30 23 27 -2 -19 2 28 -45 25 53 -49 -14 1 -79 42 12 -18 -63 12 2 43 -48 25 24 24 0 7 -22 30 -35 2 -17 -9 -34 22 7 26 9 25 -66 10 -18 11 57 6 9 10 9 3 -3 -43 7 -6 36 29 -46 14 7 -30 8 3 -12 -43 -12 8 -7 12 44 -18 -15 16 -16 -1 -1 -7 -2 -42 23 17 -10 -20 -11 -6 -2 14 12 25 -1 8 -9 57 25 35 24 15 -2 34 1 32 -7 -14 4 -32 -17 -23 -28 20 11 -36 10 3 -6 27 28 -12 -42 24 -6 26 -62 -6 17 -4 -4 -18 33 -22 9 19 12 -19 -44 36 -6 63 81 -33 -26 -62 14 37 9 10 73 8 -3 -38 -29 43 -12 29 60 21 23 -20 -26 4 34 -20 79 52 56 -33 -3 13 -49 11 23 25 -22 38 5 -55 62 -26 4 5 58 0 53 22 -32 40 42 127 31 105 76 -11 31 29 24 9 -5 97 -20 -16 40 17 -8 9 59 0 6 80 63 -30 33 28 -14 32 19 -35 -1 -90 -46 37 19 -25 -11 -1 -18 22 -46 52 -16 -3 15 19 -13 -57 4 -61 57 -11 -72 -13 -3 -24 48 -17 41 -2 -13 54 8 -30 25 58 -5 -58 -43 11 -62 -19 38 25 22 17 -18 89 -22 20 22 5 3 11 29 -21 -39 -35 -67 -13 34 -29 14 -60 9 24 -2 38 -17 83 68 -38 -72 -35 15 -10 68 2 28 25 56 27 -42 6 1 18 4 -15 18 20 15 30 -24 52 13 4 -6 -21 15 15 32 10 -41 15 28 -21 -27 20 53 5 -24 21 34 9 -41 -24 -13 47 -34 -27 -21 -26 36 -22 -19 -18 -36 8 -20 51 14 -13 -23 7 -2 -8 -7 -32 -16 3 47 28 -6 -37 26 -69 -23 11 15 6 -13 17 18 6 -13 -18 85 -29 25 -31 41 -23 3 -8 -46 -2 -1 16 9 -13 15 -18 -24 3 -5 23 -16 42 24 -11 14 18 -1 13 17 13 14 -41 -36 -14 1 36 19 43 1 -34 -44 93 8 0 21 29 18 -51 97 26 7 -14 2 72 -4 6 -61 -64 -34 -21 -46 15 -30 84 30 72 7 28 -48 -33 65 3 12 34 94 24 18 63 25 25 54 20 11 64 8 62 67 30 -13 29 15 0 -11 25 42 -86 -23 48 87 51 65 40 63 -42 -14 1 51 71 94 46 4 14 -66 22 37 56 62 23 29 5 5 -28 -26 6 88 7 -30 83 0 1 -5 56 7 -53 8 -26 23 -24 -88 16 56 16 26 5 -23 -34 -10 -40 -37 -38 -36 -11 34 -18 6 -45 -30 28 14 3 -22 26 -67 24 38 38 9 8 14 -14 -38 25 -8 -8 -32 -12 16 32 -34 53 -73 1 22 -6 37 33 -23 16 14 -52 -19 56 -10 -45 53 11 23 12 -4 36 19 -68 -10 74 22 -18 22 -5 34 30 76 54 24 49 3 -18 -33 -45 -3 -24 -13 -2 11 -45 -31 -43 4 23 10 -23 18 19 22 -1 1 -27 28 2 -1 23 -13 9 1 6 50 -2 -3 -36 16 19 48 -29 -23 25 -22 -6 -38 -31 10 2 -22 -26 18 -29 14 28 9 17 -20 -32 13 13 0 3 0 -23 57 -28 2 7 -21 -1 -23 -6 33 -7 5 -17 21 32 32 -44 29 -15 -14 39 -24 38 -19 -21 53 7 17 -1 -3 -27 -12 19 53 -8 -7 -29 17 -4 22 27 12 17 18 27 43 -35 17 -12 27 -26 108 -54 48 30 -25 14 -79 -36 18 16 48 121 4 8 93 -36 -52 39 -54 -20 27 0 56 22 -46 -2 -17 5 -3 -33 -55 98 18 4 12 37 48 18 73 45 -40 3 57 124 16 11 32 19 -30 88 2 48 53 50 58 18 -44 38 12 32 29 127 44 -66 69 42 71 39 -41 37 11 -22 -34 112 -31 -25 16 9 19 -13 27 -52 -27 38 -49 88 -9 62 18 -7 -1 -24 -7 -12 -17 -3 35 9 4 43 16 -20 14 2 30 44 26 22 -19 80 -108 7 -21 41 -43 90 24 -3 23 -28 -42 -56 124 -12 -19 17 17 -73 -66 10 8 15 1 34 71 -9 -43 89 33 -9 -71 -7 38 10 -34 15 -89 59 -12 -47 10 -31 6 -23 17 23 -105 11 43 36 0 28 -9 30 -24 57 -30 28 -81 9 -33 -47 5 -47 5 -18 9 13 41 -54 10 -33 71 17 -19 -9 -65 -8 -3 -15 15 -59 -52 9 5 32 -51 -10 -19 37 -25 -10 13 13 -22 -61 50 0 35 -7 -38 25 -9 -21 23 13 -24 -10 4 -44 23 55 31 15 -3 19 -5 -30 -35 7 -26 -2 -12 -24 31 -31 -8 12 10 27 25 -26 -49 28 38 6 32 -45 18 -24 -61 -66 -2 20 15 -16 -23 -32 7 21 -23 -35 40 37 27 28 41 -40 7 -25 36 -44 14 -7 50 -62 -26 43 -32 5 9 6 -25 7 -22 -9 -27 60 -99 37 33 78 -26 3 41 -6 -20 10 36 20 87 24 13 -34 60 -120 82 -11 -15 39 40 58 21 11 90 -38 87 15 -15 -4 -10 -22 -30 36 -36 -12 -23 -9 -16 16 47 -26 45 -63 45 28 6 32 -48 -1 23 26 -31 -43 -10 70 -108 -9 -54 49 -41 -94 -16 33 15 21 105 81 -75 14 -51 43 -18 8 -22 -15 -13 80 53 -22 -14 -29 25 1 63 -28 0 39 -11 103 3 54 50 -50 -15 15 52 -24 10 -54 -1 26 21 31 25 30 -49 9 -25 72 5 -9 -10 16 -24 58 -73 -33 -49 52 10 45 -62 70 8 -7 26 24 70 29 -18 12 80 26 25 -25 -106 16 6 11 42 24 33 23 -51 25 -17 65 43 -37 -24 -7 26 64 -85 98 39 -28 54 -8 10 -44 -17 28 69 82 -8 26 25 12 38 -50 22 20 -53 21 -10 -11 -87 -44 -26 40 -32 6 -14 -1 8 14 41 12 -23 12 -24 -1 2 26 4 9 -1 26 16 -58 -3 -19 -22 -1 5 -10 25 48 17 -10 -33 17 7 -17 18 12 4 -21 -9 -22 29 -24 26 -20 18 -85 5 40 14 15 -50 -24 55 -47 40 48 41 -4 -32 -7 -40 -25 10 10 -25 -23 18 -3 16 25 -17 -24 -3 -19 12 -36 -3 5 41 26 -36 -23 -12 -39 10 -14 25 -17 25 13 -57 35 -10 32 -31 -6 -60 38 7 21 -13 -6 13 -23 59 -27 51 -1 85 26 31 53 99 57 25 21 -7 11 80 -5 53 96 -64 45 -2 74 -10 9 16 -14 -15 81 55 44 46 77 14 35 -14 5 25 66 14 94 32 30 1 49 66 86 20 125 53 100 9 46 77 15 29 46 15 -41 67 -2 10 23 -7 45 76 36 -43 79 18 38 71 -2 70 54 4 24 19 46 -7 -14 39 -92 -24 71 100 25 4 107 23 12 27 31 24 -51 -10 3 82 62 -37 60 26 30 -27 7 23 -19 -36 24 67 53 -9 0 40 -6 15 22 -4 23 77 -76 38 -32 16 31 -6 -41 37 8 -25 -19 -2 24 21 -2 5 10 46 -17 47 52 -22 -1 51 9 61 29 -25 -40 -24 -38 -19 40 -17 -1 35 45 -1 -28 -3 -58 -40 -4 19 -16 -66 -8 -5 -43 51 2 14 -15 28 2 -16 76 24 46 51 6 -2 29 -6 -7 71 -51 25 50 26 -21 3 11 -20 -5 -4 16 8 4 1 -11 4 -34 -11 17 24 -47 14 -12 29 -42 2 -24 5 -3 18 9 -2 9 -4 -10 26 -12 11 3 -11 22 24 19 -24 29 3 -69 17 8 48 60 -23 -49 -14 69 21 26 24 17 -40 -22 19 -39 3 33 16 1 9 63 18 -27 -8 11 -8 -47 -3 66 16 28 11 -8 3 19 15 -11 9 -35 -11 -3 -48 -10 9 58 -32 -24 -22 -33 27 46 0 -22 -42 -28 51 38 -21 4 41 -12 24 -86 -25 -63 83 37 -52 23 -68 -58 80 -7 42 38 61 -61 33 58 -37 36 35 -32 21 32 63 14 -7 -13 58 66 8 -32 20 -8 48 -27 6 14 -19 43 68 9 30 75 37 -76 -14 -29 57 -3 9 -13 -109 57 12 23 59 31 30 -68 -47 21 24 -46 -101 45 -10 78 -50 29 25 -8 16 3 6 -4 -85 6 -5 127 -9 82 81 0 18 5 -10 -21 -62 -41 -86 44 31 22 -30 -36 10 -11 26 -9 25 -71 4 -73 8 57 -22 -57 22 11 -1 -59 94 -21 -77 35 13 -14 -61 2 -32 -23 -23 -58 15 7 55 -59 65 14 29 25 -64 33 -18 55 15 -29 27 -35 33 -31 3 3 12 22 -96 36 6 6 34 -14 94 6 45 70 60 7 26 40 26 -13 2 40 -57 -38 32 52 67 38 -61 18 2 -41 66 -12 -20 0 -44 -32 3 2 32 23 -10 44 1 -1 2 22 16 10 -9 45 -6 5 -28 -5 -6 -31 24 15 37 7 40 -18 51 13 -19 -52 42 -37 -5 40 -25 -9 -7 -2 -52 9 27 -14 -11 -2 34 -7 -1 18 -11 28 2 -42 -4 -26 -9 -5 -24 -27 -29 3 38 3 1 40 47 67 -32 -35 0 -27 1 -32 2 52 27 25 -35 53 6 25 0 41 -26 -51 5 -46 4 -6 8 2 17 18 -85 47 -16 -29 -40 4 3 43 33 -39 38 6 11 25 28 -36 2 7 50 -34 28 -44 -41 -54 86 30 52 37 -62 -4 23 30 -32 -7 109 -47 -46 13 30 16 5 10 -15 53 -23 48 -21 -66 24 -36 -31 40 40 5 21 -66 7 67 45 49 -29 56 50 -54 38 10 63 -7 22 1 38 -2 12 0 -59 2 13 -46 21 -8 -34 13 18 -30 -12 34 24 -18 -8 24 17 -21 -4 36 26 42 20 35 -23 55 11 -23 -1 10 32 48 2 49 3 18 84 -40 20 7 29 -63 -24 7 44 9 -83 53 50 -41 20 -47 32 -39 26 -49 -12 -44 34 -41 51 0 6 47 -5 7 16 89 -68 -13 -16 -25 -2 6 -70 15 -18 -1 31 69 6 -7 14 -16 17 -41 31 2 -13 -10 -3 51 46 -37 87 -80 -17 35 24 -1 2 43 1 16 22 -15 15 -16 15 12 26 53 -18 40 -49 -2 41 -34 44 -51 3 28 -29 5 44 -22 -10 28 2 -54 27 -17 19 43 -16 -9 -11 13 -37 31 16 -1 -52 26 10 -44 -31 -8 -55 21 20 -43 -29 36 -31 -46 11 -9 -18 -22 30 42 -16 0 -50 0 -30 31 -7 -3 14 -19 21 -29 -34 50 20 20 -18 13 -5 -52 -32 -5 30 88 -26 41 -3 -1 12 38 13 22 53 8 14 13 -13 7 -12 -36 -4 -19 -16 -3 -6 -37 17 -3 -28 24 -1 23 16 -7 -42 -12 20 8 17 -16 -4 -6 42 48 -18 2 -10 20 53 -71 42 -33 8 20 -25 12 52 -23 52 16 58 -15 38 -18 1 57 -12 46 -1 -58 -10 -47 4 11 -11 -25 -1 8 -5 -30 34 -18 87 21 1 44 -70 21 -68 21 46 9 24 21 33 -33 -13 -68 -71 17 68 83 36 76 -12 -9 -22 9 13 124 17 25 12 84 -30 -61 98 -14 18 7 25 -44 39 -45 -13 36 -23 2 105 21 -17 -41 49 42 -33 2 -19 32 -12 36 13 12 -76 -33 9 -46 14 -24 -3 24 39 81 -35 48 13 -8 -23 -34 -47 -4 -50 -62 33 -23 -84 -2 -29 12 5 -126 52 -20 -35 11 -48 6 19 -34 -91 -12 -33 -12 -17 9 43 -5 -51 40 10 -18 18 59 -34 -82 -35 -110 -45 22 8 27 -41 7 -12 24 -18 32 26 64 41 -3 6 -26 -45 22 39 -43 5 18 -4 -121 -7 3 -42 4 -39 -18 43 -16 -92 -50 13 -18 -2 -21 26 12 10 9 -1 -9 19 26 5 17 31 -12 -31 -8 -33 -15 13 -2 41 -23 -23 -12 -25 28 -11 10 -11 -26 33 -17 -31 -30 32 -7 -20 21 3 -13 -11 -8 -17 -12 -5 -35 -8 16 27 -10 -64 -52 -19 28 23 5 14 -32 -13 -37 -31 23 -49 30 -32 10 14 -2 -2 -3 11 23 15 -19 10 -10 30 49 -17 -45 -19 12 -11 6 1 6 -5 49 7 -37 9 5 -9 -20 34 -40 2 97 46 55 26 56 16 61 -6 -43 62 -90 17 -18 49 68 -2 2 60 37 -28 1 52 -55 -36 -58 34 65 29 27 28 -40 63 42 -15 -10 -19 -1 -7 -74 58 -10 -27 -7 41 -4 -35 -27 -11 45 -52 44 -5 45 40 41 -96 28 -22 84 -4 5 87 -80 4 3 30 75 -20 27 -69 101 -37 -91 -45 -29 -16 40 -38 57 107 26 45 -43 -3 34 0 44 22 -19 29 -37 6 -8 0 -17 58 46 -2 -29 -12 63 -19 -34 -25 13 92 -40 -6 9 -25 73 -59 10 -46 -32 80 28 8 11 -8 20 4 -22 113 -12 -75 29 -77 88 -28 26 53 -22 -13 -64 -43 -92 -7 11 -121 -1 -61 -26 52 -18 15 -49 -20 30 14 -12 5 8 29 63 -4 -122 -22 -21 25 -65 -43 82 3 -23 -82 -19 42 0 3 31 29 -18 -87 -20 -5 -19 87 -54 -44 46 -17 -3 15 -5 -72 1 43 3 -10 -52 -5 17 -18 20 -25 -1 -33 -53 -16 -5 1 -60 10 58 6 20 -29 10 -25 -20 22 -20 3 0 11 10 -16 -13 29 3 12 0 18 6 6 40 12 34 -19 20 52 -75 5 17 31 -52 -21 14 -6 30 -34 -45 27 -3 0 35 19 -5 2 12 -40 -5 -35 5 7 14 9 -8 -3 11 -50 13 3 1 -7 -41 21 -33 -43 42 -5 1 1 -37 -21 -22 18 17 57 -14 13 13 12 36 19 12 2 28 36 -82 3 41 12 6 -11 27 17 -45 -7 50 27 61 -39 72 18 -37 76 37 88 68 32 -34 -72 11 21 35 7 14 -76 55 65 32 38 100 -24 11 113 87 35 -21 33 0 19 -9 31 37 1 81 35 3 0 -43 -58 -20 29 -41 15 26 -23 -29 58 88 69 16 0 102 -6 28 -35 22 127 54 5 29 21 46 -16 37 -9 -31 43 11 -3 -21 -27 66 6 17 -18 35 -11 -13 40 54 37 -3 28 18 36 43 70 31 -14 65 -37 5 -45 100 -20 -26 -26 -21 58 64 -12 32 6 12 -75 -14 63 28 41 46 -7 45 -70 98 -61 48 4 -47 -63 -40 44 40 10 25 -19 -5 51 4 19 -63 2 -33 -34 10 -10 -11 -37 -42 -14 5 75 -7 12 43 -1 -26 -43 99 -19 -26 42 2 5 -10 -15 3 44 30 -4 -15 8 -79 7 21 9 78 47 18 -49 10 -29 24 74 37 -13 -4 -4 4 5 8 -16 -38 -9 39 -18 17 27 -5 34 -4 8 -11 41 25 49 22 60 45 42 37 43 46 2 -27 -5 -4 12 6 -10 11 7 10 -9 0 24 -3 -58 8 2 6 -11 -22 -3 36 66 54 -9 -11 -43 49 29 -16 10 5 -6 -9 7 18 45 18 -13 -19 -7 6 38 3 -7 62 45 -20 15 2 -55 8 -12 -20 -20 -11 -25 -6 3 -21 33 22 -9 4 -1 32 43 12 23 -45 -16 38 16 18 -18 -10 -25 23 48 2 -25 -13 -18 4 87 14 -9 44 48 20 36 -46 14 -18 -9 13 10 4 17 -17 -27 32 66 -8 108 -3 -44 11 -91 7 -16 29 10 -40 -4 -24 49 -16 -36 -9 20 -66 15 -72 -25 8 113 61 89 -48 -22 -30 5 -34 27 29 0 17 -3 3 -56 31 -35 -90 -37 58 -18 18 10 7 -29 -25 24 58 36 44 84 -7 42 49 -4 -40 -31 43 26 -6 -11 -4 -39 67 65 -10 -19 41 29 48 64 18 25 -48 -57 -10 55 -50 -3 12 5 17 -15 -45 -23 17 17 2 9 -3 24 -15 61 10 31 39 -41 2 -14 5 84 39 12 -29 -6 4 -27 4 -24 9 -11 13 -14 9 15 -33 -46 -28 5 -3 32 -6 10 -3 -10 21 45 -17 9 -24 43 -23 -14 5 -14 23 5 -40 21 -22 12 75 -47 35 45 -5 1 6 -13 13 -32 30 67 -6 -7 12 5 -5 -16 15 -4 9 -11 0 7 42 32 -13 -27 15 7 0 19 -38 -14 14 -24 15 -13 -20 17 2 12 38 11 3 23 14 -13 12 6 -36 25 4 4 -16 7 56 -19 -9 -3 -6 27 45 -28 -15 1 -7 18 17 -40 -12 -1 43 90 -9 -25 32 -14 -20 11 -14 37 9 9 3 -35 50 37 -8 -20 -49 2 4 8 -10 -13 27 26 -7 -6 8 -2 9 22 4 0 -12 7 -9 -20 27 -39 12 -37 65 101 -4 62 -13 41 -23 3 -92 47 90 52 17 -12 73 115 18 106 20 41 -12 7 -63 70 52 -34 -34 42 73 64 17 67 9 -21 -1 -22 42 -3 -46 23 25 -32 -55 14 42 -61 43 83 16 33 -52 -21 24 -76 9 36 14 -54 57 -21 -2 46 108 15 12 86 22 7 -18 64 126 -49 32 43 57 23 74 15 -10 42 36 40 0 78 7 12 95 -40 100 50 10 -16 38 61 -35 -9 -5 9 -15 -10 42 29 -11 -16 -26 47 -26 2 -128 -10 -18 -10 -18 64 -22 16 11 -16 -70 40 19 -15 9 -39 14 56 -68 110 36 -13 41 17 -2 5 23 49 -102 49 56 26 -62 35 -37 31 16 3 -30 56 -5 31 -13 -13 -4 5 43 -21 12 -21 -20 81 -9 14 11 3 52 31 -25 24 -34 46 -32 -35 14 -52 -21 57 -33 -39 19 -49 32 -25 37 32 -62 -113 -25 7 20 -19 -3 -6 24 42 13 -29 6 26 -61 -14 -1 14 -27 4 -15 28 9 26 -17 80 -7 12 -32 -35 16 32 23 -12 -4 33 22 -11 7 27 1 -7 -12 -40 1 13 22 -23 -27 -2 38 -31 -14 63 70 20 22 71 -3 -69 -3 -3 -35 38 -46 23 0 -24 39 -77 17 -13 0 23 31 -63 49 16 -6 -30 -9 14 3 22 34 -36 -9 -18 9 2 -21 34 -14 1 -48 -9 -3 13 45 23 15 3 12 18 -5 20 0 -2 8 0 14 -15 -9 -10 -13 12 14 -7 15 9 4 17 3 1 -7 9 18 25 3 14 -13 21 11 -13 8 1 -5 -13 6 -9 -5 -11 10 3 -12 12 0 11 7 11 -11 -9 -16 18 2 -2 -3 19 13 -33 -24 -10 -9 1 -5 -15 -19 7 -16 -8 -2 -21 -17 -12 1 -11 1 -8 3 -20 -9 -6 17 1 11 18 -18 -9 8 -17 4 -4 9 -5 10 7 22 -11 2 -22 16 13 -4 19 4 -8 -18 -4 15 11 -16 -18 22 13 0 -24 -14 29 0 -6 1 -2 -1 21 -5 15 1 -11 3 -9 -3 2 16 9 0 12 -10 16 -2 13 -8 22 -9 32 4 1 2 13 13 8 -10 19 -9 12 -12 -22 20 -17 -2 17 -17 10 6 7 7 -1 -2 8 7 5 21 -5 -10 15 -7 -1 -7 -10 7 12 -6 10 7 17 -14 10 -1 0 -1 -5 -8 -13 10 14 -8 -6 -6 5 10 2 0 9 -19 7 7 2 5 -21 5 1 2 1 9 -19 14 7 -13 -14 -1 11 11 -2 2 8 4 9 -10 3 -4 2 4 -2 10 10 18 1 11 10 -1 -13 15 8 1 1 6 18 -5 -16 7 2 16 26 3 -3 6 2 6 13 10 14 -5 -5 19 -15 14 0 -17 4 -11 2 5 -3 -12 -1 -1 -6 10 -5 -6 6 6 -20 4 8 4 -9 10 -5 -9 3 -16 -17 7 54 -5 -67 -1 46 0 -5 32 -19 0 12 4 1 -5 -35 -6 -30 16 3 -41 -10 41 -27 -14 -16 15 1 10 8 -9 15 11 -14 -2 19 8 -40 -10 11 5 3 -9 3 9 -10 5 7 -7 -30 22 -20 -16 0 -27 42 -23 9 32 18 1 6 5 -16 11 34 -23 1 18 0 -6 -8 17 3 0 19 -6 -33 19 -10 2 2 3 -6 -18 13 -6 -3 8 -18 -9 16 1 1 38 36 2 28 4 -10 33 16 11 -1 -9 17 -21 6 -15 15 3 -41 43 -36 49 42 -32 44 20 -11 -7 12 25 -13 17 9 5 -14 30 -1 11 -3 28 -7 -20 11 23 -21 3 28 30 -19 6 33 14 -31 21 -27 66 6 7 -21 21 34 -13 -9 -18 -62 -25 -28 20 -71 -32 -23 19 0 27 -6 -26 -2 36 -15 -7 -34 -8 21 22 -22 -4 -43 -48 -2 15 -7 -37 -30 39 -3 0 -1 -4 1 -8 7 8 -4 -25 -7 -15 16 30 -6 -14 -12 22 15 1 13 11 16 -32 27 -25 -15 -8 -10 13 -9 8 7 0 23 -1 -20 -37 -22 11 -8 13 10 -12 -5 -23 -16 15 -10 16 17 -6 15 3 -18 -5 25 -10 8 -19 -23 -8 -2 37 6 22 -30 -17 9 0 5 18 -2 -29 1 2 3 4 12 22 -16 -11 -13 0 -11 -19 -20 -5 -34 -8 12 -9 -8 10 28 -12 -16 -16 -26 -19 -14 9 48 -17 17 12 -4 18 7 -12 -21 6 -34 5 -37 -28 11 -19 17 22 -31 -49 -12 31 -10 -57 -21 -38 -29 21 -21 -27 -48 1 19 27 9 -12 3 25 -37 -7 22 16 -9 -15 10 7 26 13 -2 -6 -8 -8 -50 7 29 -12 4 -29 10 23 -4 -21 -14 -24 -12 10 -4 41 4 21 -20 -37 -8 -8 25 -45 -30 24 1 3 -3 47 8 -62 3 -22 -14 22 -50 3 14 25 -41 52 16 15 18 -61 -32 29 -3 22 -8 -70 -13 -32 8 4 11 25 1 25 -31 28 -39 -64 11 23 -12 -15 -7 -38 -1 -58 -103 19 9 14 21 67 8 -6 -61 -61 26 -11 3 11 32 51 -25 24 16 3 31 -19 -6 10 -20 -1 -1 -3 -24 27 -31 -19 29 -14 -45 -10 75 -53 -29 -26 22 -23 -31 10 14 -34 -39 -28 -35 -2 44 13 -36 -46 55 -32 -62 19 -72 -33 -25 -10 -8 -12 -13 4 -36 -11 14 10 -23 -29 -9 3 9 -7 -5 -24 10 27 -2 20 -28 14 3 -37 2 -29 3 0 -17 -2 -15 -20 -19 -23 19 1 23 -13 -1 10 20 6 28 -22 -17 -18 -4 -6 -9 0 -7 -36 12 -10 66 -18 31 11 -6 -18 -1 4 -8 17 -32 1 3 -2 0 -24 22 3 19 -33 22 6 6 27 12 -14 -11 26 -5 -10 -7 -8 -9 34 26 1 37 34 -2 -19 32 -8 1 14 -25 22 -27 15 -12 -3 42 55 -42 14 31 40 -8 46 36 14 -38 -17 9 -13 -13 43 -43 -22 -13 54 -22 -8 -4 7 -1 -26 77 -19 -55 -7 4 33 46 17 67 21 23 -12 -1 13 14 24 -36 35 37 -8 10 -3 9 67 -74 -63 -4 -23 0 12 -6 35 14 67 0 13 13 25 27 -6 -19 5 4 6 -7 4 56 -19 -2 -21 -17 1 11 28 6 27 -49 10 -5 -15 1 8 -4 29 -1 30 0 30 21 19 56 -39 -15 -49 4 -23 -2 20 -30 -22 -3 -10 -4 -2 -17 19 24 -33 11 -5 37 -8 7 7 -37 7 57 -18 55 -61 -11 13 27 54 -15 -10 52 -14 -21 -21 2 47 -29 11 -16 -77 -16 -57 38 53 -14 30 -4 6 -3 4 43 36 12 21 3 33 -36 -16 -2 4 18 -37 62 19 16 -24 2 -3 57 -18 24 40 29 43 -34 88 -41 -22 -12 -54 45 93 -11 10 14 10 -33 0 -12 -5 -10 18 -14 12 -25 10 -9 -14 -10 -27 -21 -11 -27 -3 32 -16 -10 -19 0 0 7 -42 -10 -24 2 13 8 -20 49 30 6 12 -9 -3 0 8 17 1 -16 -14 -20 21 -18 -17 12 -37 -18 33 6 11 -8 -14 0 15 -14 -18 -21 -42 -5 22 -15 -29 -31 6 9 -39 -3 25 -1 6 2 -16 30 -15 -17 2 30 14 -23 9 -18 5 25 43 -14 19 -20 0 17 -75 -44 -2 -11 -26 -7 7 -84 34 -47 -13 27 22 19 -5 -9 20 -24 70 -36 6 39 16 11 36 4 49 41 32 -7 14 22 31 86 15 -49 12 -44 18 25 -10 23 16 -25 -27 7 -44 -25 -16 -13 -17 -14 -53 -33 -9 -53 70 24 -16 50 40 -16 5 -19 55 -33 52 19 19 39 6 5 36 -33 26 20 -18 -28 -33 57 -4 -5 -60 -16 -3 -21 22 33 51 10 40 -2 -18 4 23 -10 30 16 60 7 -6 -3 -8 4 -36 -56 62 37 15 -21 -25 25 59 -11 3 77 -20 15 31 -9 -5 67 -36 9 70 -16 21 39 18 -30 -8 -48 36 -79 -24 53 -2 -2 -9 -35 11 36 47 0 16 -77 -33 24 -71 -10 -3 -5 14 -58 -35 2 16 -5 -25 -1 1 -95 17 -33 -76 -71 -47 -29 -43 -4 -39 -5 16 21 23 -7 -16 -72 -36 -23 -2 13 6 9 18 18 -38 -5 15 -38 -34 12 21 29 -14 -3 0 -2 -3 50 12 -3 -29 27 10 29 -36 -17 -15 -34 -17 35 -10 -24 31 -10 -40 -18 -35 36 -35 -7 55 -6 19 -38 -18 29 -22 -7 -9 -34 -6 -33 -2 0 13 -2 -21 0 -9 -19 28 -5 -21 -29 6 -2 29 -6 24 0 -8 -29 -8 29 -34 -36 8 -11 22 63 15 -31 -6 -10 14 -5 -5 -17 -29 5 8 -12 33 38 2 10 14 -18 29 16 8 -7 3 34 -44 28 -17 -68 -18 -14 -26 -18 44 26 -8 -5 7 15 -71 4 -41 -15 -30 16 9 71 -13 24 10 17 74 -19 32 26 97 -10 -13 -3 9 55 47 5 81 -22 6 33 -12 -42 -7 -13 74 21 -5 -21 43 -2 -41 -16 -57 19 -5 22 28 13 78 4 30 -6 -2 -76 1 -26 -28 8 19 -45 -46 28 23 -27 20 -13 11 -4 16 51 -25 -1 -13 -20 5 41 -6 -62 -22 -16 3 -13 -4 2 25 5 -12 12 34 -17 -19 -49 -82 -28 16 -11 -15 -25 -27 -26 -45 48 30 1 -18 -66 13 -36 44 -48 -27 -27 32 31 8 -57 -40 -29 35 62 14 64 45 -4 -37 32 28 32 4 -15 -34 -9 73 22 18 -7 -42 -14 -38 71 -5 69 28 -6 -28 -29 50 -39 29 -35 -22 79 -25 19 47 55 -69 26 31 -31 -36 11 -44 59 13 -40 -9 -12 -22 -46 5 -60 -10 29 17 38 26 30 37 52 25 -5 34 2 -4 -1 13 -11 -20 -31 -13 -11 7 -23 4 -15 2 -49 -5 0 0 0 0 -14 19 28 -34 -4 -39 19 11 -15 -79 9 16 -7 9 -15 -59 -5 9 -27 12 2 -23 -6 -5 -7 5 7 10 25 44 -50 24 59 19 -8 -30 -2 -14 -44 -15 -19 33 -1 7 65 4 1 1 -11 3 20 -17 -35 16 -20 3 1 11 -37 29 -21 16 -1 21 -4 -3 3 -4 -1 12 3 11 0 16 -26 -119 -8 -78 -45 -42 -14 56 -70 58 31 125 78 127 67 -76 -34 59 76 -82 -39 -107 -67 -75 -65 30 -114 -11 -6 127 -18 -7 104 -74 87 32 112 -20 92 96 30 -126 -2 9 106 4 -105 124 -126 85 44 -32 33 127 87 -48 -19 77 -42 -127 -55 1 16 -64 85 122 34 -80 98 -74 127 -14 91 5 69 17 67 98 -21 46 7 -25 3 -73 -14 27 -116 9 -68 -19 -125 -40 -31 -127 108 6 62 -63 -127 22 -68 -19 13 75 -46 -2 67 -32 127 104 -10 -96 -17 117 10 7 23 3 127 -28 31 57 17 12 -78 127 -9 90 12 -127 -71 49 113 -21 -1 -121 83 8 -87 -35 -2 -109 44 -78 -59 24 -22 -36 -23 17 -127 -7 -96 -2 -6 2 -66 -26 50 56 -35 -104 -65 2 -127 15 -126 40 -56 2 -22 -125 47 -99 -7 -127 -9 -29 91 10 -43 -34 85 81 -119 32 -69 -50 -120 -63 -48 -122 88 -76 -9 62 52 -28 -30 -59 -70 -21 -12 54 3 18 -44 -12 86 52 94 59 30 -15 -104 -35 28 93 123 -62 -118 10 -37 127 -51 -13 -8 46 -27 -2 20 109 62 81 10 -10 -33 -18 35 -51 39 5 57 46 -122 58 -64 114 8 -11 23 -6 -29 15 -21 2 7 126 -58 71 -43 -110 27 -16 15 91 -71 17 28 67 -60 -59 -42 33 37 -40 109 8 23 -37 -50 -38 -24 46 -11 81 -53 -56 75 -26 -54 84 58 48 -15 -21 -128 -13 -31 62 5 -9 -61 -125 4 -10 69 29 12 -46 54 -128 49 -126 -127 -110 37 63 -9 -69 117 -123 84 63 -103 74 58 22 11 -22 5 -6 -9 -78 82 44 37 -19 16 -11 2 127 -16 -70 127 -110 61 122 -121 -49 16 -8 34 18 -51 -125 -29 -79 41 36 42 108 58 118 -59 36 120 9 -57 53 -7 -43 -125 -18 -68 125 -35 33 127 -77 25 97 -27 -124 101 108 -71 -13 127 -56 77 -61 44 -52 34 44 -100 -85 90 -90 83 59 -127 -49 21 -69 44 90 -122 -58 -15 127 97 127 -118 -126 -121 -120 36 -77 57 -30 85 -102 126 126 -43 -64 -73 -8 77 57 -10 1 2 55 -60 127 127 -91 -106 116 -68 55 -30 -46 -116 60 -86 -66 127 -17 -82 -9 51 50 86 -115 -113 85 127 -53 20 -77 39 -56 -35 -3 29 -128 -54 -128 127 -90 -24 -37 -60 68 127 125 120 36 -18 35 -9 86 -69 55 -47 102 37 -77 -74 -22 -29 9 44 7 87 -30 29 -3 30 4 -7 62 108 -96 -88 55 19 -33 16 -31 31 -22 -96 -65 49 123 52 68 -81 44 -28 27 123 -72 98 -31 -39 42 -34 34 36 -51 -84 41 -4 22 -49 22 35 -47 -4 97 98 108 -42 59 5 -10 -9 -20 -50 97 -37 -23 -10 -73 27 42 26 104 37 72 -4 84 61 118 72 58 -15 5 -16 119 -5 -75 -18 12 -77 -13 13 87 -105 -22 109 -81 37 48 -48 -118 -74 9 123 -92 48 -91 -64 -85 115 -89 -121 -106 76 112 -66 -55 127 -121 -86 44 127 -103 47 86 -121 -122 -111 46 -11 -39 -40 -109 -57 22 14 -67 9 127 -44 -106 -33 -16 59 -125 10 -16 31 -53 -37 124 -88 45 -18 94 -123 -7 -13 -33 -41 -115 5 47 52 -17 -117 -65 104 -94 -76 -8 32 -63 -107 13 -98 118 44 -38 -15 -43 114 -94 -64 18 -67 35 -63 127 80 -2 14 -41 75 -9 -42 -128 -5 122 -77 -33 60 52 81 31 -19 -74 82 -3 -20 45 -127 -75 -14 -4 -61 -10 118 57 85 15 104 -16 -53 -67 5 -55 -49 -7 69 -74 -39 -13 -92 -124 -110 65 18 99 -62 62 23 100 38 96 -73 48 -53 -58 -122 -48 -93 -4 -13 -126 19 57 -5 22 -45 -22 66 50 -7 -38 29 -12 45 127 -113 -34 -2 -14 -16 -17 64 -73 123 -20 40 88 74 44 60 -57 -38 -98 -70 -21 -11 -37 -69 73 24 -67 36 -12 3 13 -63 -10 -91 14 107 25 -50 -33 58 -32 -66 -23 53 25 -98 126 9 125 17 126 17 2 -34 29 107 -8 -1 -68 -52 6 -32 65 -4 15 38 25 90 -35 83 3 -10 36 5 -51 -54 43 -28 -8 28 -87 -50 -56 3 37 40 27 3 -90 35 -9 8 34 45 -13 -115 -23 -67 -89 75 5 13 80 10 -54 44 -122 39 44 27 -17 -27 90 46 -65 41 -54 41 14 -35 -77 -63 -118 72 86 -47 -37 29 51 15 112 -51 -25 28 105 45 7 -13 -126 29 -35 -9 127 99 -17 -77 -122 -128 -98 -60 -103 -127 -103 -86 68 -120 6 38 -124 11 -88 44 63 75 -62 -15 -10 28 98 46 -10 -13 -94 102 -51 105 88 -107 48 96 -27 -12 91 89 -29 115 51 126 -128 103 -111 -86 -54 70 -126 -55 126 0 43 123 107 126 112 5 -23 65 15 -57 -32 22 70 -127 -4 -123 -107 -128 -117 86 127 -60 -28 -104 26 43 127 -125 -49 -60 113 -36 -59 -54 -54 -32 86 93 117 92 126 102 -36 98 2 -62 -18 81 75 92 -101 -126 -44 84 -120 -116 -38 127 127 23 126 6 88 -20 73 -109 90 59 -122 -101 126 -101 60 -93 28 81 -24 -83 77 -128 -99 -22 -127 -127 -57 18 -2 120 82 -101 97 127 90 -20 33 -127 -102 -2 17 127 -95 41 47 -24 -27 -19 -20 -94 -45 52 108 -109 -82 -21 70 21 -102 76 79 -4 63 67 -57 -50 50 11 6 -8 -82 -66 40 2 94 47 26 -127 -54 15 18 -40 127 120 -18 -108 -37 93 18 106 -66 -5 86 33 -41 19 11 -30 -19 16 -16 61 -21 -16 -2 -61 -127 -13 71 72 1 -86 -98 57 14 -126 -2 -87 -33 -102 28 123 44 31 22 60 17 -55 -109 91 -80 61 127 51 72 38 -39 34 -124 -58 38 -100 -19 7 29 -95 -127 -50 -51 82 3 2 -43 -123 -3 -124 -11 126 -10 -18 -73 53 127 125 120 125 93 -127 63 73 28 -89 77 72 22 -40 0 -32 -123 -17 8 -126 -111 -34 -65 -34 -31 -106 -53 -124 14 -112 15 -63 5 -18 24 57 -79 -72 -68 60 -128 39 -122 33 -63 26 -20 -79 90 -4 -9 -22 -68 125 -109 36 -105 126 -3 14 -109 -4 107 -36 -63 57 -22 -40 -28 33 -13 76 -19 -128 -31 24 -126 17 -22 -23 -27 -128 25 -111 -14 111 9 -45 126 -68 -127 124 -39 -16 120 -16 -22 -126 27 -92 -107 -120 -127 -88 52 -28 -59 54 -121 94 116 127 -13 125 60 -117 125 -110 -22 127 -5 -114 -127 -8 -72 -34 7 -32 50 -50 48 116 127 24 9 79 -128 45 87 -69 -47 120 123 -17 77 51 126 -127 126 -107 127 71 10 -127 -71 -77 -91 -33 64 -126 -126 68 79 125 49 97 83 50 -31 42 51 -76 17 57 -5 -14 47 105 -88 -36 -64 95 -94 126 -62 -3 -53 33 44 -8 36 32 50 127 -55 127 32 57 14 -104 -4 49 -32 109 29 -4 -5 -23 106 -16 30 -109 126 64 9 23 -61 -48 -49 -126 80 -54 -128 -74 20 -18 41 74 -127 44 87 -87 -96 -57 39 51 78 -70 -90 -108 -50 39 109 -5 6 -87 -57 36 72 20 81 -88 50 -36 83 -54 68 -21 109 -5 -110 47 -15 98 -32 -14 46 -56 -128 0 34 -93 14 90 -98 -42 10 55 -56 48 31 -33 126 37 25 52 12 -33 -127 112 -23 -18 -127 -23 -127 -19 56 -104 -51 31 -58 -84 -91 -107 -56 -111 -7 2 -47 -128 -87 123 58 -45 83 -127 39 69 -87 -32 126 -51 -35 18 -35 56 31 -44 -128 19 -17 68 86 -88 -58 51 -96 -127 -69 -28 33 80 -123 -128 -127 125 59 -47 -103 -127 0 43 127 -128 -17 7 -85 63 2 56 -35 -127 -30 125 118 41 -126 13 56 126 123 126 115 -123 110 -22 -95 -23 -121 -102 99 127 -128 127 -86 10 20 108 90 44 125 -27 -128 40 -77 -127 33 56 -44 14 2 126 -44 107 16 -84 -127 116 -109 -26 -38 114 123 76 127 2 -120 -126 61 -85 -126 -128 83 -20 -65 -1 49 -77 68 -42 -14 -18 33 117 -59 -25 -58 -38 -95 -40 -106 -49 -35 -113 -126 64 39 86 108 -127 114 27 -97 -122 -36 125 -56 -93 -17 -127 78 -27 28 3 -14 70 -14 65 26 80 45 102 -17 -45 35 -45 -4 36 12 1 125 -88 -57 33 117 43 103 -17 -4 15 -75 -17 30 -57 17 45 127 -50 95 76 9 83 47 106 2 68 -48 -128 86 68 35 47 -10 22 -20 -48 -33 -33 -11 -32 18 0 -9 -32 -16 93 46 -48 56 108 65 -5 -28 -50 -34 -55 -6 95 -8 -87 28 67 -24 -11 -9 5 16 28 -5 30 -60 84 -6 -92 82 83 4 -43 19 -38 1 -104 -92 60 -123 53 22 -98 -46 -11 -78 -55 79 -32 -74 24 -81 127 -14 127 -80 20 74 93 -56 -40 -92 -86 -72 -40 -36 -123 -57 -11 -95 -128 -77 -73 75 127 15 -126 -11 -127 78 4 -24 -126 59 -32 45 -124 -9 -58 -46 27 52 -38 70 52 120 6 -63 -25 -124 -90 -15 127 -31 23 -126 -33 -74 75 -58 126 53 -126 -128 58 -127 -59 15 54 41 96 -33 -93 -118 126 16 71 0 -87 84 -33 -100 -82 36 -36 -35 -126 -29 -29 120 16 -55 119 3 -59 -128 -5 -128 125 -94 -3 -101 51 -40 1 -40 -127 127 -128 46 79 104 -12 -32 41 -128 -6 67 127 -16 20 -101 118 -128 -34 121 102 118 -56 24 -84 -92 3 127 -127 7 15 -63 -66 24 11 -66 29 -128 -1 -26 12 -4 -72 -23 52 122 -49 -58 53 125 35 -125 -127 126 44 75 91 -99 63 -84 80 29 -9 -128 -19 -8 -37 -1 13 127 68 -68 84 -37 -4 -48 21 3 127 8 -30 -9 -69 19 57 -45 63 87 -7 -13 58 51 80 -27 -17 85 -10 89 111 4 35 -18 -15 42 -55 75 -80 -18 100 -58 49 -1 120 54 -128 49 96 -128 -14 -67 -78 -44 7 29 -43 -51 -49 -102 -29 109 19 -37 -3 23 30 -2 -44 34 -45 -12 36 -65 15 41 -32 -31 -15 -55 7 -43 21 -27 77 84 -3 11 -55 28 101 12 48 -75 -15 -77 -31 85 -75 107 -77 -24 122 64 23 -53 -39 82 10 124 -85 50 100 108 98 -120 127 39 -18 -128 -94 19 59 113 -2 -127 -126 -89 4 -128 7 29 71 -39 -98 -122 -41 -47 -128 86 -127 -120 -82 -14 -46 -4 69 79 22 -127 -114 11 -108 37 31 127 85 -40 -128 -78 -51 -15 -31 -62 64 125 -12 24 -27 -48 78 -10 120 -73 101 -76 -61 6 -28 122 -113 -53 8 52 -78 85 26 -30 -110 -15 -112 64 67 -121 31 -37 21 -1 -63 -123 -97 -34 -32 -25 31 -4 75 17 -124 -117 44 -13 -12 -26 108 -107 -65 125 57 19 30 125 -98 -12 13 85 124 -43 15 -86 -89 19 -128 -46 -96 94 123 75 46 67 -78 -14 -67 37 -31 82 -127 127 -88 -94 69 -127 -56 56 -35 95 -13 33 61 -36 -92 -45 -128 -44 60 -95 -34 54 -48 8 114 -79 -78 68 -9 -52 80 125 -14 49 23 -88 -40 -77 -103 15 68 -31 4 -83 -53 0 -40 31 -2 89 28 65 127 -8 17 37 32 85 -112 -48 25 -18 -19 -18 -34 18 -10 28 -30 66 45 123 127 60 -38 -38 -13 127 62 -107 -60 -53 73 -6 69 -17 101 -43 -24 -126 -119 19 17 102 16 0 -50 -86 -43 -33 -125 -95 90 43 24 -78 13 102 127 -33 -9 18 -20 -48 3 4 -2 -49 7 -65 -60 25 19 62 119 -11 94 -39 1 121 1 32 126 5 1 71 -55 -122 -65 -126 76 42 -47 -3 80 -68 92 114 -111 -115 5 -13 -128 -88 4 -49 -54 -76 62 -118 15 -80 -12 120 14 -18 10 -125 -123 -103 58 -126 -113 -76 -39 -122 -118 -123 -107 -88 -41 -127 -67 18 -120 -120 -44 -37 -122 92 15 34 127 124 -12 67 127 -76 -51 2 -107 -4 42 -109 -122 67 -44 127 29 19 -93 54 18 -22 121 -128 123 -104 -123 -82 104 126 127 27 -60 -87 45 112 123 -8 -126 -84 51 -22 66 84 72 103 -24 -85 104 -50 -86 51 -57 122 79 -69 -92 27 36 127 127 -102 31 -41 84 -112 -128 68 122 127 -123 84 -119 -82 50 127 127 8 69 110 12 -127 -113 -127 105 -68 -124 -51 -21 127 45 109 127 127 -28 26 125 -16 -95 -59 36 -24 -48 50 -76 64 26 118 127 -127 117 -128 -107 99 -59 19 -15 -128 -123 68 127 -59 124 9 -126 -88 -13 123 -128 -114 -127 -122 -39 -25 -127 67 -127 60 114 52 -33 114 39 -54 68 87 122 55 -31 -14 -16 28 108 79 52 89 69 -39 20 127 126 20 5 7 37 96 73 28 104 -78 40 -126 29 108 -24 72 -29 76 17 15 -40 31 -18 -21 -123 -32 33 -80 -124 89 -10 24 75 -56 98 -28 -75 34 20 -1 59 -26 86 -94 -32 41 -10 -62 -124 -120 -4 50 -111 -25 127 17 -84 33 -19 50 -111 -65 7 -73 73 -56 -76 -12 98 75 87 64 -110 -128 127 23 -128 122 4 -114 48 84 67 15 8 -71 -126 63 48 127 -23 26 116 9 3 -11 -118 -125 -124 93 118 88 -2 -101 -118 -39 -127 -102 -89 127 13 -120 -113 -39 -112 -70 114 -13 -44 -83 -128 -127 -23 55 -93 100 26 -41 126 84 -28 13 1 127 -17 -86 -12 -109 1 -17 -44 84 -19 116 -73 -127 124 96 127 -116 115 47 -108 -126 -94 -115 103 88 92 121 71 -127 -105 116 122 -59 -109 47 -8 -40 126 -52 33 111 -55 11 -41 123 127 -3 127 127 -56 -128 75 -110 27 127 -28 127 114 2 108 -56 87 -128 -56 -56 47 -127 -47 23 107 19 127 92 -77 -56 80 -123 -126 -125 104 -126 -127 -32 43 -6 23 -80 102 98 41 2 127 66 -70 127 -18 -47 -51 -19 9 106 -50 49 -26 -46 -120 118 -89 127 -121 102 15 118 -87 93 121 -29 -56 109 -56 121 -17 25 -127 119 -127 118 76 -10 -125 93 3 124 51 -127 115 63 112 -126 -17 -75 127 -38 125 -19 20 113 38 127 -38 54 -30 -125 -32 89 -4 -31 123 0 -13 82 -35 12 75 71 20 -127 -125 127 -25 -64 -12 64 103 -100 61 11 18 -96 -128 45 -54 -63 -110 24 17 44 103 -67 24 -89 -23 44 -65 35 64 -63 22 80 -128 83 0 63 -127 125 -26 21 -56 23 34 -12 -94 117 -125 -122 11 60 -4 -48 40 -126 98 -28 87 106 80 -52 6 -9 -60 -16 -108 105 56 -113 87 127 26 -128 120 -78 119 -88 -57 -81 -97 -98 -43 -116 88 -38 -74 51 85 -11 127 76 13 2 -9 21 127 -25 -118 -126 -12 25 -50 -63 -61 -127 6 -69 -75 -20 -126 -61 7 117 -83 49 121 -108 -59 64 102 -89 -127 68 -85 -52 -49 -18 57 -109 28 -119 -11 127 127 46 11 -125 -61 73 56 -106 -116 -8 -115 41 127 -10 -115 127 -53 -23 -45 20 79 -30 13 -125 25 127 -25 38 -17 -38 74 82 -69 25 -67 -81 96 127 37 -67 -22 -113 -115 126 105 -10 69 -30 29 1 -121 121 10 98 -85 -123 39 127 101 110 -125 -94 122 -121 -25 -103 26 -84 -64 -63 -10 -123 121 76 60 119 64 107 101 67 -128 127 9 35 43 -56 -8 57 -3 -75 127 -67 0 54 126 90 86 -52 -10 -30 -108 -82 -121 87 97 -4 64 -51 58 -127 20 -6 1 26 77 -87 -29 -126 124 33 -58 -8 2 -29 99 -52 -17 53 -128 -22 -48 -46 75 -18 -105 94 -82 41 -25 79 -22 -126 -125 38 -115 68 44 -10 37 56 125 -46 -70 50 10 -127 -8 67 -81 -20 14 -30 106 -56 123 -83 107 65 -33 126 127 82 87 42 27 31 -71 -62 -38 40 15 40 61 -128 26 51 58 24 108 48 -120 5 -7 -127 48 5 115 -14 43 -18 4 66 -46 14 -33 80 5 100 -18 56 -73 72 107 -77 82 126 127 -43 -77 124 39 125 -81 -49 39 127 20 2 24 -23 60 112 23 42 70 -78 -39 -127 127 44 -110 118 124 127 116 -128 -52 34 -127 123 127 -65 -44 127 54 -14 -51 -107 -26 -93 127 35 -5 36 -128 127 -78 -82 -127 127 16 -106 48 67 126 -12 69 115 -126 97 -119 -29 83 -79 122 120 -39 -126 72 52 69 -37 42 100 123 -127 121 -18 -120 121 126 36 -116 110 -7 -112 121 36 122 40 127 -112 127 127 71 -27 127 103 54 126 120 -127 -127 -40 77 -64 -123 -108 15 59 -115 -18 -50 -74 104 -128 -31 37 22 127 22 50 55 35 120 -9 38 125 87 124 61 -125 -123 -128 -57 -23 14 -7 -39 32 121 -126 81 54 13 83 6 19 -71 127 -128 -8 -74 -123 113 -25 95 -126 -28 30 -62 -16 122 -47 -45 71 91 2 5 121 -9 126 127 -94 58 -50 -33 -53 81 -1 -54 114 11 63 -75 -88 120 60 124 -118 97 -13 -4 47 109 -128 100 127 -37 114 125 -101 15 40 61 9 -48 72 -59 -66 13 42 -127 122 61 48 58 34 -7 100 -56 -27 118 -124 -34 124 -25 -99 67 -47 42 -54 33 47 58 -46 -82 48 -106 -68 -37 -33 -27 -120 -105 0 -6 88 -17 -126 -18 126 -44 38 71 -22 126 77 -128 -123 -43 -112 8 43 121 44 -92 -8 -51 126 -88 11 40 79 -43 112 -49 58 12 126 122 63 102 24 70 -118 -51 44 127 56 124 81 26 -83 29 -86 72 -102 14 84 -8 -13 121 127 -27 47 -43 14 -77 96 -47 5 -37 -76 49 81 -121 33 -101 -36 94 -28 -10 30 -77 -107 -24 6 -88 60 11 -43 -122 121 -28 -16 50 -12 8 -126 -46 -68 19 47 -1 -34 -45 120 -20 -47 89 18 -10 -41 116 -66 65 -29 70 29 -57 70 127 -14 -48 -1 -19 47 -37 91 -50 -57 53 -92 39 1 112 -62 20 -67 30 -55 -111 72 -56 -6 -33 -56 -50 -44 35 -61 24 77 -40 -122 -41 -23 -35 127 -47 -14 19 -15 -15 -68 16 -25 -103 -112 -120 41 51 127 -126 127 8 32 -109 54 -90 48 -73 61 52 1 -85 -21 38 -68 38 20 24 -56 51 -31 117 -36 -20 -66 4 28 -126 -44 88 83 -112 29 -20 -9 -118 -8 22 -28 -127 -83 -114 -12 -92 125 -39 -78 68 -91 -103 -7 1 -64 -116 -128 76 -14 68 51 63 120 102 17 -29 22 15 -33 22 20 17 100 -37 -58 125 -50 -37 13 4 78 59 -27 20 -28 40 -15 -80 -88 127 -25 20 -57 8 -8 88 66 -73 -96 97 109 -41 52 29 21 58 15 -19 19 -14 -39 -6 56 13 -1 58 -64 41 46 -10 -51 64 52 16 -62 0 40 23 -92 39 -2 113 -45 -86 -111 41 -67 -73 9 46 58 -11 -68 77 -4 -49 -43 -124 34 -18 -67 -41 -19 -76 26 52 127 75 -127 -20 -103 103 -127 59 74 -49 80 104 -101 127 -128 -117 20 126 -38 -76 124 -119 12 -75 -29 16 11 34 -33 56 -76 127 -35 19 5 -126 127 127 -97 -116 -71 -125 30 58 -34 -86 -116 -127 113 73 22 -119 27 111 -64 -89 48 105 -54 -109 127 -32 27 -85 82 127 -76 121 -125 -9 1 88 -68 126 -116 -128 -47 118 -110 95 64 63 -92 -88 -115 -69 -125 -126 11 9 -94 -91 29 111 -4 127 -83 -128 99 -92 -127 77 -112 87 -80 36 92 2 127 127 11 -42 126 45 29 -72 -51 65 126 46 -30 -128 -37 124 63 -101 -128 -123 113 81 -93 -127 66 -61 64 -76 12 16 2 -42 -51 -126 68 84 -124 -126 -70 124 -35 -50 106 -33 -79 -28 61 79 -127 -10 34 -68 83 30 -12 -119 14 -99 76 83 -110 -125 26 -29 -17 -81 -74 -112 -39 -61 53 116 76 124 70 115 -22 -111 26 6 127 -10 127 -106 -74 -8 11 7 77 53 -111 -90 -29 -87 63 -43 -50 -40 105 109 -4 -56 24 -40 -39 -41 100 -19 -17 -101 91 -34 78 11 -6 -93 48 80 -23 -19 -57 -5 -126 41 127 17 110 120 -2 123 2 -93 -39 -74 -13 -59 -71 60 -45 20 113 90 103 -110 -19 21 -19 24 31 45 -128 52 -12 -47 64 -109 -89 62 -33 -29 48 -95 58 3 59 25 -38 23 122 80 -128 -4 -46 -2 31 -34 73 3 -24 122 -8 -93 69 -3 -91 55 -10 10 -99 -73 -101 62 -124 -121 109 -83 -41 -57 -76 -111 107 -126 -126 92 -92 106 -50 0 -127 47 30 101 72 57 -18 -40 127 -84 44 107 68 114 12 -125 28 -72 97 -127 127 88 -76 -105 -118 -6 44 -103 59 114 -96 -55 77 -97 -80 59 -43 -49 -86 127 -106 -46 -40 69 123 -124 46 56 -34 -78 18 7 -68 67 107 -119 18 127 68 15 16 -128 -64 -112 -34 -13 -71 48 76 -64 68 -47 -83 125 -127 44 -127 -127 -23 -110 -87 118 -24 -41 36 25 16 -44 -45 -43 126 59 -3 -28 -7 -70 127 -16 -98 -88 56 -7 -61 -127 -3 -83 109 127 118 5 -88 16 127 -123 122 87 33 -67 126 -108 19 43 -35 122 71 -81 -125 96 -20 -95 -76 -62 40 127 121 -116 -101 -120 84 -56 49 -84 72 44 97 -45 78 4 124 127 12 -9 -46 -40 -128 -128 -19 15 -120 127 -37 86 127 -127 -67 125 11 16 -3 -123 -24 73 -13 22 122 121 -20 57 75 -39 -79 -51 -83 72 6 114 47 52 33 126 -57 -73 76 126 -58 -75 -18 -69 -65 73 73 72 -27 -65 118 37 -35 57 -91 -27 66 27 3 -5 -126 -82 -128 29 -90 34 74 -19 -35 57 -7 13 -126 45 -25 112 -128 24 -63 -66 3 -13 -98 10 -112 -46 -100 -49 -81 -56 93 71 34 -22 103 19 127 -40 90 -91 -2 -92 -125 -34 -19 65 -126 46 58 -83 110 80 66 -1 -74 127 41 -20 122 -60 -5 114 72 2 -128 -69 56 60 43 63 -49 27 -124 14 119 124 23 -114 107 16 37 -126 125 53 -15 -128 126 -124 23 -38 124 15 72 -74 -22 44 127 -93 -8 -126 -19 -49 15 127 -28 113 -19 -16 66 -82 -123 47 -109 -100 -122 -128 50 -107 -59 118 -31 85 67 -99 0 -2 32 31 -73 88 111 43 -4 126 -67 -2 104 115 -52 -38 116 -56 -104 119 -92 -97 -21 127 26 -126 127 127 29 55 -97 -102 -28 42 -125 127 -27 -127 53 46 -127 5 -128 121 -118 -14 -78 -31 71 -30 -5 38 -12 4 123 -21 93 -128 -57 110 127 127 -113 70 69 87 125 127 -109 -64 127 -25 71 -18 61 -5 -5 -128 123 -97 -125 -120 -43 88 -125 127 -109 57 -109 24 -50 93 74 -1 88 24 -58 -69 -40 125 127 125 -105 29 -127 12 -45 -43 -8 127 19 -91 -128 112 -5 39 -3 -23 -60 -71 10 5 -23 -87 39 62 127 -36 -44 -26 99 43 -31 -39 62 -128 -128 -14 46 -29 86 -107 -16 75 -80 40 -104 57 109 76 -57 -95 -26 -128 7 -31 -59 -127 -48 -25 -2 -73 -92 127 78 -4 -4 27 45 101 9 63 -5 -98 -127 -10 -106 -34 -28 -35 108 -45 -106 115 -2 2 76 -19 1 -19 -125 95 -69 61 41 -85 45 77 -51 125 119 126 10 127 20 20 -62 93 8 -91 -47 21 56 -19 23 -127 -17 2 -128 53 -35 -67 -66 -25 -25 47 38 -57 33 -13 -29 13 -65 -45 -40 -58 -28 14 -70 -82 -10 -65 -13 30 15 -17 -38 4 -65 -26 16 52 -24 -4 44 17 -5 2 -49 -42 -14 39 -59 29 6 -22 -36 -40 7 40 -29 -2 -39 31 -21 16 17 -89 87 -57 19 31 17 -33 52 -16 43 3 -34 -12 39 32 62 14 -15 65 6 2 11 68 6 21 -42 -125 -15 -12 -5 46 36 38 127 -88 -53 -5 59 29 -15 -6 42 -27 -79 42 3 126 -45 -98 18 77 -32 8 13 -128 92 119 -12 49 53 -4 39 8 -88 14 44 -126 -45 -2 47 99 -10 -81 -19 92 59 89 32 -43 -23 51 19 24 9 -41 -48 47 -124 49 41 -5 -11 127 -70 7 119 127 15 -58 -32 -18 22 31 -77 -15 -25 32 -24 40 -45 9 25 -5 -30 14 10 51 -8 -51 -51 -26 67 53 54 -93 -7 -21 -57 -7 -127 44 -87 -41 70 -6 -52 40 -65 35 27 11 -10 -116 13 30 -22 -39 0 7 -74 -15 6 -2 79 41 -15 58 -11 3 13 -9 26 127 16 -58 5 124 -8 20 -55 -87 17 -83 2 -32 -38 -70 100 44 -7 -20 127 13 82 -15 93 18 -100 16 -8 -21 10 127 98 -4 -2 -22 -31 -74 -72 37 -22 -10 -3 -4 -93 57 -46 13 -52 20 5 -31 -7 -127 108 -5 4 11 59 -42 -64 23 6 -14 98 -13 37 -31 -127 53 -44 66 -23 -111 -25 -16 18 -44 34 -28 -123 6 -3 65 -9 6 -22 24 -14 -15 -45 -126 0 -68 77 -68 32 -35 -123 7 -26 37 85 17 42 -84 1 75 -46 126 -21 35 -119 33 40 -37 -85 -15 -8 -77 -11 -8 -2 115 23 58 27 -124 121 12 -35 -78 94 -59 22 21 7 29 -23 116 -4 0 69 -19 40 19 -28 -102 -127 -42 -87 -60 90 -111 -30 -21 10 91 127 -10 27 -7 -24 -29 127 83 82 17 -28 -59 99 26 19 14 10 -38 114 10 116 -118 -96 86 -67 -123 -13 47 1 -36 70 41 11 -75 7 -125 126 24 58 -23 -111 -99 127 -96 36 -87 74 -107 -9 13 8 -41 125 -22 20 -54 -121 -11 127 127 -97 48 -64 -127 -60 3 -25 -71 -62 -92 -28 59 -107 52 -1 18 94 87 -59 -18 -127 -114 125 -48 34 -127 -84 12 92 84 -114 -124 -37 -127 -3 -45 -34 36 -104 -50 -47 -104 -33 10 62 30 17 -12 47 19 127 -127 -25 53 -9 -21 33 51 -47 -91 -24 -60 90 -47 38 -35 -103 50 -101 6 36 -126 36 -11 3 84 100 -8 -100 -47 -46 32 -28 125 51 20 124 62 -58 -50 127 -17 41 12 54 -127 27 -126 50 104 80 125 -40 -32 64 24 16 -73 -15 21 36 -82 -31 -103 32 76 16 -17 -21 39 122 42 -19 126 -28 -60 58 42 -35 31 -123 -14 -73 13 28 77 -41 125 124 -103 32 -128 -112 -11 -49 11 18 77 43 45 35 -77 5 94 -81 8 14 -103 75 39 14 16 -71 30 73 -74 55 -31 -114 -3 30 -32 -14 25 81 -64 43 -32 -71 54 -14 -11 -99 14 -7 66 -84 51 56 -84 12 50 10 -62 19 -66 3 4 -126 -82 -42 53 55 -108 125 36 7 21 -21 6 46 -43 72 51 122 127 38 -59 -52 -22 127 -23 102 -34 13 5 -5 48 127 126 -94 -17 -116 44 60 4 -21 -76 -127 -34 -57 68 -82 -110 12 -96 -62 23 93 26 -128 71 48 -43 -28 8 15 -5 86 -33 -53 -13 122 111 -15 62 67 -68 -12 -33 -18 -37 57 73 115 -68 79 121 60 127 -3 3 -121 120 31 -125 53 3 4 -88 -4 127 -79 -116 32 127 -21 -110 -63 3 -13 7 1 82 -46 -92 77 -46 39 -115 119 -79 -127 127 -127 55 6 34 -81 -70 3 -128 12 -44 -28 -87 46 -83 83 -60 -125 31 -67 69 -126 -69 -6 81 6 -1 -6 -95 -21 -17 127 31 -33 -35 -80 -35 0 -6 -27 42 -5 -32 -68 54 4 -110 32 127 56 -27 -122 -3 -25 54 12 -4 -35 34 14 81 -61 90 -28 33 -29 -15 -91 14 80 92 5 50 18 -52 -38 -40 65 -1 25 103 21 -93 53 -22 -46 27 -17 77 127 101 -65 -1 55 -50 70 24 -63 49 -27 -127 -91 46 -84 6 -46 -40 47 50 -123 -123 -78 79 -6 -109 -103 51 62 77 -1 -31 6 1 10 42 -3 15 23 2 105 5 -39 -12 15 72 -113 124 66 -14 91 -18 -63 -102 -124 81 -71 67 -87 -88 -50 9 -97 -10 90 -47 -82 33 82 125 46 -34 -30 -21 -126 -54 -88 84 91 -64 -33 35 -45 98 -61 -28 18 74 -109 -114 10 62 -39 -65 7 116 61 -103 56 -105 -125 7 -36 -45 81 -116 40 27 68 -15 -4 -35 87 75 6 -89 1 -3 54 125 76 -112 -89 8 33 32 19 -101 125 -119 -5 17 -3 -77 73 -125 12 -110 -35 111 75 -34 74 -115 -126 -103 -50 7 -127 58 105 107 18 -124 126 67 -125 120 8 19 -17 -115 9 -53 -76 -79 -127 64 85 2 126 67 40 -33 127 127 65 -42 63 -19 -44 -10 75 -81 110 15 64 108 8 105 -102 -127 77 39 -105 8 -22 -69 48 -128 127 -87 -126 -48 -37 51 118 -68 68 -15 -67 -28 -65 42 3 -32 3 -1 41 13 115 -75 -64 79 118 40 -30 -36 17 -3 -65 -16 33 -45 -58 72 0 20 28 28 111 -9 -82 126 -116 126 26 86 67 59 -15 40 0 -2 23 -99 -4 -13 8 51 -90 -112 115 27 10 7 -3 -21 31 -2 -103 -128 -69 17 -4 -94 -48 -27 42 -53 -127 -45 -39 -63 -58 -95 -94 26 81 127 56 62 -13 -125 -46 10 13 -127 38 39 40 -14 88 -42 -94 47 0 -39 2 31 85 -126 -128 55 8 58 -25 104 -114 -126 99 3 114 -30 -110 -107 -58 -23 90 -24 70 -44 -121 127 -13 47 126 -56 66 8 119 14 -86 102 -97 126 99 -72 16 -4 115 -50 -27 126 127 3 -21 -11 -110 -27 -31 -20 -126 -128 -125 -37 96 23 42 12 51 99 28 95 125 -42 -57 -27 -117 0 -71 -63 -19 68 -65 -56 -30 50 -36 -58 -86 96 78 -126 -67 127 -91 9 -112 -128 123 -66 116 108 52 -119 -33 58 -54 -124 103 21 108 65 -36 71 -13 56 -50 36 76 49 15 26 -22 54 -61 -65 15 -48 127 121 -69 13 -52 -7 127 -128 -59 127 106 -125 -128 -16 7 127 34 -2 127 -127 -127 -10 -49 -54 37 37 -122 -93 -24 51 93 7 -65 -17 -126 -95 -50 35 -93 -128 -128 -37 -127 -4 -61 127 17 -10 -78 -61 -84 -4 -128 -7 -127 -74 68 57 -26 -99 29 -128 93 -81 -88 11 104 -29 -128 4 63 3 -94 127 30 -113 -66 11 45 68 118 -26 -20 -56 30 24 -75 61 96 -27 -72 -14 38 -28 -17 -81 83 -21 124 88 -127 70 105 -74 20 -20 36 -61 6 -75 -39 -27 -54 -33 24 34 -54 -123 -127 -90 -77 73 32 2 16 -118 110 -127 29 106 -68 59 126 -42 -52 71 62 -101 -6 -125 -49 32 -22 -43 -112 -114 -8 38 93 -38 -34 -9 -27 -127 124 -33 -90 126 -27 17 -19 115 56 10 82 49 -41 54 -58 88 7 -9 -6 -126 32 61 32 -120 65 82 127 4 -47 121 -74 -97 59 -110 -6 -22 103 -38 127 127 68 -61 126 -8 127 83 -122 4 -75 -126 0 52 33 -111 78 -125 80 -59 -22 21 -16 79 24 -6 -118 -41 81 -23 -122 -118 35 8 58 -127 -90 61 -5 -127 -26 -65 61 28 12 29 90 -128 -16 125 85 -73 -52 78 44 -13 -19 127 63 105 35 127 14 87 125 22 110 52 29 -105 -15 -35 104 56 13 -25 -124 6 -52 65 -125 44 127 -93 77 -77 -101 -61 121 -42 -92 114 -24 89 81 -54 -126 -35 106 -77 36 72 123 66 -49 125 36 -58 -22 -66 10 97 -95 112 118 37 -122 -17 -109 127 -30 108 -28 -21 120 -1 105 86 50 9 47 33 60 -117 -29 52 -56 50 117 -11 99 -59 -110 -91 -43 -111 -86 14 41 127 97 50 -126 -7 -57 -112 -75 18 -122 -77 127 27 127 38 -74 44 -72 89 50 -90 2 20 11 -54 -2 110 -95 -90 126 127 46 -49 -14 14 39 95 -64 99 -37 35 -26 25 -94 46 118 28 -26 -79 32 -5 29 33 80 16 21 -91 127 43 -59 -87 -31 -115 -89 -115 -58 -21 76 15 -88 -8 -77 -22 44 -49 -28 122 -3 -17 93 -6 69 -19 -22 -14 33 -61 71 -3 -61 -127 25 -127 127 66 39 -24 10 -47 17 127 -45 -45 93 125 18 46 33 16 40 64 -30 -38 -16 -127 -6 39 -86 -18 49 -9 -81 -11 98 -33 36 7 22 -8 -35 18 120 -52 -51 -61 52 -44 -24 17 -17 -6 35 -21 -32 -47 49 40 -15 7 -29 -80 -61 -5 39 37 -18 -95 -27 -49 66 -50 -93 91 -36 -27 90 -4 16 -21 6 -5 -53 -45 44 -39 71 -126 64 26 -49 10 -28 -31 88 -107 -103 16 -74 -31 17 -73 -35 -49 -49 -28 83 -3 -23 -34 14 -35 2 -5 -67 -75 -17 22 -52 20 68 -19 -24 -72 -55 -16 24 -25 -16 25 -81 53 52 -34 -84 -20 -20 34 22 -82 9 -56 -83 86 7 43 -20 -57 4 56 -70 6 57 -58 6 9 34 99 -91 -28 -64 107 -63 -50 11 -38 -31 24 -80 -7 -76 -15 -20 21 -7 -34 54 -126 29 38 -1 -11 18 126 -7 -53 -21 43 50 47 -42 55 -5 -100 28 25 -21 -28 -56 16 -106 13 28 -16 -34 -73 47 12 -11 -34 33 -123 -40 42 -109 12 -63 127 -76 -76 76 -70 -46 -7 -74 36 -58 -28 -110 72 -62 2 -33 29 -27 0 38 15 36 9 -23 4 -19 127 60 120 -18 42 49 127 -18 95 26 57 -60 53 -70 -44 37 57 -26 -12 17 29 116 74 -16 9 68 2 16 -31 62 18 42 21 27 57 -70 113 18 -16 -48 -44 -128 -30 -26 6 45 -98 -52 105 -64 63 -23 -12 -88 127 -18 -10 -6 -45 -4 -39 -28 -38 73 -9 53 102 -16 56 11 -22 -22 36 4 99 23 -23 19 -4 -2 26 22 24 27 -63 21 69 -25 54 82 -10 -25 105 84 -22 14 29 -13 16 -61 -29 4 -16 -128 -69 -8 31 83 -83 -9 -56 76 123 -49 43 81 -3 -36 -35 -4 127 -47 -30 4 86 27 27 -77 72 -116 24 8 -54 61 -75 5 -83 -34 -77 16 5 49 0 -16 43 -51 -20 -25 -29 50 36 53 51 -44 -4 80 -49 -68 -16 108 -32 -33 9 96 46 44 -11 44 46 60 34 41 -23 23 32 -30 -11 -10 -42 -19 33 -125 1 2 -71 -2 20 -64 -128 -56 -41 11 -126 13 -7 -89 -54 -49 2 -99 -46 121 16 60 -57 98 -47 117 22 -45 43 35 89 -21 -38 -23 -2 -122 8 -31 0 82 94 -63 17 -45 -61 12 113 -2 -55 33 27 -4 13 6 -17 -13 126 12 67 40 -12 -105 -119 110 -25 -34 -49 -83 -56 9 13 -64 69 -43 -127 36 -107 -50 7 -11 -9 -105 38 76 -6 -27 -22 15 62 85 -25 21 -26 16 -19 4 16 -11 2 21 -74 11 54 62 -99 4 31 -60 -65 127 4 56 -125 10 -44 117 -37 56 71 76 35 -79 10 71 -7 76 50 91 -43 -65 -60 51 1 25 -52 59 -22 21 -124 -23 54 8 71 -49 -32 -1 19 105 -30 -127 33 -4 -44 16 -34 -61 119 18 6 -61 -24 -36 -35 -21 -45 27 -126 60 -13 74 27 109 16 -2 54 52 124 0 36 127 -124 43 -98 52 28 69 47 -34 -41 0 -11 -4 -44 -21 78 -3 110 -9 -83 58 -10 -1 -44 -20 94 -97 -122 -54 11 10 23 -2 -14 -41 32 32 -94 20 43 -27 52 -37 13 -85 -3 -6 53 -85 62 -40 -53 53 -14 -40 -10 57 -18 -67 79 -11 63 126 -1 28 26 -38 -85 -8 -27 27 64 46 -90 7 52 123 -36 -41 10 65 -63 71 -98 12 14 -83 -15 37 66 1 39 -25 43 -42 13 120 -29 37 -90 -25 -48 -69 82 -54 -24 60 9 45 38 75 -22 19 63 -102 -53 6 -26 92 50 19 -71 5 -29 70 17 90 1 -60 -6 4 58 -47 1 -40 -60 -26 33 -18 -1 23 31 11 6 10 -126 95 25 34 -50 18 48 22 -6 24 -97 -26 22 22 -17 -34 -22 -15 127 -15 -110 -38 -86 -67 -126 -128 64 59 -18 -63 55 -58 81 69 -64 -107 -15 -61 -65 -12 33 28 -42 12 -127 24 -7 -103 -21 -127 -45 -24 -19 -127 -33 6 -65 -64 -27 9 -28 72 20 40 -15 25 11 1 25 -11 21 42 7 27 53 0 -106 -9 65 -25 64 40 -36 -17 83 -4 -84 -34 -20 -10 65 37 -48 -10 68 15 2 15 93 -94 124 51 69 29 -119 21 -53 -24 28 96 9 43 -42 -64 11 -115 36 -11 15 93 79 -45 -5 -38 -111 -65 -84 19 99 -89 -77 -52 7 -76 82 -66 -124 57 93 -20 -97 124 -84 -34 -2 -78 -96 -61 -11 -65 23 -22 22 -77 40 -18 96 127 75 -46 -26 12 101 -76 -19 -92 -59 -41 9 35 18 80 -19 -102 -10 21 -15 -65 -102 90 -12 -27 -128 37 57 -125 -16 67 -101 -3 -30 23 33 49 -24 83 37 -56 37 -13 7 54 73 -50 -22 -90 -71 65 3 -9 90 88 -29 -25 80 -12 -66 -6 -47 -65 17 -39 76 -32 85 34 66 -85 100 36 -96 25 51 -106 -26 -20 123 76 51 -50 24 -9 25 13 -35 13 26 40 -15 43 -90 -110 -28 -46 14 26 -65 127 66 -25 16 -25 80 -11 0 28 90 -98 -77 33 -3 -30 -10 -12 -50 -120 -10 -34 95 -23 -10 63 32 16 7 -54 -118 -32 57 26 -76 88 1 -35 57 27 -4 -10 -124 64 38 87 127 38 -34 63 89 41 10 33 41 12 116 110 35 -64 -83 81 -22 25 -29 58 77 -49 2 87 3 -41 89 -29 -36 4 26 -107 -55 25 -30 118 3 58 -96 49 40 88 31 21 103 -20 22 -36 -6 -17 23 -46 51 88 -127 -30 -27 96 -19 84 12 -70 127 13 41 50 -19 -86 85 -67 1 30 26 62 25 -36 -13 -39 0 58 -1 -72 4 -7 25 -122 81 127 2 25 -68 -10 -33 64 31 -127 44 -23 9 33 -10 -19 85 52 -110 108 116 21 -53 64 -105 17 32 12 -122 -53 35 36 24 -118 -20 46 113 -12 6 -61 36 -3 -38 -127 -48 28 -112 -128 -28 -3 2 82 33 68 0 -78 20 127 -64 41 55 -4 77 9 31 -13 -76 127 -77 -57 25 26 -21 21 4 -116 9 78 51 -49 71 40 8 -22 -16 33 -113 41 -9 -115 -2 -42 38 -68 -42 127 -27 -5 90 84 -26 123 86 97 -106 111 -71 47 -87 -127 -49 56 64 -35 7 45 -112 -67 35 -85 -103 -50 -128 -24 15 91 20 10 -128 71 2 -28 51 -57 31 2 85 -28 1 -79 -34 -1 -2 53 -67 -34 36 -32 -69 -16 127 117 0 34 63 -56 -23 -23 -13 -10 -44 127 118 37 -40 -18 121 77 -126 14 42 -21 -18 -53 89 22 91 104 -39 88 -59 -53 -71 -3 -41 -115 -113 -128 -24 -17 -35 18 -109 -95 -50 19 -36 -114 -43 -74 -30 -22 -46 -85 75 -32 -46 11 -80 -83 26 99 -103 -8 -19 -95 -13 28 4 38 -117 113 -19 -7 58 -87 -61 11 -127 -90 10 27 5 39 62 60 -65 64 -99 -41 41 27 -15 -38 -38 29 -124 87 118 -9 -24 -40 -47 9 66 -49 -13 19 -17 -22 30 17 30 -6 -85 -5 119 97 -13 21 -124 127 -40 -60 -83 -60 61 76 -34 -42 -90 -7 -13 -25 3 -11 -45 -119 17 19 24 -47 115 -43 8 79 -1 42 64 77 39 -20 21 -85 -13 -6 -48 -51 55 28 -8 15 -55 -54 -119 -115 -4 86 87 -21 18 -9 118 54 -47 -44 -11 -29 -54 -39 -77 46 16 72 -15 -72 39 -99 -64 26 -82 20 -30 0 112 106 0 28 -60 40 -128 -75 -30 5 -47 -57 -85 -44 -29 -77 48 -84 35 -30 19 -9 1 50 -118 95 -111 -25 28 12 -54 70 68 -24 -118 -2 106 -4 -114 -69 119 -12 -26 69 68 -125 -37 -82 77 -64 32 2 2 -30 10 12 -100 9 127 -34 -123 39 127 42 -14 7 24 -80 -66 32 -24 42 -3 30 -118 36 -6 -61 -1 -42 -37 29 -13 -3 -21 -8 77 -59 -118 -48 75 127 -57 41 -46 34 76 -1 127 -107 -126 -3 49 78 28 -96 126 38 -41 11 -110 81 -29 -83 -20 13 122 -37 40 -32 36 2 113 48 -23 -28 2 26 86 -18 -34 -19 -53 12 64 13 -44 33 -42 73 3 -24 1 -42 4 -41 88 -28 -4 -23 25 13 67 -22 6 -55 36 68 30 -30 -87 -34 30 -3 -13 -6 116 86 47 58 61 62 61 8 -9 50 -61 55 -93 -43 17 -76 10 29 29 115 8 28 19 65 78 26 -66 -70 9 -19 41 -27 -113 14 -60 -37 -34 -17 56 -15 -32 38 3 12 -120 46 -93 -32 39 -31 39 1 -58 -127 -32 -67 -67 -111 29 38 -2 15 -14 107 126 1 61 6 93 2 5 44 5 -81 47 -84 -12 -15 -5 -11 -11 -125 94 14 5 -6 97 23 -48 11 36 -12 -99 68 90 -122 127 49 -18 -9 26 25 -14 -127 -18 -12 104 65 79 -30 -127 63 -80 29 -126 -70 37 -99 -80 -127 -108 -112 -65 57 8 27 -2 -23 -48 -49 41 -64 -40 -40 66 -38 17 -50 56 -65 -98 -27 -77 127 -126 -36 57 -100 -14 -127 -127 -64 84 119 23 54 121 126 -7 40 -71 -123 -65 65 -124 -46 -17 -122 83 -38 -4 72 -126 14 74 -126 -126 -30 -127 78 -65 -16 -127 111 -102 -126 15 -69 -47 -17 -50 10 -126 126 -128 -39 -45 -119 -119 127 -22 -126 24 89 126 -91 -32 -9 13 -127 -88 83 -28 91 101 -50 -19 -45 -66 -48 91 46 117 -1 -33 127 -105 45 105 -119 -28 23 -14 69 -39 60 57 22 -50 40 -43 41 -30 -28 59 -21 -28 -43 -127 59 36 51 -53 39 39 50 62 -104 -17 -75 1 -66 10 -14 -64 -7 103 -83 -43 -124 114 46 -28 6 -44 57 -29 -110 31 -37 -57 125 66 -32 62 71 0 -36 -53 -11 41 14 127 22 19 110 -16 5 -22 92 -12 57 70 -21 -78 -7 68 -128 -25 -32 14 -1 -86 112 17 19 114 -18 -18 38 -60 -60 1 -18 -19 11 -13 -53 -19 24 -23 -38 -14 65 -61 -4 4 44 -115 -127 20 122 111 -102 -11 -72 -30 31 18 65 -6 37 -23 -123 125 4 65 67 27 -51 16 76 49 59 -48 44 77 127 -73 -17 96 51 -34 34 -61 -89 -50 119 41 21 -64 74 2 -55 127 81 34 -121 -94 -45 -57 -76 99 100 -46 127 69 -42 59 49 51 40 73 89 -26 5 8 -69 15 -123 -36 39 126 74 -34 124 23 -3 126 -37 -84 -50 85 -121 -93 -22 32 -40 29 70 -20 3 -1 -33 83 -34 40 -127 4 -21 14 41 -95 125 109 118 48 -87 -20 -99 -29 56 -32 -16 -12 4 86 -22 57 69 -50 39 18 1 -123 62 -68 115 -77 -9 -128 69 -55 9 10 -126 90 -50 31 43 -128 127 27 93 -113 -124 92 26 55 -19 87 70 -89 -99 -30 30 -43 -5 -103 127 -75 -127 -77 65 -17 53 67 13 -50 -3 83 -47 -123 109 127 -58 79 -26 8 40 8 13 -8 127 -119 29 12 66 45 45 -23 17 -57 21 8 46 -124 29 -72 -23 -69 127 -19 50 -22 -61 0 -37 -16 6 -9 -43 -34 -29 -59 -59 27 -128 98 -28 -7 58 -63 33 -2 -18 127 -44 62 35 17 -61 3 114 -38 43 -2 12 55 -124 23 -31 89 111 -98 -53 -26 -26 22 -16 -122 -41 57 13 -83 -94 -14 73 -10 25 -9 127 45 -79 -57 87 -102 -106 65 -1 -55 -36 61 30 30 -111 25 16 -42 22 -21 -40 -8 -2 108 55 30 -44 -53 104 29 -68 57 -48 10 29 78 -39 13 -22 -50 -114 76 63 36 20 -1 -32 -115 40 -2 79 -38 -26 42 12 -9 -2 105 103 -40 -20 -128 37 -79 -75 66 -64 59 81 -26 12 126 -11 0 11 -85 -68 -122 121 108 73 -36 26 -6 -92 52 -127 -127 -5 126 124 20 19 117 91 39 -128 29 -14 53 127 -124 125 -44 52 125 121 -70 125 -41 -58 -65 21 -42 -128 -11 66 66 -117 124 82 -36 102 39 58 127 98 -7 123 -3 -59 1 51 31 -27 -4 58 127 -4 22 109 2 62 76 -126 26 -40 81 -16 -59 124 127 52 126 105 -23 127 -113 57 110 127 68 18 -93 -92 75 24 -24 -59 127 125 14 -89 -51 87 -75 93 -128 84 -125 105 -68 53 -22 114 -74 40 57 19 -125 63 -25 11 85 105 -124 -122 -77 -68 84 -77 127 -64 -63 72 -2 45 -36 107 -10 47 -29 -91 -3 -42 -108 -67 -2 83 -18 -6 -114 -32 71 -65 -92 -74 63 113 -79 -16 -100 48 -44 97 -30 69 -59 -59 109 21 54 96 24 -19 71 -80 11 -54 -121 15 -113 -24 16 -4 120 -128 -89 7 -39 -33 -34 -9 -122 4 29 -121 -77 -95 74 -19 91 -65 109 88 -51 -29 68 87 25 -10 -106 11 36 -40 -83 83 54 62 50 21 25 13 -80 -128 1 -83 127 20 82 -124 44 -82 50 54 40 -49 44 -59 33 127 4 -32 61 12 -3 -16 -114 70 -5 56 -88 -49 -51 6 6 21 7 -13 23 -118 24 2 68 -32 -9 94 -10 -47 71 -44 -2 -48 63 35 -38 26 -82 -105 -128 -61 42 -107 -56 41 -127 12 79 -24 100 -125 5 -33 -43 48 54 5 56 -30 99 -105 28 44 87 -127 -121 -104 5 -2 91 86 -29 -59 -15 -111 25 14 121 50 5 97 -32 -106 127 -21 111 127 -6 74 127 -128 56 -101 27 -58 119 126 56 53 28 -128 -8 100 -68 30 110 15 108 -26 5 45 -48 80 9 -24 119 -21 -113 -21 -7 -8 -118 -20 -29 62 46 -128 21 59 -38 -99 92 121 -78 -25 -120 127 21 14 75 108 85 -25 -53 0 73 59 -128 3 99 -32 1 82 -99 1 43 86 52 29 -121 -25 36 -33 -37 -89 -69 -19 -41 -49 -55 -104 -32 -128 -126 -64 -32 2 127 31 50 94 98 -4 112 32 -29 13 -86 -74 36 24 -75 95 -124 18 -8 2 -36 -43 3 -49 27 65 96 -90 33 72 -67 -49 -15 -46 -7 -7 32 9 7 -79 -16 70 127 15 -89 -30 49 69 -36 -59 -118 -87 -57 -18 -62 -1 -79 47 46 -1 44 -77 40 37 -76 27 58 0 73 24 48 3 48 23 3 -29 -36 42 103 80 10 11 43 -52 27 -26 -33 -53 77 8 53 39 -11 -29 -10 -89 -5 -62 78 -5 23 -114 -30 -93 -53 17 -38 -6 -50 54 38 -99 -2 -58 4 -96 78 -18 23 57 74 -7 8 19 -87 97 4 91 -35 -17 -67 -89 127 30 14 -6 19 -55 -42 20 -7 20 6 -26 27 -99 -123 -22 19 19 -107 -24 -15 28 -48 -30 5 -4 -44 -12 12 39 -13 -9 -60 4 -19 -20 12 -43 -42 52 -62 83 -33 31 -59 63 47 -37 -127 -58 -45 -117 -124 -85 -30 19 54 114 93 25 -52 -76 49 -97 66 127 35 -48 84 -20 -7 -25 53 50 127 -109 38 65 -40 -41 -40 126 -120 2 -14 -125 63 127 -36 -83 61 11 25 -85 -67 29 -65 -52 -81 60 32 10 26 -96 127 -33 -43 24 21 -34 -71 121 -28 16 -42 68 11 -119 64 118 -1 65 -67 56 107 23 -38 -3 -66 16 -60 77 10 102 126 -49 -36 -50 -25 52 -69 32 -13 -29 18 -19 -35 9 -45 -21 21 -128 -32 -94 6 -34 -18 -32 115 -9 45 -26 42 -8 -109 32 -26 55 -7 -53 -18 -20 -18 -41 -40 -24 44 33 -32 55 26 3 4 13 46 93 -73 -71 16 16 54 -26 15 -9 -100 -21 67 14 -67 19 -82 29 12 -37 30 12 85 83 58 14 -12 -14 35 -13 -53 -49 -13 -15 -42 -2 14 -3 -68 -86 62 74 37 -1 -41 19 -83 34 45 -26 107 -2 99 -40 33 16 -59 20 -59 -19 -27 97 46 7 34 -85 -69 -18 73 -37 47 -30 -4 53 -105 -88 -27 -33 29 -20 -58 -49 -11 85 50 29 -2 -55 13 -126 -11 79 -8 22 10 -21 0 -19 31 -52 42 -19 -24 -128 9 33 -112 34 -13 -2 37 35 -102 92 -43 37 -18 22 -40 1 -73 9 -78 -15 -25 15 -18 -126 -34 -33 61 -89 -124 -28 -1 56 -33 -38 -127 126 14 111 -118 23 62 -41 42 -32 -12 -30 -33 -75 -127 127 -17 -127 50 -128 -31 52 28 -72 21 33 -8 35 8 124 89 -57 121 119 -72 68 -79 -32 26 -62 53 -11 127 46 -57 93 -95 -76 -95 -4 -9 -2 -61 -4 127 -16 -34 7 -42 57 -114 -56 26 101 37 112 53 -16 49 -31 -1 -42 -126 23 -32 125 -128 4 -10 55 94 -8 55 58 71 -34 -104 -69 -25 -9 97 -31 57 29 -53 64 -77 41 -50 -17 37 -46 -112 79 -20 -21 9 20 48 17 -18 -46 -39 -16 1 98 62 -91 -119 -17 116 108 -125 -69 34 52 -5 110 -31 42 -86 -52 -2 -66 90 3 16 13 -58 16 10 115 -51 59 25 91 5 -66 -79 -115 -35 49 -78 -4 26 83 26 -87 29 -126 18 -105 20 44 50 -44 -114 35 -43 -8 -6 -48 125 28 111 53 49 47 -128 -106 -84 14 -9 21 -76 16 26 -86 28 -36 3 92 39 -71 49 -64 90 -116 -124 -14 50 -21 127 86 1 15 -81 -22 41 -36 -30 117 -33 30 23 104 -36 -125 -16 45 120 -29 24 3 -62 54 -15 -8 -28 22 -92 43 -55 -12 -15 -61 -37 38 -61 -24 -26 40 1 7 10 -14 -21 -68 -23 54 12 -107 -9 13 -41 -45 127 50 34 7 -36 114 9 18 -30 3 -7 127 -53 -126 -36 30 -27 -8 85 -17 11 75 90 38 -102 106 -115 -39 -66 -27 -68 13 58 3 30 22 -32 4 0 -17 5 68 -42 3 18 -31 52 14 77 20 10 -60 96 19 -6 -29 -25 32 62 -47 7 57 9 -1 83 -33 19 36 -15 124 33 49 53 -10 -19 35 14 107 40 -41 112 -13 -19 -23 -21 -6 35 10 -27 37 92 -26 18 24 61 29 6 43 9 -7 -38 -11 13 116 39 29 39 -1 17 12 56 36 19 0 13 -4 -34 125 -35 -32 48 -15 -1 7 42 5 42 0 19 5 -5 21 -35 -1 6 18 39 -16 -17 -27 12 -32 -1 -20 -67 8 23 -25 17 -5 31 56 -35 69 39 -24 -106 -12 62 39 -50 19 71 2 52 -75 36 -14 -37 11 -27 -30 2 -39 7 -39 -31 32 49 19 31 -1 -71 42 -27 88 20 66 51 15 -2 21 11 -1 9 21 18 -32 83 20 -27 -9 -42 6 -17 -4 -22 -54 41 29 -35 -19 59 3 -11 -39 -37 -3 -38 -15 89 -22 -36 2 3 -31 1 4 38 -7 3 13 -7 -3 41 16 -36 42 -15 26 5 -1 -25 -27 -48 24 10 25 35 -54 41 23 37 9 7 -6 49 -33 2 -4 -4 44 23 -31 41 3 -31 4 -6 63 -36 50 -57 -11 9 21 17 -3 1 -26 7 31 -16 -34 -34 15 -14 -11 48 12 15 12 2 2 39 -94 20 77 59 -16 -51 2 52 21 -5 9 11 49 -54 15 -17 63 -23 8 -44 -16 0 -13 -16 12 -36 -22 6 7 -100 4 -9 -28 34 -81 20 -47 -16 15 -74 69 53 -60 7 -20 -21 -1 -19 0 -19 5 -9 73 23 -37 -19 -3 -34 -22 -93 7 -6 24 -9 10 -35 31 -33 -16 -51 35 -58 -8 -9 7 10 -1 11 -89 -68 -56 -8 -35 -27 25 -17 23 29 -12 -9 -35 -20 -16 1 -14 24 11 -13 -1 -62 -22 -27 41 -20 -31 -19 23 -46 -56 -19 -27 3 -13 -55 8 17 -11 -15 35 -16 12 0 -3 25 -13 -56 21 -74 -30 -18 11 5 53 58 -14 30 24 5 -67 60 20 26 -15 -25 -23 27 -125 -31 -43 127 -1 9 -1 8 -36 -15 -32 -100 -6 4 47 21 12 28 -16 -46 -46 12 43 -14 -22 -8 9 5 -36 15 -39 9 -37 -54 8 -30 -43 31 38 46 35 29 65 -43 -22 -66 52 67 24 8 14 -5 -20 30 -44 16 109 45 37 -29 38 21 49 15 -25 21 -1 -40 -48 -5 -36 -17 -13 -2 8 48 49 -3 3 -2 29 27 8 4 9 16 2 -126 -51 -17 -30 -31 -15 -9 -19 -16 39 -6 40 -25 -36 -28 9 -22 -8 -13 -9 -3 5 16 11 18 -13 -6 15 1 -15 -32 -43 7 5 -52 26 -46 -4 8 8 10 7 19 -31 -18 -51 -7 -44 35 1 -12 -4 9 -18 -27 14 11 -13 -12 7 9 -18 -2 -35 -22 16 5 -47 -9 29 0 -43 35 -69 -38 -18 29 -3 -6 -39 -35 -78 44 -64 27 -127 2 31 -36 -54 21 24 -72 -32 -74 49 -79 106 53 -19 -35 48 -27 34 43 -63 -65 38 -2 50 -25 -42 -15 -83 109 -13 126 34 -24 5 -20 -31 -75 -71 6 -46 88 54 -128 -117 -31 71 3 -2 -10 -9 -13 22 20 -1 8 -55 -53 -3 -11 -21 90 -59 7 -33 -86 -23 127 -110 -76 -33 -100 64 -117 -2 -1 7 -38 -28 -102 -38 -66 10 -91 -31 -80 -47 -3 -97 65 -21 40 37 76 23 -35 48 5 8 -29 9 -13 -65 33 24 -13 16 -20 35 -79 5 64 16 -50 -26 8 42 -26 62 -1 -1 -69 29 31 23 -33 5 1 -73 -33 10 -30 103 -13 -20 37 58 2 79 -62 -8 37 -4 20 -43 47 -40 -9 -36 -46 -12 0 -45 -24 16 53 -34 14 -62 -8 33 -54 6 -69 24 -18 17 -51 37 32 16 -3 -16 45 5 -51 -11 6 60 42 -25 15 34 -10 51 18 57 -44 -36 -42 107 -75 10 -19 -15 -63 -20 -11 -53 62 56 125 -40 -12 -52 29 -128 -81 -79 -20 -25 -26 -39 42 -20 -43 66 -39 -84 -125 -4 -20 16 -44 -7 3 32 3 -8 32 -1 -65 -6 -58 -36 26 70 4 21 -21 32 18 0 97 127 -55 -96 -78 -90 -2 24 94 19 -61 -6 -54 26 -128 -12 -10 -33 -60 25 -42 17 -54 44 -4 -87 13 40 127 -60 12 -18 -35 -60 -7 -1 -55 -29 7 -46 50 77 8 40 72 -16 13 83 -35 -37 123 -2 17 -52 14 61 63 16 47 -96 -14 14 -46 39 -36 36 72 66 -70 -15 36 -71 -26 59 31 12 58 -10 40 -21 6 -59 25 57 -44 65 -5 -45 85 -44 17 75 -24 -43 -106 -1 -79 42 -59 -22 12 -32 72 69 -72 18 6 4 73 -51 86 60 0 -28 21 -50 7 -15 17 47 -31 -16 6 -20 -3 36 127 -49 3 3 96 124 51 118 43 -92 2 -34 42 16 104 -52 -13 -59 36 -70 73 -23 -10 -3 84 21 26 -39 -15 -99 22 51 -82 35 21 22 47 71 75 -50 -34 1 35 -18 15 87 38 32 -40 47 -5 -25 79 -63 35 -38 20 -60 3 -83 -28 15 -9 -61 30 48 -62 -17 9 -45 -15 4 32 68 -17 -54 47 53 11 28 26 -67 -42 35 -115 52 -44 -27 39 -20 6 16 9 54 -35 37 0 11 -79 54 17 9 -2 36 78 -55 19 29 -52 48 32 12 59 18 98 49 -1 4 -34 -61 -23 -11 10 -25 42 3 63 40 60 -89 -19 26 -63 -14 23 -16 -15 5 14 17 11 23 75 -31 35 29 -48 0 65 -1 54 -42 -52 40 -32 -4 -74 16 -35 -13 -40 -26 -63 -62 -30 54 16 12 9 51 -53 -8 17 31 63 -48 16 16 -23 95 8 0 -89 13 59 4 -4 4 0 41 -62 -10 12 -35 50 -31 -33 -59 56 -64 5 -95 17 -54 -38 12 -67 81 -60 34 -1 21 -7 -34 -35 15 105 -110 10 -115 -19 49 15 39 -25 -128 -77 55 55 -16 23 -50 35 -43 52 4 -34 -31 5 110 85 -51 39 -64 -50 -18 -65 -100 -14 -23 39 -121 64 61 2 -44 91 8 -65 -53 -5 -26 -103 33 -100 55 -19 -74 -52 -56 -78 -127 102 34 38 11 -20 52 -15 2 -19 19 -66 -121 -31 -53 -25 7 20 32 22 34 58 -11 -10 58 -107 -118 -12 -5 -26 16 44 -37 -8 -72 84 -10 32 -45 33 16 37 43 48 48 49 -13 -4 37 31 -37 26 1 -41 48 -17 -64 -40 -35 27 -7 26 17 44 47 21 117 -30 10 126 32 -4 15 51 -74 25 51 -19 13 -47 22 42 71 -24 22 -31 16 -54 40 -5 20 17 -3 -50 -49 -21 -21 -11 -49 82 39 88 84 86 -65 -39 20 -6 86 49 90 18 -30 -78 -28 50 19 12 28 35 -23 126 -128 51 66 61 30 -25 -77 56 52 51 41 -34 56 19 17 37 -1 10 41 2 81 54 -10 -127 40 -117 3 91 55 84 -39 73 11 -12 -99 35 -44 -30 -128 12 37 -75 -45 -81 0 126 -31 11 68 -10 2 -61 53 13 -15 -52 48 47 10 32 -4 85 49 -22 112 0 -47 98 19 23 107 -35 -38 -95 56 -65 38 48 -95 18 -3 -42 69 -125 83 -3 -69 41 37 -5 53 77 41 -32 -19 5 -26 -4 -23 49 -91 65 32 -16 -26 72 8 16 60 -128 -103 56 -21 -7 20 -88 29 10 88 53 -101 -91 -27 53 -75 48 12 -18 1 15 3 -100 -114 -126 -50 -14 -54 57 -52 56 22 -13 -107 -25 19 -48 -6 -94 4 -7 27 -36 -119 18 13 -71 58 21 -35 44 126 114 50 -101 16 79 37 9 -121 -41 108 -128 -66 -42 -15 -45 -79 -24 56 -74 -103 47 12 -1 78 -51 -19 -89 21 -13 -93 -55 -49 -34 -25 -66 -80 -9 -31 15 36 32 -40 1 38 94 15 29 3 10 -39 19 -28 75 -33 13 54 5 -23 57 43 2 17 48 -17 46 -12 40 32 -28 -18 9 118 -94 -56 -124 -10 20 30 2 -14 55 3 115 -7 -48 -22 21 22 -123 -19 9 14 -38 19 -76 -51 -5 32 -75 -8 22 37 -23 37 1 -44 20 -12 9 -34 -33 82 20 59 -29 -11 -44 -62 -15 -28 31 -56 43 -42 40 -39 73 -2 20 -24 -17 -29 39 -12 -39 0 -6 -1 -13 30 15 25 -36 -95 -16 79 29 40 27 1 -7 31 38 -26 14 37 46 -3 41 -9 21 87 18 -34 48 -44 44 86 -3 33 -44 4 89 3 84 -17 12 -26 -51 11 -12 -61 -101 55 -45 -81 -11 -9 0 18 56 53 -19 -3 15 64 64 33 21 30 -72 -6 19 -11 -26 27 25 -40 -3 83 -75 74 -72 23 -55 23 -17 -49 46 -88 25 99 -5 -29 69 -107 14 -96 8 41 -97 127 -66 -126 1 13 105 -10 3 -21 3 -6 -126 1 -27 125 -7 34 96 25 -102 67 58 -51 117 121 12 105 63 -18 78 27 -7 42 42 127 13 81 23 -33 -54 -12 75 -89 20 127 -39 -35 127 21 94 -74 23 -38 -27 49 -28 89 109 1 116 99 -62 98 92 88 127 -40 -92 -55 -116 12 -18 -126 70 42 45 127 40 -90 7 -56 -126 -83 76 50 -90 -127 -18 -128 -113 118 -71 -4 2 -62 74 3 115 54 70 -30 127 -83 34 117 -12 31 107 86 -82 61 82 112 -96 86 6 15 -8 -9 25 -12 14 102 -27 29 -35 -64 33 -84 36 -101 126 51 -125 121 51 -36 69 13 101 -104 67 54 -119 35 -37 94 22 17 63 74 77 34 -25 24 8 127 3 90 -18 34 62 101 15 124 -45 16 -107 77 16 13 5 82 -47 56 49 -11 46 41 -23 80 38 90 80 -38 11 56 -47 95 3 -22 17 -29 12 18 124 65 25 -67 27 96 -44 65 -20 39 12 42 58 -101 -47 25 -36 -109 -16 -6 -75 -3 116 -56 -48 -51 -101 78 36 41 -34 40 -106 -24 0 74 -70 7 4 -84 33 -126 -48 37 127 -63 38 -4 -69 2 65 61 -19 11 -36 42 -4 116 -28 -20 56 -21 127 -28 6 78 4 59 87 -50 -71 41 72 66 -80 78 36 43 -60 -31 29 81 -84 11 69 44 -44 -96 23 35 93 -54 67 25 123 -38 -71 37 -117 11 90 61 -29 -78 49 -18 -53 98 80 6 -47 -33 65 25 -17 107 74 -122 40 -122 -44 -64 25 43 -10 -33 -32 16 82 -50 6 -97 9 -125 1 -84 90 -64 59 54 -18 -14 -10 83 -61 -79 -125 -17 -9 32 -55 -15 35 -22 69 -46 -40 -18 -47 -57 -71 124 -52 36 -19 72 -62 -111 -46 -47 -34 -88 126 -72 -14 -6 -48 126 -8 58 -16 -19 -45 -43 -41 -67 34 -31 -5 118 69 -29 -8 -32 39 -53 -2 17 18 -13 33 55 47 -8 69 30 -46 30 -43 119 -60 -65 43 26 -122 -28 38 19 50 -113 38 126 -43 -31 0 -105 12 73 33 -18 16 -4 73 -29 -41 -51 30 96 -101 116 35 40 -36 125 0 24 -40 41 66 -27 106 37 106 -20 123 -74 -49 17 57 -30 39 65 70 70 41 -28 -71 4 -1 32 9 -33 122 11 44 -11 -7 -73 100 59 54 73 59 70 -34 33 -9 18 -62 127 65 56 4 51 0 127 -65 69 -22 -49 -40 -19 11 -39 -40 39 13 35 104 36 32 -56 0 -95 85 59 -28 16 -123 48 -94 49 2 -1 -14 33 106 -64 -10 -15 -58 29 -72 -34 4 76 -49 -125 118 44 79 -36 27 9 11 2 19 -7 -112 -43 -36 31 -40 101 24 -98 -16 34 14 14 32 50 -98 -13 -41 45 124 -86 75 -28 -17 -13 21 -54 118 78 -79 48 -61 -21 114 -29 74 1 -37 20 31 3 24 86 33 -15 -68 -77 -86 28 -10 10 127 -20 -94 -56 -26 19 121 -2 -60 66 71 67 65 -125 36 -31 -69 12 32 96 48 90 66 43 13 21 -91 93 29 -33 68 121 -21 -34 -14 18 -16 -36 47 -31 62 6 63 -40 -11 28 -128 -32 -25 45 -38 -40 -88 22 -1 -128 37 38 94 -30 78 112 -48 -54 -88 70 32 38 -54 -39 -6 -14 -9 -14 -40 -85 -48 9 -83 54 4 -20 -20 -37 -80 39 9 22 13 -57 47 44 -96 6 28 -54 34 -38 -15 25 35 -39 56 63 60 72 -17 7 36 50 -53 45 -47 -41 -56 64 -18 77 -44 49 54 5 -62 8 -8 82 92 -50 -73 46 38 25 -18 63 -8 -5 -8 62 -16 19 17 -5 39 -34 127 -23 -35 -9 -13 -42 -14 27 38 59 10 14 -90 -1 -54 57 23 0 26 -125 13 32 72 -95 44 -19 54 48 -13 57 22 6 -105 33 125 89 -36 34 -34 34 52 -12 -6 57 40 -79 -28 -32 -48 15 -124 -3 30 59 -27 27 53 89 83 29 -28 -1 -44 -33 -20 39 27 50 17 -17 47 -34 69 48 -25 26 -24 -13 -104 1 11 -9 41 51 44 -31 47 3 29 -48 -34 -37 13 10 -24 68 -12 39 8 67 -29 -121 67 12 -94 47 -33 -35 14 23 39 2 96 -6 81 -41 33 15 -76 46 62 46 -3 7 21 65 -10 27 -59 -93 -5 -22 -14 16 -18 3 -7 47 58 -23 -64 -57 -31 42 90 26 -81 79 3 127 5 -33 -17 -36 -31 13 66 0 -89 2 -78 0 11 84 -23 -6 -52 5 -59 59 -15 36 -33 26 -2 35 97 -87 7 35 74 -41 112 -74 -42 -19 30 -37 -57 -56 32 -68 4 -115 42 -73 4 -18 4 19 95 -81 -45 47 -12 -28 -92 36 -55 -48 -76 -64 27 -55 -35 -73 90 -81 90 -18 2 23 -31 -108 34 -7 -55 5 9 8 -66 -95 3 71 15 18 125 -6 83 -13 -50 6 18 -65 61 -5 -57 -65 -24 16 -70 82 -64 -2 -4 -53 -18 -8 50 -22 -20 -35 -17 -15 2 -69 -41 3 -11 -51 -74 -58 70 67 -27 -8 -68 22 -10 -67 58 0 54 -25 -17 23 -51 48 15 41 121 35 -78 -91 -29 17 -21 112 6 -63 61 -37 26 63 -65 10 -16 12 -50 -44 4 -19 8 40 -33 -7 -80 16 -17 21 -36 48 12 -20 -18 -7 -49 -17 -8 56 -95 50 -105 -37 2 28 -13 -29 8 -6 -2 -39 -15 -51 -5 -6 -30 33 -60 41 -24 -85 80 -66 -20 37 -66 52 34 -66 -100 96 33 24 20 70 72 -46 50 13 4 -4 5 48 -46 -15 -24 -42 20 -2 6 20 -33 -10 -26 17 67 -33 -1 46 18 -1 58 10 26 -35 -47 15 -44 73 -92 22 -54 9 -50 25 -26 39 43 -17 16 108 86 38 59 62 15 -95 -62 -11 29 -38 60 -125 19 43 59 73 -47 0 64 -30 -60 16 33 20 41 -18 -42 -110 -3 16 119 63 111 -25 30 24 -62 -103 22 -42 -36 21 53 -41 17 -25 13 94 5 -1 63 126 -34 12 -26 -19 -16 57 -1 -33 -40 -35 -110 -70 25 -19 -79 -13 36 -5 -80 45 -24 66 12 62 -72 -36 -47 -45 -44 -1 115 -1 -75 -42 -111 -20 -29 -8 -4 -19 -16 -57 11 -20 58 -37 125 -26 -3 17 -40 -4 33 -6 36 53 16 -40 -26 -22 -77 49 -23 28 -25 -11 -45 110 28 16 -4 -1 -25 -92 -3 11 -29 9 1 80 56 45 8 -14 21 -17 47 35 26 80 -4 17 -1 28 18 -41 31 82 6 -45 -18 13 37 69 0 -32 127 25 43 -8 126 59 -18 22 -1 9 -24 -28 -7 24 36 57 20 47 -16 -23 -33 -7 -35 -25 71 22 -23 20 14 15 88 -24 -25 107 76 43 57 -36 5 22 71 81 20 30 17 126 30 -6 18 41 59 6 37 -90 43 38 32 78 -10 -19 28 71 22 -13 13 -42 -26 -12 -64 104 -59 63 -2 -11 25 -23 24 53 110 -27 -15 -50 42 -11 -45 34 -22 -79 45 -15 10 17 6 10 26 12 13 11 1 31 -37 31 63 -32 -127 32 100 -28 4 -44 -13 14 6 45 9 -35 46 58 -18 -70 78 -109 45 82 -110 -126 -42 -36 -8 22 -112 73 98 -117 -122 18 40 -30 11 3 73 -98 -3 45 107 -67 8 -45 -10 44 -39 10 78 35 -39 -67 -84 -88 -37 -65 -77 17 -74 -35 42 -16 -58 -125 6 -20 0 -43 -34 -21 17 58 32 25 -72 16 -69 -64 -50 -19 80 -61 72 -50 -84 72 81 62 118 101 7 7 123 -51 -54 79 -70 31 1 -27 35 -18 -58 86 -29 -120 63 -35 -71 -105 -18 -34 5 -48 17 46 -51 56 -119 49 -58 -115 -106 37 49 -50 -98 27 15 -1 -11 -2 -14 23 -6 -11 -10 79 -41 -37 -80 -71 -75 9 -58 -40 -126 42 -42 -89 -12 -45 99 -85 29 71 63 75 -78 -93 -128 12 -87 0 9 -37 -30 -53 -12 11 54 45 48 15 -78 -21 55 -38 8 5 -51 -10 -84 36 -1 -82 19 58 -45 -15 22 70 9 -57 -26 77 6 4 -10 10 -25 86 -74 -101 5 -52 34 28 51 13 119 -1 -11 24 -70 -56 123 -60 -13 -11 7 -30 -30 -6 60 -16 -41 12 -16 -60 12 -51 -22 15 -31 -35 127 41 37 -27 -39 -102 -42 43 -109 -68 -67 48 -45 -6 -31 73 15 85 2 -39 112 22 -41 29 -34 15 -74 -6 21 -82 -28 112 -15 -2 62 57 -35 33 15 -61 17 -109 67 18 -56 -34 -4 47 -34 -1 -10 50 72 10 -39 55 -37 8 90 -128 39 -75 -55 4 -113 15 14 -44 -16 5 -91 -12 53 41 29 13 -10 25 -31 126 7 54 37 11 23 -25 -57 -39 25 4 67 -12 51 73 -29 15 43 52 -39 -7 18 17 -7 -29 42 -40 22 69 42 11 13 -17 76 -2 -86 13 44 -40 89 -51 -40 51 -5 14 52 -18 52 -62 39 -35 22 11 -28 17 0 5 -8 24 11 55 10 11 -31 73 0 -82 51 113 14 -1 35 -10 -25 -53 -37 77 -57 73 45 -29 -11 15 -19 21 -47 37 -43 -16 0 77 -11 58 14 32 27 -42 -28 1 -6 10 -42 48 -56 -57 19 0 11 0 44 -18 64 5 -77 -10 -55 -8 37 -25 52 3 -21 -78 -19 17 30 73 -2 40 17 34 10 -23 2 -8 27 -57 42 -52 10 12 7 58 -27 -10 14 31 -20 25 -16 11 -33 -14 -23 23 26 -5 -33 -15 49 0 53 48 -32 52 53 3 26 -29 -45 7 -16 -64 -9 27 -21 16 43 -23 -24 -11 23 1 23 -26 30 -29 -3 32 62 -4 5 67 -33 24 1 -35 -10 103 19 -13 -37 -54 -2 40 -29 67 57 -3 -2 -5 15 65 -2 90 31 -40 22 9 -8 -56 48 -14 36 -29 5 51 16 86 -30 18 14 -26 74 2 30 24 -35 67 -4 -64 -49 62 -30 -25 19 7 18 8 36 53 49 -10 44 -27 42 -23 -20 -4 -36 5 -54 -6 73 -21 -45 2 -37 56 -10 79 -12 -4 -56 9 13 -15 48 -41 49 7 -20 -89 -41 -51 -112 32 -95 87 25 -1 -79 -13 -18 106 49 -31 11 57 -110 -20 36 24 7 -30 -30 18 88 14 23 31 -19 127 -67 -25 22 88 3 17 116 -87 22 -46 -38 -61 -124 43 -65 -61 -13 -45 -78 -19 3 26 -75 -14 10 37 58 -49 94 -69 86 -15 -88 105 -106 48 -26 -126 -19 127 -24 17 22 25 -122 -21 86 21 111 16 32 66 -19 -76 34 64 -50 -48 56 -102 26 -47 -73 -54 13 -34 21 -16 21 32 13 -35 -25 10 -31 -22 -47 -94 80 -25 20 41 20 -37 -36 -19 9 19 72 17 3 41 0 -31 -23 -21 -25 9 15 14 -60 -55 -81 -80 -46 -31 20 18 63 15 -7 81 -6 26 3 90 2 17 -58 -17 24 100 -12 28 -21 11 -34 26 97 74 84 62 -23 10 39 86 40 43 30 105 -91 76 15 -36 -23 60 -81 47 -36 -24 52 -10 -127 10 -124 12 -5 -28 51 13 94 96 -27 43 9 49 0 -18 -6 31 -34 -18 8 47 45 -36 43 -5 40 -53 6 71 30 61 -115 -28 52 23 76 65 8 -116 16 60 14 24 97 -31 102 -75 53 54 17 47 -33 -53 39 -22 -46 -64 16 9 -50 80 10 -47 -50 14 -106 -81 1 -16 -64 14 -49 77 -70 -3 15 38 9 -111 21 -16 42 22 -92 -6 -11 36 15 53 28 80 -49 95 7 61 98 29 5 59 35 -13 -52 45 -34 -18 -5 -61 -101 -4 -50 -14 -48 33 0 -87 126 -71 24 -42 28 -47 -20 -54 -94 -33 -60 -11 -31 -48 29 -60 -47 -55 3 -56 -36 -82 43 -95 -49 -98 -47 -45 25 49 -24 48 -40 -4 -42 -6 12 -33 -36 4 -11 16 -28 -127 -25 125 -68 -128 12 -30 1 -11 -32 -25 -116 -17 -42 -6 -69 125 -1 65 7 43 -34 11 -27 -27 -85 -86 33 -15 12 1 12 -10 66 29 -75 -48 -53 -63 -58 43 46 8 5 64 -11 -12 40 -65 -29 50 7 -79 26 -19 10 -107 -31 -35 -35 -10 11 21 -5 -13 -59 39 1 58 -49 -20 -39 33 30 0 1 36 19 -101 -66 -65 -43 -28 -30 -18 6 -2 -73 -36 -10 18 -39 102 12 -53 88 5 -56 27 -125 112 65 -30 16 31 39 3 -45 14 -72 -1 23 11 64 21 -4 38 26 52 -38 -26 -54 50 -23 -125 -13 -88 0 -43 107 -10 -78 -13 -33 53 66 30 -14 -9 -5 -50 52 -4 -52 52 23 -25 34 -30 -56 30 -60 42 -20 23 71 74 34 -79 -18 -45 104 27 9 -68 -121 -71 -70 87 -89 -57 24 115 -8 7 -84 66 -17 65 6 5 -103 -55 9 55 -81 10 -37 6 -42 -66 -29 -7 71 -68 80 -48 -4 41 -11 -31 31 -45 3 -63 -54 39 -38 1 23 -36 109 15 87 106 -26 48 62 71 40 -15 112 -94 1 29 -12 -48 30 -78 -80 44 -65 -89 65 -47 -127 -67 -127 -2 -6 27 -37 -30 50 25 -85 -37 15 -29 84 -59 -38 -81 -15 20 127 -82 103 -22 -80 -32 -6 73 -76 13 -4 -85 51 -102 -47 4 -16 35 -45 109 -125 -7 -29 -31 6 -34 -93 -125 -83 -124 37 -58 20 6 3 28 -47 123 14 -20 -124 -39 -62 -96 -42 -128 -95 -15 104 15 33 29 127 77 -73 8 26 103 10 97 -112 -59 -128 -28 -7 -51 127 -15 127 29 -80 2 -34 59 -62 -81 -20 -9 15 32 -26 -7 6 -69 -10 23 31 -33 11 91 117 -20 41 -23 41 10 73 12 40 44 26 -4 48 9 -9 -46 -89 11 -15 -60 -36 19 -65 -9 18 125 -39 0 41 -9 37 -78 17 -104 -14 -63 -4 -59 11 -73 65 -9 -78 39 24 42 0 111 -7 45 7 108 -19 -126 -13 -29 18 63 95 28 -86 75 19 34 -1 56 -66 0 -83 30 21 8 -26 44 -23 62 74 -14 -59 68 4 -12 -21 58 108 117 47 -29 16 6 121 22 -37 1 61 -71 48 -15 -5 126 -127 99 75 -26 -22 -55 -39 24 -30 -8 49 5 91 14 -32 -89 -23 -26 8 -70 -55 51 -46 39 -64 4 58 -51 -24 11 -19 -40 -38 104 -4 -3 -18 25 -9 12 -14 -66 52 -46 21 11 -64 39 42 -2 -1 -33 -23 -22 -21 -29 -47 102 78 -81 -47 38 -35 86 -39 -43 -48 -40 12 59 -40 -3 19 -38 -4 -38 3 22 -13 -96 86 -16 52 -6 -30 -21 8 47 -22 19 53 91 -99 -29 5 42 35 -14 -128 -59 -45 54 -43 -38 -65 11 42 -40 -77 64 -124 -13 -12 -65 0 -35 79 -42 -64 -116 19 -6 59 19 -100 -40 4 -43 96 22 -128 60 92 -90 25 -94 23 -50 -56 -37 -46 47 -115 -49 10 -22 -61 -127 -91 2 61 -110 11 -110 9 52 -92 -56 -83 15 -13 -1 -38 -47 -78 -49 -112 -35 -100 -48 104 -93 -65 2 27 56 -29 -47 -88 -66 -9 -36 -12 -91 -15 3 14 26 54 -63 -39 -21 5 23 -60 -47 6 -24 -12 -19 -11 82 -46 9 -12 26 -33 116 79 -21 -90 -20 -25 7 -17 43 -18 -13 -35 44 -82 54 -33 23 -97 -52 -4 24 -11 -84 -48 -54 -87 -27 42 -59 48 40 -1 85 -14 33 -73 -89 56 -28 -53 -26 -20 -29 1 -128 1 1 16 25 -5 -21 7 31 -24 96 1 51 -109 30 48 26 -19 5 -10 96 11 67 -32 13 -47 34 -28 27 49 113 -1 126 0 51 -26 48 -12 30 -97 31 -43 -59 35 -43 -63 -23 97 9 26 11 -11 -13 44 -55 -22 -43 -41 5 -68 -88 -9 9 28 -32 19 36 -26 -64 92 43 -5 -93 86 64 -51 -11 55 -5 10 -10 127 -3 -52 -49 22 42 -7 27 2 -10 -11 30 -62 33 -92 -3 14 -24 -34 127 6 65 -6 58 127 -14 -33 57 -5 -90 43 -12 50 -119 -11 -37 40 -13 -37 11 -60 46 -90 -7 -116 84 -64 -95 -11 -76 -67 14 -99 -108 -69 -52 -46 -7 -24 -9 -32 24 -57 116 -108 -84 6 33 -42 -29 -26 29 36 -78 -25 -9 -122 -55 -20 -125 118 52 32 -33 -116 -74 -102 -62 -33 -23 17 2 -13 18 -17 -27 -51 22 -18 -88 -49 -61 22 64 -97 -35 21 -19 -127 -48 -83 -87 -31 -91 -5 37 -47 3 -62 -35 -97 -113 -84 -116 1 -81 -85 -118 12 39 -89 80 88 -23 84 -42 43 24 82 -38 -10 -38 64 -32 -31 51 104 -89 -5 -6 -42 0 41 -1 -35 -33 -14 -4 63 17 27 -12 6 34 -99 58 -51 -36 -18 22 24 -27 51 -25 -17 53 31 14 -13 56 65 77 -3 3 -18 60 -31 -29 105 86 6 20 36 -32 -48 35 108 -25 -1 60 23 -25 38 34 59 5 -8 -11 -5 2 -33 61 26 -25 7 18 -8 3 -23 -25 16 22 59 20 -18 126 48 -22 59 47 41 44 -60 -11 4 -1 106 -8 -17 81 76 51 64 -36 13 79 -22 45 -128 -74 -70 -2 32 123 127 57 -31 113 -32 -18 -45 -39 76 -48 24 38 83 116 3 29 -57 -102 -31 -22 56 -21 -101 -74 -21 -34 -128 -9 -106 11 -65 -69 -13 -57 -91 87 43 59 127 -13 121 -76 -45 33 -35 -109 69 126 69 -6 11 71 -93 86 -127 24 -8 9 104 -7 11 -2 42 -10 -63 28 43 -22 23 -58 16 43 14 107 -36 64 2 33 125 31 40 -3 28 -70 0 -41 26 123 -82 80 15 -37 -64 73 12 -97 -1 9 -29 -16 43 125 7 20 44 1 20 40 52 65 -63 46 111 -9 -14 -30 -128 38 113 76 -61 -15 108 97 -113 47 -48 40 11 46 27 -78 63 2 26 42 -58 -70 4 33 97 29 1 11 98 47 42 26 125 -77 -105 33 127 -18 81 -6 81 3 -97 -108 -15 4 24 -79 -127 68 10 -42 -105 6 -73 -8 82 -67 -62 53 -77 31 -23 21 4 27 67 76 -58 1 -101 -25 -89 62 5 19 -29 -33 48 -66 -30 94 106 57 61 17 41 -18 7 -55 84 14 75 -14 -19 42 -68 18 -85 -127 108 57 -82 -51 -56 22 -14 -21 -126 11 36 10 116 -68 42 61 55 -49 124 5 -98 13 -41 18 18 -101 -128 -81 17 -128 -54 -81 -77 -11 -38 32 -16 63 -63 10 -1 -29 10 61 -8 20 2 16 -44 9 -36 85 -31 -54 -105 25 -56 -4 -1 123 63 -42 65 -127 12 -40 43 103 -79 -81 12 -98 -112 -18 63 -42 19 95 -71 24 3 119 39 -45 -93 39 17 3 1 74 19 -102 -32 15 -6 -1 -43 24 39 -56 47 -10 -2 38 -49 43 -87 53 -33 1 -44 -53 5 -1 -8 -36 15 34 7 20 -2 -1 20 98 -4 -30 -3 -46 91 56 -1 -30 -28 43 26 86 19 101 10 33 -3 51 44 -11 127 -16 -10 -3 -96 4 -34 -43 -55 18 -28 4 -125 34 -25 -16 127 47 -23 12 10 -42 -21 -27 -42 97 30 14 18 8 74 -8 -31 -58 -104 0 0 -49 -20 -49 32 70 57 -26 -43 -33 31 -40 -26 -4 13 -58 115 74 22 -7 28 11 -76 19 -55 1 64 5 -79 -23 -92 27 34 91 51 -8 -128 90 23 3 34 60 -14 -7 -18 -36 -59 -81 2 -88 22 60 -59 -91 -112 -126 65 29 -1 21 -64 -42 2 86 96 -3 58 -56 53 -41 106 127 11 64 -31 -12 -44 -51 11 53 -48 115 -49 113 -84 31 3 70 -78 -41 11 -19 74 -112 95 45 17 56 10 -24 25 106 -6 -70 -15 58 123 75 46 61 -63 122 -61 32 -18 -88 -35 40 -81 -69 52 3 -108 -17 -71 107 -13 49 -76 25 -85 19 82 22 -55 -4 -14 -109 3 -1 -32 35 -21 -124 4 21 -46 -29 43 25 62 -54 18 62 -16 124 76 -28 -69 -64 -59 12 27 67 44 -81 33 58 115 81 -62 29 113 42 3 -104 -55 -9 -14 116 -70 -44 89 88 -63 -59 51 -84 91 -4 -2 70 -88 22 -124 65 -83 -67 15 27 122 -102 -47 37 30 118 -45 -46 -78 -106 36 -64 59 27 -49 -5 39 -13 57 30 1 17 28 81 -30 66 -118 85 76 -63 -72 91 -61 -1 -127 8 22 40 -45 66 80 -6 96 33 112 -5 -43 -15 -16 21 -29 -46 -37 -14 -98 -46 -92 -38 -86 26 -52 -20 -53 -28 -72 34 -50 -118 -70 -54 4 -104 -90 -22 -127 -37 -30 -26 -86 -67 -49 -71 -55 -41 -125 -24 -55 -66 -29 54 -1 6 -72 -14 -67 -82 -73 -96 -42 -125 -37 21 -62 -3 -15 -38 24 66 -63 -26 -108 -3 -11 -34 -82 -52 -49 -39 -63 33 -9 -24 2 -52 -76 -36 -75 -92 -65 -2 -63 24 -27 -114 -53 -55 -126 -90 -22 -51 -30 -86 -49 38 -62 -37 7 25 -54 -30 18 -63 -8 -38 -13 -11 22 -10 -16 18 -16 -15 -10 23 -28 8 11 27 5 25 -41 20 6 1 -30 -57 -12 -30 9 18 -14 -29 -4 -39 -15 -6 32 -18 26 -41 -79 -49 -58 -19 -36 -50 -34 -25 28 -9 48 -7 22 11 -66 -8 9 28 59 30 13 -47 48 -9 -21 -18 -50 -20 55 -10 -10 -58 42 1 -20 3 12 30 4 6 22 67 -1 33 -52 -16 25 -15 -29 -5 -3 -13 -42 50 41 0 71 23 38 -25 8 97 -3 3 -11 4 -30 -16 46 34 -67 -8 39 -7 10 11 6 -18 -43 73 6 -47 -7 -19 -71 -14 -42 48 -51 25 -17 5 -16 17 -38 -10 -13 16 7 16 12 47 -32 62 -82 16 127 82 -26 -40 14 -36 -32 -13 32 69 38 24 -55 76 0 4 -7 22 24 14 24 -25 10 4 -1 -57 58 -19 -7 -7 -12 64 -14 27 32 93 -80 -48 64 10 -18 -14 49 -83 -43 21 126 -26 -71 -125 -23 -74 -26 62 -28 -10 -20 -64 24 21 42 5 -93 33 3 24 -19 119 49 15 -50 77 -22 -41 -82 2 41 55 -26 9 122 -5 -28 21 -50 76 33 19 29 60 26 -65 41 47 60 26 -60 -115 7 -30 -13 -114 32 59 0 38 54 -17 19 57 19 -35 6 82 -11 -18 7 -69 -16 -83 -7 50 114 73 97 51 -85 -1 48 46 27 -65 -120 41 126 98 -15 6 70 4 5 -7 -72 9 -90 33 9 -105 9 -58 -4 29 -34 59 -13 -14 27 3 -40 -12 -74 -19 0 21 33 -38 27 -15 40 -53 71 -14 48 -44 -29 -67 -8 20 10 -75 -53 -21 -19 -10 1 34 -32 -103 88 24 46 -63 -11 -31 -37 -61 89 40 -48 2 10 -12 88 28 -70 90 -7 -35 -4 -20 126 -40 -30 -63 -45 56 21 45 30 -17 23 -128 80 24 -2 -65 -79 64 -57 -24 57 61 -51 64 23 -21 -13 -31 -48 21 -41 -33 -92 -10 -69 2 104 -4 23 -1 -122 -16 -29 -17 49 75 127 47 15 -108 -70 40 -24 -30 -48 18 -46 98 -46 12 -7 79 3 -59 57 4 27 27 -30 10 -48 23 -5 -49 -79 2 62 4 25 -80 -6 95 21 -8 -66 -24 -8 -69 -119 -66 41 36 127 52 -20 -58 -10 -6 -48 -48 52 25 0 -55 83 33 -15 74 57 -123 -15 -32 57 35 -98 11 56 -52 -128 -17 -123 47 -35 -49 44 28 -4 27 -15 26 103 -40 67 -79 68 -37 -119 -48 -88 38 29 -51 112 96 -17 34 32 28 76 -37 -50 60 -44 17 48 21 42 99 -46 4 28 -99 -125 0 0 31 65 49 -9 49 -46 -35 107 118 0 13 79 -61 -19 60 -53 9 -25 59 126 29 -60 50 93 -27 -53 11 -5 90 30 -83 -13 -61 -42 11 53 -7 -67 -31 69 -29 54 76 122 -23 -6 -70 -110 -72 -11 76 -70 10 90 -7 9 -15 -15 37 -52 -44 53 7 -11 52 23 -15 22 -12 54 -4 -18 -40 -7 56 20 -57 63 -30 1 15 98 -33 -43 35 -71 67 -22 63 -49 -37 -21 25 -121 39 12 -85 56 30 29 -2 -73 56 35 -10 -77 127 20 -1 1 76 -31 -45 0 47 -17 74 6 17 61 -2 77 -71 82 103 23 31 -68 44 66 60 -29 -18 -68 52 7 24 0 -19 70 25 4 45 2 -58 45 73 10 96 8 -46 45 -54 -71 31 126 69 0 -49 5 -97 22 -84 -55 103 19 15 -33 -3 -40 -33 72 -11 23 26 -21 -24 63 -76 59 47 -3 -17 55 111 27 -87 -45 33 -51 9 -15 7 37 -62 -33 29 -56 22 -33 -36 -55 -70 -106 -67 28 18 -118 25 -38 5 -51 73 -38 28 68 -18 -13 22 56 58 -3 8 20 2 -19 -28 -18 -29 42 50 6 123 -16 10 22 79 -65 14 0 51 95 51 -6 36 17 76 -59 92 11 127 90 40 -68 24 82 34 78 46 17 72 10 55 31 0 40 115 71 16 21 -74 73 56 58 52 93 21 37 -9 16 -6 1 42 17 31 58 10 64 109 101 30 -19 -25 62 23 -39 25 5 42 -53 30 68 27 88 27 23 -4 51 22 -2 -48 1 24 26 98 17 41 -47 44 16 32 29 13 56 59 64 -3 57 26 68 31 16 13 -12 73 83 32 -30 20 17 -39 22 -6 12 7 61 51 -31 -22 20 -58 5 16 17 -8 -6 -14 52 7 1 -6 -26 -2 15 -23 32 -34 -27 7 -6 24 33 58 48 11 13 6 -50 17 12 -9 -15 -4 37 6 38 9 45 41 -31 -27 30 -30 1 9 32 16 -43 -17 -13 -19 0 29 -14 16 36 25 54 9 26 36 3 -18 28 -18 -9 14 -5 -13 9 25 -40 11 37 -9 49 -29 22 40 -27 -9 36 -10 -62 52 -82 45 91 -13 14 28 15 -20 10 -44 37 -43 -18 -60 11 -69 -22 12 58 15 -40 -3 -37 -21 47 39 -20 27 28 -32 10 -71 37 -34 -7 28 -75 -17 17 3 40 -57 55 26 -7 18 -32 21 -90 75 -10 -28 3 15 -91 -76 -56 -26 -37 -12 -29 52 -62 61 59 -19 127 -1 -7 -4 -47 -6 -34 22 38 -14 -24 3 53 50 -29 47 -1 50 -37 111 -2 -67 -23 -59 23 67 -42 -16 122 -51 11 -46 -55 -62 -56 119 -14 67 20 -38 33 -23 62 80 54 -95 110 -123 27 80 -67 105 45 -11 -31 95 9 -22 -24 70 -41 -127 -50 -36 33 98 -5 15 -40 8 9 -62 -31 -46 -6 -128 46 -27 17 40 -14 -106 47 64 83 -29 37 -14 -69 68 7 -24 -7 -59 -103 -91 66 -98 54 53 -78 63 -14 -85 115 23 -20 -79 22 -92 -22 18 -34 -30 63 -40 72 19 -95 -1 -17 -34 125 -23 -45 90 19 5 68 14 45 60 48 -74 124 -49 39 29 18 23 -18 -18 62 -48 -116 -17 43 43 57 18 -30 -29 -24 -45 -2 110 27 -3 -24 74 -3 1 -27 99 70 -128 40 -51 -54 65 -53 32 -30 52 25 -2 -53 -19 7 51 3 40 -27 30 37 -3 -50 48 -26 54 17 7 127 -54 -22 -41 38 -17 23 -2 -14 12 -21 -20 78 9 32 74 31 -67 -13 5 -73 -93 25 55 -3 20 36 -27 45 59 -54 51 81 66 -6 -1 18 -29 -14 49 90 -3 30 2 36 -12 -57 44 -27 66 -13 -30 54 24 3 54 21 36 25 89 -22 -23 59 41 51 37 108 122 -19 -19 -14 4 23 -27 -44 16 46 5 -12 4 -38 -1 -16 16 -78 -27 -21 -33 44 -58 10 23 -44 -35 -12 54 36 -52 -21 34 -22 -5 -34 77 37 4 -8 21 -70 36 15 6 -88 -27 -40 -19 22 -60 -39 -18 49 -22 -15 38 71 43 9 14 75 -66 79 15 66 45 -33 -63 50 35 -32 123 -15 10 31 0 7 -39 -31 19 -14 62 31 -27 25 82 7 104 28 14 -65 -27 21 2 -15 -57 -11 -16 -4 76 32 98 24 -20 64 118 66 64 32 38 -12 108 62 -53 -5 87 -49 -45 8 -109 48 35 22 -1 51 10 44 52 -13 53 44 -80 -54 -33 125 -100 23 -47 34 -21 -21 70 53 -52 50 73 23 22 -26 28 75 44 -107 68 -91 -44 -28 -17 -56 47 38 19 43 -22 -15 -68 3 36 28 76 -68 -27 7 37 10 -51 -7 46 -22 -62 21 -51 50 -49 -30 -40 -76 12 19 2 54 -5 53 -63 19 91 13 -7 -5 -1 3 32 -4 31 28 29 44 -35 -9 -52 -30 -29 20 -37 -62 -56 -61 -2 -58 63 -49 33 -40 -28 11 -14 68 -113 -23 20 23 6 -105 54 21 -18 69 -77 -39 -97 -29 -37 -53 -102 -59 17 -43 -20 -123 34 22 45 71 17 -45 -17 0 35 2 -43 36 -34 19 -36 2 -89 -78 74 -54 3 7 28 11 18 -73 37 -11 16 -65 69 15 88 5 14 -4 36 33 11 -58 -42 14 7 -22 -30 12 28 -63 -32 -12 -31 -6 -9 14 61 25 -60 56 17 -84 -12 -53 -57 106 -42 14 -10 38 -1 22 -13 26 45 3 -6 -18 11 66 53 8 -52 46 -57 20 115 -111 -35 32 82 -25 -28 40 -31 -9 18 -43 4 121 83 -63 -24 3 -78 -53 -15 -58 35 127 27 -17 -21 4 48 -38 -37 -21 28 85 14 0 5 44 34 -11 15 -126 24 81 14 19 -39 -30 67 29 -13 53 40 -9 14 -43 124 72 28 116 -16 73 -33 -11 63 120 -4 -11 -24 -67 59 24 -17 0 29 22 68 2 58 -76 -16 -3 35 -126 79 12 -25 -40 -17 7 -9 -38 -18 24 5 -21 -122 -64 32 -9 -18 37 -10 -104 -61 41 116 -50 11 31 -46 2 27 -17 -26 -64 42 32 6 -24 58 -19 -83 -43 103 27 -17 80 -15 -41 2 69 -69 -7 45 81 -22 76 -52 42 -39 -74 -25 11 30 57 -15 9 27 -73 -8 -78 -13 -28 56 14 40 86 58 12 -3 59 33 45 -69 5 -88 2 -48 -78 -23 -2 5 -28 76 -6 -19 -88 64 -116 17 38 -35 -5 92 28 23 102 -50 -51 -90 -46 51 -29 -51 -10 -37 23 -28 -25 -8 0 -23 -53 -45 10 -126 -18 -26 0 -28 -31 -21 -29 -42 -27 40 -1 -65 3 1 47 -23 6 -11 20 92 98 -75 59 55 -96 -35 -35 -61 -31 35 -57 -1 2 127 -51 -66 39 -43 64 -54 -113 7 7 -54 -42 83 8 57 -46 5 -11 -15 -24 -39 24 13 -84 3 -20 -34 -78 25 -84 -14 41 15 19 -6 -59 43 69 -71 -39 96 18 -43 -32 -44 76 16 35 96 0 -14 -3 -65 -17 -45 -58 10 92 62 -68 58 35 31 3 1 10 -36 -2 -4 -36 27 64 -69 -40 21 -4 -27 35 -81 38 -17 35 -27 -63 -72 -9 -58 45 -29 117 36 44 100 88 114 -41 -37 -22 -13 27 -29 8 -20 -19 5 29 -50 51 22 -34 23 6 20 -66 -38 -83 -5 38 40 36 24 51 -83 21 -49 40 45 9 42 -3 48 -4 125 -1 0 -3 15 -1 59 -34 -16 59 23 47 11 34 40 33 2 -3 55 97 54 1 13 16 -6 81 -37 44 45 9 2 -96 53 -22 -37 -36 36 -24 -14 2 -7 -44 17 -4 8 7 33 3 16 -5 -43 -56 10 51 -11 21 -100 23 -9 72 4 29 -22 2 -7 -63 4 10 -10 12 17 34 1 28 7 15 71 62 37 -4 -41 -9 6 -21 9 28 11 -30 87 12 61 20 -52 29 20 32 17 55 -8 -32 -30 -6 -27 41 1 18 29 57 -29 59 6 -1 16 19 -48 87 7 1 18 -96 -109 -17 29 -37 16 37 -43 24 5 -25 -47 -19 20 -29 2 54 14 94 -106 -78 -17 120 53 36 -15 55 -22 81 18 -53 12 -105 -39 10 51 -102 -27 63 -34 106 -95 45 42 -20 10 -3 38 -17 -44 -17 -44 88 5 60 -21 12 28 101 85 30 -23 2 -37 72 57 2 -27 72 52 109 16 -36 27 34 -83 -68 -30 -80 -20 82 23 62 -24 122 114 -8 -112 38 106 -28 -13 -28 22 26 -20 12 89 41 62 -59 14 13 47 103 -43 54 -10 83 -111 -18 41 -25 -29 -26 4 106 14 -44 89 102 110 48 106 30 -16 36 1 31 94 12 84 -42 -93 30 10 -37 41 -2 92 24 -51 15 10 73 -16 57 67 75 -46 -1 117 4 39 4 53 -86 51 67 -57 64 -84 49 -77 -1 -22 21 29 3 9 -22 45 -1 -31 9 -12 64 -5 0 14 7 -8 106 55 25 81 14 -29 16 67 36 47 -44 126 21 -29 49 78 54 -12 59 -19 21 1 15 32 -1 0 64 -40 13 14 58 60 60 22 32 -21 26 -84 -10 -10 -53 46 -11 -48 41 -10 -56 55 83 80 -46 -80 18 -38 0 -112 99 -8 -22 26 -21 -49 13 -99 62 42 -47 56 32 -19 -41 61 -4 -48 -6 -16 39 12 -128 -34 75 -72 48 46 -10 3 13 -23 -66 -11 -6 49 43 65 47 14 6 -90 41 -39 126 -12 -46 -39 24 -36 -2 34 -21 35 68 28 23 29 -84 -31 95 57 33 -52 4 12 -16 -14 -58 18 61 40 41 -21 -63 64 -2 4 9 -19 58 45 37 -16 44 -31 21 -32 125 80 42 6 -50 42 7 41 -19 36 23 -66 -24 -1 31 -22 0 93 -26 -91 -23 26 6 60 -57 9 -44 7 46 78 108 26 -26 42 11 -41 -35 3 59 -17 69 57 86 22 20 49 -44 55 -62 34 29 -32 2 -49 67 -33 -126 26 15 -90 -6 -19 21 50 22 3 72 -105 26 -12 16 16 -15 43 45 -5 106 8 -68 50 -64 -21 74 98 -78 15 30 -42 63 102 54 39 44 37 -82 -49 -12 -2 -25 -8 111 -15 -54 36 11 -39 -112 -16 -35 6 -70 83 -18 27 -101 51 -19 48 -4 35 111 2 62 127 31 91 -43 -11 99 -66 5 38 48 81 11 -24 30 -3 8 0 1 33 41 42 -9 -2 -92 -38 -13 3 -11 -91 -27 -34 -10 43 -106 -10 -40 109 9 -20 -69 121 -28 15 17 26 -16 -42 -35 29 -14 1 26 -24 5 -49 17 -35 -9 8 5 -18 -21 29 5 -34 44 -67 49 4 72 -42 37 47 11 43 6 43 13 24 -36 -34 51 -12 -23 11 9 -3 31 46 -46 17 6 -48 28 -9 23 -29 -44 71 12 15 -68 22 -28 -47 -51 -43 8 93 7 -22 39 -30 -18 -16 -58 124 -109 -19 -45 -37 -7 104 -34 -54 -62 -30 -22 14 58 8 -14 -20 5 -55 -31 -24 35 -35 -46 -10 43 15 21 -1 24 4 -45 20 41 48 -20 -1 40 -20 -44 -37 25 26 -24 -72 -73 23 -44 55 -76 5 -8 -56 55 -48 -44 40 49 9 -21 7 46 -17 113 35 41 -49 20 -49 -27 -8 5 -16 80 38 -53 34 -22 15 -29 10 19 24 -72 50 24 -36 16 81 23 -7 22 -8 8 -27 52 -26 57 36 -35 15 -12 58 27 -2 -3 43 -111 -26 -50 49 40 -63 -29 -43 -24 -12 -6 -18 -110 -27 40 -39 -14 12 74 56 55 -106 -2 36 8 11 43 86 -8 -6 -22 -58 84 9 125 28 65 -1 -40 11 -53 -42 -31 -104 -13 -128 22 -82 -29 -64 62 71 -5 14 -71 62 -32 68 2 -80 -43 -24 41 -16 -118 -88 -55 -72 -12 -103 10 -20 52 -17 -42 45 62 48 -25 58 -25 -17 -34 -73 -48 60 26 -79 0 -3 22 45 -43 6 63 -74 39 53 88 58 24 -44 3 68 37 63 -2 24 28 17 24 43 2 -106 -59 64 -29 76 -41 -31 -24 36 2 -40 36 43 -61 -62 0 1 -19 33 -51 31 -24 69 21 56 -6 -35 -20 -53 29 -24 -31 -66 69 -43 -11 -40 -23 61 37 62 13 -16 -9 34 44 71 -75 -80 28 -31 -10 -6 17 9 16 -16 6 28 17 7 32 -13 -15 -19 32 -33 -10 52 -33 66 -21 2 26 2 19 42 39 94 -47 -77 -90 3 44 -39 -23 19 0 100 -36 3 62 -78 65 -23 -17 59 -71 -7 26 36 -83 -2 -19 18 18 -3 -60 -1 28 53 43 14 94 -70 -39 -19 47 -17 -37 25 2 -23 4 72 -104 -121 64 21 29 119 19 21 -34 33 -92 -26 -52 53 28 -24 -106 -9 -40 -33 106 -34 21 -26 11 -30 -44 -74 -68 -4 3 -29 37 -1 127 58 97 57 -89 -86 34 -50 100 60 13 -125 57 1 8 -125 34 -23 81 68 -48 -26 -10 33 10 85 -79 -17 -128 -33 68 -33 59 -9 13 -72 -11 -59 50 -77 -94 37 31 -47 -14 -7 -24 36 -1 -81 1 -27 -41 38 29 50 -66 3 -50 -48 -31 -114 2 -54 -108 38 -52 -36 -47 -33 57 -73 82 29 5 -113 -43 39 -126 26 -33 32 -52 26 -91 -72 4 -98 -48 30 -111 19 26 80 -79 16 -31 57 -93 15 27 52 21 -43 15 -30 -59 11 -67 -59 -27 17 4 42 -49 -18 26 -47 -26 48 0 -40 -33 20 71 44 42 67 62 -76 -2 -51 9 9 -2 23 21 -7 21 12 11 -80 64 -2 31 -39 -64 98 -78 27 75 98 -19 -44 8 -38 -26 31 42 -48 -47 65 19 66 27 -30 -37 21 -127 -18 35 127 -1 123 -44 3 -2 -75 -3 18 34 45 8 11 22 65 -91 75 19 -19 2 -47 56 57 -54 -87 -37 -29 -34 -33 -69 36 30 88 -37 -11 64 9 60 93 -26 -38 51 -95 -96 54 25 -28 33 17 3 -98 -12 -20 -6 39 -76 14 26 50 48 58 -107 10 -24 86 70 -27 118 35 49 -63 65 -85 127 79 101 102 -41 16 65 21 -38 5 -25 106 39 -96 34 41 -116 -12 9 24 -26 -26 -6 -126 -4 60 102 -5 -76 -8 -20 -11 -73 -59 -91 13 -42 58 35 36 90 68 -92 -21 -66 16 -67 -53 -2 45 2 40 -10 -115 29 -128 -1 48 -60 -3 -44 16 -18 -86 0 39 29 -12 15 8 -29 -1 32 -23 -96 -23 26 0 -82 -26 13 -39 -77 20 7 -18 -102 13 69 127 -84 19 -13 -56 61 -57 8 -2 -8 -23 50 34 -75 61 8 40 -38 47 21 17 -33 -14 -25 51 -22 -27 -117 1 0 -17 -2 -21 49 -31 8 29 -21 3 -26 -51 -1 83 -56 -5 5 -113 -25 -62 85 -24 -28 -97 46 -40 30 2 -91 39 -23 -35 44 -64 -56 -26 5 8 -33 29 48 13 -11 -5 13 -41 -69 -8 32 10 -6 9 -33 -45 -42 23 5 7 39 -25 6 -47 -27 4 -38 -98 -16 16 86 18 9 -6 -4 -71 38 -30 0 -12 -16 14 15 -63 -65 -49 -52 -14 -62 -26 -26 -8 6 11 -28 -68 -63 66 -5 13 43 20 -4 -24 27 126 -20 -25 -15 -3 -22 10 86 34 2 16 -94 -51 47 -14 21 28 19 -72 107 -2 -2 -30 21 25 -113 -29 -6 6 24 -21 -87 4 61 82 -12 22 -24 -71 -17 55 -48 -9 -62 -3 65 49 -19 53 24 -43 -10 -7 78 40 -44 -34 -35 12 -24 -24 -50 6 58 97 34 36 -21 33 47 -33 39 -73 -55 36 -69 22 21 -8 -117 5 -1 65 3 45 5 13 51 -49 78 -10 9 -20 -20 -5 5 -27 13 -23 -122 69 55 -16 60 67 121 8 -60 18 41 -14 21 -81 85 -33 37 19 -35 30 72 32 -16 95 -4 6 -30 -1 -49 -104 -84 83 38 -26 58 -57 -65 56 -77 -28 -32 -86 126 -113 -41 -117 -37 36 122 -87 74 -36 33 49 45 3 40 93 -48 -128 43 -54 34 75 127 -107 5 8 -124 -2 98 -85 -45 -124 86 -115 -67 -64 125 66 -88 56 -7 123 90 -15 64 -127 -121 35 18 -62 -124 -52 -39 -100 -58 -42 73 -99 61 34 -128 57 -14 127 -49 119 -128 -114 -102 -98 -6 -102 48 -23 93 127 -127 92 37 64 -72 -4 112 36 7 40 1 108 -9 81 -2 34 -43 -31 -28 -16 69 -88 55 -68 -11 -19 63 15 -52 -12 5 -30 49 21 108 13 -22 56 -51 -39 -17 86 -13 -17 -11 39 120 19 29 -21 114 43 0 32 75 -23 115 12 -9 -38 20 61 33 82 49 -46 -45 9 12 23 23 -53 89 9 -10 -59 54 41 -35 -1 -31 -57 61 25 31 -86 8 -116 -58 -8 -3 77 -4 -51 -33 -32 20 86 -6 -1 -13 -7 56 29 13 62 45 28 32 42 17 52 -56 40 2 -66 13 119 -7 57 -16 44 108 -47 3 24 -70 -2 76 -3 18 -46 80 46 -18 14 36 -51 35 -23 -67 34 -16 93 107 71 50 -48 -35 4 100 -28 -26 3 68 23 -15 1 30 -28 4 -24 55 46 127 61 -5 1 52 -65 -36 120 -67 -8 -38 -59 -72 -22 55 18 -47 -13 -67 2 -91 92 3 -48 -6 69 10 -14 96 -50 -60 26 -33 -11 41 20 -124 -61 -105 15 49 -77 14 86 21 7 54 31 -65 -69 -13 -94 68 14 72 35 8 47 -42 37 -28 6 50 36 -3 11 42 14 -24 29 9 -100 21 60 -51 12 -19 -81 89 -86 -3 -88 -102 70 -3 -61 -98 13 16 4 -23 127 73 -14 55 4 -12 -68 9 27 -22 -125 52 53 54 -31 13 127 -42 99 91 95 97 25 3 -69 -72 29 -32 52 31 23 6 -11 -78 84 -10 16 23 -65 112 -34 -49 -37 23 -10 14 -63 98 -15 -35 -9 -59 100 80 23 68 -113 43 32 0 54 -43 43 30 -15 -117 76 3 29 -44 -18 67 -17 -32 41 -38 -18 -13 1 0 103 91 -55 67 -48 11 -64 19 -14 -36 10 -44 10 45 88 -3 55 59 -51 13 76 -6 36 11 -16 -19 22 -43 -54 55 23 -60 -1 -123 91 38 -17 -36 9 -57 -51 -120 46 -40 85 -116 40 -36 74 90 -24 -22 46 51 -5 6 -79 -35 48 -20 54 31 22 49 22 34 -15 70 21 89 123 31 -6 -117 -9 124 13 -39 -36 2 -26 -15 65 41 -81 46 59 -39 15 2 -27 37 -19 63 -25 -65 0 33 81 53 -81 -16 -3 13 -29 -58 -87 -6 -62 -42 -64 -17 -95 30 -51 56 30 110 20 2 -12 8 -25 -26 -95 -51 -30 -10 -30 -124 66 53 -1 -9 93 11 -13 -45 45 -58 -49 -101 -10 95 7 4 -87 -10 -48 29 -25 41 28 98 66 -34 -12 -7 86 24 -23 127 25 89 -47 -106 -105 126 45 32 108 -61 -41 -58 30 68 1 3 119 -70 -67 -54 -17 101 70 7 -33 89 57 32 117 70 60 113 68 -99 111 -128 52 -32 68 53 92 61 9 -29 14 26 -14 101 105 2 0 61 6 57 8 -61 -4 -37 66 71 14 70 -31 51 -80 60 -125 42 108 35 -115 120 4 -41 120 76 114 86 22 111 16 -8 73 50 -11 90 -53 -11 41 27 60 -9 -19 -69 63 69 53 32 34 -64 -18 -105 26 102 -46 -60 40 52 77 -56 20 -48 -91 -22 27 -38 -122 12 -37 77 -15 20 26 2 -70 22 17 14 9 -113 -40 19 15 11 42 32 -110 0 29 -56 -123 41 3 -120 -39 -19 20 30 21 14 4 8 16 119 36 -111 -5 -128 -104 57 -19 -48 -34 44 31 46 82 4 127 36 69 -1 99 117 48 -35 76 -42 -41 -83 53 8 7 14 -23 -38 39 38 35 -36 -14 -18 -54 -113 20 -41 -47 -49 -77 -49 -76 75 25 -53 17 61 -91 24 -9 -86 11 -54 -30 45 52 -9 88 -42 -51 -10 -8 100 -77 34 -61 -10 22 -31 19 -39 69 120 -36 7 -25 76 -17 45 65 23 74 16 -69 -43 54 24 -38 52 -25 50 75 38 -50 32 -83 52 17 -18 26 69 -18 103 68 47 -42 24 -4 126 -59 -49 43 -39 8 -65 66 40 42 92 74 53 -55 -18 77 -41 -104 12 44 -101 -92 13 -68 -48 20 -38 -39 73 -28 12 -41 123 127 -26 -126 -12 28 -24 59 55 -41 -125 6 85 82 5 -58 32 -39 -3 21 25 47 -86 51 1 31 52 -30 -104 55 55 0 -22 -36 40 62 -99 -2 -98 -77 14 -78 25 -115 7 -4 4 46 11 -19 -4 -5 -11 54 26 5 -32 66 72 -118 126 9 47 6 -43 37 -126 -28 127 63 36 51 -52 43 127 -122 106 83 1 -20 30 -29 -42 26 -37 80 82 -32 -71 -34 6 -61 -33 15 -33 15 -36 -18 -19 -24 16 19 2 12 -20 10 -37 40 -47 22 42 -48 -26 -59 43 -8 -55 -29 -21 2 -48 72 40 -72 -84 -78 52 1 -47 -36 27 -41 41 74 -13 42 25 -9 -1 -24 102 -4 -18 33 55 19 -31 -42 6 -35 -67 -45 -5 -13 -13 -77 66 3 -55 41 72 -52 67 -16 -13 -67 21 31 -123 39 28 -103 -38 12 43 126 -38 38 -56 -15 -30 -19 0 25 -76 -50 5 -62 0 -118 69 48 -67 4 69 23 -25 49 -72 -1 3 60 87 96 6 -27 112 -1 -6 -25 16 126 75 85 -30 15 52 -21 126 118 74 25 17 44 -64 7 -21 -36 1 15 -57 -126 13 58 60 -16 65 -7 51 15 80 119 -11 32 0 -96 -75 0 51 27 70 95 -58 58 -42 -31 38 -58 19 1 4 -109 89 -30 -40 -59 -71 26 -128 70 11 45 41 4 -22 53 61 3 96 -16 66 28 -5 -74 62 74 127 14 114 -16 -5 92 108 65 -53 73 6 -8 48 47 -20 58 120 -29 71 91 85 -124 -54 -39 -6 -108 -5 -55 -75 30 -52 -5 -35 -50 -7 115 -8 88 29 -11 -104 9 15 -73 -53 -16 -33 15 95 -6 94 -16 -6 61 -87 83 71 93 28 61 10 -85 -59 -127 32 32 127 124 123 53 -85 35 110 67 -86 -51 69 -75 -84 -38 0 8 -33 42 -44 35 32 -34 -17 7 21 -42 94 2 -50 15 -21 33 -9 -79 20 -9 -41 60 16 50 26 -5 -28 37 -52 33 -42 65 41 54 6 43 78 91 43 29 -31 9 -44 7 56 64 -4 -93 31 90 -110 31 1 44 -70 7 -24 58 5 39 20 15 -39 -31 28 -46 76 -27 -40 72 11 -15 -20 -69 7 85 38 -89 46 25 -66 43 -41 -48 24 -12 3 -37 20 -19 -12 -3 49 28 47 94 71 55 20 94 -8 2 119 -47 24 62 -92 90 -9 97 27 -75 3 37 -74 -29 90 -38 -16 1 127 69 12 7 -16 -33 -38 -23 -5 35 -7 42 -12 49 70 -11 -45 41 0 -25 -4 24 -16 -61 -45 -46 -5 -9 77 -28 15 44 -32 96 -13 -21 -38 -24 59 -52 -47 13 46 0 -101 -37 58 -6 -46 -90 20 38 -44 -1 -23 -17 32 81 -45 -10 89 -85 47 44 26 -53 -114 2 -1 -55 -31 -80 -64 15 34 -42 55 1 -114 67 85 -2 -3 -23 -53 -127 46 -36 -46 -121 28 -35 7 -35 -36 -108 -72 15 62 2 13 102 -73 20 43 -90 40 63 -52 47 -46 32 -51 111 119 -128 -23 -39 -21 -70 -47 -72 -64 -30 -101 -94 30 -2 -36 -27 25 1 -63 -78 -76 29 -50 70 -91 -35 71 -42 -7 0 74 -25 -53 -125 -51 14 -79 -126 69 8 21 96 34 14 -124 63 -8 -47 123 48 -126 -15 41 72 -58 -62 -17 -39 -107 17 22 35 -86 25 -24 -11 -4 -79 -45 3 0 12 34 42 -63 15 48 13 54 -95 93 -126 50 16 -104 -66 24 30 16 -9 -46 -8 -72 -34 -35 47 -8 34 38 -59 30 82 7 33 11 -54 -58 14 86 -126 -3 -70 -28 110 -9 -15 74 -31 -97 3 77 -40 64 -53 -16 -48 53 60 -18 9 57 -32 -10 -60 68 -27 -26 5 27 -128 18 -31 -64 -28 75 30 -5 -65 22 20 26 -21 57 -3 -83 69 -55 -54 -30 29 17 16 19 77 37 5 10 -83 -28 28 -82 107 13 44 17 40 31 -26 85 -4 69 -37 11 36 100 -4 25 -10 3 -33 -40 125 -18 42 -64 -46 -56 -96 -87 48 -66 -55 -32 -37 23 -44 48 7 9 -83 44 52 55 27 66 54 -53 -21 -21 16 17 10 13 -15 84 127 -90 75 -24 105 34 5 -4 -90 -48 -63 127 -14 -36 -27 -69 50 -34 82 -19 -106 -13 -15 -15 -67 -74 18 -56 -18 -10 -48 11 -53 50 -28 -45 -57 -50 -52 -76 33 -9 -5 43 -49 -11 -127 0 23 28 90 48 -4 15 -22 -47 -126 -42 -106 -5 -29 126 -46 -70 61 6 -2 67 -28 -93 -75 -91 47 -38 38 -106 -70 -82 -45 -93 -40 -127 -43 73 -57 -8 19 -127 1 -106 -3 0 73 30 102 -24 -1 -90 -74 -120 -100 127 -56 65 33 -7 -79 0 79 -19 -35 48 -40 34 -11 30 36 59 87 62 30 -51 43 -25 25 90 -25 45 -40 -42 34 75 -9 -7 -15 -61 35 -3 -40 75 55 9 57 2 -47 40 -20 -39 40 -11 78 0 -62 68 -8 -7 5 -60 -6 -6 6 32 105 -42 105 35 25 -63 -25 -26 -38 -5 40 94 58 -66 7 66 12 -120 -2 10 -19 58 -24 57 87 -9 9 3 -11 25 -20 78 -22 49 -12 -11 58 -102 -36 27 -34 13 2 21 -42 73 -57 -71 -11 -60 105 6 65 4 -29 7 72 17 32 25 -11 -128 120 36 -38 -15 -48 -10 -14 32 1 2 60 -95 11 68 -26 31 86 52 -80 127 12 -43 -38 -52 114 40 38 -36 -33 -38 -54 68 79 -31 -4 -36 -18 -126 25 -9 18 39 -53 -63 55 -62 -95 -113 -5 28 -32 -37 -100 -46 6 7 -25 -33 61 85 32 74 9 -16 4 43 -13 -18 1 6 52 4 -57 9 -69 -57 6 -13 122 -29 119 71 -89 -33 -64 -30 13 22 55 57 -95 -109 9 -121 -18 -14 -5 -42 -89 -36 60 -50 -40 -107 15 20 -41 7 27 44 49 36 -33 -78 -118 13 53 32 -128 127 32 -13 -10 48 4 -7 50 58 30 32 -25 -96 36 99 -123 34 -11 -61 -42 80 -95 53 53 39 121 -127 125 80 2 -115 -4 -64 -70 5 25 -128 -1 -48 -126 118 63 31 94 49 -51 -116 -70 -95 -124 127 -43 6 -126 87 -8 0 -30 -39 -28 37 -45 -40 -62 17 -40 7 -8 32 28 -25 -106 -12 5 55 36 -14 -27 -12 -75 62 -6 -105 -4 2 -25 -20 -31 3 -22 94 -72 30 -14 -10 48 -72 76 82 -26 -4 46 -128 22 40 5 23 27 -14 7 -15 -21 -48 -78 -17 -17 47 9 -41 55 26 7 -102 -18 32 12 -121 54 -17 18 89 -14 14 -44 14 66 115 38 -5 14 -43 -32 9 -24 35 -84 -60 -16 -19 85 9 86 -14 -60 -23 -30 66 -48 -57 6 -29 3 1 -32 7 43 -51 -38 60 27 -48 -87 -50 25 9 -19 9 -29 -97 81 -1 31 43 40 -28 39 31 112 71 -69 68 -38 -57 83 -37 18 -12 16 56 9 41 -2 -117 101 -17 -15 -41 41 -27 -51 76 -20 -85 -57 17 -36 20 37 34 48 88 -7 -70 7 -74 63 -29 82 -49 -34 -37 35 12 63 -37 -58 18 -34 4 -34 26 13 56 -61 62 -74 -85 -79 -18 68 -86 127 47 51 -51 32 35 49 -63 82 123 63 -76 -127 15 -121 7 22 -27 64 35 -81 -112 -77 60 125 24 -29 -3 -33 -20 25 -117 -75 -113 -35 127 97 105 20 99 40 14 -65 -34 70 21 -37 -35 91 64 90 33 110 -53 -18 -13 -2 -54 71 -10 -6 -67 40 39 76 88 -100 123 -75 -128 -6 13 17 -69 -100 -17 20 63 -28 -60 -59 -40 -23 30 78 -39 30 0 -11 66 43 -40 -51 11 7 -16 -19 -19 -8 11 -68 101 -40 36 54 -57 57 39 26 -71 -2 -11 -48 -53 21 -26 -21 -9 -45 -16 -83 18 -15 -21 -78 -45 40 54 86 -41 7 69 50 -37 -109 11 -46 60 -83 46 -6 -22 -86 -98 -42 48 16 -9 -25 -2 -23 -60 -34 24 68 -56 -10 -9 -30 -19 -10 -70 -53 -78 -126 -23 -31 48 -6 -104 -10 -128 -72 -64 28 78 15 49 25 -16 125 -58 -3 -17 -34 26 -60 49 -64 27 46 -10 32 -27 -40 -1 -21 42 23 -70 14 16 -40 29 0 -128 -14 33 127 0 52 -37 28 -54 29 -10 -56 75 14 -20 -2 35 -105 121 -7 42 -105 72 -3 70 -33 44 -32 127 75 -10 -36 -124 -34 -12 -24 -27 -107 -66 78 -84 -51 56 17 -22 -10 54 39 -56 -19 9 68 34 -35 -77 -20 -36 -2 -68 66 3 -27 -14 -19 -102 -42 38 33 -48 -86 -41 42 -27 -66 -28 -34 61 -12 -19 -35 -8 14 -15 -109 7 29 -100 18 -58 -1 -74 23 -81 -82 -77 -44 -83 -52 -112 -46 18 -68 -1 -67 -33 0 -121 -22 -6 99 61 -66 -73 -30 12 -64 22 -47 -55 -33 -5 22 -19 32 -96 -68 -47 -73 -9 0 -107 74 -35 -79 18 40 30 -63 13 -2 -53 -109 -6 -18 30 8 84 59 -3 37 34 -26 -4 -61 -78 15 -46 -69 -21 -29 -65 -19 16 -19 -81 -112 -36 -63 -68 -26 68 -16 -62 -60 -7 -13 12 -16 40 5 -15 -41 -13 76 42 11 -43 -27 45 -44 -42 29 -44 -60 -30 -41 -15 -39 43 32 26 25 -40 -7 -9 6 56 -14 -6 -60 -93 -40 -34 38 15 -17 -20 -4 0 60 -127 25 -47 3 10 36 32 30 28 42 -2 37 -49 18 43 15 25 -20 -25 12 -28 19 -26 19 43 66 -23 -33 64 -1 17 2 9 -30 -1 4 14 30 37 -17 27 -6 37 -13 -23 -24 -24 -21 35 -2 24 60 -37 -6 104 10 16 38 -73 -60 -26 49 36 41 -7 -28 107 -89 58 -16 -64 28 7 63 16 55 -14 28 -63 31 116 8 -45 -21 57 -5 24 12 8 -52 75 125 8 -21 -112 -14 -87 -61 21 17 47 31 -3 7 -45 -86 -67 -83 -23 -48 0 -27 -12 -53 7 -44 45 36 61 17 27 4 23 20 -7 77 -10 82 56 -4 1 45 19 29 -38 -6 75 12 50 -13 31 -94 -22 -76 33 -62 -46 63 0 -8 -48 -23 42 2 44 17 -27 -62 -22 58 106 76 -51 -83 -11 17 79 8 71 101 -6 14 -18 -46 -21 28 9 25 22 105 -14 -128 -8 -22 89 6 63 -38 40 101 -34 42 -44 124 -84 30 93 -24 80 18 27 -117 55 34 -33 27 -15 -29 -9 20 -89 -2 -42 5 -18 21 3 56 -46 14 73 -57 -21 0 -64 -87 -45 -76 -2 -3 60 117 -3 11 31 50 -123 45 114 -60 80 -23 -30 70 34 27 58 13 9 5 3 -9 -20 25 -44 -47 95 -17 -64 -56 -54 -31 41 -32 14 41 5 -5 -9 111 -26 -122 48 53 -74 36 35 0 -1 -50 -87 -49 7 -9 -16 -46 -63 80 -62 17 -44 25 -16 27 9 -85 -12 -50 -35 0 50 -31 -71 -1 38 -49 60 -56 28 73 -50 15 -36 8 8 30 31 -43 13 -10 37 -13 29 -31 -93 -2 47 73 83 9 16 43 -19 -62 -25 -77 0 -43 -83 7 -3 -35 72 -9 -74 15 -57 -116 -67 -23 20 -55 -48 10 31 -46 -45 -45 55 29 -22 21 43 13 -27 -56 10 -75 -10 -10 -23 -34 16 -2 -66 -7 -40 -5 14 -30 -51 -30 13 -25 -14 -16 -14 31 -41 20 54 -50 16 -54 13 -12 111 16 -9 0 -10 -28 16 13 58 -50 18 11 -23 43 68 -59 58 -102 34 7 -43 88 57 18 -50 -3 -7 -34 19 39 -7 -126 22 -18 -33 8 -16 40 7 -83 -11 116 -103 126 -71 29 27 -88 57 42 127 -110 -36 21 -38 -1 2 7 28 -35 -42 57 -10 70 51 71 67 117 -55 -5 74 -16 48 -17 -18 30 127 49 -55 -10 -10 -120 62 -7 106 45 -68 -92 110 19 89 122 87 -121 -2 -87 -55 27 -51 42 40 33 96 11 -63 -2 25 -22 124 -3 126 -14 57 -16 -49 118 89 39 66 64 -2 43 -27 -42 -87 18 11 -5 -4 96 90 99 109 99 -10 -75 -54 -37 -42 -72 -114 18 5 4 94 -26 68 -40 -86 37 95 37 -15 -117 -5 13 8 -58 -121 -124 65 9 7 10 43 -1 -61 -31 4 -13 5 6 7 67 -3 68 24 -33 -55 34 116 14 -37 -46 -22 -46 37 -4 -32 78 23 -51 -39 -9 25 -49 10 27 -25 24 -69 -41 127 -72 -11 -33 79 -32 84 -26 27 34 -23 -10 -29 -81 -31 18 9 5 -69 53 -43 -1 -107 0 58 25 -21 66 -6 -1 -23 -29 -81 127 34 -36 127 72 101 73 5 69 70 -33 1 32 -7 14 34 49 48 -2 -39 45 -65 -69 38 -47 -40 56 84 84 40 -73 77 -15 40 -36 75 -65 -78 46 57 45 104 -11 -56 -38 17 8 -65 77 -30 -102 -8 -31 -37 34 -13 -25 30 -11 52 21 -19 25 64 0 70 -15 -69 3 -25 -16 -115 43 -67 -39 -25 1 39 83 -21 26 -64 -10 -66 64 -61 -33 33 -60 -7 21 -2 33 -80 -7 -16 22 -127 -7 125 -44 -12 101 -8 -88 3 94 -44 48 89 -40 127 2 56 38 13 -3 19 65 -16 -127 -32 -85 -124 -21 36 13 39 34 -52 -70 101 29 -66 -128 -94 -13 -87 10 32 73 -77 96 -1 -29 33 2 7 -16 -104 32 2 55 22 -20 122 34 64 77 -67 19 31 6 101 1 119 113 5 -59 50 23 -37 -39 16 82 39 -40 -33 31 -6 68 113 8 -18 17 7 79 -122 -18 25 -18 27 -106 13 67 -52 -52 -25 -65 16 -37 41 18 3 -86 14 68 25 49 20 8 -67 -26 33 -65 -34 38 -4 -72 -35 29 5 -45 37 -21 25 -5 -76 -10 -35 58 -49 23 10 -31 -83 66 -35 38 -50 0 28 -117 -20 4 -66 1 20 -37 43 -32 -25 -11 -40 -7 -81 24 -32 -23 -102 10 -42 77 31 -6 25 -77 -9 27 32 -59 -91 51 -50 -63 -7 37 -55 21 78 -40 -17 83 -13 -36 -47 -56 66 -93 -4 123 31 51 14 -3 -29 -66 17 -94 80 -81 -24 -18 93 -77 -46 -12 90 45 108 -18 10 16 74 -40 -24 -1 46 -38 -3 -51 34 -10 -20 -57 22 34 112 37 -65 8 55 -83 -37 34 -36 -56 -28 -63 -9 -13 -34 -59 -10 8 1 26 11 -44 -51 -5 -56 -22 55 -9 1 4 115 -48 9 -6 -39 56 46 26 79 -34 38 -15 -36 53 -11 -45 -13 -15 -35 -43 55 -2 9 -4 -106 -13 -38 64 -125 6 51 -108 20 6 49 -20 18 17 37 -126 -27 3 53 -6 -10 58 11 35 -22 -26 -50 80 -36 -39 -2 -110 22 -67 73 -23 102 39 -46 -94 -53 -110 -23 -77 -92 2 -21 -69 -40 -28 20 -42 22 -11 38 -125 -78 -9 35 55 40 -59 -110 40 -12 -57 -29 32 96 -114 122 -16 91 41 -72 -37 25 -12 31 36 -11 -43 9 -75 15 61 56 -30 -13 -17 13 79 36 -29 -60 -7 46 -25 59 -28 -80 77 40 -127 39 -14 30 -20 -18 61 105 -62 12 15 30 111 46 30 -1 -7 29 -30 0 38 -43 -6 -110 -10 -24 -52 -15 2 -4 -8 -18 -31 18 -6 10 12 34 -4 -15 -22 33 -118 -27 -8 70 39 0 -92 7 52 38 -1 14 57 23 47 -19 9 -76 8 39 -39 -3 -2 -35 -87 52 44 20 -8 -29 10 -26 -81 4 15 -37 -44 85 52 3 51 44 21 -23 24 15 -33 124 -7 49 85 5 -42 8 75 80 43 28 67 39 1 -35 18 -10 71 23 -6 19 6 -25 32 -29 2 29 62 20 -11 47 33 -46 -63 70 11 17 -29 24 -11 -65 34 37 71 17 43 41 -6 34 -62 38 63 -41 59 35 70 29 -70 41 6 55 -19 20 -1 92 -4 72 58 -48 -14 -111 25 -87 37 -10 18 -31 -29 -24 35 -39 46 -27 36 45 59 24 80 96 -20 125 22 108 -53 8 -29 87 0 -74 39 28 75 32 -7 83 -35 127 23 37 -31 -63 -37 8 11 106 118 47 56 106 60 -126 -8 48 88 74 47 78 53 4 -50 -9 117 94 124 115 125 12 36 44 16 37 37 28 -103 -51 34 124 127 14 62 84 34 40 -27 -36 90 20 71 32 -47 -56 -43 33 -17 25 -44 52 1 127 78 -3 44 111 126 61 74 -29 48 -111 7 -63 -8 90 -1 -29 41 69 98 109 58 72 -87 -106 -57 51 -41 -43 -3 82 -25 -6 23 62 38 -85 -21 34 118 -64 -58 -11 8 45 72 -73 -14 -52 -36 106 36 -61 -42 -113 65 -23 79 123 75 -1 32 101 58 -17 -23 -65 12 12 41 127 -50 -17 -47 -66 58 -11 -20 13 43 97 106 -50 4 -72 31 63 77 -52 -90 42 47 -62 -54 90 -56 -3 75 -72 23 -39 -12 -55 -41 -56 -81 2 -25 27 -17 -90 56 18 54 42 59 9 -15 98 -7 5 -37 -90 20 -89 3 50 -37 35 -33 -72 -41 -66 42 -25 74 1 -10 -29 -124 35 -28 105 43 -81 -39 107 -118 -63 -7 18 4 55 -26 -69 -53 -67 124 -29 -16 -85 -36 72 -67 92 13 29 -46 -52 6 100 -32 42 93 -21 -88 26 -5 3 -35 -4 32 -23 -47 -17 3 -113 -18 -39 -5 -47 -62 69 -113 24 60 -16 20 50 34 31 -5 87 26 -7 -57 0 10 29 58 38 -75 -61 111 81 -50 114 -2 67 -125 24 20 24 46 43 -64 -44 50 9 -28 -97 79 -66 44 15 42 -88 -1 33 68 69 -55 7 -11 19 -52 91 -70 -80 51 16 29 14 28 -22 53 6 125 15 29 -16 3 -27 31 -32 12 -16 5 -11 65 3 77 -10 -39 41 28 -29 11 12 -23 20 -47 20 -43 -78 27 5 51 -20 -127 85 9 -40 34 24 -125 53 12 106 60 86 -5 -82 15 -117 -62 24 21 -63 -43 -6 74 -18 -18 4 122 -57 -49 -45 35 -76 47 -88 -4 13 -54 -124 -37 19 -51 37 -55 -2 -22 -5 -5 -58 65 -20 -51 -30 -20 -1 24 -30 5 -22 38 2 -69 26 -13 83 12 98 24 36 -8 20 33 -9 23 60 -43 50 -4 -39 -13 43 19 -52 24 81 -64 40 -126 45 94 21 -11 -89 -5 -7 25 76 39 -81 -112 4 -16 -69 -4 -8 -1 -66 -27 53 26 85 -32 -8 8 56 -72 -64 19 -125 1 -3 -30 -47 -60 -30 13 -8 40 -46 11 26 -57 -55 11 -32 24 -32 21 -14 -65 9 -74 0 9 -29 -48 -26 -26 -45 46 6 0 57 -18 50 -19 -18 32 46 -99 -89 37 19 -1 12 45 16 -9 -62 17 4 -37 -52 3 15 -13 -33 -47 -63 14 -69 58 -8 5 -41 127 -4 3 -39 -18 -8 4 32 -64 72 -30 -117 38 92 -42 -7 24 -28 8 16 9 120 21 -83 84 -11 18 -39 13 -38 -23 -76 46 22 41 16 74 -97 -64 52 -22 -76 4 -36 42 41 0 56 71 0 20 25 9 -29 -32 -33 -8 61 76 62 -37 80 -4 -18 -26 34 12 15 0 42 -53 23 -78 18 -59 13 13 22 -17 -85 20 48 -59 97 51 -53 10 -12 99 -44 30 -7 38 -14 -9 -58 -51 -31 68 18 -3 15 -14 53 -18 -59 3 -9 83 -9 30 -7 63 -26 -41 68 -14 74 4 80 69 -8 2 -14 114 -11 -28 -18 -4 -42 40 -16 -47 0 34 37 -6 -4 4 -16 14 46 11 6 -17 0 6 11 -1 -93 -15 20 -14 -7 59 66 -12 51 13 19 -66 42 -27 62 22 54 31 -4 -3 10 6 44 28 19 22 22 -15 1 62 -11 24 -3 0 -18 -11 2 -36 -35 36 -20 66 -26 14 47 44 -17 10 69 19 17 18 6 7 31 -34 33 -34 33 -7 -54 35 -2 -2 -43 -52 -11 -10 12 -31 -1 21 47 -20 35 -20 -25 9 26 15 35 8 65 -27 5 -18 99 1 -8 3 -26 29 43 106 34 72 21 -3 -25 45 43 19 63 50 58 -2 36 -35 9 -127 71 -121 -59 13 -43 90 26 -9 76 -53 -16 36 14 1 -38 -39 57 -19 -38 37 -39 7 20 -2 6 34 44 0 7 -28 40 5 -2 -1 -31 6 -50 -8 -49 -53 -33 -26 -19 -57 -55 -17 -102 36 -42 -26 -22 35 -21 29 35 -29 13 42 -15 49 25 -60 -74 34 39 45 -3 7 24 2 76 26 93 -21 60 -114 -31 -20 80 123 108 47 37 -91 -73 114 28 38 97 -44 -92 -83 124 -8 -66 -27 53 41 14 26 106 -33 13 -34 -16 8 15 -55 12 23 90 -25 72 62 2 67 -26 90 58 127 52 24 97 15 5 -10 -42 -82 -35 -15 73 51 -111 75 -124 -80 65 -11 116 33 -69 -112 -73 -127 -4 6 127 -61 126 121 -98 127 25 75 2 -29 -113 -30 13 0 -2 -81 127 14 51 37 56 -21 -28 -11 79 45 -23 46 -68 82 -110 2 -18 -42 -34 87 77 -22 -66 78 29 5 14 24 -59 6 11 11 -29 -26 12 -28 -20 -24 -26 -24 34 -12 -34 -38 3 9 25 46 -21 -33 13 4 -45 -104 -86 50 -14 6 33 -53 -12 78 61 -10 15 -39 2 -37 -69 55 -55 -28 -38 -50 -113 -41 -19 32 -64 36 -23 -31 64 55 -21 59 -41 -85 97 -95 38 -18 51 23 -16 21 -39 0 38 4 -55 51 33 -8 107 42 80 49 -19 57 -5 13 46 6 -16 27 1 -15 -10 3 54 -11 -93 28 -19 -22 21 -25 7 15 -50 -31 -45 7 94 11 55 -65 -10 -67 -5 40 15 -14 2 20 -28 29 51 -11 59 23 72 17 -38 -1 60 80 -17 28 14 21 -22 59 -18 -1 42 -7 2 73 4 -51 19 -10 -30 15 -32 -35 81 -73 20 37 34 -33 74 -3 2 -99 -98 42 87 23 -65 45 -74 7 -19 -54 22 -21 53 5 -91 28 -65 102 -8 -4 -73 11 -15 -62 -69 69 -46 63 16 -56 -31 -1 -8 25 97 74 -83 3 -37 -113 -72 -120 -29 -35 -102 -68 -28 25 -14 18 -9 -52 -108 75 86 20 -15 -64 -20 -8 -30 -27 -58 -3 14 -22 77 35 92 -9 45 45 -56 51 22 27 48 33 -6 -14 -31 -52 -126 -25 -7 -83 40 22 23 39 21 31 4 -37 10 18 43 6 -50 -10 14 6 18 -13 85 -16 -2 18 41 10 26 -56 85 32 -57 -23 19 8 26 -59 -17 13 30 75 -71 11 -29 -59 1 16 -42 -14 9 21 -3 23 -11 -19 -21 16 -27 -9 -21 -46 -34 -14 -19 -6 -4 5 -41 25 39 49 -33 25 -17 -22 -23 -47 23 -14 22 26 32 70 -17 30 -3 92 28 -43 11 63 8 -31 -53 -8 -53 6 68 13 61 49 4 69 3 21 15 34 44 -121 -37 -2 36 87 56 48 58 -44 39 91 73 15 46 86 52 26 -10 37 39 -36 -128 -103 49 49 -18 14 49 -4 21 76 -96 94 -25 -68 34 -77 -125 104 -79 14 4 41 35 -127 21 32 92 4 -28 -4 -26 -33 20 -21 -65 15 -93 -50 78 17 46 46 6 24 4 -66 -4 -15 -101 65 -61 -73 -108 16 114 14 -39 65 -13 9 -25 50 -28 -104 13 -24 66 10 106 -43 18 -57 -5 -12 77 60 92 31 44 31 -8 -26 8 -127 22 50 -23 -20 89 99 53 -1 46 -70 -6 56 -24 55 79 69 84 11 -6 24 93 76 22 23 33 -17 -13 -25 30 -113 95 121 -29 65 -68 -4 88 69 55 55 -20 122 33 -54 47 -1 -7 -127 -30 56 27 -69 -18 102 120 34 -30 34 20 125 20 -75 21 77 60 -27 -41 -16 25 26 27 10 124 68 -7 52 -53 -3 85 25 12 70 -99 -117 -7 -9 127 -64 14 4 84 120 -17 -26 -6 -25 -95 -34 45 -54 -116 -88 1 -10 3 8 -28 -30 -21 -12 -45 18 -45 -43 -6 4 41 -10 109 32 7 -20 -117 -49 7 -47 13 46 -96 53 -69 0 -76 45 73 44 -36 18 -50 -9 47 -20 16 -18 -28 -5 -10 -15 -97 42 -47 47 27 -17 30 36 -64 47 76 -13 9 -126 -9 85 11 70 1 104 9 67 -15 34 64 -12 32 -50 30 -23 70 -36 -29 50 -128 -49 29 -70 -31 28 0 38 9 28 -33 -123 -68 -8 -43 -124 -49 -94 -35 -2 43 -98 -8 28 37 -57 15 -76 -114 48 -94 -19 64 77 23 117 -95 75 -59 -44 21 -54 98 13 -59 -22 51 -91 -8 48 -6 -46 31 -3 -12 -52 105 38 -88 24 -55 45 -72 -37 5 61 -70 -95 -31 85 39 -20 1 -45 75 -14 -50 -26 51 -46 110 16 71 -41 4 -4 -11 -42 -31 17 -43 -24 -24 24 6 95 89 28 53 -127 49 -8 -2 125 26 -13 8 -105 44 59 38 -35 -7 98 -13 17 79 38 -59 42 38 16 -33 59 66 -15 -65 38 -24 -123 -36 30 65 -57 81 29 123 124 44 7 0 96 -70 51 49 91 92 -34 -42 -1 70 82 69 -22 45 58 73 44 -114 29 85 73 108 16 66 -44 70 -54 3 -42 45 -50 66 60 -7 27 57 -102 10 13 88 100 -56 -1 -106 -67 23 49 53 -59 20 69 110 -4 -20 106 -29 21 -23 1 -13 1 -22 -5 -31 -55 -60 -128 -63 49 -49 -108 -28 -11 61 50 -24 2 -32 -105 -14 5 23 45 1 -43 -22 -57 43 -7 -43 -118 29 22 35 11 -19 -14 -76 8 -45 47 15 -66 51 -56 -21 -44 79 -10 -118 -14 16 -92 70 -6 5 17 89 63 26 79 -84 0 -93 19 7 -102 -76 2 27 -21 61 24 45 72 100 42 8 -61 -40 -35 -113 -32 46 -20 -34 57 -71 57 -1 0 -51 -121 -64 -21 -74 26 8 25 -84 -32 -50 -16 3 18 31 -110 2 57 25 16 25 31 14 -67 -91 9 -9 -6 3 64 -81 69 -69 79 34 -42 -2 -111 -56 8 -14 77 17 -8 -87 -2 31 2 -51 98 112 -11 48 -15 13 -7 -5 2 -72 -73 -78 1 -29 22 1 -89 0 -39 49 68 62 -25 -24 30 60 45 45 36 53 -89 54 -18 38 -11 -26 11 12 62 -127 -106 6 -35 -81 13 12 57 -49 24 -2 12 12 -31 -45 54 -15 -41 33 -127 98 58 49 35 -63 -124 36 -47 -63 -25 -127 -22 -14 22 15 -116 -22 37 -37 58 45 -42 34 124 -62 2 3 20 -27 -26 -8 13 -44 -114 58 -24 -43 56 -125 -128 55 34 -25 -34 14 -21 33 -126 -15 6 42 5 9 -69 -10 -85 15 77 -38 -24 58 -108 -46 5 5 17 -73 5 -39 45 0 36 -72 -22 -68 -33 -50 11 -107 -99 62 9 21 -5 -36 15 21 -6 99 -49 -15 15 2 20 127 -44 -55 -47 33 -73 4 11 -6 -28 27 -26 58 -50 44 -24 -42 -64 -5 -10 90 73 -94 7 -37 26 -36 54 -26 -3 32 -13 -16 -55 -13 -39 -23 37 -40 15 -25 -8 -66 10 38 67 -3 24 38 81 1 -57 33 -44 83 -16 65 40 47 29 110 69 51 4 45 12 -26 -24 24 -57 34 22 -54 10 4 -11 10 76 -26 53 45 10 123 0 -31 114 25 -4 77 56 -22 14 -38 -10 -12 -37 92 125 -118 94 -39 79 -11 -32 -56 -9 -37 -2 18 31 41 -30 49 89 36 1 74 -51 6 24 18 30 -57 58 -10 -13 35 -60 -45 43 60 20 -12 37 -14 -83 123 59 -57 -26 101 -43 69 12 -37 10 -15 7 127 27 110 2 -23 -41 -63 -30 -128 -38 -34 -38 3 -25 -39 96 -127 83 -72 97 -91 78 -49 -19 45 -128 51 70 -22 50 -10 33 73 -29 -18 -38 -14 -57 28 -10 19 65 43 64 -8 -37 1 -92 96 -19 69 -38 126 93 -2 47 -99 63 71 25 -29 6 -22 -28 61 -12 13 -47 9 -4 -8 -71 -10 2 -17 65 32 -48 -28 37 47 -8 -81 96 -125 18 44 64 -10 24 -20 2 -12 32 26 38 -12 83 64 -26 42 21 7 -61 106 15 -45 51 -35 80 -3 19 15 -9 -40 -10 24 19 23 -39 9 -7 53 -56 -12 -56 47 -8 -47 -59 -79 30 -10 -22 -61 25 8 -3 -9 -24 18 27 -8 9 -9 24 38 25 5 -12 2 26 12 27 -45 36 33 57 25 -72 -16 -40 6 28 44 -56 10 59 -60 19 -30 81 -8 -37 1 -3 -58 -1 -55 4 -23 65 28 0 -22 -44 76 27 54 68 -125 10 -22 2 10 -16 -1 7 -34 1 -10 -60 -18 79 67 -43 -18 -12 -51 1 20 25 -91 -48 -9 -26 -44 -77 64 -28 -17 -19 -63 -29 40 -35 -6 -29 79 -4 -16 -22 61 -37 -57 24 -29 -59 -3 56 56 -121 -7 -34 127 28 11 -23 18 -46 -66 127 -79 -44 -10 77 -37 73 -39 51 -16 -64 -38 -77 46 16 -69 -23 48 26 -49 50 -2 21 50 127 24 -3 127 36 18 3 -47 22 -47 2 -70 1 -103 28 -73 57 7 -22 28 26 4 0 -17 61 -69 -14 39 -121 29 -52 -1 -124 -41 -43 -2 -9 -25 62 -56 -17 7 127 -21 35 28 -47 75 -30 107 -66 11 -1 -25 91 -89 119 -25 100 47 -69 6 23 7 13 -71 -30 -68 -101 -57 74 -55 32 -100 29 40 59 28 -120 -13 -45 -23 -69 49 77 -45 -76 -19 126 86 91 56 -20 5 72 -63 30 10 44 109 -12 -35 41 -17 -47 -101 -10 124 -24 18 -21 -99 -31 -43 10 125 91 44 7 -83 -47 16 -10 -42 -20 33 50 -60 -42 -126 121 -53 -83 -56 -9 -85 -3 16 -4 25 61 -88 80 58 -17 27 -3 -99 -37 -25 -70 -11 59 3 -90 87 42 36 2 -50 2 55 -4 59 -43 -15 120 -4 -32 46 8 21 -31 -12 -2 82 2 -65 -55 -46 127 32 -28 27 92 -123 53 70 70 -54 -81 -121 19 -14 36 44 -67 -35 15 53 24 42 10 -9 -41 -63 52 -22 23 -88 7 2 40 111 -38 68 -22 55 72 49 -83 -78 111 -20 40 -69 -101 -14 -6 -53 -43 -89 -16 -16 98 -55 43 -37 2 13 -29 -24 -28 -8 -63 -20 -60 30 -41 20 -28 30 -47 -19 -128 12 -106 -29 1 -8 11 -40 -23 -10 -3 42 -5 -46 -7 69 -10 107 -75 13 58 110 -78 -34 21 33 -75 -47 16 53 0 23 106 -55 -17 -77 -7 -63 -65 28 -11 -59 4 7 67 -34 36 97 14 52 -58 -3 55 -16 -39 -125 3 -21 -26 32 47 0 50 -128 28 -14 75 -96 -10 2 -53 54 -38 51 -109 -62 72 20 -17 23 -37 58 12 -60 15 -2 72 40 52 69 96 -41 68 -41 -114 -37 42 29 64 -37 32 -18 37 68 -49 58 38 -87 91 44 34 -55 27 -59 11 -20 42 51 65 -12 112 54 83 32 60 53 -25 36 -47 59 -12 50 52 -26 11 52 89 42 66 9 14 98 -17 20 -17 -2 5 12 122 50 -32 67 -30 -5 -15 67 50 9 13 33 96 127 122 -6 19 -40 19 84 62 42 81 -29 63 -34 -96 53 59 -4 -13 42 -24 -4 47 -27 -21 32 11 -11 -28 -24 -7 0 -23 -67 17 41 -7 -6 -25 52 -14 -7 4 -7 -31 -56 9 -40 63 -27 44 17 -39 16 25 -19 -46 -14 5 44 62 58 -12 -37 18 -2 26 4 6 52 31 -27 24 -31 11 8 0 99 46 0 -22 -4 22 26 -11 6 49 59 17 0 62 -44 -10 5 -14 50 9 47 -25 40 0 -23 64 2 -9 17 10 -31 -47 -36 -63 32 -11 -19 5 8 0 -72 45 65 -52 -45 -43 -33 -60 -83 41 -17 9 99 7 -30 -27 74 111 -39 25 44 -35 2 10 -2 -18 22 97 17 -25 19 -53 60 9 79 58 18 47 58 -47 -23 -29 8 5 -29 55 38 63 3 -62 5 27 -49 4 35 -34 18 -14 2 11 -127 21 99 52 -44 -103 2 -85 -67 16 0 -37 -49 -21 54 -61 -53 92 -10 -38 22 19 4 72 64 -43 50 -106 -62 -74 35 105 -11 23 8 -87 -32 -114 -85 -45 -46 12 116 -122 38 -72 22 -60 -37 7 25 -70 -128 -26 47 -128 14 -3 -102 -121 -1 -113 -26 27 -97 -67 -36 -25 -76 -9 40 -25 9 -57 -65 -127 -65 -123 59 -115 16 18 -44 90 21 25 4 -85 -128 17 -30 -68 -118 -16 -71 -105 127 -43 18 93 52 -72 -61 35 -4 74 -24 35 -54 3 -123 44 -11 -53 105 1 6 -26 -78 -17 -95 91 -56 -13 -65 -54 -70 -9 56 37 89 -41 -57 1 39 -10 36 28 46 57 17 -128 4 -87 -11 45 39 -52 57 -8 8 119 15 47 11 20 29 -49 -81 30 -88 58 3 38 -29 -8 -55 -24 4 20 -27 -2 0 37 -35 25 -23 -47 26 -14 32 24 23 56 29 37 -2 80 -11 44 32 -104 -52 -20 64 -34 123 -98 69 6 2 4 16 -16 -3 -33 42 92 18 -63 14 36 -75 34 31 21 42 -67 -5 -32 80 39 -15 16 22 127 -13 77 125 -64 83 -6 42 -30 34 -17 -72 93 -15 87 10 -10 -3 14 21 47 -1 33 2 -11 91 -44 30 58 32 20 76 -29 -47 21 10 21 54 79 40 -31 -58 -66 35 4 -11 125 -30 -45 -114 124 -30 -16 35 -7 24 -19 73 1 -57 72 31 -53 62 59 -32 -56 -110 -43 -27 36 68 3 -36 27 -8 -53 55 33 -25 -83 50 51 -32 -66 2 -25 65 14 35 -29 20 -19 -36 -124 2 -37 -28 44 38 -127 37 79 126 50 -2 92 70 17 -93 -17 -24 70 15 44 41 -70 -119 -13 83 -128 97 126 1 -24 -116 -122 -92 -24 46 27 50 88 39 127 36 124 -24 122 42 105 68 108 -33 69 23 -11 -89 -124 55 6 48 -47 64 -15 28 26 -3 19 -43 105 -74 19 -28 -66 123 -93 -65 -119 15 -60 13 -27 -1 -43 121 41 -127 39 -110 -124 105 -101 -76 -24 8 -10 43 3 -126 12 20 42 -72 -23 -6 -29 -38 21 57 -22 -98 -114 1 66 32 -45 38 45 63 73 8 -36 -24 31 -73 -4 110 -22 -10 -77 36 -30 -19 13 -82 -67 55 90 55 -18 -73 24 -47 2 -6 -34 15 -2 -59 -13 -7 -125 30 -76 3 29 124 -30 6 91 -49 24 -65 59 57 30 -115 19 -90 -3 116 -50 -37 125 81 26 -67 92 -15 2 76 6 -10 -17 19 -55 -66 32 -72 -31 -28 -76 61 28 90 -86 -12 32 -60 -11 -100 -30 -56 -72 -50 28 26 -9 -13 -128 14 -72 52 -41 7 22 -28 42 -112 55 69 33 -41 18 56 34 120 91 6 -39 124 -29 -42 7 46 43 -17 11 66 36 -22 22 -48 17 -61 -5 -25 56 6 -68 -40 48 -27 -120 54 30 -47 -126 62 109 -15 -36 87 -4 31 -49 70 -27 -41 -80 54 65 11 21 -88 -22 123 44 -63 -127 28 37 -30 22 41 -80 11 -25 -66 2 25 -45 -12 -85 -12 -70 62 -54 -28 -31 2 37 -67 -58 -77 -39 -74 -49 -30 8 -58 -40 6 -79 -54 -77 -19 51 -26 -25 -40 -126 -25 -81 -68 31 5 15 -23 -72 -29 -15 -112 -38 4 -76 -87 -70 -4 -127 -95 9 -57 25 -16 -74 78 -22 -31 17 4 8 95 -68 -60 14 25 17 -61 17 -44 43 -3 -109 -57 -28 29 -1 -10 45 0 -80 -44 -24 -126 -17 -26 -101 -8 10 31 -18 -50 -7 -10 55 -2 1 -20 23 5 -32 -45 -34 -2 6 -22 43 65 -4 -27 33 15 -3 23 -37 31 0 11 2 -1 -15 -37 17 17 -19 -3 -60 -40 -19 1 16 -7 2 -50 64 -23 2 5 -8 -86 -38 -22 -12 -5 19 -58 2 -7 -7 70 18 -41 -18 -6 -27 49 26 -39 -87 -15 -23 -7 -10 -46 -23 -40 -16 -4 3 -7 16 -11 -16 43 70 26 25 -4 -28 -23 39 -51 47 -10 -11 -25 -35 -49 2 10 -44 51 -35 -52 5 -8 33 -86 -42 36 -31 48 50 -4 20 -52 -22 -24 -52 -126 15 -2 -38 -27 28 -32 -39 22 1 -31 -64 -73 -3 13 48 28 -10 -21 -16 -1 -27 -14 -47 -79 -13 -45 32 -61 80 25 14 10 21 46 9 37 125 0 44 15 -40 22 4 -58 -1 18 25 -22 -22 18 15 1 10 35 5 -17 -20 -43 21 7 4 10 -92 51 -31 62 -47 1 -26 -20 32 -6 -19 -3 -64 74 29 -126 53 -20 -64 64 -10 1 95 28 -5 115 13 -13 -39 -28 -45 87 -30 33 -24 75 102 -11 -14 -19 -12 49 126 -15 60 -116 -28 62 19 40 -40 -3 49 -19 -55 -4 79 -46 -36 55 -53 -92 34 16 55 23 -83 33 17 79 29 -70 -13 -62 -52 20 -67 -4 2 -2 40 64 -18 106 -76 -61 -80 -114 22 25 83 -84 -74 10 -89 -61 -94 126 76 66 78 28 -12 -33 120 102 -120 -48 38 57 -71 66 -26 -60 47 9 1 -5 -28 52 5 -70 42 -9 -9 -17 -50 -7 -10 32 15 -97 39 7 12 49 68 -14 -38 -36 -19 53 31 -63 22 -1 -7 -64 -6 20 -33 -16 42 45 62 -25 10 47 -21 25 -36 -68 44 -38 19 75 41 38 -23 24 -11 86 81 36 -73 22 -2 -60 -55 -6 9 -34 -7 -9 -57 35 -11 63 27 89 -61 67 56 87 1 -18 107 38 102 45 0 45 8 27 -19 -50 58 47 -17 36 46 -45 -18 -42 74 -46 -74 60 -52 -33 -57 -21 26 50 -46 8 -30 10 23 -13 -42 -114 8 51 -6 3 50 3 15 -44 -113 46 25 9 26 -32 31 47 2 3 -41 81 -9 26 25 -39 35 -8 -15 4 -18 -11 -16 -13 -43 -3 55 7 28 -44 -56 2 -14 26 -60 -5 -31 -34 86 -81 86 9 -27 35 24 -40 19 -2 34 -10 -58 -54 25 30 -80 12 -74 11 32 -40 91 32 -63 88 9 117 11 22 45 -9 -81 68 -26 1 15 -11 127 10 61 65 -39 31 -2 -71 28 68 -6 -10 -45 -24 -47 127 117 -94 10 -39 67 52 23 79 -12 126 72 50 35 33 39 33 122 127 -7 -125 59 4 -125 35 49 21 30 -44 -37 70 -87 -35 -84 18 33 71 115 -64 122 -11 17 60 -19 94 -6 -88 -21 -53 -52 61 -40 -36 79 97 33 30 31 -111 -10 48 -128 -126 -2 -26 41 68 29 -12 9 68 -5 -63 86 28 -22 -35 127 -27 -17 -28 5 15 92 -50 52 48 -39 12 -52 -63 -7 16 -52 -15 54 100 -68 -59 59 18 98 -5 -81 -26 -16 -14 47 -71 45 86 34 -52 53 -34 -23 58 -23 112 -38 5 1 -68 -78 -56 -17 41 -26 -16 -50 -21 -50 72 33 47 -32 -61 80 -8 30 19 -67 -41 -86 -78 -65 -118 39 69 -36 63 -83 31 38 -54 -14 -72 -118 -46 -31 -10 85 28 -75 23 12 -9 113 -45 -37 -66 -10 23 -3 -64 52 -32 -23 56 -77 51 -38 -24 27 -26 -58 40 -56 -54 16 3 17 -110 -106 -28 50 -66 89 2 127 -41 -10 65 15 -8 -87 -106 54 13 -35 -19 0 -18 -15 -21 25 5 -56 59 -15 -50 16 -24 24 7 -59 115 59 -61 -64 -72 18 16 -1 98 -4 122 -38 -63 30 -71 15 68 -83 122 -27 21 93 -28 -128 -8 16 -16 14 30 -24 -77 -45 -122 -40 -40 35 -70 9 80 -52 14 120 97 -23 78 -61 8 -42 -13 1 20 38 -56 -8 36 23 -94 -16 43 -104 95 14 2 7 55 69 -15 84 -5 53 45 47 -14 -57 50 -63 -70 -51 59 -12 -28 124 42 8 -66 60 -28 -91 25 -5 45 -50 -28 6 -98 -48 -30 -114 43 -20 17 -124 -75 48 16 44 -74 -59 28 89 16 -5 -100 83 -18 0 106 6 20 32 87 6 -47 78 42 -98 -50 2 -12 9 -27 64 -96 82 68 -35 58 30 99 -50 -80 23 42 -47 20 28 -41 76 -6 25 53 -56 67 -36 44 13 -38 -38 -11 19 -30 -64 4 97 -37 79 -16 0 -45 0 -11 -104 126 -14 26 -127 25 -88 -32 39 21 9 16 -42 71 69 65 34 -10 44 1 63 -26 -7 4 -75 37 -36 86 -3 -1 31 -32 -12 -33 -93 -45 23 10 -5 1 -22 -126 -19 -22 15 16 -20 -25 -54 -20 -1 84 -16 127 -18 39 -10 24 45 25 2 52 72 53 -23 10 -20 1 113 46 26 -8 8 -21 40 -75 -34 -56 34 -22 84 22 -50 63 30 -58 -67 11 -44 14 -29 58 -30 -68 6 8 76 49 -29 0 11 19 -22 -22 31 -22 -15 -46 83 -13 -6 70 -3 103 19 48 36 -69 37 124 -4 2 56 -61 27 -71 -11 -18 -1 57 -23 -82 -14 -40 -36 26 11 -118 -66 63 12 55 -9 28 23 28 -46 83 26 -36 72 -67 -17 114 -37 53 -53 -2 -27 42 62 -31 -20 3 4 44 59 84 67 23 -4 77 -58 13 93 90 60 40 2 -24 -13 47 119 20 -51 2 -38 13 -27 96 22 -15 19 22 90 -8 67 -14 64 -13 107 97 95 38 65 -13 45 64 71 31 -128 21 -26 -36 12 22 -26 -19 22 -6 36 54 13 -52 55 10 12 -7 100 -57 -8 102 25 37 -47 119 97 54 29 62 74 -9 103 30 38 42 -125 -60 39 -27 21 -28 -31 -45 73 123 4 -57 -52 9 0 -59 29 -85 48 66 2 17 -5 59 -29 51 29 -35 50 -18 -11 40 9 -41 49 -8 12 -56 -13 11 75 -28 8 -51 -75 -43 -14 -48 -9 -1 -39 40 -28 22 -9 118 37 -68 -82 -77 48 -9 20 127 29 -27 12 76 -79 -48 -8 -24 -36 54 -20 -4 -11 58 12 -46 20 22 -25 59 -8 5 77 18 -90 -8 3 42 -51 20 15 -39 57 -79 -86 -46 -82 -29 13 3 -4 -23 -90 -69 -15 -54 -70 73 117 55 -9 29 -55 -26 82 30 3 56 -61 -124 -61 -3 -116 -6 49 -51 -21 -16 -35 13 -37 0 36 -39 -61 -57 24 -48 -35 4 47 -15 -115 116 14 -2 -54 -25 -35 -2 40 3 19 -51 -36 -63 20 -124 -47 -71 116 76 31 7 10 23 -55 -22 -48 67 -13 52 -45 104 9 11 35 18 8 75 95 2 -10 14 17 33 -64 -42 93 -67 39 -54 -15 101 -14 -118 44 91 -15 9 54 6 -128 81 -104 74 -3 -47 -19 -2 -27 -17 40 -26 -27 9 16 50 -17 33 -20 -1 86 -113 -63 -15 -123 -109 -51 46 62 121 -36 -56 11 -26 25 -1 -23 -109 57 61 28 -76 -16 -15 17 65 -2 -15 57 15 -5 61 -39 74 -67 -3 64 -24 12 -48 17 39 127 74 83 -23 120 12 21 61 31 124 -15 126 -105 25 115 32 0 14 -28 36 -30 71 -39 4 11 51 -42 8 24 16 -24 -62 95 117 23 2 -13 70 -23 -46 -11 -68 -9 8 -40 -24 -55 -54 25 -87 -9 -44 -55 55 33 -44 54 -49 39 -3 -45 -18 0 32 -47 -4 -28 16 -85 -43 31 16 -38 50 -60 110 -13 48 6 -62 15 -45 60 -50 -102 -46 -90 -61 -59 -1 56 28 58 -32 76 -7 40 -7 101 -13 -62 -44 63 -109 69 -2 -7 -41 102 76 23 -22 24 31 7 97 113 -30 -28 -3 54 61 74 94 -50 -18 -1 -6 105 -119 -55 -14 -47 -17 19 -96 -65 -85 -56 -8 15 -32 -21 -19 -63 84 -28 3 1 97 -124 114 -13 -23 -46 6 63 8 55 99 -48 61 39 9 -45 105 3 -8 -18 26 16 -86 -12 9 -59 123 1 122 22 -4 -54 13 4 -59 -88 15 11 1 83 -12 -24 -46 7 9 55 83 -12 -82 90 25 32 37 44 -24 17 8 -60 55 11 -6 -7 43 -30 -84 8 74 100 33 -13 65 46 102 126 -40 -65 47 -21 68 -38 113 12 -1 -13 15 3 17 23 96 98 -35 44 -13 -62 -2 84 -127 -13 57 -26 38 57 -2 78 0 1 39 -79 -39 -57 -59 -6 -15 127 6 32 -12 35 -63 -21 46 5 20 3 121 -116 -34 -115 41 -10 125 38 65 -1 42 -26 -13 38 43 -6 -48 125 16 -19 13 4 23 -2 49 16 85 64 -46 41 127 -3 -23 -56 -127 14 6 -30 38 94 40 66 40 38 73 4 -6 -23 30 19 44 9 4 96 66 -30 73 -3 -5 11 44 49 17 74 74 -11 59 -11 31 23 24 -73 21 -55 50 22 -4 14 85 6 126 66 5 -37 -67 -65 24 35 -46 -26 16 95 -18 -75 -64 5 -19 8 -65 -87 27 48 57 -24 87 14 37 -3 18 22 48 -42 -10 -38 -49 71 -67 53 60 5 -49 -93 90 -21 -1 -6 -13 -29 -37 -2 -105 -6 -66 70 4 -35 112 60 67 31 -30 47 3 -98 40 21 27 64 -30 47 21 -127 -60 18 127 51 13 -6 10 49 -19 -3 -53 -91 -22 -35 -39 -84 -17 60 -127 1 44 -91 72 -52 -13 -126 1 5 -52 102 39 -37 23 -12 -2 -35 4 26 39 32 -5 -2 -1 -2 3 -88 38 12 -74 -8 12 -62 -125 41 35 68 20 -8 -50 49 -1 16 5 -20 -89 46 -18 -58 41 -56 -15 45 62 29 29 -105 24 36 -23 25 -111 48 92 -32 -10 0 7 -8 -56 119 21 40 -124 -23 81 -9 -126 -58 40 -22 28 27 22 -127 19 -13 -14 32 90 -65 -107 66 -73 18 -50 35 -76 -41 -40 26 -79 -38 49 -30 -12 38 -43 -98 15 91 -109 85 -11 67 -43 -20 -54 36 114 125 45 -92 -72 32 66 -58 2 -61 -40 15 12 -60 76 -66 -32 -65 -70 -29 31 -60 60 -15 -66 -45 64 -126 -45 -3 52 55 -19 67 -126 -115 -25 -115 5 25 12 33 127 4 -3 -14 25 16 5 -43 59 -36 -88 66 -41 -35 -4 -20 -58 -37 65 55 124 10 127 46 -58 -48 -8 29 60 41 -46 -3 9 32 -26 -46 -70 -53 -57 126 -32 -47 111 70 76 -22 -84 -15 76 -2 29 36 -69 -78 -44 -3 30 33 0 68 6 -37 27 5 -4 127 0 -40 5 -18 81 4 19 29 -76 65 -23 -31 -19 -27 -68 61 -29 -39 9 19 50 0 11 -24 68 -53 -3 89 58 62 -33 17 37 -126 -6 72 -35 -34 -73 -59 124 18 -83 -37 9 38 -104 127 25 -58 52 5 -54 17 80 -10 -5 -42 19 66 61 27 -5 10 25 -12 57 21 87 5 -14 92 -97 -30 15 -16 -128 0 -27 -18 0 -38 55 127 -75 -9 15 9 127 -118 -48 -15 -56 -10 -76 58 -56 42 -18 -29 -35 45 -117 8 -37 -23 -128 -54 7 -127 63 -100 108 -49 5 -73 -68 -35 64 16 91 72 52 -12 40 -66 -56 -34 -70 -55 33 -11 -1 127 -6 -80 91 -35 11 20 72 58 15 26 -70 30 -10 -116 -128 -113 14 33 -4 91 -59 -67 -123 -39 -48 -125 -108 -127 10 -74 -98 -126 17 -8 -15 -104 -85 20 39 91 17 71 -93 -25 -97 59 74 81 -57 74 101 -114 40 -98 -49 73 21 24 -107 -76 -33 -12 55 -75 86 -56 -43 -65 -50 36 -63 -43 -20 16 -71 -125 68 -15 -11 41 -41 -91 55 -47 -56 63 -21 -106 -31 -31 25 -54 -53 -100 39 76 10 -82 -31 -34 31 21 -14 26 -32 -40 1 -9 28 62 41 40 3 -95 -11 -57 -33 35 -90 -3 19 58 -128 69 -32 38 -30 -52 46 13 37 56 -12 50 -59 28 26 -55 9 -67 -66 -69 -52 -66 -68 32 -50 -89 -64 2 -13 -45 124 -9 -35 34 -9 40 91 -8 -4 -1 59 35 -33 -10 37 -97 24 47 -41 66 47 -14 -59 13 59 -18 -19 -52 8 -5 -17 4 -39 -40 -26 -46 -13 -79 31 41 30 41 -32 -6 26 71 -8 -40 -27 -47 54 -55 11 -26 16 33 -49 -7 -33 -1 -46 30 -40 -109 -21 -70 15 -59 -31 60 14 127 21 108 -35 18 -5 0 -11 23 -41 -49 2 12 4 9 43 103 -28 -41 -12 79 -10 -55 -21 -61 35 7 -5 53 11 -3 -127 33 21 31 -17 -10 58 54 12 -6 19 46 0 -1 -48 28 -89 -24 23 105 14 -12 -14 -18 -69 -31 -80 19 -114 -50 67 -53 53 33 -49 70 -92 -42 44 22 50 48 32 36 -32 40 47 -69 -43 -29 18 -5 -2 -46 -3 -17 -86 -25 9 68 -80 -44 -5 33 -2 -96 -33 2 13 -71 -46 -15 -39 47 35 -99 70 15 18 -37 -16 -76 -14 -86 16 -48 51 1 -14 -14 -79 -78 30 -15 2 -5 52 -63 -93 12 22 -105 -32 -88 -25 72 -45 -85 -119 -19 -119 1 1 61 26 20 -50 50 -11 52 61 -11 -92 43 30 54 19 33 -17 -94 1 55 40 -9 6 -63 -44 37 29 -47 24 10 -75 66 -29 -15 101 42 -82 -18 7 42 4 -66 -55 53 -13 -59 69 -34 -49 1 -46 -46 83 39 17 7 -7 61 65 38 88 19 120 43 -72 16 -40 -5 -32 19 123 33 13 -21 -16 -36 35 -17 -1 -1 41 -58 -39 58 -61 32 13 -32 12 -13 26 21 47 41 -30 8 18 22 18 37 -40 56 -9 -128 127 -6 -8 -6 -12 -51 37 35 -5 47 23 83 -72 -62 49 5 8 -40 -20 -75 35 21 -100 -102 -2 46 -93 -54 -94 -38 -128 1 -21 -126 77 -57 18 -28 -24 -23 -2 43 106 -28 -25 -6 19 11 -19 48 20 -9 23 -44 16 -110 -18 44 32 -6 27 60 8 -38 41 33 -24 127 -47 2 -4 68 -52 3 27 79 21 7 12 -27 41 19 -6 -1 -12 -87 -4 -37 63 -30 -125 12 -8 -26 -97 98 -5 61 4 -31 23 -3 4 -57 30 5 127 45 -68 -21 42 -3 -84 76 24 33 67 73 82 58 23 -76 -63 52 42 89 64 117 18 23 -48 47 61 -5 19 28 88 35 30 23 50 10 42 81 58 -27 30 -14 41 121 80 4 26 -86 47 -68 -71 -19 6 56 -19 -46 -4 95 9 8 23 -11 19 1 42 86 102 -50 1 49 -22 29 26 42 -2 82 45 11 -8 39 -14 7 -53 -77 0 -53 127 -72 14 -66 -30 28 60 -8 -31 -75 -19 -38 30 -46 -11 11 -56 35 -14 -36 9 -99 -45 21 14 -49 -47 -117 11 3 101 41 29 -55 80 -11 -15 18 25 11 48 9 -96 35 46 -57 -28 -35 99 18 61 67 -38 53 127 2 -22 52 100 10 -10 25 77 41 50 52 -52 43 8 -95 -15 -64 57 -84 -35 24 -6 -14 -34 -22 -22 7 12 -49 -17 61 8 -16 19 -15 -19 14 80 7 -47 14 49 -33 9 38 43 -19 23 23 2 64 -64 -5 -54 127 35 -90 13 -15 -21 1 -18 -45 24 44 56 -5 16 -89 -14 -4 90 -27 35 24 -2 75 92 41 -45 115 -74 -28 18 7 -97 -48 28 9 -32 -7 38 30 5 -6 4 -48 41 23 14 -5 -49 -14 -6 13 -13 22 12 34 -50 -61 33 33 -5 8 6 42 -35 2 -10 68 24 82 3 12 -55 -59 -44 73 56 -17 10 106 -38 -20 -11 -45 -62 -22 13 -8 40 -83 114 1 3 13 -37 -43 59 37 79 10 -11 -9 -21 104 49 117 -37 -72 -12 -53 -8 45 25 -17 -25 47 -72 -22 -21 -45 26 -128 6 -49 -72 -49 47 56 62 6 -26 62 113 -6 44 -53 15 -69 -82 -34 -99 -23 -68 -41 -128 68 106 -116 -19 -22 -94 35 6 -24 -50 82 -14 31 -66 5 -76 -75 115 21 75 98 -47 31 13 30 -16 -13 -13 9 41 -90 73 13 -4 35 4 14 76 17 27 3 64 17 61 -58 -34 18 -18 62 38 61 95 -31 13 66 1 -14 -49 6 -33 14 -103 46 -3 -68 -57 43 27 18 4 -37 2 8 33 -5 38 11 51 10 21 -102 30 53 8 38 2 45 -94 88 4 8 -24 13 121 -2 9 -30 120 -36 89 22 -41 27 18 -83 -26 -70 55 62 -4 -12 46 28 -35 48 -29 34 99 -13 78 -67 126 23 79 -31 -76 -60 99 85 54 31 117 -26 -10 38 123 -55 5 65 -10 69 21 126 -11 -32 -31 -65 -19 -66 48 89 -22 -31 66 4 33 8 -1 -91 55 -59 -53 -14 68 54 51 -94 44 -51 10 19 65 48 -26 -42 48 -116 -55 41 -72 -90 -12 19 -26 -23 -74 20 -51 97 88 51 -2 -23 -111 4 -55 47 -53 36 -35 -37 115 2 -20 40 -67 4 -26 92 -22 85 42 15 -28 -91 56 -7 0 -8 -21 44 45 -4 -35 -28 52 86 -31 -40 -4 53 -109 25 5 27 -30 21 -38 34 38 -36 -69 -80 13 75 -70 -11 31 -27 35 -30 -25 -20 -93 -40 64 37 81 -2 63 121 -8 127 -74 -15 -17 25 -28 -24 -44 50 8 3 72 106 18 -6 -43 -24 -71 30 -29 -42 25 -61 -6 -36 60 123 29 70 7 70 -81 20 -24 -38 -92 -22 9 -59 26 94 -32 -3 -44 3 -81 -40 -99 -30 -73 -84 -35 50 47 52 -28 60 -33 0 -24 -27 -23 48 -52 5 25 -25 -59 -83 -21 17 -42 -11 -16 32 -1 -24 32 71 -38 125 -9 -5 -44 -34 84 -24 -20 -32 -51 -16 -30 6 -13 -22 -105 100 -82 127 -43 54 -30 32 13 -75 -23 33 -55 14 -16 15 11 41 72 -97 124 9 18 -40 21 -95 -14 48 -17 21 -43 -39 11 -47 50 -35 9 -13 -31 -45 19 57 60 -67 31 122 2 -69 -18 59 49 -5 0 -2 -35 13 -12 -24 -40 64 47 30 17 -47 72 -5 -34 33 10 -36 48 72 56 12 -59 -54 -19 7 -87 -114 -9 -35 -18 -46 50 -82 -18 99 -17 8 -66 1 -84 37 6 -39 87 -36 -41 -18 -18 18 -9 -20 -16 -33 62 -28 -23 -4 39 19 -4 10 -32 5 8 -46 -4 29 -7 0 -88 55 111 -18 -50 20 36 -11 -7 65 -5 3 -73 -87 37 -41 65 87 35 7 -29 64 -16 63 -25 -8 -16 59 -73 -40 13 -26 57 -73 -68 85 24 83 9 110 75 -66 37 -34 17 -25 16 121 6 66 53 -82 -60 24 -22 -56 44 -75 -44 103 8 41 -19 -14 107 31 -59 21 116 60 8 106 4 89 -50 -8 104 -19 26 -44 25 85 55 -88 61 -121 -93 70 73 102 10 -19 80 43 -2 120 -23 -54 127 62 -28 11 79 -34 -56 101 22 10 -24 -120 11 102 71 9 36 -43 -24 16 27 8 13 20 46 70 -77 -34 -86 15 11 -56 55 13 45 4 55 -55 -8 -21 -26 51 -16 95 -36 -13 -91 29 -10 50 -27 21 45 -82 23 -38 76 17 5 47 86 18 53 31 21 -51 63 -50 14 6 57 11 11 7 17 -72 7 -59 -2 47 -61 -71 52 -64 -85 44 -11 27 51 -108 -40 43 16 42 50 48 85 39 -20 -1 53 17 -23 -40 87 -3 -50 66 43 -6 11 37 -12 68 -74 -113 -35 -57 -8 -25 17 -77 44 -35 72 19 127 9 29 60 2 -24 -20 59 -31 29 -82 50 -22 -19 59 105 73 40 121 -6 76 11 -29 19 18 -21 46 -3 70 -10 -17 -47 -14 -54 46 25 -3 88 -121 7 35 30 -8 59 39 -73 -2 23 22 -2 63 27 15 -22 -85 -17 117 -31 -9 31 -22 3 22 -26 35 26 12 59 71 -58 79 -125 -15 70 60 -45 -44 -53 68 33 46 43 41 19 -55 40 58 111 -48 26 9 -72 -91 78 -123 105 -125 16 -12 -41 -48 20 61 15 115 -6 6 -41 -81 -81 64 44 9 86 38 27 -13 7 -18 72 -48 -53 -123 -65 20 76 23 -55 -1 83 39 43 -14 -6 -35 -57 40 18 -39 -85 55 -82 50 11 74 10 -113 -103 122 -43 -49 -25 -27 11 30 -65 5 -54 -16 38 86 107 -27 127 29 -57 65 17 34 51 50 -19 29 54 -29 -36 -16 65 -28 -101 97 73 -29 78 100 -37 75 29 -43 26 -16 -20 49 -76 1 9 -9 -47 127 -54 28 15 53 -35 18 -121 -11 2 -79 43 -55 -9 7 -43 44 39 56 12 -25 63 -25 74 37 -32 -7 35 122 -25 -42 -35 -14 -15 -15 14 -54 -27 75 -108 11 49 -1 42 -7 0 -28 -33 35 71 -37 76 27 -61 -9 -47 -22 48 71 -29 82 -2 -9 1 -78 55 42 -34 -10 26 -44 -18 24 7 -55 15 11 3 45 55 76 26 49 -17 -44 -37 58 4 -72 82 40 42 -29 -3 -74 43 0 92 54 -43 25 52 -4 -56 -21 52 -8 -13 -73 -53 -40 -11 19 35 74 -13 46 45 21 -70 -8 -13 21 -28 -13 4 -34 18 -64 -13 -40 -93 -29 73 111 -6 39 -62 17 -55 43 -48 -20 32 8 -69 7 -43 52 13 -16 -63 -45 1 92 -23 -11 27 -76 -36 -51 37 42 -23 41 -19 -26 101 -127 15 -53 -47 1 29 8 -20 29 -2 38 -32 -30 81 -22 -15 -13 -67 72 -13 -61 -11 53 -93 30 -59 124 -12 -28 106 29 -24 12 115 5 17 -126 8 116 7 12 -31 16 -30 -26 98 70 -11 16 -66 12 118 -11 40 44 49 -40 66 55 127 -99 104 118 31 11 67 -22 22 101 9 -2 -23 97 -14 119 -9 3 75 63 94 93 5 -24 42 -67 12 0 52 76 -17 63 19 93 -123 4 -70 103 37 21 29 -76 75 69 49 51 -126 -37 40 -17 40 0 34 37 30 -17 30 -24 -6 -38 57 8 -49 -77 49 -123 -16 -6 96 5 5 -24 -27 45 6 -4 -40 86 18 -47 -4 -5 -77 14 49 -56 22 43 70 -15 -74 62 43 52 78 -74 1 29 -2 -40 55 -74 -20 86 -35 -5 7 66 -10 -16 -63 -47 -57 17 -5 33 84 33 31 37 -53 1 -41 24 -4 9 -70 -50 9 -64 -53 86 -34 48 -8 121 25 -17 81 -43 -14 -45 -44 -12 -21 20 6 -35 -98 -56 -35 -48 12 18 -71 -52 -23 -45 -30 16 2 -51 5 -49 -85 -11 -30 82 -53 -55 20 30 -14 -31 -36 -5 -40 -65 18 126 125 -44 15 -9 29 -42 -127 62 0 -105 -1 -39 54 48 -5 -27 -25 127 -26 9 20 72 -76 62 -91 62 34 29 4 -41 -7 42 50 16 98 -25 -50 43 0 111 -54 -37 -91 -42 26 25 -36 -5 -52 56 -71 51 66 -127 -60 9 16 -47 35 -26 -40 -47 37 -24 5 1 7 41 -50 -93 -36 36 95 40 -70 -1 13 55 -122 -33 -58 30 -11 -98 -10 -7 -65 -9 -34 83 -8 67 -8 49 -34 11 -89 -25 11 15 12 -71 57 -56 25 -30 32 -6 -58 60 18 7 -99 78 25 58 -3 -31 -12 -52 25 -29 72 -64 68 3 25 -13 -30 5 -45 -10 -104 79 -10 52 -70 18 57 20 22 37 0 -38 -127 -50 -15 42 -75 90 35 123 -25 -56 114 -14 -8 11 26 -18 -3 12 31 -38 -21 43 28 -37 75 22 -1 -20 6 -12 -27 44 -56 -62 51 54 -65 58 44 66 19 1 -103 -18 -1 -48 10 -2 -97 10 18 61 26 19 7 78 -66 82 -58 23 -44 71 7 52 -58 -18 19 47 -23 -118 -25 0 106 -25 7 -42 12 -33 12 27 50 38 -25 -90 -11 -28 -20 32 -1 -12 -30 40 77 -30 42 68 3 10 -6 21 -1 13 -65 22 98 44 -15 -13 17 -59 5 38 20 58 -10 -29 -9 -24 39 -64 36 -7 -32 90 29 -37 3 -50 54 -3 -28 -5 46 -31 -92 -6 19 -39 12 -26 -31 23 48 32 -74 -23 -69 -2 27 38 82 41 123 -22 42 28 -5 -7 -36 -11 12 -69 89 -43 4 24 8 -27 26 14 31 -61 -3 41 25 10 -4 124 2 62 -43 -102 58 52 -8 14 14 40 -41 22 -1 -6 8 -97 75 -2 -47 -106 -27 56 37 40 -17 -12 21 -38 120 86 95 127 -70 73 14 -30 110 55 -40 69 101 14 -102 -67 68 122 69 -36 -9 -116 16 23 52 -13 12 23 127 51 14 59 33 -22 -16 80 54 43 -32 -102 -25 122 126 25 49 -27 95 52 79 39 -7 -17 5 -89 68 6 9 -48 -32 -37 94 57 40 112 119 34 82 30 80 -65 27 -49 -26 8 -105 12 -39 -116 -68 -43 -123 91 31 63 127 39 85 -127 -3 -85 -4 -12 -25 65 -108 46 47 -126 20 108 75 41 41 36 9 -63 51 90 9 67 -94 -127 -26 -25 89 7 -17 -75 -4 42 -50 -47 85 -35 -58 -2 -18 69 72 -30 49 -27 -18 19 -68 12 -128 -49 -85 -127 30 -128 -2 28 64 -58 6 18 -127 -31 92 -115 -128 -19 35 -48 84 127 -38 36 -47 31 6 -64 17 47 64 -47 35 9 -86 19 -103 -13 54 70 -73 92 42 46 -68 59 -1 -13 19 -41 -91 -99 -9 -11 8 -82 43 83 26 -6 -98 27 -96 -62 54 -124 -2 -25 -57 -24 123 -30 44 47 -41 36 -37 -50 15 -37 37 7 -83 -39 -55 -26 -11 -54 -14 40 121 -2 38 -30 31 31 -113 -44 -55 26 59 -17 -65 46 -5 -43 -26 69 -48 45 59 38 -36 -35 44 -29 -76 17 68 21 -52 22 -70 -5 -23 -6 1 33 4 67 -2 -2 -2 -88 111 68 -58 44 11 17 45 34 74 18 -83 -35 77 -18 24 31 44 24 42 15 -80 20 -81 54 -4 -49 -3 -35 50 -23 -19 -27 -22 -54 -16 -98 43 -45 -18 2 -3 -24 33 -30 -105 -126 -19 24 101 16 -3 -16 11 70 -43 -32 -13 -91 -19 -64 49 -44 13 71 -107 42 44 -17 -15 56 -106 -49 -59 -44 -31 76 28 38 -49 -63 14 28 37 -97 -4 75 12 -114 127 -73 -73 -53 -44 -122 -128 -83 33 -22 -63 72 25 -26 16 52 -6 -128 14 -120 -126 -76 -126 -22 -73 4 14 21 56 22 -14 18 -82 2 -4 32 -35 0 -25 52 26 -8 -66 66 -69 33 40 -77 -31 -22 62 -73 1 39 -1 -14 27 -24 99 -21 -11 28 -67 -15 -10 12 39 16 -14 31 -17 21 45 4 46 12 51 6 -6 -62 -31 -13 55 -28 79 4 72 27 41 53 47 -28 26 83 43 51 10 35 35 0 19 -24 -35 35 52 -14 -24 15 -19 -4 41 -3 31 -7 -42 100 8 38 28 71 32 9 9 67 14 49 -58 72 27 -76 -47 -32 60 26 25 31 -24 -5 80 38 -90 -88 53 62 55 -122 -51 -87 -35 -48 126 95 -7 105 78 39 -40 64 56 125 29 -9 39 -1 -18 29 77 4 -51 54 97 16 -40 -4 82 0 -70 -128 81 -99 -38 86 25 -45 -11 43 84 34 3 127 99 -1 12 -81 36 -122 -23 -76 127 31 31 -30 51 -62 98 -128 -30 -54 -14 -26 -14 -5 8 39 -49 89 -8 -6 -16 85 127 -16 24 21 47 -62 -23 -46 -45 31 18 25 -75 -10 -26 -34 52 -76 -12 2 8 41 -17 -38 -31 -8 -92 114 -77 96 3 -79 -9 31 -28 -101 32 56 -75 -8 -26 81 39 44 -107 48 -16 25 103 -65 7 -111 -34 -78 22 -11 59 -22 45 -11 39 89 -21 31 -39 -38 38 -17 -62 66 91 -21 -54 -38 113 -87 -65 7 16 -52 50 23 5 -92 -3 31 28 -3 -71 69 60 41 -40 56 -36 32 19 75 -30 39 -97 11 -3 72 66 24 -14 68 -58 80 -57 17 -38 19 80 -51 -49 -3 1 90 17 4 -17 66 81 -24 31 30 12 58 11 -67 -48 86 9 69 -43 67 12 -75 92 -7 -16 26 33 78 51 -11 -6 49 51 -34 21 53 31 4 19 32 50 -20 -104 -9 -4 49 27 18 15 80 103 -9 47 7 14 -15 -1 -41 27 -67 69 22 15 -58 -11 102 17 -11 44 17 1 -29 -46 32 103 -23 65 23 -79 -14 -28 -3 -3 59 -3 7 -88 45 -58 25 82 -91 -60 -15 19 -4 2 -37 20 -36 -5 67 -59 31 81 -68 -14 -9 -45 24 15 23 127 -44 -65 -50 26 -1 -38 6 22 33 -42 -6 41 32 44 -22 -34 -20 67 125 -47 10 -1 -45 13 42 40 15 46 -6 -19 -69 16 -43 40 -26 47 78 -37 -49 16 19 66 -20 -7 2 2 -11 9 67 10 15 -16 13 -68 -23 27 -34 70 -53 -127 -74 55 13 -51 -78 61 -5 -11 56 19 -77 6 16 -32 45 -42 127 22 -64 38 -33 6 12 20 61 -43 -111 42 60 25 -44 -14 17 66 -106 -1 76 25 -29 23 2 77 -9 -79 55 -4 -79 -83 -8 -14 31 -17 -33 -11 -28 86 66 -118 107 18 -49 36 -70 69 -35 -25 -14 65 -33 31 44 -127 -25 -69 61 35 40 -34 65 19 21 -38 -6 -24 68 -128 55 -29 11 -7 -6 -6 19 -4 85 78 15 -11 -3 29 -81 -15 -90 -22 45 21 33 -12 -5 55 -45 -16 -29 -48 -20 -27 -16 6 -4 -63 7 -3 -31 -44 74 56 -33 -14 13 7 24 -16 -80 -24 21 -7 -11 2 -67 -31 -43 -5 9 -43 -4 18 6 14 -56 -12 32 -96 -18 -36 -80 -96 32 4 2 -3 18 -7 -90 43 -34 -126 25 22 -40 -77 -47 -23 -25 7 99 11 83 36 69 13 -52 27 -64 36 -67 91 -40 54 -28 17 26 9 -52 -74 -17 -20 -25 -67 1 -2 -12 -41 78 -32 14 -9 -5 -73 0 9 6 -13 56 -60 -32 -10 -46 88 -70 6 -9 -60 -23 23 -15 39 24 -20 -83 -71 -19 13 -60 -26 -28 -19 -45 4 -14 -8 -73 64 117 -3 92 -27 -61 -32 -48 -64 -59 -84 -58 -26 -107 29 -71 -35 73 -7 -10 -39 -3 16 -34 -23 -11 23 44 -2 58 -73 17 45 40 -10 -2 -4 -83 34 -24 -7 35 89 -21 -42 125 -122 33 70 -55 63 57 -42 88 -19 -21 8 -64 85 -90 -31 -127 -32 -60 -62 -30 -82 44 -7 -114 70 -112 26 74 35 -17 29 -104 29 33 39 -30 62 77 -43 -128 3 44 85 -116 22 -26 29 46 28 46 -1 46 -31 -76 -113 -96 50 -101 -21 10 121 -34 26 76 27 -59 96 37 -19 -76 -21 114 -70 32 -66 -26 -77 37 -86 17 -30 -96 -8 -57 -54 -66 0 26 32 -121 -8 68 45 -13 27 12 -71 10 -41 -20 -33 90 -70 -57 -122 -13 33 -128 -48 -18 14 54 102 -42 48 -18 2 -18 -4 53 -93 -34 -88 -45 62 -13 71 44 -56 9 -58 22 6 1 125 17 -11 -70 -72 -109 62 -60 58 -106 65 57 11 -51 15 27 1 4 2 -10 70 37 -128 25 115 -70 -22 -100 0 -52 36 -52 -72 8 -17 -38 -9 1 42 33 61 99 -61 16 38 31 126 -59 10 -59 -61 -11 -5 11 -53 -55 54 55 -81 -84 30 52 -74 -57 -55 -32 78 -91 12 -16 -16 -52 -124 -31 68 9 -47 68 51 97 11 26 -59 -67 51 -71 -24 40 52 -52 50 20 12 -16 -22 103 -68 17 -16 -34 58 -9 -103 -87 34 77 -66 15 -5 -115 14 31 49 -37 13 -25 41 -42 -68 8 126 -52 -28 15 121 79 -94 69 -69 36 24 -41 24 115 -7 -4 -42 48 -64 66 42 111 -103 32 34 -77 -11 -24 -83 -4 16 77 43 85 65 -83 -78 -45 -71 -60 53 -53 -21 35 5 17 120 -10 -46 34 -55 -29 83 66 92 37 -1 -25 -25 -6 47 -70 44 -37 -28 -39 -68 -45 -11 8 -60 15 -16 59 -28 -9 -75 16 41 -38 7 81 15 32 9 -53 57 87 9 95 -96 -91 93 33 -24 -39 -39 28 -42 -16 14 36 -76 -29 -13 -127 2 -98 -25 -73 -8 22 47 -78 -16 6 -22 13 98 -96 -71 -3 -49 42 -45 47 29 22 36 29 -84 91 -26 48 -8 36 -6 18 5 80 19 51 -34 78 -93 64 75 -7 30 -13 42 -76 9 -27 14 -71 48 1 72 12 -80 -3 18 -69 -58 32 77 26 -16 -47 15 -51 66 28 -62 14 25 10 -50 41 -7 23 8 12 56 15 45 65 63 81 27 -89 -16 97 -38 77 45 79 -44 4 65 -23 -20 39 127 56 -7 6 62 -32 89 -23 3 -85 -17 33 46 14 59 60 30 -33 4 54 23 11 66 44 14 -14 67 33 -9 107 111 -27 -13 5 -13 25 -20 -39 -5 -12 13 -47 -22 12 -20 10 -17 34 -55 87 92 -26 26 -19 -42 52 15 5 46 -21 56 -17 28 10 -38 -26 41 79 -31 6 7 33 19 -63 22 14 43 33 -45 2 -21 -3 52 -9 -2 51 -9 26 48 -63 52 -25 -12 12 118 -9 33 9 -6 -20 -21 2 53 -5 -68 -26 -13 -33 -35 54 69 -88 -3 -53 3 98 -16 10 -87 -25 -76 113 47 75 24 87 -76 113 -42 -3 80 87 121 127 43 38 -27 74 127 -73 -45 116 12 92 26 91 105 122 87 62 63 93 -26 7 -59 50 41 -32 -40 95 46 -66 82 103 41 -30 69 46 2 61 -76 -27 40 1 -101 41 116 99 -97 112 27 3 52 -85 -1 -19 33 40 -73 30 80 8 45 63 127 127 68 -4 0 -2 127 19 81 13 -21 101 -23 -60 112 93 59 -83 -15 -12 94 46 41 41 67 49 36 -62 -56 68 -51 -50 26 -12 9 4 -5 -2 -36 3 -10 -59 78 -16 -58 -124 34 80 -92 -13 -109 30 19 10 -47 -2 -69 86 50 16 -24 13 -27 -14 -13 -54 -25 -9 4 55 1 -38 -56 50 -18 -127 -59 -34 -25 84 -23 18 82 -27 -19 5 23 -62 39 -68 48 23 -113 -1 -42 48 -29 -27 3 -67 -57 -3 -51 -17 30 11 -85 -88 -20 -20 -6 -18 68 2 67 -22 -35 -42 -14 7 -63 7 12 -11 50 3 15 -41 -116 -33 -44 -127 -128 25 50 5 -106 79 14 119 -26 64 -6 -69 42 -38 -72 -14 -21 -52 20 -17 -60 83 -49 11 -47 22 24 -43 47 -3 -12 39 -19 11 44 55 2 20 -42 -26 87 75 88 -126 23 29 -128 -5 -50 -17 40 25 -2 99 -65 55 -64 -79 -54 -32 -30 93 -2 52 26 55 68 20 2 66 49 -121 37 -42 37 -5 60 -45 -28 62 -58 8 109 -76 36 -18 102 56 -46 -62 -48 25 -82 4 -34 -52 -88 61 -75 77 -48 -63 -45 -25 -97 -25 -5 13 -88 -40 34 126 14 40 -78 73 -6 -28 -109 -22 -66 84 -127 -18 -1 -25 -116 73 60 -1 -85 -69 -128 -69 -82 -7 71 -49 -54 1 -44 0 -119 104 18 38 5 38 -47 47 22 -126 44 -69 62 -65 28 0 -1 -45 -88 -42 43 81 42 42 -39 -89 122 55 -33 4 -2 56 -26 0 -35 116 -38 35 73 59 85 37 -2 42 23 67 -11 -8 -45 105 -20 -11 -3 23 -20 71 51 -22 97 39 15 -82 -26 14 43 59 40 24 22 34 89 -70 99 81 -7 -21 43 -49 5 31 39 55 15 27 -96 -14 62 -126 -2 21 -6 -68 127 -16 57 69 26 11 -20 72 -15 123 -13 1 44 -17 126 71 -6 4 34 6 30 2 -28 -27 32 -16 -45 101 10 40 112 34 47 99 -33 14 77 -20 61 21 -60 74 23 92 42 -35 119 99 -77 -52 127 -1 76 80 31 86 5 -24 21 -128 -2 54 1 -33 -3 111 100 13 -113 4 -89 0 -36 -74 -9 -72 18 -25 -30 67 26 8 50 68 -3 33 78 -23 11 -33 -53 -13 14 42 -74 -23 86 -19 81 -34 -3 44 -28 46 35 -61 -40 26 -6 -122 28 103 -25 37 -83 -30 -47 -107 81 5 3 25 121 -96 -40 127 -57 -9 77 17 94 24 35 65 -92 48 -76 43 -63 -36 -82 -93 17 -126 -121 -61 32 -6 -36 11 10 -2 11 -31 19 -6 -52 99 9 15 48 -33 -88 -2 5 117 -44 -103 0 -25 -57 -39 30 33 -61 31 -27 -9 3 -126 72 -59 -61 -36 56 6 -78 14 7 -28 -19 -7 -13 2 -4 63 27 -95 6 -77 -38 -23 -16 -127 -1 -24 -27 -80 -106 -8 -108 -68 126 47 -69 -34 -60 -67 15 -84 -24 -7 25 -6 -3 116 -68 -36 -46 20 62 36 -2 0 -52 6 -92 -5 126 -25 51 -52 70 -20 83 -77 -2 -75 25 18 57 9 -34 22 -33 -46 -70 -37 -71 -25 87 16 -17 56 9 -68 64 -55 -17 -13 -40 5 -3 -22 -35 -3 -3 31 15 -58 -86 42 8 -6 -59 -2 -23 -19 35 -46 46 25 -42 -16 33 -45 -20 -111 31 20 -12 58 -24 -41 -38 -33 -33 44 32 37 -45 8 -33 7 108 -1 -108 -25 -58 33 52 -30 52 49 21 -19 -121 21 -14 -35 9 -50 -23 -73 -22 -57 -76 -53 52 12 -112 -33 -73 -39 -15 -37 -9 -19 -56 -112 -3 -37 36 -1 29 -29 71 -2 71 -7 -61 -27 30 -33 104 25 21 68 -27 17 77 49 -34 -57 29 83 75 -12 38 -77 -35 81 -40 55 -7 15 31 48 -39 59 48 -21 95 -40 28 57 43 -84 -102 -6 -10 -95 -4 18 40 -38 33 -42 -39 25 -14 25 -6 64 3 127 66 -80 -126 -12 -64 -119 60 13 69 82 -47 -42 -62 49 5 -7 -11 112 27 30 23 7 37 1 -55 -52 -48 45 61 33 64 -24 -52 -33 -105 41 -57 82 127 79 -48 32 -3 -117 -50 -57 -17 -15 -117 -14 -124 -11 -47 29 -2 -12 -16 -16 23 -60 -17 19 31 -18 -14 34 42 -4 -101 35 -7 43 -68 92 1 87 0 -30 38 63 -13 -3 -89 -56 -109 -118 -31 -83 61 127 -14 -6 127 14 -13 12 -43 -88 -49 -128 4 67 -64 -78 -1 37 -59 -10 -80 17 2 -25 18 29 120 5 -75 0 -55 55 126 -1 32 -14 -17 39 -7 -102 -6 -92 -21 12 -23 48 11 17 31 82 47 -66 -51 -66 21 -3 -53 20 -13 10 3 -55 8 15 101 -56 -8 -30 50 -6 -51 -84 9 -67 5 53 -53 15 15 58 -83 46 -70 -20 61 -11 34 36 -38 40 -31 -37 -35 -56 17 -76 65 -39 -23 -31 32 48 -27 -12 45 89 -28 -18 -20 -5 44 -22 -39 -69 91 75 54 -46 -24 36 -126 80 -9 24 12 -46 28 -8 -25 54 -30 -29 23 42 24 -63 -46 59 -22 1 22 -12 -72 60 -38 -119 125 -22 29 17 -2 37 -14 -9 -79 35 -11 -79 -4 56 -42 9 34 -79 29 -48 16 -12 58 41 18 5 25 16 -54 45 -11 -17 -77 18 26 -4 -21 19 -32 50 63 -44 -80 80 63 -22 -27 -98 -38 22 -56 -8 -47 82 -60 41 -35 -42 -56 45 36 63 -12 -101 65 -37 -64 -128 -50 2 123 -28 4 40 -21 -128 -52 -23 16 -28 -119 -90 -89 -65 7 -105 -87 -43 -17 -73 -94 -35 -112 -22 29 71 -24 -53 28 52 16 62 37 -33 -10 104 13 -24 48 1 21 13 55 16 18 -26 -66 43 -65 -19 -31 -120 10 -36 -112 40 -67 5 44 -32 -106 4 -2 -73 -43 -38 -37 -50 -22 15 88 -34 -107 -65 -21 -118 -55 -66 -96 -6 -6 -41 34 63 -57 -37 65 -11 50 -16 -7 48 22 -37 53 40 64 -40 57 -7 -18 41 4 -69 -29 32 -58 -26 -35 -33 -59 38 10 -18 22 -43 -48 23 28 -8 -20 -26 -27 113 -13 -17 43 -47 22 24 38 -73 -11 70 -116 14 7 -8 -41 -81 -51 7 38 87 -50 37 -53 -27 116 15 -55 -12 29 -24 50 -10 -16 74 -63 -33 11 45 -32 67 58 25 -13 -14 18 -75 3 -7 11 -48 -33 1 -71 -67 42 -2 5 -6 7 -62 -5 -6 -62 -78 -52 -64 4 -95 55 66 -41 63 -72 -95 -37 -49 28 3 40 30 -34 64 -40 -48 2 16 -45 5 28 -60 118 -18 100 -52 60 65 -16 25 -13 -50 -6 20 10 17 26 50 -8 -4 19 15 -19 42 34 50 -28 -85 -31 -18 -128 24 -45 26 6 -96 72 67 18 -38 -35 95 25 17 89 59 -11 23 -15 30 1 31 51 63 -43 37 28 -35 48 -15 8 -74 23 -17 7 41 23 115 23 -36 77 -90 7 127 -18 58 79 65 16 -12 -70 8 62 -36 54 -46 -52 47 61 98 -51 5 -126 -4 113 51 48 -57 57 40 -30 31 106 93 -83 62 99 31 124 -120 79 -6 80 121 45 127 -29 35 39 -30 54 34 4 113 45 49 -7 22 54 -20 1 -44 -66 -35 86 -6 37 -54 88 123 14 123 43 -22 4 43 43 28 86 93 103 -128 119 -17 -48 51 127 -22 -1 -29 44 -43 10 -61 -85 -16 2 105 -47 15 -26 36 -37 -20 35 8 124 -12 31 -35 14 60 47 -78 39 47 -44 -11 -15 10 -93 79 -46 63 -7 30 12 19 -27 27 -36 74 10 -25 2 30 -15 -53 59 -50 -125 127 50 -93 55 61 66 -28 -47 4 -75 69 -74 -44 109 40 125 -125 22 32 8 32 51 71 30 -78 22 -23 -25 26 -46 -1 -102 37 52 59 -34 -26 -44 -33 -52 14 12 16 -77 26 44 114 54 -8 54 -12 4 -128 55 -18 127 -76 46 -68 96 39 96 71 6 27 -20 127 18 55 -26 -54 -83 -16 112 -61 -34 5 -88 61 36 -52 -9 -44 19 14 -127 10 9 12 18 -84 -11 -97 -62 25 43 -76 42 -77 58 127 -33 0 53 -30 -12 -51 -15 33 53 -34 84 -43 86 110 -24 98 -2 127 -51 19 -25 20 14 -28 -81 113 -59 37 124 -49 100 -20 -29 37 0 -42 -42 -37 39 -19 10 -30 -32 -25 -17 32 -22 3 -49 120 31 35 -22 -66 14 -83 34 84 -30 -62 -17 93 -3 30 -87 -38 -35 -25 19 31 -17 14 -57 -6 -16 51 66 -15 -10 -47 -116 -37 27 -23 -47 76 -53 -38 -1 -3 2 -38 73 8 0 51 -92 40 44 -27 -6 6 -47 -16 -36 29 -45 -15 -29 -127 34 -39 -30 41 28 18 -15 -40 44 -44 -90 -60 -32 -71 -23 -54 -53 14 -79 19 -21 17 -31 30 13 37 32 1 18 4 -33 46 -3 13 -56 -4 17 41 -64 52 -95 -10 20 71 14 80 -1 -41 -3 -61 60 38 2 46 56 0 28 79 7 -82 -39 -40 -4 19 32 4 38 -14 42 -43 29 -21 19 16 -21 11 24 -2 3 -42 -49 -49 36 -19 0 80 6 17 5 -5 22 1 -73 -62 17 -31 12 -52 -16 -9 -20 -6 91 9 5 -48 -28 -51 14 -53 -25 -124 -12 -15 -11 -71 -28 -25 4 -64 54 -80 40 -78 -1 57 -33 -34 -15 -47 -91 127 -100 -44 73 6 15 67 85 -41 12 -117 -42 85 99 -71 -18 126 -15 24 104 25 -21 -37 -27 -54 0 -98 69 -28 41 36 -127 23 -13 -107 13 9 -16 -15 12 43 -46 -4 127 20 6 127 30 11 37 34 70 -19 3 -60 -36 -114 14 -128 25 23 -26 11 -43 71 47 -10 -47 -21 -16 23 -128 -16 -21 -8 -96 94 -81 -21 77 -31 124 -86 -50 -20 -64 -51 14 11 99 -20 -4 -25 108 119 41 -36 35 -43 -13 51 -125 -33 5 -125 4 24 51 39 -79 -28 80 -45 -128 12 22 42 -15 35 -43 -26 -53 -62 1 30 -38 -15 -4 36 -27 9 -19 21 -29 -64 109 27 -68 -119 -15 -96 28 -108 71 18 20 -43 75 32 -29 -3 124 -38 30 15 -18 24 49 -28 29 45 4 -15 -16 -36 8 59 47 -77 -52 -76 -36 41 6 -44 -64 -4 33 -16 -68 -25 51 12 111 -126 -24 23 52 -5 9 2 -3 -27 8 -15 6 8 55 40 53 66 30 23 36 -35 -17 -24 38 -69 -99 -8 -3 66 -1 59 -73 9 2 67 16 -95 -20 4 -3 -72 99 0 69 -59 3 -12 31 53 -56 68 32 15 88 -125 127 13 57 -43 56 -74 -39 -18 -23 -99 -79 37 56 -23 -15 102 -9 25 37 63 56 31 77 127 28 -10 40 -53 20 41 10 -19 -60 79 1 -16 60 21 11 -29 37 66 -76 79 24 14 -118 -4 -5 -74 72 27 1 14 -86 97 15 32 100 3 -5 75 58 28 8 -20 -16 44 127 -30 -37 21 65 -56 32 -22 53 3 87 -14 -101 -46 -45 -83 43 -52 -15 -88 -39 -46 25 8 -88 -82 -50 45 17 -51 -32 -11 -1 -18 -84 -21 75 -27 -58 -21 77 -31 -68 30 71 87 -33 32 97 18 7 -1 -63 79 -58 27 38 -51 8 -14 35 -9 -11 -99 30 61 36 -1 121 54 127 -52 -11 22 8 -14 -40 73 19 -85 -17 105 -38 9 -58 -49 40 -37 67 71 10 46 -33 20 17 76 -24 22 85 3 -32 53 37 31 90 65 35 -19 8 22 14 46 35 -22 39 73 -1 2 -62 8 26 -66 5 49 63 74 -5 -7 84 10 -64 -53 45 -25 -51 -25 -60 5 127 -5 -14 10 102 -3 72 -7 45 4 -72 5 41 69 15 28 47 86 115 15 -28 20 21 16 2 -74 -81 -63 46 37 -59 24 65 73 48 17 58 -11 4 -70 -33 87 19 -16 27 48 47 -40 -23 -43 -63 61 4 97 50 54 27 -8 -97 39 -100 -20 25 -19 32 46 72 42 -20 -64 66 54 33 18 3 86 -27 -17 -35 42 -51 -55 6 -26 -19 13 -18 57 64 -28 88 17 -27 -46 3 41 29 22 79 17 -46 23 70 68 -21 -93 13 -61 16 123 -100 18 -14 39 31 32 -75 3 -33 25 -77 82 -53 2 16 5 -13 -16 -11 19 -23 -41 10 18 -76 -84 -20 -26 -40 60 44 -48 18 -79 19 39 29 -26 51 -52 51 6 65 -72 63 33 49 14 -5 15 78 22 79 81 -9 -34 -9 72 70 55 -71 27 -38 -57 -31 -4 -1 -4 0 99 67 38 53 -37 -47 115 -100 6 93 -1 55 7 40 -39 -71 -37 -62 -14 78 7 -20 -25 25 -40 20 -68 6 40 -31 -3 44 30 -39 -12 73 -19 120 -6 2 98 -15 27 -39 48 -3 122 33 41 81 -121 41 53 -3 19 -42 97 62 18 61 52 27 7 -58 86 -24 55 54 -43 120 -14 54 -1 -49 -40 -37 -114 95 95 -27 52 -54 63 92 53 21 61 -28 127 19 59 121 -128 -73 63 125 -82 40 -24 70 49 -42 42 16 -60 127 38 42 -57 11 -5 6 19 -25 -28 83 -24 125 -60 51 -15 -11 90 -90 12 127 96 55 61 -113 9 -29 11 -16 108 7 -42 12 74 20 -7 23 -66 110 -25 -40 24 42 -57 2 31 -57 -69 40 52 11 27 -6 -12 107 30 16 39 67 88 45 -34 -52 19 70 -64 24 -7 -88 94 116 -38 15 87 101 -13 39 -59 -1 -45 101 -102 -47 3 -7 -21 -28 -117 28 37 -54 18 24 79 109 42 82 93 -16 -38 53 -12 36 -1 -124 124 71 127 -5 5 43 -42 -11 -23 -97 -123 38 -11 -3 -15 16 56 -29 9 2 -77 -55 -23 -20 -16 -4 -21 45 -109 1 23 -124 2 125 -70 -4 37 -12 -94 -38 -6 -44 -85 -49 -81 -23 23 -39 -77 -58 23 28 -14 74 6 6 -38 -33 -58 -101 -29 -15 -7 -30 -26 -25 39 -17 76 43 -38 37 70 87 54 -6 57 -9 75 -17 -5 6 -13 16 -126 13 5 -18 -102 75 -33 48 -10 11 -23 26 -32 -121 -23 26 38 17 -76 -81 46 -64 -5 -114 42 127 65 29 102 15 49 -63 -84 -29 -72 108 -28 -19 13 -39 -108 24 -39 -50 19 11 29 -38 41 -10 7 -9 61 16 7 19 -49 33 -33 68 -93 -33 58 -124 15 49 -11 44 29 2 -1 19 -11 -13 -68 -25 15 13 -1 -123 -10 -66 109 -24 -41 -13 92 53 -8 -36 -98 17 -45 -57 -125 -71 -62 -8 54 -37 68 -92 4 -19 127 -80 2 21 6 120 -31 21 8 -27 -128 -34 -4 23 -3 -72 -73 77 -128 57 -43 40 -128 -76 -15 15 -35 21 -50 74 40 -124 8 57 14 6 -42 -10 63 13 10 21 99 59 54 60 -9 -33 14 5 24 11 67 15 87 -69 16 43 -39 22 0 100 43 -26 26 23 -3 44 8 -33 6 40 0 -49 -115 -37 -4 -5 9 -3 29 30 80 -31 22 22 37 44 -9 -42 21 27 -34 79 48 -40 11 1 33 93 -10 15 37 39 -31 -123 -12 5 -2 49 36 42 48 35 23 40 51 -69 21 68 -40 34 -4 33 2 -1 8 32 -29 73 -47 63 -15 -74 90 -11 70 73 -82 10 19 -126 -18 -33 24 52 -30 -3 -15 5 25 -12 -13 44 -39 -41 32 67 -82 49 26 -6 24 68 -38 -68 -2 -68 -25 27 -31 -15 -18 4 55 -15 -51 -66 -20 5 31 -44 29 2 -46 14 24 -112 108 -28 -78 -35 -45 63 33 40 42 -30 67 103 -38 13 -7 95 2 -36 -58 -3 24 18 46 -15 27 -87 -4 36 -51 3 89 -88 49 7 15 49 -34 -58 25 96 64 -46 -50 -45 -5 8 43 28 -3 45 -97 29 -106 -24 16 11 -42 83 -20 63 24 -60 -23 -18 -121 -52 -34 -65 89 126 -26 101 70 70 -25 14 45 -20 -36 -52 -12 78 48 37 -1 0 -31 53 75 -14 -14 -48 45 127 -26 112 30 38 -82 89 51 -33 125 -128 -46 -47 24 -36 -5 55 97 127 -19 -88 -127 -93 -64 -51 40 62 40 55 11 67 -46 93 31 22 -8 -4 13 -15 -19 24 39 -65 48 -43 -23 -19 -14 74 -25 42 -1 48 57 -40 -16 23 72 18 -48 23 41 25 6 -20 -55 22 -5 -16 16 -125 2 -39 66 14 -1 31 -30 -22 -45 -36 -44 -66 -17 38 -43 -27 21 -48 -1 63 26 -59 42 -37 43 21 -75 55 -41 108 -124 -11 -97 -21 51 -37 -9 57 2 48 -62 -39 87 55 -53 34 15 -30 17 1 -126 -15 52 -22 -65 -57 -125 -25 -70 -36 -29 62 -54 -1 -80 -66 4 -74 -52 24 -18 -63 21 75 -31 8 53 -9 -30 -4 79 53 49 -61 -87 -51 -38 -111 11 16 -56 62 -65 12 -17 56 8 -103 -114 77 9 21 -2 -34 27 45 102 7 44 30 127 95 45 126 -55 11 46 24 14 -30 -40 59 -53 -30 -125 -20 127 92 13 -16 34 -123 2 12 -41 -2 -20 -116 59 52 78 -15 7 -64 -49 127 4 69 -17 -46 26 28 -59 -45 -1 118 47 -12 -107 -53 76 -17 -24 -58 -10 54 57 -58 89 -83 69 -53 79 37 69 9 -46 69 124 -31 -21 -14 -100 -16 -6 41 21 124 -84 12 -75 5 -126 -128 -29 -47 50 -119 50 29 -52 -21 45 -75 97 -25 -128 10 41 80 106 54 -54 54 48 -7 19 -23 32 23 124 38 75 -29 5 116 -44 32 39 90 87 93 -46 -50 -49 -128 -14 66 127 78 78 107 -27 124 71 127 -76 1 4 2 -60 -15 -34 -20 11 -34 64 -44 19 -42 -25 50 63 43 -1 -35 3 -3 -2 26 -7 -11 12 0 18 -33 -23 -75 -42 24 37 5 -8 0 -39 54 -5 71 -37 39 14 -4 67 3 25 2 41 11 -34 -35 35 -10 7 49 -19 26 -27 -23 -14 64 -10 -75 -24 80 63 -49 -63 -69 77 -5 56 35 -40 42 32 -3 23 -2 -49 -20 15 -18 -43 3 50 18 -62 73 120 -110 42 18 35 12 34 -27 8 9 73 53 42 -19 57 17 -49 40 37 -36 -51 -19 -15 7 57 74 -38 -73 31 -7 -54 13 51 -28 -42 -15 68 27 68 58 39 -55 115 -34 23 9 21 2 70 95 43 7 34 86 -23 -22 71 60 29 4 68 -32 -62 -7 95 -17 6 64 -46 -18 61 -30 17 16 -51 -83 -31 31 -34 70 -87 -50 16 -38 6 -9 55 2 -54 -38 0 39 26 99 39 -18 1 2 4 51 -47 -42 -35 -62 67 -58 0 -49 40 26 124 27 17 71 85 127 -32 71 -61 -22 -25 -54 34 -28 25 -73 -2 -27 -120 -18 -2 65 -51 71 -76 37 36 42 37 57 55 82 -3 -45 2 -19 -27 71 22 -83 -112 39 104 107 -5 111 -38 85 -20 118 -124 92 -32 -38 57 103 -25 69 34 41 28 44 -22 -5 16 -15 100 -46 6 126 13 -39 -25 -96 -64 -29 -84 -18 31 -35 16 63 45 -59 -32 -67 3 -40 39 48 -125 8 -23 107 -72 -54 -69 43 7 -6 51 -28 28 23 -66 12 19 18 22 27 -17 15 121 -82 -21 -39 18 37 27 9 61 -43 -9 -91 24 -15 38 -57 -26 -2 -19 27 -10 92 -44 22 -8 -36 -45 -68 -90 -16 0 44 -21 -72 -86 10 54 -59 -2 -5 -77 -75 -26 55 36 -81 -126 -28 48 18 31 -37 12 35 39 16 0 60 -80 -124 25 -79 -81 5 36 -62 44 -14 -39 -43 58 -37 -17 -5 34 -79 -13 -103 51 -69 -98 -23 48 -52 -36 96 45 19 -33 11 37 12 -84 0 34 54 -13 -31 58 -14 25 30 -50 35 36 15 -33 18 -50 -36 -59 -16 31 -127 19 -18 -3 11 -31 50 -17 15 -3 16 11 32 106 27 88 47 -38 10 -53 3 -19 -18 -126 -43 -125 -65 -55 43 -19 -42 -11 -64 63 -1 -40 49 31 -10 13 -9 18 -75 48 -13 24 -35 -21 12 -62 67 -6 14 9 -42 -2 66 -28 -127 -104 -37 -9 92 48 -79 44 -15 -64 5 -85 -50 -16 95 -38 1 32 -34 62 -10 -34 -47 6 -58 18 -30 25 -72 44 123 -103 -32 -115 -115 -70 -59 -88 89 -22 69 111 51 2 28 -11 -34 -17 62 -7 36 56 -123 -28 -47 -42 25 3 77 18 -40 97 41 89 7 41 29 5 35 36 -48 1 36 -42 49 -13 -46 -46 110 -26 99 22 -31 -35 58 -40 -18 -44 -22 13 -31 4 58 2 4 65 72 -9 67 -27 -39 -71 34 -79 20 -29 -2 -22 36 -65 53 21 56 33 4 17 -39 23 -58 7 56 -123 17 9 -23 -36 14 69 -35 6 35 21 -21 -21 43 -103 38 49 -55 17 -48 -19 -5 -127 17 -8 25 -39 -29 -8 -49 -38 -20 32 15 -1 85 -36 67 -11 -7 -75 20 -91 -38 -123 -16 -19 -82 -18 32 -3 1 14 -63 18 -15 -2 28 -18 -116 2 45 -5 -30 9 -19 -21 61 -32 -41 1 -88 -67 5 -40 -71 30 -44 -4 -94 -60 32 -48 10 49 -2 72 -1 -9 -16 10 1 53 -38 -9 -24 -42 38 -80 -82 -3 1 -55 26 -79 127 -93 -26 -32 -17 -32 42 -39 80 -2 39 46 -33 36 -95 6 64 24 -91 55 -10 6 -48 43 30 -11 -25 -8 101 -52 56 -79 -10 22 -22 103 8 34 -14 23 22 17 -45 32 29 20 -62 7 -1 -51 13 -7 12 -21 73 -48 18 69 31 7 30 -1 44 30 37 16 46 69 40 33 -6 -6 7 63 16 31 19 3 115 79 62 -20 -19 34 40 49 -30 12 -52 46 64 52 90 23 47 -58 -87 63 33 12 1 21 29 67 -17 13 14 15 37 10 52 42 16 42 19 -11 59 27 32 8 75 39 -35 20 -10 78 21 12 -1 -6 22 53 34 -7 67 44 52 34 52 -1 15 -39 41 35 61 53 71 31 47 -13 67 20 47 -7 12 27 -20 -1 3 1 18 -1 19 27 15 -11 0 -18 -8 -23 -21 -1 24 13 -15 2 -2 -3 -10 12 -3 0 -26 -26 7 -41 -12 7 -41 29 29 22 11 20 4 2 -12 -13 8 6 6 35 15 14 -18 4 40 24 18 17 0 4 9 -18 -52 -20 -8 -2 -4 6 14 -21 11 -5 1 7 8 -15 -12 -25 -36 14 8 -66 -19 23 0 14 2 -18 -22 0 -4 1 -26 24 -27 -1 -4 30 -27 7 18 28 16 -1 33 -15 -5 6 18 -21 -16 -8 -19 -26 -18 5 -59 11 11 48 -2 19 -1 4 20 0 -35 4 -26 14 -3 -1 -17 32 -2 -49 -29 23 -5 6 -6 1 10 17 0 39 1 6 -5 12 -34 7 -10 -3 -19 14 -44 9 10 7 11 19 25 1 -35 -36 22 5 -25 21 6 1 18 -13 -16 12 7 -6 -11 21 14 -22 -1 -11 28 -30 -6 14 -35 -11 -9 33 8 -2 96 22 1 -53 -69 -38 4 25 28 34 31 31 17 19 26 32 43 41 48 41 19 -11 8 41 9 19 16 40 46 21 19 21 26 24 26 42 39 36 30 25 25 27 22 12 8 24 6 59 92 80 63 34 9 17 34 55 62 76 78 61 49 23 14 17 29 21 15 27 -1 75 73 70 102 63 12 -21 -26 2 -15 -14 12 26 21 14 23 32 45 82 110 124 91 41 36 30 22 37 40 32 25 25 24 4 -20 -28 -21 -12 -11 -18 -14 -15 -11 -4 23 12 23 10 -3 7 4 13 17 16 13 23 25 30 30 22 13 2 -6 7 12 15 14 11 8 -9 -28 -30 -24 -27 -40 -38 -20 -22 1 9 24 39 46 42 39 49 50 51 45 18 -7 -20 -13 13 22 34 28 7 -9 -32 -41 -33 -33 -35 -38 -31 -44 -30 -7 34 73 9 23 47 58 53 43 44 46 54 61 75 55 46 40 40 40 38 31 16 10 1 -18 33 40 2 -45 -89 -91 -73 -53 -30 4 14 20 29 53 47 42 37 53 31 18 -15 -16 34 8 16 30 33 41 47 49 42 33 35 43 40 16 -11 -23 -26 -32 -48 -35 -6 31 60 49 52 29 10 7 18 32 22 19 35 27 25 10 4 14 7 -22 -41 -54 -93 -92 38 50 30 23 15 8 12 7 -2 -13 -16 -35 -42 -45 -40 -35 -18 65 118 77 55 58 -12 14 57 56 38 43 35 37 46 62 53 70 63 67 62 47 46 40 26 33 17 -5 -20 12 26 0 -22 -31 -40 -46 -49 -57 -55 -51 -44 -32 -31 -44 -49 -48 -31 -48 -77 -78 49 58 23 16 18 31 37 46 64 73 71 54 38 21 24 33 34 37 36 2 -2 -5 50 72 89 77 52 50 46 39 31 17 14 2 -7 -27 -47 -54 -48 -40 -25 -14 -3 -19 0 37 57 35 14 10 29 41 41 43 38 21 6 0 8 9 6 19 -6 -20 -55 -24 -24 18 13 27 30 1 -8 -45 -74 -97 -107 -106 -90 -104 -125 -111 -90 -70 -46 -58 -58 -48 -44 -26 -37 -57 -66 -74 -69 -58 -74 -92 -91 -95 -79 -49 -21 -5 13 17 41 59 39 -39 127 72 6 1 1 12 17 27 26 34 32 42 48 51 46 44 33 22 20 15 6 -70 73 61 49 45 46 57 59 58 51 43 44 35 42 43 53 51 40 24 20 31 88 74 36 37 6 2 12 20 6 -10 -4 -1 -11 5 9 10 13 11 4 0 10 10 28 57 -58 -40 -53 -61 -32 -22 -60 -94 -105 -90 -66 -52 -53 -51 -46 -38 -32 -17 22 24 64 96 25 16 1 -32 -45 -22 -15 -1 -13 -25 -18 -29 -29 -29 -29 -26 -20 -16 -22 -39 -43 -21 -58 -86 -89 -81 -57 -42 -27 -27 -39 -49 -48 -37 -29 -14 -5 9 7 19 20 28 22 -1 63 32 16 13 17 14 12 11 0 -3 3 10 7 11 19 30 22 14 22 34 27 20 1 4 -6 -34 -23 -6 -3 -14 -33 -46 -43 -49 -46 -31 -18 -17 -14 -39 -87 -68 -65 -116 24 12 14 32 40 41 28 31 56 62 55 54 46 39 32 28 26 24 16 13 18 56 96 85 27 21 17 25 22 29 24 35 20 13 15 31 27 19 -1 -3 21 48 65 44 -11 -23 -49 -68 -55 -46 -35 -47 -46 -53 -64 -65 -92 -110 -89 -61 -35 0 2 -9 -14 -24 11 30 41 58 52 31 35 37 50 50 48 49 44 46 47 52 51 39 9 -8 -27 -28 3 21 48 58 68 70 69 72 72 62 56 42 45 39 25 28 29 36 13 12 21 36 -26 -20 -22 -35 -36 -27 -29 -33 -30 -19 -7 -8 -12 -18 -5 -9 -15 -35 -23 -17 -13 -6 -79 -63 -55 -59 -53 -51 -30 -14 -16 -16 -12 -37 -40 -34 -35 -33 -28 -16 16 16 -10 -70 26 39 26 35 77 116 89 81 76 64 57 54 41 37 24 20 15 31 70 74 70 39 -2 -17 -10 -35 -45 -45 -34 -27 -21 -29 -39 -66 -78 -92 -116 -126 -119 -91 -9 2 16 -43 23 24 38 50 41 39 40 53 69 84 89 93 111 122 127 127 127 126 114 101 61 38 -128 -128 -35 -33 -52 -67 -66 -45 -15 -3 -12 -20 -26 -29 -31 -34 -38 -34 -16 -6 -23 -30 60 66 57 40 20 4 -3 -8 -3 15 23 23 27 25 15 8 10 37 58 32 -1 -10 107 64 21 7 21 32 36 22 15 17 -1 27 25 28 33 22 24 13 34 37 62 88 -27 -18 -28 -37 -33 -34 -36 -42 -44 -34 -33 -31 -33 -35 -44 -48 -40 -25 -28 -23 -12 0 -23 -49 -34 -17 -15 -1 3 12 32 48 60 74 97 112 126 127 127 117 100 104 90 28 -65 -56 -21 5 4 -4 6 19 23 17 28 1 -5 -16 -34 -40 -14 55 95 27 -59 -61 -40 -37 -19 15 39 28 17 17 40 56 57 62 55 52 42 22 5 25 3 -1 0 7 97 127 109 87 75 65 62 63 78 72 59 50 57 51 41 48 45 25 9 9 20 59 -39 -55 -66 -67 -61 -55 -50 -44 -41 -49 -55 -63 -67 -72 -80 -82 -76 -51 -21 -37 -34 -29 12 20 33 25 11 0 5 3 10 21 25 30 35 32 35 41 43 48 28 13 4 12 30 47 49 41 43 50 51 51 43 45 48 38 42 45 37 32 29 27 9 31 28 34 -16 3 5 16 24 39 68 94 87 77 87 53 48 55 54 59 59 22 15 31 23 5 -12 -14 -41 -44 -29 -20 -36 -40 -17 -6 -6 9 -1 -12 -20 -30 -39 -46 -47 -53 -61 -38 -54 -87 -74 -76 -82 -70 -48 -22 -6 -19 -35 -36 -32 -31 -19 -7 -8 -15 -31 -27 -43 -9 36 35 47 56 66 75 91 70 37 22 10 8 13 15 8 5 4 4 5 15 45 28 -14 -18 -37 -33 -33 -29 -23 -16 -5 2 -14 -13 -12 3 -8 -16 -39 -58 -65 -105 -83 -38 -50 -42 10 44 50 32 16 -6 -24 -29 -44 -52 -71 -95 -114 -128 -128 -115 -60 -49 -57 -23 -37 -36 -56 -44 -47 -49 -45 -48 -53 -47 -45 -45 -46 -40 -46 -56 -60 -84 -124 -115 -69 -14 11 56 66 45 24 17 11 20 13 13 11 -6 -12 -10 -6 -14 -16 -14 -2 -5 -11 -29 -15 -2 -36 -53 -104 -110 -98 -71 -99 -124 -128 -128 -128 -114 -98 -98 -112 -87 -29 -48 -66 -33 15 1 -8 -26 -22 -25 -22 -17 -19 -20 -20 -32 -37 -38 -30 -26 -32 -55 -113 -106 -81 -50 -11 3 0 -9 -2 3 7 10 8 7 8 10 8 2 -1 -3 -4 -2 25 28 26 13 -53 -13 -33 -42 -38 -36 -40 -54 -65 -60 -58 -26 -36 -39 -34 -42 -64 -70 -40 -47 -33 23 27 17 9 7 16 30 34 40 40 46 42 32 25 26 27 26 21 13 21 28 48 55 7 -8 -41 -44 -44 -46 -37 -36 -12 -3 -1 -13 -10 -5 -5 -26 -40 -80 -64 -19 28 -81 14 32 40 21 6 7 -2 3 2 13 18 22 25 33 54 66 52 28 5 1 13 -18 3 25 80 92 76 43 24 28 48 76 72 63 60 51 33 21 15 17 8 10 15 27 -13 -8 -15 -26 -21 -18 -17 -15 -18 -29 -37 -35 -32 -26 -9 21 47 79 127 107 84 68 -25 -40 -48 -35 -28 -28 -26 -11 -12 -10 10 -1 4 2 9 0 -2 -5 -20 -16 -8 7 50 60 80 89 97 104 98 98 94 81 68 74 69 51 23 26 29 42 60 38 21 46 28 32 39 42 33 27 25 20 21 29 23 23 17 15 12 12 21 24 41 30 10 -23 33 35 35 55 69 57 36 28 33 32 30 35 41 54 55 59 62 83 69 51 33 22 3 27 34 25 15 9 1 -5 -6 -4 -8 -27 -36 -36 -48 -55 -53 -39 -32 -44 -64 -60 29 17 2 -28 -51 -54 -40 -33 -50 -49 -52 -59 -58 -49 -39 -27 -20 -12 -12 -46 -76 -64 14 -2 18 28 27 23 29 27 31 31 28 29 27 23 23 28 34 38 39 18 -12 3 -79 -84 -80 -71 -47 -29 -29 -33 -31 -28 -36 -41 -52 -47 -29 -37 -44 -37 -6 -3 9 2 -4 14 28 25 32 26 8 1 11 22 19 16 18 15 9 8 10 2 9 19 42 17 -61 -60 -78 -76 -71 -67 -71 -92 -104 -96 -96 -98 -96 -83 -67 -57 -63 -60 -39 -39 -38 -23 9 7 20 27 33 35 37 33 29 39 38 42 41 44 30 25 17 34 63 89 58 32 47 63 40 9 -7 -2 15 13 30 38 56 35 17 20 46 43 22 -25 -17 2 50 66 -31 -72 -92 -105 -90 -75 -64 -60 -51 -42 -19 -9 7 14 24 29 28 -1 -58 -65 -38 -6 -53 -42 -42 -24 -24 -47 -64 -59 -53 -43 -34 -57 -61 -51 -40 -34 -24 -30 -51 -47 -56 -96 -1 17 42 55 55 48 37 28 18 18 57 66 74 85 101 98 89 35 -7 -16 20 47 -110 -110 -85 -45 -12 -7 -3 5 1 -2 -8 -4 -3 -8 -11 -14 -13 4 7 3 -3 10 -2 43 87 92 67 65 70 79 48 42 43 32 38 64 88 93 88 72 47 27 37 44 -19 -74 -128 -128 -128 -128 -128 -123 -104 -87 -88 -91 -104 -102 -87 -69 -65 -34 -30 -34 -25 -9 20 51 26 42 26 32 43 59 67 74 62 73 77 78 65 50 34 35 60 49 14 -9 -28 -3 -1 -5 -20 -27 -52 -63 -67 -62 -47 -52 -48 -36 -21 -21 -19 -27 -30 -44 -63 -85 25 11 26 19 14 15 23 10 -4 -19 -24 -16 -15 -27 -40 -34 -23 17 31 32 25 41 27 18 5 13 21 21 24 21 18 8 5 2 13 7 -1 -6 -14 -26 -91 -128 -128 -128 33 56 51 65 66 52 45 34 7 -15 -28 -35 -35 -36 -35 -28 -12 18 68 41 14 30 -2 16 25 31 40 39 34 31 40 44 39 36 40 42 38 42 35 61 69 41 1 -14 -101 -67 -49 -50 -46 -34 -29 -36 -14 2 -4 -4 -18 -45 -64 -62 -48 -60 -112 -127 -126 -128 -13 18 68 107 127 120 77 39 1 -33 -36 -25 -16 -14 -9 -9 -5 -1 1 0 -9 -43 -7 -5 -37 -54 -58 -68 -90 -99 -84 -92 -100 -95 -85 -78 -68 -72 -70 -91 -112 -117 -119 -95 11 26 28 38 35 48 60 66 57 66 82 87 98 103 102 98 89 79 90 79 35 20 -4 0 16 22 12 -13 -16 -18 -14 -20 -21 -25 -40 -49 -45 -44 -57 -115 -127 -79 6 71 -32 -28 -9 -10 -5 -7 -8 -17 -26 -31 -17 -15 -10 -4 4 7 12 2 -15 -22 -33 -37 14 35 37 27 16 26 33 19 22 34 19 6 8 10 5 7 43 58 29 1 14 12 24 1 1 127 -128 127 127 127 -128 127 100 -128 127 -128 -128 127 127 127 -128 -128 127 -127 -128 81 -128 127 127 80 boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/boca.dsp.rnnoise/sh.rnnn000066400000000000000000011052561516712004000273020ustar00rootroot00000000000000rnnoise-nu model file version 1 42 24 0 -16 13 24 36 -17 5 8 55 19 3 36 -72 41 11 7 1 57 -16 0 -16 7 9 7 -13 -28 17 9 -39 -10 -4 26 23 11 -16 -13 -58 58 -17 -7 3 28 -32 60 35 -26 6 13 -11 -15 2 68 -19 -40 25 -44 -5 26 10 22 -54 22 -18 0 7 40 31 18 49 -32 -53 22 -45 -50 8 50 -68 -10 -52 54 -37 -30 61 40 12 -33 -27 5 47 -28 -40 -17 13 -17 -71 -44 25 61 20 -8 29 -8 -55 -54 38 -6 0 66 -23 -9 -6 21 34 0 -46 22 -48 25 -26 -81 -32 -13 38 -15 10 8 28 59 66 6 -65 -2 -20 -68 -27 -2 16 8 27 26 -10 33 31 -30 9 114 -87 1 -12 80 -19 -66 86 1 6 -91 81 -51 -85 72 4 117 -121 -125 -125 -17 121 56 99 65 -3 -4 99 123 54 127 64 -32 -1 -53 -86 52 -65 72 115 33 -53 11 -40 -3 94 19 126 127 -122 9 52 127 100 -60 51 36 2 -128 73 -68 -69 29 -4 106 -115 -126 -52 29 127 29 52 -64 96 -115 -13 126 -47 -29 40 -59 -35 -59 0 -114 63 18 48 123 -121 -48 -87 -4 30 -125 66 30 73 -117 37 70 -95 -121 -23 110 110 13 -97 -18 58 -31 -30 53 -53 -69 -6 -5 17 46 8 63 -119 -44 -107 122 94 40 14 -112 -77 -66 85 -128 -126 48 32 121 -48 50 7 -27 13 9 3 -112 127 -86 62 -51 121 -127 -114 127 88 -8 -53 50 -10 -63 -39 127 61 -20 -29 -69 69 83 43 -124 87 -7 104 51 62 8 81 127 21 126 125 106 -41 -37 -124 58 39 1 126 -10 -47 53 -24 24 -23 -13 -23 -1 51 -23 9 127 89 -125 -125 127 127 -79 12 -20 83 1 19 51 27 -51 19 51 -23 -3 -39 -27 126 3 -30 99 35 122 -9 -109 71 9 40 116 90 -20 -118 109 32 71 48 -128 56 125 57 29 -107 -120 23 127 65 -121 80 94 89 -23 -124 81 36 8 113 80 124 -78 25 -110 -54 66 -8 -30 127 25 122 -11 55 127 -8 111 99 75 13 92 22 73 -24 34 -122 -123 -57 -47 -118 17 61 -6 48 -55 -1 127 108 78 6 -28 -32 60 -111 107 -75 1 113 -45 123 -11 -39 33 27 90 77 13 67 -6 90 -20 -15 100 114 120 114 124 -97 -126 -72 1 -128 -126 -35 -89 117 6 -103 -24 30 -21 -5 -56 76 104 -11 -34 46 -98 52 43 -88 39 41 114 -69 -9 17 -32 -88 -119 127 127 114 98 111 -16 8 117 -9 122 4 126 -97 -34 -128 50 -97 41 61 -71 127 -54 5 -71 31 21 -54 15 96 39 9 -27 121 8 -89 80 127 125 115 -128 -58 39 18 127 -56 47 -78 -26 26 119 95 -120 -128 -6 -128 122 -20 -125 -80 -37 -86 -6 43 -97 -101 124 89 87 102 125 -128 -118 -26 85 114 -101 127 -31 -48 -5 91 -66 -67 7 -86 96 9 -76 8 82 -47 -108 18 126 -128 -117 117 -77 -20 -23 81 41 -9 -28 127 127 -115 127 101 86 117 2 -106 -32 12 58 -52 -79 3 31 46 119 96 -45 -101 -70 -54 108 4 -45 -49 57 -128 86 55 -105 -126 120 71 -57 73 -20 -118 -109 -21 -74 -34 -18 127 -2 -70 -13 27 -21 45 -70 -96 17 97 37 32 3 102 -124 3 -25 -21 39 65 -2 -109 -19 58 -60 -97 2 127 100 -52 119 38 46 32 3 -91 12 12 87 -47 25 -58 -64 4 80 9 -4 -36 -20 -12 40 -11 4 31 51 124 61 57 -36 54 54 78 -46 -46 24 -49 -10 -1 3 -65 1 9 -59 110 -50 14 73 -33 -113 15 17 -47 -64 3 27 -37 7 57 17 -78 -14 -71 94 50 13 -50 82 21 -84 77 39 110 78 20 46 36 -71 -18 19 75 -20 47 9 0 120 86 -48 -69 29 -6 -69 -5 -5 23 32 -81 -116 34 3 121 -48 64 31 35 25 -63 11 -37 -6 -58 118 -70 59 -6 -75 11 -3 -29 -37 55 99 8 -20 81 -31 68 -31 43 -74 60 -27 1 58 118 -127 -114 -116 123 -13 7 21 127 27 -121 -14 -54 -128 98 -53 127 126 30 118 -57 124 -116 42 127 -128 -114 -117 123 23 58 70 127 3 -119 -119 25 -128 127 -82 127 64 -122 120 -31 126 -116 -64 124 -111 -102 -112 -33 26 77 31 42 -42 -82 -50 114 90 117 -44 127 71 -128 50 -71 3 82 -63 9 46 118 64 -59 -82 39 106 -113 11 107 59 84 -17 -18 -36 61 37 97 -51 22 -127 -50 -77 83 -6 -35 -77 124 73 75 89 74 -49 -29 54 99 -10 -39 -39 9 34 58 -23 -55 -30 -81 -99 -25 43 -123 127 0 124 123 78 -81 43 19 46 11 119 43 119 -16 7 49 -93 8 -125 127 -70 -15 27 73 -1 -31 -18 -9 -35 -46 -52 -34 1 -33 32 20 -22 -46 -33 91 44 -42 -38 56 -64 61 -38 28 80 -19 -14 -55 39 -10 65 58 -25 89 4 48 6 58 -15 -61 67 -128 -26 49 -29 -110 -15 27 -55 -124 82 -100 -127 -1 -121 -32 -64 -2 -55 104 -111 27 -33 42 82 -34 1 -82 24 24 0 6 91 -48 -46 101 -56 -50 -13 -33 -73 -123 79 -128 -75 28 -6 19 68 116 -16 -30 -108 -80 65 -42 -41 -58 66 -36 51 48 60 35 -99 -44 6 -86 -65 -61 14 -44 58 16 -37 -14 18 35 0 -41 18 -5 11 -35 11 8 29 -29 -63 6 87 75 -38 -13 -18 -40 -48 60 11 -26 -14 -30 -13 -89 -111 -56 34 -42 16 -85 17 40 -60 114 -121 -61 68 73 -5 106 -13 24 -56 71 7 50 -57 -13 -54 -59 -44 42 61 -119 -93 -28 -6 16 -32 34 -44 49 32 -50 17 -62 6 -52 -5 -13 41 -16 5 18 -44 89 0 -50 14 1 62 -27 -68 -33 14 -7 -22 8 -29 -54 -18 -27 69 -49 -80 63 30 127 26 -28 63 48 127 -2 28 125 29 124 119 -7 106 -26 -123 63 37 95 48 113 -6 7 74 127 74 51 48 -78 -1 -33 -11 125 -103 -10 -26 78 -6 35 -60 -87 105 -4 -38 -14 64 -17 33 -27 -21 5 -53 7 14 37 45 13 -80 2 -45 8 -60 -9 -47 67 -35 69 14 29 6 -75 -68 -92 99 4 -120 -63 -45 0 -5 -102 -30 44 0 -66 -13 -86 12 15 78 19 -85 -30 61 -112 19 -50 46 -75 27 126 -2 52 22 -71 14 -31 82 30 -22 47 -65 28 106 -12 -10 36 -4 -56 46 -27 -27 -13 -4 -6 -35 -58 2 52 -3 -13 -47 -41 11 -85 -44 12 24 80 -27 -32 8 125 -64 90 18 -60 -109 126 -59 64 72 -43 49 72 127 53 83 90 107 127 27 77 59 123 -8 113 12 41 97 28 -41 83 70 -50 57 -124 -62 7 32 127 2 35 113 121 -72 72 126 -104 -45 44 92 -30 111 -46 62 74 7 -106 -126 -113 -17 -65 -113 -111 111 -74 -80 90 -10 52 -115 85 -4 92 105 7 110 127 2 69 77 3 1 11 -75 -62 37 121 115 48 96 24 39 42 67 67 12 125 -34 35 7 40 -54 -72 10 44 25 35 -126 -36 -21 59 19 -44 -8 -45 -69 -1 -90 64 -75 85 70 85 51 30 10 41 78 -11 21 30 -45 3 14 10 -26 14 18 -67 -48 -76 27 -20 -21 -9 -77 2 127 -76 29 26 -30 127 5 41 121 127 31 -64 -39 4 -49 -121 6 69 -67 5 -122 -100 -18 -117 -23 -26 41 4 -96 -81 11 -9 -14 106 -97 65 -126 127 -20 44 8 -28 -40 -102 -56 30 -90 -90 11 5 -99 1 43 59 5 42 -39 -31 -17 94 -1 18 87 -24 -39 -19 52 -73 -17 79 4 -67 2 -117 10 -9 -14 -13 -25 127 -71 -79 29 -8 -90 26 35 -24 -30 -3 106 -6 -68 63 9 28 5 31 35 -74 -75 16 36 39 -122 11 3 43 74 -26 124 45 -15 42 64 -18 -58 54 41 -9 -40 -70 -1 -16 -33 -3 38 -25 -71 -31 34 8 -51 48 -33 -6 -44 25 -72 -6 62 -36 -69 -84 17 -56 -128 -109 -14 -60 -88 -52 -127 -125 90 -7 -73 -84 -28 -77 39 28 109 117 -124 -72 -1 43 12 44 -5 -44 -50 -6 95 69 -106 -6 -15 -14 11 -32 -57 53 31 12 -4 -35 -88 -2 16 38 9 74 24 24 13 -24 109 42 32 25 31 -22 -36 -57 -27 -1 -11 -3 -28 -23 17 19 60 29 -44 74 -86 19 -50 -6 -92 28 27 -68 -31 22 125 6 -64 -20 -124 -97 -30 -75 -37 25 -105 -61 -35 120 21 4 -41 -77 -75 54 -9 -118 -35 -112 58 -81 91 64 -122 -89 -70 18 62 105 -119 102 3 119 -17 2 99 40 -21 -9 -51 51 58 103 -87 -10 116 -101 8 -43 125 -125 -72 -49 -64 -9 -6 -81 -65 85 56 -20 -19 49 -108 -38 33 1 11 -56 -9 5 55 21 -9 42 -87 42 -11 68 -37 37 -30 -118 -82 -4 5 9 -120 0 33 11 98 -71 -87 -79 -49 15 37 -70 21 -30 -34 1 -49 1 -58 -3 -44 53 -11 63 -27 -3 0 55 37 58 32 -14 -2 36 52 0 6 -74 26 -8 6 95 77 -39 -63 -3 -64 -126 57 53 91 27 95 -15 23 57 -26 60 20 87 33 -26 -12 59 -58 55 -60 -18 77 -51 -4 -77 60 41 14 -5 -8 -18 -40 56 21 42 -7 18 -12 20 -44 -17 -44 -9 -6 29 -30 76 -49 76 10 -39 28 33 63 -66 -1 -23 25 63 -37 86 57 99 -23 -48 -49 -79 3 5 1 58 -9 -1 -81 -74 39 -2 -1 107 58 42 62 -1 -42 -3 -45 -9 -15 -53 -68 4 28 5 -68 -46 -41 73 -101 48 51 38 72 -41 -97 -82 20 64 44 28 -56 25 -22 42 -60 -7 -7 79 -26 -36 34 -35 -27 -26 23 53 30 24 -47 46 30 29 44 60 -19 57 70 10 55 -63 -41 9 -86 39 19 -61 29 21 -43 75 117 43 0 106 -126 -31 38 81 60 122 -38 7 -96 124 -46 -55 79 -116 4 -110 -15 86 -64 5 124 -41 -120 -3 114 -117 -34 -23 123 108 -43 -38 -78 82 -34 61 50 56 10 41 -25 47 -28 23 -65 82 -14 -85 61 -43 9 53 -76 0 108 127 40 82 120 126 126 -74 1 -111 -73 105 121 115 -8 120 81 127 58 127 127 127 122 119 -29 127 56 126 127 87 104 17 -81 -31 -113 119 -56 121 -101 72 28 -95 -102 81 115 59 126 91 -1 77 8 80 61 33 31 123 19 15 -99 21 -113 44 -127 -49 -106 23 -19 122 16 92 0 -42 110 94 -120 -81 -102 -12 94 -48 -3 -43 121 61 5 -107 -86 -77 -122 92 -40 -75 -2 26 14 -17 -76 -15 117 12 30 75 -102 -60 4 -44 8 1 -39 5 -127 -37 93 29 -52 -41 -35 -2 58 -17 -9 -9 -18 109 -92 -123 64 72 -13 116 28 -16 34 74 -117 27 44 -71 -33 -15 91 -119 -104 -106 77 -41 16 6 -44 -19 -88 0 7 -14 -123 -126 62 64 -53 63 87 23 51 101 87 59 -55 -12 9 -2 -86 35 -13 12 -21 76 14 28 -50 -111 52 50 -28 -56 60 -1 -89 68 30 -31 -51 -19 -20 -38 44 19 118 -2 -80 -49 52 -41 48 -10 -36 -87 -5 -99 -26 -32 62 -71 -97 -13 33 -15 124 44 35 -45 17 -127 -13 -95 21 -3 49 -42 -83 -103 118 -125 -117 -109 -56 -83 -105 -116 25 -17 -82 -56 -31 -13 -81 -108 66 -60 18 11 120 -123 -97 -70 57 14 95 -20 79 -13 10 100 24 -51 21 -2 39 46 2 -52 -14 -22 -23 33 3 24 1 -37 35 53 16 -74 39 -72 -32 -28 -70 101 -6 -11 49 46 60 -122 78 -5 32 -128 -50 -67 -42 8 82 78 127 64 -24 -48 115 -5 -34 -105 -33 -22 19 14 49 -4 -86 -5 -10 -8 -18 126 -53 113 -19 62 0 -50 -18 -55 -96 -17 -62 46 -9 -34 8 82 -126 -63 -3 81 37 94 -22 26 -33 78 -5 77 104 -37 -16 -125 5 -9 -30 18 -56 48 33 123 77 -33 127 -65 1 -85 -59 77 -5 39 -17 73 -32 7 -10 -12 -39 -68 92 -45 -45 -3 20 -83 -12 49 55 1 -36 -71 127 -9 62 -22 -25 55 35 -53 97 115 117 56 74 -35 -26 38 85 -81 -10 27 -36 -57 -36 -23 -13 -79 20 -63 61 22 -70 -59 17 34 -29 84 4 77 -7 34 -11 -40 -117 -37 -122 48 -12 -29 -1 68 72 -15 46 -94 53 94 -128 -105 -53 -50 -51 53 16 -9 126 93 -15 114 45 -48 -97 -121 28 -41 -47 -42 32 68 26 121 19 -84 -18 -84 55 -20 -25 38 -54 70 54 -78 62 11 33 -45 -13 24 10 115 -74 -62 68 15 -106 -8 -10 -126 -111 30 33 -31 123 47 81 56 10 94 -59 127 -9 -58 118 126 124 74 127 38 80 96 123 102 124 29 22 -40 65 86 1 -91 18 98 56 35 39 81 73 16 23 11 60 17 -9 100 13 52 -13 -59 -6 60 77 -85 10 46 -44 -4 32 -123 26 47 43 8 64 -71 -125 43 -14 -35 -52 63 -40 106 9 -109 62 37 -14 -58 -57 29 -54 -122 -68 -126 -101 66 120 -28 117 47 -42 -59 112 -99 98 -91 -25 52 -67 51 -27 73 15 -29 47 -117 71 -39 55 25 25 -124 -19 -32 106 -127 -105 102 -8 12 -87 9 -66 22 17 -113 113 49 19 2 -52 -21 -7 116 21 68 126 -75 -66 -109 34 -64 26 -67 -113 102 10 -37 -56 122 -115 7 19 101 61 106 127 18 -6 90 32 68 84 73 -38 50 -60 105 117 -14 28 42 -114 -53 56 37 -31 29 9 23 -89 -13 -123 25 -56 119 -124 124 125 -62 10 -15 127 14 108 -32 -17 54 -30 -47 26 -52 85 -49 -45 -126 70 -121 -69 87 62 -30 -72 32 -2 94 99 3 47 75 15 26 17 43 21 -51 -43 52 50 77 116 83 -33 5 -64 4 127 51 -27 80 30 -35 -21 13 27 -121 66 3 -36 -30 -96 -13 -24 -49 32 52 -14 7 -91 31 -72 -54 -34 72 -111 21 -101 106 1 -97 127 127 86 21 -88 -4 21 127 -85 115 90 -72 -36 -73 127 -104 -101 -25 -76 38 -75 -32 -123 -75 -96 -103 -63 -64 50 87 -123 -47 -53 -108 -112 -5 -64 -57 -120 -126 -25 58 -50 43 -56 -31 -59 109 10 18 -75 -25 -57 50 -33 11 -43 -31 44 49 28 -42 -92 48 -13 -17 66 20 3 -56 -59 17 27 -15 31 45 82 -8 17 -1 -54 44 10 54 -74 31 0 63 -38 -115 127 44 -83 -128 -123 -21 -87 -109 127 -128 110 114 61 -128 -91 -127 37 49 1 -25 106 45 -125 36 78 21 68 -39 43 17 2 -27 -74 10 75 35 -48 -4 1 62 26 -31 85 -114 -119 -25 -21 4 48 5 -97 53 -51 -93 -16 17 -109 -100 66 97 73 115 45 91 33 -18 -125 22 80 -121 -121 -49 -115 68 -97 -27 -5 -83 -69 -89 -55 -20 92 67 -103 -84 -127 -98 -109 -72 -52 -107 -126 -22 -66 25 -2 27 53 10 -22 -16 24 40 -10 -117 76 -47 -123 0 -76 -30 19 -3 -77 52 -96 47 -48 -92 19 118 13 -116 -125 18 -49 -70 42 22 0 20 17 15 9 -11 -58 4 -9 51 -77 75 3 26 125 -5 61 -75 52 52 51 16 45 71 28 26 114 -20 65 -37 -10 36 -19 -39 77 35 -10 61 93 -82 42 -57 -14 -30 -8 13 9 13 -26 -9 -18 35 -25 88 -1 23 -39 43 37 0 28 18 -61 26 -44 83 53 15 90 90 118 80 44 -4 26 82 26 47 47 -30 -35 -2 79 -55 -61 88 -13 -50 94 127 -25 -19 76 -1 -53 -48 -128 -40 -107 121 96 103 70 42 -24 65 77 58 14 10 21 -12 -27 71 -26 -79 -51 -26 -49 0 -5 -2 -52 13 -53 -14 63 -59 -89 -7 13 68 -41 -42 75 -103 71 -76 76 84 -20 -39 15 -74 120 -35 -10 -127 -38 -127 -74 -38 -8 106 -46 112 64 127 -112 126 -21 127 -62 -126 0 16 -113 43 29 44 -125 125 12 -72 -32 22 -22 26 -94 -117 25 120 -47 -4 14 10 -34 -53 14 16 -104 57 -11 -12 23 14 112 -4 -53 -17 67 47 104 -22 -10 -27 99 -56 51 -127 114 -13 -82 -125 76 0 29 -88 -117 -127 90 -101 8 -36 -18 53 -99 -7 52 22 111 -86 112 38 -59 103 40 126 14 -77 -21 -42 61 102 81 -24 95 69 124 125 118 71 18 -8 40 -87 83 1 5 42 64 -4 63 -3 -128 -35 17 23 -45 15 61 36 -20 -30 36 -16 21 91 -127 -15 -102 97 -50 11 86 119 -1 90 -12 38 -37 122 -56 60 20 -61 -60 -64 55 -34 -82 -4 127 -40 116 114 99 113 122 54 115 -51 -6 29 123 116 103 96 76 100 82 113 127 127 85 34 2 31 -1 14 35 -9 38 22 88 119 -15 26 -37 18 -50 75 -42 -96 -54 14 -30 17 -37 -4 -80 112 -43 79 25 -16 18 51 50 24 -13 82 -101 88 -18 29 -34 16 74 13 11 7 33 68 -8 -74 -101 -32 -93 -116 -87 6 -43 127 -118 -124 31 -7 -38 -28 -40 -104 -114 -125 -51 -66 -63 70 6 6 -12 61 -78 -122 -93 -105 26 124 31 -104 -87 -127 -20 42 -67 -20 -63 -24 -11 -44 -88 -30 -58 -20 6 -42 65 8 -40 31 86 -29 -62 -96 -35 -36 46 83 14 17 34 -25 15 -26 27 -122 -67 7 40 -96 -102 74 -66 -128 65 84 102 -21 72 -126 -107 -77 -101 32 70 84 34 116 -123 -61 117 -65 -84 -15 105 -1 66 -19 123 73 -108 69 119 -19 -117 7 44 104 -60 120 -93 114 -3 -124 17 -95 42 -5 -24 -45 29 -85 -22 121 -76 -102 -111 -14 126 16 20 122 124 78 -99 -19 112 116 58 105 -31 126 106 -10 77 74 -100 -103 -128 -28 29 124 50 97 27 -54 49 114 58 80 -52 -128 40 116 -91 -69 -15 71 -114 98 -120 -1 -34 122 123 -10 -51 19 -56 -41 -29 -66 -62 15 -46 127 -128 22 -128 127 -88 -126 125 126 -36 6 114 40 -128 127 -53 117 127 -126 -97 -126 125 -48 -126 -128 120 105 -95 -128 -128 -16 -93 -120 119 -123 94 108 40 -128 -115 -127 95 -27 29 -27 116 106 -116 -33 117 16 -36 -111 112 -69 -102 -28 127 -27 32 16 -48 -93 -57 46 -76 -29 -39 -108 -37 -40 58 57 18 111 -68 127 -82 -108 83 99 -87 10 -26 51 87 127 -51 127 33 -84 -126 24 109 -102 -125 -127 12 -51 6 -126 -117 98 13 -34 -63 113 122 -64 79 -116 -121 -63 -25 -13 37 -2 -53 87 66 -20 -92 -36 125 -38 37 96 34 31 45 -83 23 -101 99 60 -8 48 -26 22 -19 49 -18 127 74 10 -2 117 -7 127 -92 -60 8 95 29 29 -15 120 66 115 -73 117 -9 -10 -27 -88 37 -86 25 85 127 -66 113 11 42 -19 34 20 37 34 36 -49 30 86 86 -11 9 62 60 77 101 71 20 3 7 -2 59 32 -1 -18 25 -74 115 -14 -15 -3 17 12 83 48 58 61 83 29 2 -27 41 -17 -3 50 -107 -8 67 -22 75 43 73 -79 -59 67 -91 7 47 27 -96 -18 8 -99 -31 37 43 -65 -92 25 63 -2 123 104 16 -38 -4 -84 -16 92 54 31 62 121 124 42 -64 58 113 126 46 -65 28 -49 -79 -65 -49 -7 -66 41 -18 -98 52 20 41 30 23 -13 14 -34 100 -52 -78 5 -36 -81 -85 -93 67 -127 44 80 -94 -40 -24 -68 -118 -77 12 64 94 126 -92 38 110 90 -105 114 92 -83 20 -36 0 -108 68 65 -3 -34 39 86 100 18 85 -113 -53 99 -17 23 1 -29 -36 -6 -8 30 20 11 64 -27 -29 14 89 48 18 -77 47 74 107 -13 81 35 35 32 127 89 13 63 88 14 -16 123 21 80 -49 -55 -36 59 -65 -86 -70 -24 -46 44 -57 56 11 -43 30 -19 -23 -6 -8 100 22 -83 22 -56 42 -126 -100 109 -19 -66 15 -122 -31 2 97 38 104 -61 -37 41 127 -82 -127 -61 12 -110 5 -8 -81 -9 56 -51 25 -65 -56 -32 87 16 33 -8 84 26 13 -3 -64 -37 -6 72 -119 13 -49 13 -127 -61 79 86 45 115 -34 34 47 113 37 33 48 -68 -7 -103 112 -102 -9 60 -18 125 -48 -46 -76 112 -17 -11 127 122 95 122 -35 -108 -127 -100 -87 -76 -83 -69 -118 -23 29 9 -43 40 83 -34 -59 63 52 -27 -59 -10 -60 97 31 -14 -45 7 -6 43 33 -5 55 -93 -33 -117 30 -24 69 -48 -34 83 -42 -68 19 -70 5 -32 -7 -62 66 -21 -79 49 49 120 -26 -20 8 -16 -109 23 -3 88 49 122 21 -84 -41 59 -38 -27 78 127 54 47 -37 68 -81 -13 -80 -45 82 120 35 -46 -103 10 -82 88 19 5 26 -54 75 -107 -82 -52 68 -68 -4 10 9 83 116 7 31 -120 114 -76 124 -125 73 63 -123 -127 -39 -22 35 -121 -120 -127 127 -110 -118 77 110 106 -118 114 44 -105 -114 126 -122 12 -116 -88 -108 -108 21 -28 108 122 -99 -120 -59 -112 -125 -127 -100 -85 -127 -120 -101 -25 -30 119 -36 -8 -44 18 -23 -13 -115 79 -35 90 -20 -27 -40 -41 -46 25 32 -21 -7 -54 -21 -38 127 -67 75 -78 64 121 -57 -127 -44 -2 28 -96 -4 -128 -45 -124 -42 -8 -51 90 -115 109 -7 26 94 -51 69 -87 -2 -110 22 29 28 71 -102 -51 27 -85 -29 17 12 -26 56 49 77 -32 -12 -19 29 39 79 -37 7 18 32 -36 46 78 4 -4 24 24 -50 35 -44 23 -71 -15 93 -36 -27 -22 -100 13 -75 41 15 7 -30 122 115 -48 -62 11 99 116 -46 89 37 21 -10 -1 68 -115 -3 1 59 114 35 127 71 -40 27 -10 -24 -26 -28 -30 -123 108 18 117 1 -27 0 93 3 -127 5 78 33 117 -103 87 22 -72 2 -49 -68 0 -32 -4 -90 17 20 -113 -46 -88 91 -7 5 -9 35 102 38 -122 9 -45 127 47 11 -48 14 -62 -52 -43 -28 -79 -58 -33 -9 -37 40 14 9 75 4 17 -33 37 86 127 127 102 127 -56 -49 -9 -43 -26 -21 126 94 127 119 107 19 108 36 121 124 -1 -22 -21 -77 98 2 -21 -1 25 96 -7 5 39 7 11 -10 -30 45 48 17 69 -28 31 -6 -70 116 -56 127 -52 68 57 -62 -75 -37 -41 -25 -39 -77 -84 94 -30 -52 14 121 7 -105 114 29 -76 -101 94 -127 -128 -80 -124 -119 -112 127 127 127 126 -20 -119 -118 -110 -123 -121 -124 -123 -121 -121 -96 -15 1 78 -28 -55 16 22 23 74 8 4 -12 26 32 15 43 40 44 32 52 61 0 11 58 11 -13 16 -39 41 -100 -32 9 25 -77 19 -90 7 27 44 -30 81 21 -23 -33 -25 13 -64 -41 90 48 2 -6 -26 117 -37 37 10 81 20 -35 -23 51 -28 -20 -51 12 53 27 -29 -19 75 23 5 -37 59 -35 5 35 -6 -39 -9 -18 26 32 -34 -16 -51 37 -64 -43 60 -14 87 31 31 14 -4 -44 48 20 13 -40 12 20 22 -59 -11 7 -81 -95 -6 -21 60 13 0 32 91 -17 6 -72 -29 -4 10 -30 -41 51 8 11 4 -20 -23 4 -6 -35 -40 -1 -85 48 -13 -4 88 -53 -81 32 47 50 49 -4 10 -47 37 -11 26 -34 -8 19 -5 6 50 50 -17 -24 9 3 19 17 4 -72 3 8 -18 -27 8 16 32 -95 14 -33 -28 30 -13 1 19 3 -16 19 21 30 -56 51 -33 62 6 1 -13 -43 20 -48 -33 -33 -14 28 70 16 15 8 -49 -73 3 -21 25 -26 19 28 32 50 -78 12 -26 78 108 78 -5 49 -7 -60 -10 14 56 -46 -40 50 -4 -4 36 -29 28 -13 -11 27 3 31 -25 -25 9 47 -47 35 -13 -5 -22 27 25 -25 20 -29 -80 -6 47 -30 -99 -43 10 -28 36 50 20 24 0 46 12 -52 -53 -51 15 -13 -19 64 45 -30 -66 -30 3 -28 48 56 31 4 -10 -12 1 -1 -12 -4 11 23 -29 29 -1 -8 26 -17 8 36 0 -11 8 19 7 45 33 56 -32 22 -17 32 49 -67 -18 40 8 3 -20 -21 -2 26 -46 25 -13 3 13 22 33 -39 -23 55 -35 -11 -23 -3 92 60 45 44 59 -28 -29 -7 -29 -42 5 -24 -19 -37 47 38 29 -93 29 -25 -39 48 7 41 -10 -24 96 -16 30 33 -46 -6 11 42 38 29 -44 -46 -91 -37 39 -63 28 -22 32 75 26 14 17 35 -61 -52 77 -45 13 -20 65 34 21 -34 -56 -14 -26 -59 -42 56 19 20 59 -36 15 57 85 -92 18 53 -3 -37 -30 41 39 73 -17 -98 18 23 0 -36 -59 0 93 -45 39 -31 -19 31 -40 -23 7 -3 -63 -8 17 -37 3 -23 5 -14 -25 -28 -7 5 21 27 15 28 -2 58 -5 29 -25 40 -5 48 -48 20 -13 -10 -28 -16 -22 -7 -17 20 22 -28 -18 40 -10 -33 3 -42 -2 96 44 26 10 -15 30 12 35 41 -28 62 26 -25 -12 -5 16 -20 24 26 -34 9 -3 17 8 -62 -2 -60 -30 -12 -52 61 29 -11 -46 25 22 -12 10 3 -1 86 41 36 -30 -20 -10 -1 21 22 10 -3 -37 -73 21 5 -25 36 -21 53 -18 21 26 31 21 -17 30 13 40 25 -31 -14 22 58 37 51 -19 13 -20 49 -49 -3 8 -1 54 23 -6 30 2 33 20 13 -5 28 1 60 -53 12 2 14 11 -18 5 -15 -11 -17 17 -9 22 -21 26 24 2 -16 2 -30 -11 -15 12 -10 28 -7 -37 -26 32 -22 -19 0 11 13 4 -11 5 13 -18 8 -24 49 -10 -8 -16 15 18 -19 5 -61 39 32 -62 20 -12 -68 7 -64 14 37 -17 -12 -50 15 60 78 35 -36 0 0 -24 5 22 11 -15 38 -10 32 36 29 41 9 -56 57 -28 -11 7 104 -72 -23 -10 -14 -30 40 -32 -25 14 37 28 -42 -10 10 31 40 1 21 -42 65 -24 -50 55 59 -27 44 9 5 14 -52 -37 -14 51 89 -28 18 -6 15 -9 4 30 27 19 -6 23 14 -46 16 71 -13 19 40 -67 -41 -25 47 -17 -21 -56 -31 1 1 -18 -22 25 -17 68 45 37 14 -50 -11 14 -16 20 38 -29 -36 -20 -4 33 53 -12 -10 11 -22 45 -7 -23 -10 63 -60 31 -47 -49 17 -14 1 -1 10 33 -4 13 -25 15 23 -15 40 19 50 -38 -79 24 61 35 -24 34 40 -32 -50 -58 63 24 5 -19 31 -77 19 2 -34 -42 -16 -17 -16 74 -38 -6 -15 93 -48 40 -14 0 1 -41 -7 -44 -42 -23 57 2 13 3 -13 22 -38 45 48 -21 26 23 12 -19 -3 69 -40 -83 -4 -2 -68 -29 80 -45 29 102 22 17 -45 21 63 39 -61 9 43 -26 -43 -16 -6 -53 50 -13 -23 21 7 31 -2 -11 37 -53 -26 -21 -43 15 10 -39 -32 -50 15 11 12 -12 -27 17 28 -11 46 -8 -14 -20 -53 -3 -3 -17 37 -70 44 -7 -9 -26 -43 -15 8 27 -10 -35 7 52 -30 8 5 2 3 24 18 49 24 28 -24 9 31 -16 -17 67 31 -47 -2 -77 10 -24 32 45 -35 -5 -5 8 30 -8 -40 59 -11 -20 31 52 -37 10 35 62 16 -21 26 50 9 7 -35 -13 -55 12 16 34 63 31 45 12 -54 -29 30 -2 -23 -9 66 20 -18 -24 -52 -41 -44 1 -31 1 14 53 -31 71 6 -5 -35 27 29 -6 -33 -33 61 -16 67 53 48 24 -29 -44 -11 -62 -45 1 -34 45 -65 -22 2 -57 -48 11 -49 11 44 -22 -12 -10 -6 -6 22 13 -33 26 -18 36 26 -43 13 -2 -13 -6 -29 -20 -32 7 -23 14 5 -28 -17 26 -33 -31 26 -12 -14 -34 -54 -40 22 28 20 35 -59 5 0 -29 -17 -20 -1 -37 39 -11 89 -17 6 41 -17 52 -26 -89 29 4 -126 -55 -43 -28 -58 -43 33 39 92 42 -17 0 2 -42 26 -42 44 30 15 -28 18 -42 -29 -24 -16 39 -32 47 10 2 83 -5 -15 18 -10 27 40 32 28 -48 -7 66 -40 -1 1 -15 -17 56 17 37 -51 -78 19 -61 -18 -9 28 9 57 68 -8 8 49 -19 -22 -20 -7 -25 -68 16 41 2 -53 27 -86 -37 21 18 11 53 -5 6 -28 8 10 -78 -2 -26 9 -3 -12 -1 -3 -1 -36 -7 -1 20 14 -34 8 29 -3 1 40 -1 58 7 24 -11 -39 25 -37 -2 -30 5 -7 13 4 -53 -20 -21 -7 16 -18 -2 22 2 12 0 -6 23 21 -19 -23 33 28 -39 -21 47 19 68 -25 13 92 17 -27 5 -7 -61 -15 -9 17 60 -13 -71 21 28 36 -57 -27 33 6 39 -22 41 93 2 -46 -22 12 13 31 -13 -9 -41 46 -31 51 -43 -27 -64 11 70 -13 11 -44 16 -3 -32 -22 47 -8 -13 -71 -45 12 35 -1 -7 -19 9 -8 54 36 5 15 -22 87 -84 -9 -54 28 -32 25 -77 -20 7 -13 -67 -21 -21 -68 -75 21 -32 -24 -88 16 -56 -39 -36 -15 -27 13 -15 37 26 -7 -14 -54 13 31 23 -27 -25 12 -39 57 -5 47 6 21 -42 7 23 -14 -11 23 -8 -16 5 -33 34 13 -36 -77 6 23 19 58 6 -30 66 47 -12 -24 27 -46 2 -83 0 -26 -90 39 -15 -33 112 -41 -69 19 52 -19 -32 -26 -43 -17 -7 -14 -16 -66 12 2 -17 -1 -14 47 9 -126 -121 -65 15 -49 -2 37 -6 6 5 -83 -60 -40 -41 88 -39 8 -36 -72 72 34 28 -45 -54 3 -82 16 58 -9 127 -46 -74 -57 -22 -67 -28 50 -16 -37 14 38 -40 -79 -26 -10 34 10 -68 -40 -9 -70 4 33 25 -12 108 -60 -7 79 -19 44 105 30 2 -74 40 78 80 12 56 -23 10 -18 8 -114 58 31 44 21 29 14 -19 -56 4 -88 32 -20 -37 -23 -26 -7 32 -43 53 62 1 23 93 11 28 -18 8 -9 28 4 44 -15 20 39 37 -99 46 -5 -9 -34 61 9 11 -55 -35 46 0 -1 -32 -57 -40 4 -18 -16 -19 -15 43 49 -58 72 -71 -1 37 82 127 -12 -54 35 -20 -37 -6 19 -74 -39 -16 6 47 68 -17 67 -35 -124 -12 80 43 62 3 -21 -57 58 -83 -38 29 -34 1 -12 64 -78 42 -21 -78 30 -74 -38 -56 18 54 -80 46 19 -17 -18 -29 -48 -33 -44 -48 42 -44 18 13 38 39 13 6 -74 47 3 -6 -25 21 -13 -32 3 -20 -5 -1 -36 19 -37 -31 48 15 7 -62 19 -7 46 -11 -15 4 13 35 35 9 37 2 0 -53 -28 57 -7 8 12 -29 17 -4 -6 17 26 -17 -17 -10 4 -8 -24 -6 7 -14 17 -6 1 -3 -82 -51 46 -11 26 -9 -25 9 30 12 41 50 -28 15 48 0 -26 -29 -57 -19 25 -45 -17 17 -42 25 -18 -21 -22 24 0 3 -5 -2 73 78 2 -41 17 22 -59 74 33 41 22 37 -75 29 9 -9 -18 22 42 22 32 32 7 -48 -66 -52 -1 43 -82 54 35 65 -56 45 81 -40 52 -77 -55 22 5 -33 -48 19 -32 25 -74 -3 36 -18 71 0 -7 -66 -7 12 -48 -45 -57 -8 20 -17 7 6 -24 19 14 -10 -6 29 33 -25 -4 55 -24 -25 -31 -13 2 27 3 35 -25 38 -14 24 22 -42 52 -22 -21 -41 -23 12 -18 -35 3 38 10 -18 -6 1 26 -50 37 -43 18 -16 -11 1 0 73 -73 -38 -3 2 -3 22 8 -20 -8 -12 29 0 38 -15 7 -4 30 -35 -43 -23 -8 48 39 -86 55 21 -5 102 -36 -54 -79 10 29 -12 32 60 45 -30 -17 45 -30 -116 27 -74 -66 -34 -25 120 -40 -5 -52 -17 -22 117 -8 82 -65 5 -18 21 21 -9 14 51 -21 -20 45 59 -56 56 -4 -48 47 -4 1 -36 29 -13 -7 28 -35 38 -100 -71 33 21 -36 52 19 33 78 37 -20 3 22 -12 10 -5 -28 1 -3 -6 -73 5 -82 -39 -49 18 1 14 56 18 4 34 26 16 -2 40 34 -41 23 -19 0 -12 25 -9 6 -8 -14 40 -11 -11 29 -23 13 22 -42 -61 2 -11 -8 -33 -3 80 -59 -47 47 0 18 -25 46 85 10 -6 -27 -5 67 -69 64 -40 -118 -25 -37 -65 -63 -46 -9 16 17 -84 -9 34 -89 -61 -1 3 -64 -70 -33 -5 48 55 67 30 -55 -29 24 -59 49 -35 50 66 0 43 74 -47 52 -50 -27 48 14 -53 67 -22 14 17 50 -28 22 68 -54 -15 -20 -25 -24 71 -9 -10 -17 40 70 -23 13 -81 35 -11 40 3 45 77 100 2 64 6 -31 42 20 -24 37 13 3 1 1 -11 17 64 -72 63 -41 64 -17 30 10 -15 -12 -15 -41 29 63 -32 38 40 0 -1 -41 22 19 -27 40 24 -87 4 -39 -41 -12 3 28 63 -57 -28 -41 -25 -13 43 74 -17 -76 124 -48 -5 117 100 -93 -58 -62 43 -37 73 -58 27 24 -22 -25 -46 -84 12 55 9 -4 1 35 10 76 -50 2 113 43 -34 -41 23 57 29 40 17 94 -94 -42 29 9 6 -14 -102 21 32 19 43 -62 36 -8 36 75 -35 -37 2 41 -9 26 -42 30 -45 42 -22 -2 3 7 49 -122 -17 -22 -1 -15 20 37 78 99 44 -26 34 59 26 33 4 21 -41 35 -4 39 19 8 36 -124 -2 18 -107 4 -96 36 19 -7 25 -95 25 37 22 -14 22 -27 -59 -31 -11 98 -34 91 -6 -63 18 -15 -45 -33 -81 83 -17 -25 79 -61 -101 12 -33 -12 38 -14 3 20 21 23 -15 27 -19 -4 -43 68 -45 -67 -45 -15 -83 -38 -39 -61 2 -28 -27 -54 7 23 -39 -53 -89 -123 -24 38 -37 32 8 -82 -15 26 48 -10 66 13 63 -63 -12 2 79 -1 92 32 106 17 113 -50 26 -57 -69 -13 18 -6 122 18 48 47 8 10 -75 54 23 82 -4 -22 27 9 15 2 3 54 -29 -56 62 -33 -17 -35 -16 -2 -14 23 27 -19 21 -38 5 -50 1 -8 -43 -46 9 43 55 -97 74 66 -43 -84 100 37 43 -21 -38 19 74 -43 -28 -50 -22 10 -13 -17 58 -14 -116 -57 27 -52 -35 -89 38 -51 -60 -45 -11 -26 23 31 27 -55 29 17 29 49 33 47 57 -13 1 1 15 -4 -13 8 -12 15 -28 -28 -2 9 -12 5 29 -39 26 52 -31 51 64 20 -47 -63 -27 34 68 31 54 -13 -7 34 -59 -1 -107 -20 -64 35 0 18 30 44 18 -67 -58 26 17 -26 -40 -37 -109 -12 21 24 -66 -1 -39 -20 5 47 38 -35 78 -19 -24 -36 26 -66 28 -59 -27 -33 -21 -55 -52 37 -21 8 54 -34 -5 -53 -38 33 1 -40 -16 4 8 -67 -1 31 -5 -33 -36 -8 -12 -20 16 52 10 21 13 7 -45 -19 -18 -30 -44 13 -13 -11 9 3 -6 -22 36 -3 -27 -37 -8 -16 9 28 -1 4 -26 39 -25 -1 14 -28 -10 -16 6 -1 -9 -15 -12 -7 20 -8 -4 -1 18 -28 -22 21 -7 35 -12 -3 28 -35 7 -22 51 -1 -29 51 31 -5 -17 -18 66 -30 -39 21 5 11 1 -26 46 -50 7 -21 38 2 -36 -1 32 12 -18 -45 -15 40 -39 -50 62 64 -12 -29 43 1 -27 0 24 19 42 -34 10 -53 100 -9 10 -92 -10 8 -55 27 -6 6 9 9 0 -16 13 -21 86 36 49 -9 -66 56 -53 -25 55 -53 -9 -28 20 65 -56 -1 -71 -15 -3 95 38 40 6 -60 -46 -69 -38 -7 42 -12 59 39 4 35 -18 -28 -52 16 52 -9 31 28 27 1 7 -1 -52 -42 -6 -14 4 -10 3 -26 -23 34 -89 52 17 -57 19 2 25 10 19 14 -3 -7 26 -38 -5 -2 -27 21 -8 16 24 -30 -32 -60 40 35 47 -60 -56 15 -12 22 -37 2 16 12 13 -46 -40 -66 -66 -56 -67 20 -10 -58 -27 -36 19 19 -65 11 11 -57 -4 -31 -29 -31 -45 -78 77 42 12 -53 44 -19 -34 -60 -42 -13 1 26 57 24 -27 39 -37 -12 44 -44 -34 -67 43 50 29 4 21 -83 51 33 -6 13 -74 30 2 52 -12 4 16 26 -32 -53 3 -23 34 -44 -21 72 10 -35 -33 -35 11 11 -4 52 -2 6 -70 64 15 -17 3 16 -14 4 -52 -73 -2 -22 -18 -89 0 28 12 -51 -23 -24 10 45 34 13 -61 -9 33 -55 -6 -5 -58 35 11 -16 22 -36 -19 -60 50 3 -55 10 -31 -27 -62 45 -64 46 11 18 90 50 -20 -36 -103 30 7 -6 -12 -24 1 6 9 62 -12 -68 -27 -79 -37 18 85 14 -11 -29 54 -57 63 47 -15 3 17 -46 101 76 31 -51 -40 -20 -60 -43 -9 15 -39 -60 1 -15 5 -41 -34 27 -23 8 -23 45 -25 33 -70 5 -41 46 5 -8 51 35 -38 -34 -67 -122 -11 -50 -6 11 10 -41 1 33 -27 -40 -7 -65 72 35 0 -30 -78 25 -11 61 -15 -44 -33 22 -51 -41 71 40 3 -36 10 40 -41 -22 -21 3 -1 22 11 8 11 49 -31 -17 -11 -7 74 -65 12 16 32 -22 -3 34 15 35 -3 20 36 14 -25 31 -4 65 11 -39 -22 -78 -28 3 -11 14 22 38 -45 -15 -32 -77 -58 17 -65 11 24 -33 22 10 -36 36 4 -48 71 6 -92 -77 71 -17 -46 -43 -18 87 -40 77 -63 -16 -26 -16 -27 18 -39 -67 88 -74 -9 28 69 -11 -37 0 -14 -68 7 16 34 27 -15 -23 16 -28 33 55 6 36 4 -59 19 93 -59 2 78 26 -1 8 0 -8 28 -2 -59 42 2 -23 -18 -98 15 68 -10 -12 69 84 9 7 21 -34 -31 8 85 66 -34 9 38 106 53 22 36 -11 35 -36 22 2 19 -66 33 38 -16 5 41 44 16 -30 -58 -66 50 0 -51 36 -1 -21 -4 -38 37 2 -36 -26 45 -18 36 20 -44 89 -13 14 38 -77 4 -5 17 7 1 89 -49 69 -22 48 26 31 43 20 -58 -39 -18 -26 79 11 1 -3 -28 69 -26 22 93 35 10 -16 -34 -38 -54 14 -43 -1 25 72 -66 -30 53 -30 -6 -11 49 24 -31 17 70 78 31 40 84 -7 118 15 48 -56 68 -40 -8 44 -35 13 8 -32 -8 -53 41 32 42 -59 36 13 36 32 14 32 105 -60 -57 -54 -11 -49 -55 43 75 19 -4 -32 10 -50 -24 4 -15 -101 30 39 6 -2 -23 54 -19 -29 -12 -12 12 3 11 31 29 1 -48 -71 -57 -41 -35 6 46 -1 17 27 -5 30 -11 -28 -6 -32 42 -9 -45 -28 -5 32 7 -22 -17 20 -9 -26 -12 -11 24 21 31 -19 42 -17 -20 41 13 -15 -97 -52 49 -21 -5 28 -9 35 9 24 75 0 69 -65 -98 -4 10 48 -38 4 -95 41 -7 -11 -39 -45 -15 -11 -59 -83 -59 -43 -41 -22 22 -73 58 -10 -46 -54 9 -13 -102 11 -50 -2 14 -78 8 -32 1 -65 -27 -24 -1 -40 -33 -54 17 -15 9 -70 23 -8 17 -25 -87 -12 -28 19 -1 22 -6 -36 11 -34 -97 -71 -11 3 -1 49 -33 -7 -28 -7 -16 -127 16 5 21 -13 10 -53 44 -70 50 -13 7 -16 62 29 -20 -78 -8 -13 45 22 41 -11 1 3 39 -11 -15 30 9 -68 -37 37 21 -33 35 -5 -20 66 -41 -8 21 20 -45 -49 67 1 46 -13 -14 -55 -14 24 -11 -3 -54 -4 7 49 -40 80 86 -29 -13 -42 -42 25 30 -6 2 23 40 97 5 71 104 50 44 -39 -6 99 47 -37 -12 12 36 120 6 -13 -55 58 72 104 -1 77 -14 26 25 22 73 17 48 -29 6 76 45 -62 11 -47 36 -7 50 -35 -26 89 5 -60 -6 -3 -30 48 -80 29 11 81 -21 32 -18 75 -59 32 31 -43 32 47 34 15 51 15 17 -6 -52 14 60 -23 79 87 19 -34 -2 2 38 -60 -36 -24 19 -15 31 29 57 29 22 33 43 58 -49 -28 13 21 15 42 -24 -30 19 23 48 -55 8 55 -15 36 53 -66 14 31 5 -46 5 44 -34 -6 30 -41 -18 -42 86 -3 37 -17 21 47 10 -10 -13 2 43 5 -41 10 35 20 -7 2 14 -38 -3 56 -32 -43 -23 -34 55 -31 9 28 -8 -53 2 -23 22 21 58 -1 19 3 -37 41 15 -6 -43 -31 -32 -41 -24 -5 19 23 54 28 5 -4 9 -37 -45 16 16 12 -3 9 0 -5 42 -25 29 -12 17 10 34 5 4 -42 -8 8 -25 42 21 26 14 17 34 -5 3 8 -15 -44 64 13 9 -24 22 31 -41 -3 44 -14 -28 -13 -5 7 17 -17 -15 -11 -1 1 48 47 0 6 -43 34 6 16 30 -23 -12 -28 -6 -7 3 65 5 25 16 4 1 14 26 -1 -37 -4 -6 -7 -10 18 -20 -9 29 7 13 13 13 17 -3 6 -47 14 39 64 -34 4 -20 -17 22 52 -56 -2 -47 -7 -31 -6 -38 -4 20 -7 -5 31 34 1 -69 18 -47 -44 -42 -23 -36 38 31 15 9 52 -28 -14 37 46 50 0 10 -9 46 1 -70 52 1 12 -8 21 65 -29 6 -13 22 60 -4 4 1 -21 9 14 11 -14 15 -63 -25 -4 -11 -15 -18 -52 12 -49 -38 -17 14 -12 26 5 3 11 -38 37 51 -21 9 -34 -15 25 -40 -26 -21 10 24 -27 -14 22 1 8 10 -29 -33 -10 -8 44 -3 15 -1 -37 -2 6 8 -35 -9 3 -7 -45 -14 -33 36 -29 -28 -18 -6 17 11 12 13 8 13 7 15 -36 -12 -17 35 39 -21 -21 4 38 -20 13 -11 -34 -18 31 89 -27 -55 28 -5 -6 -64 42 -20 1 -2 8 81 81 -2 -20 41 -10 -56 -66 28 40 32 28 -29 62 11 44 -30 -15 -55 -5 49 35 38 -29 54 37 -75 -76 -10 0 6 -17 18 30 -23 1 -6 11 -49 -22 -58 -53 -4 12 11 4 6 22 -14 2 -20 52 26 -1 -80 38 40 12 -2 16 5 20 34 -37 27 13 -61 25 -87 -57 -4 -3 22 2 -43 53 45 38 -1 -12 -13 -22 -8 10 40 -25 12 0 15 -5 14 0 11 -20 21 -1 25 -20 29 3 28 -30 -8 -38 29 50 22 -10 -1 14 40 16 -5 10 -24 -24 -40 -15 -13 16 -7 5 -13 -49 17 27 -3 -13 -18 -20 6 36 6 -31 31 56 13 -33 38 -19 40 -24 -14 11 27 50 82 -36 15 -35 -19 -3 45 34 -12 14 17 -50 -25 0 -28 0 37 60 50 -37 12 -13 15 -15 66 5 -38 -27 2 28 31 -4 27 34 -13 35 26 57 -22 -14 -9 -28 -34 18 25 20 11 -46 6 36 13 15 37 9 4 -44 -4 -12 18 -24 -1 34 5 52 -18 -74 13 21 19 7 49 -27 -38 6 62 37 -1 18 9 -32 13 4 19 -9 34 -9 -22 17 -4 0 19 16 17 -43 -2 -21 11 14 -26 -9 27 -22 7 25 18 13 -12 27 0 17 -23 -63 -31 -13 -25 -25 4 -10 -8 -35 19 39 -8 -55 26 30 42 -59 -19 23 9 0 -5 33 -20 -59 15 -55 12 15 -16 4 -4 -19 -54 -6 7 20 -13 6 -53 45 -28 -49 24 -22 -14 -39 34 15 -8 16 38 33 24 -1 18 -17 9 43 47 8 -5 13 -15 28 -13 -14 12 5 -32 -24 -29 -27 68 -45 -32 42 -4 34 2 16 23 -4 -3 0 -14 77 8 26 27 -22 7 -4 17 -49 13 15 -8 23 11 -9 9 35 30 32 -11 -5 -3 20 18 -10 15 47 10 19 -2 59 -9 -26 -21 19 -12 9 20 42 18 -14 20 -52 4 21 28 -11 35 27 -21 -4 -11 -22 -17 29 23 17 -8 -4 13 -14 -33 19 7 50 24 0 -25 30 -4 -28 30 -43 -44 -21 57 26 -8 -10 -35 22 10 15 3 1 -33 -20 -10 23 9 19 -29 12 5 -2 35 -74 33 -13 -5 -72 -40 3 15 -2 -3 -47 26 -29 10 -19 -25 -27 -60 12 -35 -89 -18 -23 1 -48 30 -13 6 -19 -53 32 3 -55 38 -17 1 -13 15 -20 -3 -6 -24 32 -25 -7 -5 -30 32 -6 2 33 -31 54 34 17 13 23 10 52 25 24 41 -5 38 11 20 24 5 -34 2 -9 -16 -17 -8 2 1 0 8 -1 0 -14 -21 15 16 -15 14 24 7 -31 -9 -28 -5 -13 27 33 34 23 -37 9 27 -9 20 -16 7 8 -49 -25 15 -8 -22 14 -28 -38 2 -24 6 -14 -35 7 44 0 -27 45 -21 -23 24 -78 7 -26 4 16 -4 -1 -36 10 18 -1 84 -6 55 38 -39 81 -61 -46 12 -13 52 8 -71 26 31 -17 -3 19 10 -63 -5 8 32 29 -11 36 6 -32 34 -14 -7 8 19 -10 -2 -29 -6 27 25 -14 46 -12 37 4 49 10 62 -23 43 -32 -5 -18 -18 -36 -10 11 4 2 32 22 -38 -9 17 16 -12 38 22 36 34 9 -25 2 -19 -9 -19 -19 -3 16 -15 0 22 -6 -21 -1 7 23 -24 19 -15 -6 -28 -28 37 10 -2 -3 -19 13 -12 -22 -7 -22 5 13 -26 4 12 17 -34 28 -6 -28 15 24 -22 1 -8 33 -28 14 1 29 13 3 -8 59 13 11 26 -26 3 -21 -34 13 40 59 7 16 -5 -18 -25 19 5 -15 14 -67 -3 12 -16 8 18 -1 43 17 -56 -6 15 22 -6 -2 -48 60 -18 11 4 -11 13 -53 -3 16 -12 -1 -2 35 -23 -2 -11 9 -17 -44 -23 3 -1 -9 4 -16 12 7 2 -14 14 -4 14 -42 35 10 -28 19 10 28 30 21 65 39 -13 -7 -13 -22 18 6 7 -16 -10 36 -50 5 -23 34 -6 -26 -3 -39 26 -20 -11 5 11 -2 22 -29 -6 -21 -9 18 -31 29 4 -15 14 -27 26 33 24 15 -43 -12 -43 9 19 -31 -13 -27 -27 -6 20 -21 1 13 -12 -8 -6 -36 20 2 35 10 12 35 -20 -23 -29 -10 50 11 41 13 -46 17 -44 -46 27 23 -6 10 26 26 -14 45 54 22 51 60 35 7 43 27 -35 -38 -1 37 -15 -24 -2 -28 -7 43 -44 -14 4 6 -18 13 -13 21 -3 -17 62 23 -59 41 36 15 -2 13 -34 27 18 -29 -6 5 37 -43 6 -4 37 3 4 79 23 -27 15 -32 -25 -1 -1 67 -14 -19 7 -4 -15 -13 -39 11 36 9 -44 -26 22 7 16 17 0 -33 -42 -12 5 -11 -16 -7 20 -31 -31 -11 -16 -22 6 11 -3 44 32 -17 17 0 -55 26 49 11 -5 14 -36 4 15 20 -6 -15 -37 -2 -40 7 5 1 22 -13 0 34 14 19 48 10 -17 20 -17 -38 -27 -61 3 26 7 -17 -41 -32 -18 20 72 49 -18 -9 -18 3 -3 18 52 52 26 6 19 6 -96 0 -26 -7 10 15 -18 -32 3 -19 44 -26 13 -46 -50 -28 34 0 14 30 -42 -19 -21 30 22 -44 74 -29 -4 -11 -2 1 10 -58 -7 57 -44 10 -13 -13 7 6 -13 -20 81 -27 -22 18 -7 11 -12 -5 4 34 -13 54 -7 2 -23 -51 -13 -9 -37 -34 49 61 30 39 -3 -57 3 -31 17 -22 16 -33 19 -9 -1 65 -32 6 -38 16 21 -3 16 14 7 29 -57 19 -33 -5 -13 53 63 0 4 37 -24 53 -39 9 -91 -1 38 -17 19 -37 -41 -12 -15 29 4 21 -15 -31 -8 12 -16 -4 -24 -118 12 -11 -64 59 -8 28 24 -69 -10 20 27 -20 55 29 -69 -14 -29 -12 36 -50 74 57 -116 22 -28 80 16 -20 -38 10 -2 -1 35 13 3 29 46 -45 -25 15 -26 62 2 -1 31 98 -53 49 -3 18 -25 45 36 -43 -49 22 -6 -36 35 42 9 -19 -22 54 -3 12 12 49 -16 35 -20 34 75 -42 -33 42 -77 -8 -15 -5 -27 -12 -45 55 -5 51 19 12 30 -33 -43 -58 -12 15 5 52 38 -16 3 0 3 -25 26 11 38 44 41 -27 -23 -7 -45 -24 -29 -13 -12 44 -3 -21 36 -56 22 -50 50 18 -9 -59 38 31 30 5 21 -1 -46 -2 7 2 -26 10 -31 -6 -10 33 -74 74 -86 -105 -30 -13 -78 33 -37 1 33 -72 14 3 -96 23 31 -19 52 -53 6 47 -52 -36 -27 -50 -86 22 29 -19 24 -63 -96 -19 -33 -49 -113 3 -23 107 34 25 -26 11 49 39 -28 -15 -31 -4 -19 -8 -12 -42 -7 -20 -6 -32 86 -17 10 -96 38 14 10 42 -74 -17 -53 13 4 26 -18 -11 76 -8 55 -29 -11 -25 31 39 63 -14 -26 -21 20 6 5 104 40 5 22 -25 4 4 24 -32 6 -29 -3 -52 66 20 -30 -28 -23 -32 8 -16 13 16 -2 29 28 -31 3 -13 -77 10 16 -3 24 3 35 17 10 16 -11 36 4 6 43 56 -11 -23 28 26 -7 -44 1 -1 15 39 49 30 16 15 58 59 -59 50 25 1 -93 43 35 -8 19 -114 -101 -25 24 27 11 -12 -19 -14 -12 40 27 14 -21 32 13 -9 -47 -25 -106 11 -22 -4 33 -55 -33 -25 -67 -113 7 -25 -34 26 16 42 -14 20 -2 5 -25 -1 -31 -85 12 -2 -51 40 18 -27 -17 -15 21 10 15 15 -54 -8 17 -72 16 -38 -29 -26 0 -52 -18 -21 -51 46 -41 13 -102 -28 45 -56 -38 90 28 16 -4 -27 1 -14 -22 -18 30 -74 25 -1 -12 17 9 5 35 5 -6 -9 -16 16 21 22 63 28 20 -10 -31 -36 -9 -40 12 -41 4 8 -26 47 -34 3 2 19 -14 5 -4 26 -1 -27 -1 22 34 -13 24 -78 64 30 35 13 51 -8 -76 38 52 -31 23 -22 -27 34 -108 0 -43 -59 17 -109 56 -5 -16 20 -8 51 3 12 -8 -45 5 32 -12 9 -28 14 -114 -42 -29 -68 -15 -34 -9 -71 -40 -28 -78 -5 -1 34 -27 23 -19 31 23 -5 -33 20 -17 -16 -25 -92 45 29 24 3 -15 -29 -6 31 37 -57 -48 34 -76 -37 26 38 111 27 -41 -6 -27 67 -48 -37 26 -62 -90 25 -69 47 -27 24 18 -4 13 26 -38 -37 37 -1 13 29 0 44 15 -41 -2 -13 31 -6 31 2 -28 0 -16 15 5 0 14 -12 43 -43 -41 23 -59 65 -11 -17 -9 45 25 -47 -14 -48 -11 4 12 -26 -20 -5 -9 -43 -11 -1 -11 -29 -15 23 -17 -3 -2 69 10 14 -38 12 30 -3 45 52 -1 19 34 -8 30 16 -37 -23 -85 -5 -11 -12 -46 29 42 -5 10 -14 23 -27 9 16 24 12 15 -8 -2 -15 13 24 -3 -3 -28 -40 -9 -32 -6 40 -20 -20 -22 7 6 19 7 37 20 -29 -29 2 -24 34 11 64 46 -34 -7 22 3 -9 20 0 30 -7 -20 16 23 -23 7 -17 -2 11 -29 10 35 5 -5 -13 -23 -9 9 -6 23 6 13 1 -23 -11 -22 -20 -33 2 26 5 -16 37 -10 -15 25 -10 -19 -14 -3 41 23 -1 -11 -8 9 27 9 -5 15 -10 -23 -13 -34 -3 -6 -10 27 -23 -23 45 -79 -10 -43 1 6 27 -51 -17 53 1 1 14 28 -26 24 81 24 37 0 29 -25 33 23 0 -37 -17 55 -51 -12 -32 -66 59 55 -22 -36 52 47 0 3 -3 -52 -31 -55 -30 -4 -15 27 -51 -43 29 18 -5 42 -4 -57 -48 -62 23 -5 2 -18 -5 1 -14 -28 -30 -29 22 -53 68 -16 11 17 -15 -28 -4 48 19 -32 -12 -50 31 -37 5 1 -52 2 6 13 27 1 26 35 -56 -10 6 19 3 -21 3 4 -19 -28 -20 -25 -17 8 -13 -5 41 -38 15 28 -5 0 -10 46 -69 17 4 21 -41 -8 -15 -24 7 -2 0 3 11 15 -1 2 13 -2 -12 9 1 -12 -66 -5 27 32 -25 5 -19 -14 8 -31 3 -31 -34 -36 -25 -48 35 21 -11 -30 6 -32 -52 9 -12 24 0 -2 -33 24 35 16 -34 5 -24 -28 45 -4 10 7 21 -43 6 -12 -32 15 24 -15 -7 22 -19 -17 -6 -25 30 38 -21 2 -23 8 22 -6 -7 18 0 -15 19 -46 9 -17 55 12 0 -10 14 -11 -4 -34 -21 -27 -3 -2 10 4 -15 15 23 -39 22 -4 -27 22 -4 35 28 10 19 3 -34 -17 -10 1 -43 17 -33 -24 18 -18 7 -8 -15 27 -18 3 29 -17 38 -28 4 -32 4 2 -21 4 -20 1 -20 17 46 19 25 -27 -23 -1 23 -16 -14 29 -25 -21 -51 41 0 11 -23 -3 -31 9 -16 14 -51 -36 -18 -5 -76 43 39 52 35 -21 -3 -29 -1 14 -25 -15 -67 27 4 2 0 8 -4 -42 25 26 -49 -5 -9 -26 31 59 18 7 -20 7 55 -46 -40 -56 2 35 52 36 -23 -21 -15 3 58 6 -24 27 -12 -11 -14 15 -36 14 -16 15 24 3 40 -7 -39 -24 22 -36 -23 1 -21 6 -45 2 15 -53 35 20 13 -11 31 17 9 -16 -58 45 -23 -10 7 43 14 -24 -47 6 -46 -65 35 5 -11 15 -16 9 -17 -33 -7 -10 -8 -20 -39 12 -20 24 30 -46 -19 -25 -28 31 20 6 23 15 32 -38 10 -26 5 -40 58 6 -11 5 -15 5 30 -10 11 -17 -46 -13 -5 32 -40 42 44 -30 -14 7 27 -15 -19 -12 32 -7 65 76 13 -17 46 41 42 35 -7 27 89 -23 29 -18 16 42 27 -49 30 -30 30 61 8 -15 57 -20 29 36 2 26 -34 -46 -24 32 12 30 1 -19 -1 70 -33 53 -37 -6 38 53 43 -40 29 -36 -39 -31 2 -5 -10 13 -32 -10 64 -53 -17 21 -36 2 -36 24 39 4 -15 28 -46 -41 18 -10 -28 35 8 -23 -43 -11 10 44 17 -2 11 24 -46 28 10 25 19 -22 17 -1 -41 -49 -40 -19 20 25 43 -21 -57 -1 19 58 -16 -8 2 -19 0 -20 -18 -30 -5 -16 19 -21 -35 -32 -28 -19 15 33 9 37 54 39 -20 -6 22 61 -20 31 -20 46 28 -36 54 -78 -24 97 -18 75 40 -50 45 -43 41 26 88 15 -70 -21 -17 44 6 -69 -11 72 6 9 -2 2 18 15 70 2 5 49 -43 63 -32 67 37 -28 -45 -77 -12 63 -46 24 28 -3 -40 -54 26 -26 -46 10 39 74 -23 -48 88 12 -13 -58 51 -7 65 29 -49 17 9 38 74 12 47 31 9 -16 10 4 54 14 28 67 45 52 51 74 -31 1 -45 2 3 -32 -37 9 32 -23 28 0 1 -11 14 12 -54 0 12 24 7 -22 16 3 -31 15 4 18 -1 -26 -13 47 10 -2 37 4 4 -77 -20 -36 -23 11 -26 -44 -47 25 19 12 2 1 -2 -1 1 34 -20 14 53 -31 32 37 -51 15 102 17 -19 -15 29 -18 -6 -17 39 43 56 28 0 -28 10 -61 -10 -26 41 -27 15 65 -72 -11 10 23 -28 27 21 -2 69 14 34 -28 21 -32 -7 27 -31 -16 -26 0 4 -14 48 25 -4 4 65 3 11 -32 -4 -25 41 -52 7 -21 -103 41 -13 49 -8 -1 -62 4 1 -21 -9 16 -6 20 36 37 -33 -10 16 17 63 3 -23 -30 11 3 -16 43 -27 -44 16 -36 -37 0 -28 17 32 37 31 5 -17 25 -7 -11 -35 14 17 -19 -31 -15 6 -4 -8 39 15 -14 4 12 6 -28 -18 -27 27 0 5 -55 0 -28 30 7 14 -20 -2 -13 -17 -28 -3 24 8 12 11 -12 5 48 -30 -50 -28 -30 15 14 19 23 -3 25 26 -16 14 20 -1 -18 0 -69 61 2 -20 33 -12 23 7 -12 0 54 12 -1 -29 -21 -6 -22 -29 -36 5 29 -36 -4 -31 -43 38 -21 47 8 4 47 -16 5 -42 40 -28 -46 3 28 18 -27 7 1 26 9 -21 2 -20 25 0 25 -26 4 43 -10 -9 -24 -37 -1 -13 30 16 14 -9 -35 -39 -27 22 -32 -22 20 -19 -32 26 16 21 10 34 21 -34 -21 -5 -2 15 19 -3 -3 14 -22 30 2 -18 -30 -24 -7 -19 -12 -16 -1 -22 -9 6 -20 13 -26 -8 -9 6 -34 9 36 -18 12 8 -33 -6 23 -37 5 11 -29 -7 62 12 10 14 -50 -49 -24 50 -8 5 25 -6 -6 -27 -10 -59 -10 41 52 -55 4 -23 28 -15 15 42 3 38 -8 -76 34 -36 -59 -1 3 -15 46 24 69 56 31 -29 -29 -5 38 42 6 7 4 -43 -31 45 11 27 41 -18 -21 -8 -9 -8 21 -26 -3 41 40 14 -10 -42 -25 -17 8 -52 -17 54 25 44 5 21 25 -6 15 27 2 24 18 -17 46 -12 43 10 11 5 -7 -22 4 2 -38 -12 -14 -16 6 -25 17 -23 13 -24 35 22 29 41 -26 0 22 38 37 -8 40 -12 54 17 -10 45 -8 -17 31 -27 -12 -38 0 32 -15 -8 -8 5 40 32 -21 -15 -41 6 -7 -27 62 -30 -24 21 8 -56 -36 -37 -27 -41 63 0 -1 45 65 2 61 9 -18 -11 -24 29 -55 65 -23 22 -29 -36 56 -5 -32 58 13 61 28 -37 -11 -70 14 -92 -22 -4 -9 -6 13 -50 -53 -16 -19 -14 -46 2 -5 -7 -18 -25 -5 6 -11 -11 -14 34 -6 -37 -12 8 -4 58 -31 -20 -15 -19 -7 -59 -7 15 -15 -13 53 22 -16 -31 -57 8 -1 67 25 -17 -25 4 35 -6 10 -61 -63 4 -23 -7 -19 31 0 23 -7 31 -10 0 -6 -16 -21 -9 -11 -13 -18 2 -18 38 -8 14 6 13 16 -60 -25 38 33 -19 35 -18 -22 -7 -5 10 14 9 6 42 -25 0 2 35 24 15 42 3 -12 12 0 20 -10 -5 20 9 -15 15 -8 -3 -6 8 19 12 -14 -20 -6 12 12 -10 14 -4 42 -20 -24 13 -4 21 -9 11 13 -6 -12 2 -21 -5 5 -1 -7 1 0 -34 20 -31 4 7 -12 -11 -25 28 -2 41 15 -9 -22 -18 -28 5 14 -10 10 19 11 12 -7 -41 1 35 -19 -32 -10 -25 8 19 6 8 -30 -12 9 -24 -19 15 18 -8 -22 -14 -43 -17 0 2 1 19 18 21 2 2 8 3 0 -4 3 -6 19 16 7 2 -2 3 0 -9 0 -3 9 -18 10 -1 16 0 -16 13 -4 -7 8 -4 5 6 14 16 20 13 -6 -1 2 -1 -5 9 -13 -3 8 -16 0 -17 -16 28 47 -6 8 11 14 5 -16 26 -8 21 32 -20 -9 -12 -5 -2 -60 12 -25 9 -15 -26 -33 -55 10 -39 -10 -19 -10 -16 36 -21 5 -6 26 15 -9 16 19 46 14 26 -1 -26 -4 10 13 40 49 -8 5 17 -22 38 -35 40 2 72 -33 62 -8 15 -17 15 33 -23 -111 -32 53 37 6 41 -48 1 -5 46 -12 5 -13 1 -21 11 6 18 -23 12 -36 -51 -12 -7 23 -32 -14 16 15 5 9 15 16 -37 9 13 -42 -16 -21 13 1 19 -31 27 13 -6 2 -24 -18 -10 13 -23 22 22 35 -1 19 9 -7 -34 8 21 1 8 -9 0 25 -36 22 -26 8 -29 -44 -19 2 -19 -28 13 22 -4 43 14 -23 11 10 -13 40 35 -24 -40 5 -48 -17 1 29 -6 -1 22 -42 -9 11 14 -9 -21 16 -24 -14 -22 35 -13 -5 -9 -1 22 -39 4 -27 -34 7 53 -25 -17 -8 13 12 12 -50 29 -35 5 -53 10 38 46 -25 5 -55 7 -43 39 5 36 -18 -32 47 10 -29 45 -28 52 2 -35 -40 -18 -83 4 -14 -14 -18 10 41 11 -3 33 -75 -10 36 9 -51 -116 -4 9 -6 50 15 18 8 -54 -23 19 -18 -24 -1 -33 1 57 -35 30 5 17 -5 11 0 -34 9 45 32 39 -25 30 30 30 22 -34 -13 22 6 22 14 -23 7 -66 14 15 -22 -31 30 28 12 -27 -24 33 -6 -45 -55 30 -56 21 11 16 -17 3 -19 -41 -2 17 14 -27 -7 77 -5 11 12 37 8 -17 43 0 0 20 -8 12 29 -13 -28 -27 -52 -4 -29 49 30 8 -10 -74 -4 -5 -17 -8 57 15 2 26 18 -60 22 47 31 -47 2 -16 -13 -38 -9 -35 52 4 7 -3 -52 -21 -50 -21 -41 33 -23 45 -3 37 36 3 -3 -37 40 -7 -15 -43 32 80 -24 -122 -1 22 29 -3 13 -3 13 -50 62 -25 -38 -19 -17 -20 31 -15 33 -14 11 -26 -18 -47 23 26 24 -11 11 -18 -18 23 20 0 -2 22 6 -8 -34 36 -37 -18 -2 -21 18 -41 28 12 24 -84 -16 18 -6 -17 16 -26 -23 71 -4 -16 -70 -38 -9 32 -33 23 -25 6 -27 8 -22 -75 44 -18 -120 -43 4 64 11 -58 82 -1 -53 -11 7 35 -43 -14 67 -26 -3 4 70 4 7 51 10 -16 -18 -12 -52 21 28 -16 18 15 8 9 34 -39 0 -37 4 -45 -16 -38 18 28 39 23 -36 -15 51 -41 -4 39 105 48 -52 -21 -1 -5 -12 0 98 -26 100 -63 79 -44 33 -77 -43 81 -33 -93 -42 16 56 -22 7 -18 -8 -50 19 36 -66 -35 9 -34 -10 -23 -56 -27 47 -45 20 -6 23 -32 13 16 -10 -36 -9 -35 -20 9 -7 -7 14 -3 -9 -19 -19 26 2 -12 11 -10 30 40 -4 100 13 14 -45 -35 7 2 -39 17 -40 -58 10 9 -13 -65 6 53 -51 51 -19 13 8 -74 -36 46 45 31 16 26 -9 -43 61 48 -20 56 -10 -24 -20 -23 80 23 11 13 1 -36 -47 27 -40 -82 -26 -36 -2 -16 -11 -13 39 64 -70 0 -64 -8 54 0 -36 8 59 20 -10 -38 3 -119 -63 -36 -14 1 14 58 -70 30 24 -45 26 -44 17 -41 16 -66 23 -42 -19 73 -2 -35 -8 27 31 -85 41 94 -50 28 -27 5 -12 87 -20 -13 -16 -55 -2 -6 -1 -5 -19 -62 25 -59 37 -5 7 -10 17 -25 -25 -24 -22 32 -28 -3 -24 -2 4 -3 6 -33 -15 9 -26 29 13 35 27 50 20 -38 29 1 47 -11 -19 -22 -121 -9 14 67 125 -88 -78 -30 -69 42 -58 89 -34 -18 0 -13 -95 114 40 21 -119 53 -40 127 -87 114 30 -127 -74 127 -75 125 24 40 66 -52 -35 -117 -96 -11 5 73 -6 19 124 -42 89 -13 19 -127 -7 7 79 -6 58 126 -71 127 5 -116 91 -44 -113 90 -7 4 -66 -45 28 -56 -101 -70 -87 -45 -31 42 97 -53 37 82 -9 9 -28 25 -24 28 -99 -104 15 -31 -24 59 78 -15 -118 -34 -68 35 -9 -69 107 -110 -45 79 -11 66 127 -28 -5 -124 42 124 1 -7 -127 119 -10 -93 99 67 18 36 8 -31 -33 -74 32 36 -120 -80 -34 72 22 63 63 21 34 123 9 -29 -126 85 -36 126 -68 -18 10 13 -4 20 -27 -101 9 99 -31 120 -88 120 -56 11 -4 58 3 30 -51 7 29 -122 -22 -32 -125 5 -91 114 127 -31 -61 2 41 -102 63 -44 -74 70 49 -29 -5 -7 112 88 126 -37 68 49 51 -126 109 -87 -126 -56 -73 81 4 -15 121 -39 -68 -65 10 127 -26 -100 63 45 105 78 -37 77 -10 79 50 -65 -5 75 -8 -42 -1 -128 -104 115 35 -14 -7 -70 3 -20 -54 -20 11 -97 -85 -128 8 -26 112 78 35 11 39 118 51 119 -117 -99 -60 -127 10 38 -24 -125 86 -77 -26 24 -5 -6 6 34 -23 -127 10 6 -66 24 2 -7 12 -62 25 32 -31 -42 48 -104 96 -125 84 127 48 125 -54 -36 31 -33 117 -42 22 127 -8 4 10 -89 49 52 96 18 57 43 42 119 14 -90 -86 -78 -100 -22 -6 83 -87 7 126 -28 38 31 -18 -110 -86 -14 38 120 108 56 -69 40 127 -54 15 -55 68 -77 55 -125 9 63 -7 28 31 -82 67 36 52 39 61 94 -39 126 -57 -70 125 65 -81 17 -35 -12 31 35 -24 -41 -116 -14 34 49 -17 127 37 -124 -10 39 -125 -35 69 126 127 -31 16 -60 -23 25 -12 29 -26 -54 26 -55 45 -63 -106 -10 29 14 -42 41 0 127 7 30 127 122 -67 55 -11 -54 56 -97 42 -112 -98 44 -60 47 28 64 -30 0 -34 -17 0 -127 42 27 56 -126 3 46 48 -114 108 -73 8 -59 122 44 30 -41 -37 -29 85 69 60 11 -87 -26 87 20 16 79 -99 -35 -48 -54 -39 -42 13 62 44 45 49 47 -91 -103 -116 -4 124 -23 -18 -128 74 66 84 20 72 127 48 84 -26 -8 20 57 109 64 127 40 -66 13 120 -95 -128 -93 28 -126 122 3 -47 -2 44 55 19 -101 -120 70 -8 33 127 -45 -97 -76 84 -70 -22 33 22 -17 22 -26 61 -44 14 -27 4 -120 -85 55 -52 -104 43 18 19 -35 30 -126 -91 104 126 -7 -7 -46 125 -123 2 -48 -56 40 55 6 -53 -50 124 -34 -48 -14 69 -23 -32 -101 -105 26 -6 -2 -87 108 9 77 -75 -24 -79 28 87 20 15 -62 64 24 26 59 67 -31 89 -60 -73 -46 -58 -21 -61 44 -111 -127 -26 -93 -105 -52 43 -123 -94 -10 -53 -90 -71 -33 22 -85 37 -105 -125 -76 -127 125 127 64 -123 83 -94 90 0 -9 126 38 -81 77 -83 61 59 126 -120 71 -4 14 -124 92 127 -6 -3 125 36 -127 -79 127 127 -127 -72 127 -38 -9 107 -19 16 124 103 -128 -65 30 -70 28 -66 21 -121 -43 44 -69 -127 60 -119 -36 4 -81 32 27 24 78 55 -18 -47 -127 64 25 -51 65 125 -3 -95 56 -20 -105 -9 56 126 118 10 -21 -18 -128 66 40 -19 85 126 -128 78 -127 49 40 26 -127 -116 -126 -65 122 -2 -22 -58 -20 107 127 -85 0 -84 -47 -120 -23 74 -21 -56 -100 5 -128 7 -53 -8 -125 -41 -107 -11 -53 -127 -54 36 79 11 26 -128 -75 52 53 -27 -37 -124 7 -109 -22 -128 -40 125 -4 -84 99 103 -34 -20 -127 -107 -92 119 63 82 123 98 40 123 93 -124 33 43 34 -31 -113 16 123 2 126 75 -48 127 -50 -61 -35 31 62 37 127 -128 58 122 112 -39 -96 58 32 126 -16 -67 39 -87 -108 127 39 -108 65 -1 -96 22 18 67 78 24 70 127 47 2 127 -127 23 39 10 -94 99 23 8 -45 56 -12 115 117 -38 27 20 92 20 101 -71 116 -122 77 -109 -23 -80 62 50 -69 127 94 20 -108 101 41 -69 127 41 -77 -16 -26 -126 126 -115 77 39 127 -70 73 -126 50 50 55 127 -10 12 10 22 72 45 54 2 18 -45 -120 -122 -100 -63 0 87 -7 -63 -92 4 -96 -50 -21 -75 -86 46 -124 -4 -39 -125 55 82 -59 -72 -67 57 1 22 -92 70 118 -100 1 37 -110 -120 -127 -9 -47 -122 -83 54 125 -122 -25 17 -65 1 94 107 -10 11 5 17 -34 35 57 -124 52 103 36 65 5 -14 -97 -35 -4 -40 -6 23 5 43 -67 126 99 -38 12 127 127 96 -19 109 -68 -122 -118 -124 -31 3 34 48 46 47 -16 -13 -29 37 8 107 4 79 104 -3 -61 -88 48 -127 -18 24 -18 -106 39 -33 85 -81 -91 -11 127 -125 122 -33 22 -127 -90 -101 -126 122 -128 10 51 -81 -15 65 56 -13 -83 16 -125 10 95 21 28 125 45 -59 -127 -65 34 -127 52 114 127 68 -89 8 -29 46 15 53 -122 52 -71 -30 -16 124 50 -43 8 -100 -71 30 101 60 -18 -113 126 -122 121 2 12 -59 6 0 123 113 35 3 -18 40 -68 59 5 -9 21 9 17 -6 111 20 92 -100 -32 -36 -90 -98 2 -79 105 54 -99 13 -85 -34 100 -123 73 28 -128 16 75 67 0 -85 -7 0 55 38 -121 -123 -127 60 2 -19 -1 -125 127 -127 -122 -81 -34 60 72 83 96 115 126 -25 33 -98 -30 -89 -125 96 -37 112 86 25 -68 -46 -31 -127 127 -6 -116 10 45 -125 -104 -127 124 -124 -76 -122 -115 -75 48 -14 76 13 36 70 -87 -39 -127 115 -66 -93 127 -17 -69 -117 -127 116 117 120 -36 123 0 40 -33 127 -43 103 -5 -127 -37 84 -3 97 126 -127 36 25 116 127 61 3 125 30 42 2 56 -56 125 125 -59 -122 20 -117 77 -79 106 29 109 127 53 17 -88 93 -120 -28 125 59 32 -28 -75 -127 39 9 -59 -126 18 20 -126 -1 -62 36 45 27 123 -29 -78 106 110 37 13 -126 81 127 -52 -68 72 -54 -127 65 -85 -117 -102 29 -38 -12 -52 -106 -13 55 -6 37 -52 -38 126 -120 127 -98 -114 -128 28 2 -78 -53 -30 117 -44 69 -51 -14 127 34 -5 23 -40 -128 -8 21 120 -2 50 -118 -82 -66 -73 88 126 -28 21 41 17 -91 91 48 -121 3 -13 18 123 -127 68 -9 39 -23 88 -121 15 121 99 127 80 49 53 -76 114 58 -83 -125 127 66 -123 98 120 55 114 27 -20 47 -2 13 -111 5 124 107 4 78 -22 -35 127 3 127 32 23 122 30 99 21 58 -56 -123 75 111 -128 -105 -97 -127 11 13 -44 46 46 -35 -108 -49 47 -128 13 28 -24 -81 121 127 98 -69 27 29 -11 23 36 -128 126 3 -114 -122 1 123 6 119 127 -86 -127 -119 -14 37 -1 24 41 -4 39 -36 -106 0 -49 -127 -79 -114 -116 4 -2 120 -63 -86 -9 -92 110 31 73 -70 -42 -119 -14 -47 127 -117 108 127 26 -18 -18 -92 -96 84 -2 -96 50 57 -52 126 88 50 -94 -36 95 -26 -31 91 124 -13 -85 -82 127 67 87 94 93 59 -103 -40 -22 -19 -62 55 127 42 30 39 -114 -19 68 85 24 -26 67 -125 -1 75 124 -22 -106 -18 43 12 -128 105 117 -67 120 -31 -72 -71 -113 48 -78 -93 18 -58 -86 110 -118 -102 -128 -56 -15 -128 6 -88 -43 66 48 69 112 -49 127 -31 -127 127 127 31 -11 -25 80 -90 -60 -39 40 -32 -124 78 -31 -71 -112 4 -26 -49 -61 -74 127 -32 14 94 -42 50 -101 8 -2 127 -79 48 -125 56 20 40 -20 49 -83 17 36 45 107 -41 119 -52 91 -56 127 -69 -13 52 -31 87 -21 -29 -17 -92 127 -117 -78 71 6 -1 -63 -127 -9 112 -76 -123 70 -63 42 40 125 29 -104 -83 -127 63 76 49 -114 39 82 106 -127 70 48 9 9 -58 -18 -54 -31 56 66 1 -61 -114 47 46 -55 4 127 -13 100 83 29 -102 10 -48 29 126 20 19 32 -97 26 97 -37 -85 127 -112 29 1 -115 0 -121 -100 -41 -120 32 -116 -11 126 67 1 -46 -127 -94 -69 -124 127 125 -24 -127 5 -107 39 -108 46 125 52 -126 115 -41 121 95 -122 17 -45 -101 -122 40 9 -126 3 -48 -21 -6 -125 117 81 20 14 -115 -72 7 -40 -60 46 -11 103 27 -56 -124 4 106 51 -128 -61 -89 -78 124 30 -89 -119 51 75 127 -35 123 127 123 95 79 -121 101 54 59 27 -105 2 25 -81 126 15 57 -52 111 -9 25 115 95 -30 121 95 40 59 124 124 -84 2 -48 76 -18 -126 39 65 0 -71 -59 3 -57 63 -58 -37 28 -50 -8 9 -56 0 -75 125 -125 -51 -46 -119 73 8 -96 5 24 45 39 -28 -126 9 16 -78 -105 -23 -65 -3 -88 -47 -36 -49 -38 -125 34 -95 39 -78 -87 102 84 -12 105 -38 -23 73 -112 17 -35 -125 -32 -58 -26 2 -49 88 34 -52 -14 -57 103 -91 -60 -20 -49 93 -115 75 26 87 -47 -53 -125 57 -5 -87 48 9 22 -67 -12 102 -72 96 37 122 -48 -48 -128 124 -36 -126 92 -74 1 5 -128 6 -115 -77 -75 27 -50 -45 39 127 -75 125 -115 -48 110 -16 -126 -126 -1 51 112 126 123 29 127 -89 69 55 62 -113 -30 112 127 -35 -128 -10 -124 97 -6 -18 -54 -123 -125 76 86 -33 -122 83 -85 125 -128 -61 0 -32 -93 32 -24 -5 -86 -114 -20 -3 -128 -12 -47 11 -92 -84 4 49 -85 -127 21 -43 -6 113 -114 -97 40 -125 123 -109 38 -16 125 29 89 -91 -31 -97 127 -71 41 -19 -54 -121 115 125 -46 105 -127 127 8 120 -9 -14 127 4 34 24 -69 123 72 57 -115 83 -56 95 -76 -52 -128 -70 61 21 -75 10 26 -125 -18 33 -91 118 -127 121 -94 126 -60 17 -57 -54 -41 127 -43 107 -118 -18 7 58 3 -41 5 -121 -15 -128 -61 66 21 71 127 -128 124 -30 -121 -18 -119 14 53 116 73 24 -72 84 108 118 17 -106 126 -86 -127 -106 0 -37 38 -8 18 -125 -108 71 -3 76 4 -117 -92 -81 20 34 -10 69 -65 -35 -90 98 -11 -41 -83 37 0 -47 -38 -3 60 -73 -111 49 -124 127 82 -123 -7 49 49 -82 31 78 -126 127 42 -64 35 93 127 -55 -125 37 -33 -90 -25 74 -69 -84 -32 -118 111 72 -127 -88 83 47 92 -39 121 -45 -19 2 -116 68 -91 30 39 14 125 99 -35 127 -128 40 -68 -64 -63 -126 -116 127 -6 -17 -45 -29 -84 105 126 -77 -66 -45 66 127 122 35 123 71 127 -53 -34 -127 126 -22 49 80 74 -19 -62 -69 -118 -41 98 -128 -98 -103 -94 -77 127 11 9 -68 -81 111 -9 97 25 60 127 -56 122 115 -36 29 -20 57 -66 85 16 -126 -53 82 -127 -5 47 -29 -125 -122 -73 -80 9 80 -90 112 -59 -29 6 -125 67 17 -68 -39 26 -39 18 17 14 34 -98 -48 -83 126 113 -22 115 -29 -10 -89 70 -123 24 -32 121 44 -126 92 32 -66 -50 20 84 63 -16 101 -97 -122 -127 -120 -4 57 -51 81 -112 63 -120 -80 100 90 -123 65 53 -9 -27 87 33 62 -23 118 -78 126 -126 127 9 79 -9 -47 -3 27 2 -7 41 -97 -53 -29 -23 4 46 -34 -4 14 26 -31 -72 46 -29 -29 -52 41 -80 -16 6 4 -7 31 -3 15 82 77 -27 -2 28 -52 124 -48 -13 -28 23 -21 35 -20 -114 37 -86 -43 73 -49 92 90 32 51 -17 41 -4 -1 -53 32 -25 -24 -16 -15 -43 84 44 -74 -4 -10 -54 6 23 -38 2 -110 -16 47 8 27 18 -6 57 -42 0 20 -12 17 -47 61 22 35 127 122 71 -24 -46 -9 -6 -22 15 42 -9 19 37 -126 2 71 46 -38 -45 -22 -120 45 -127 -84 -17 107 -73 -24 75 -5 15 -23 -63 -14 3 -43 35 -126 21 -68 -19 41 -45 126 2 -34 10 25 -12 43 4 9 -128 -3 124 -43 19 0 64 58 41 -34 -28 27 -42 -39 18 -5 -14 -47 -1 -81 -3 50 -58 12 6 -87 -5 9 119 79 22 5 -20 75 14 -32 38 -68 -12 -21 -33 51 121 102 -69 -120 -33 2 70 -35 -62 -25 -47 -38 10 78 5 51 -23 33 -105 84 -28 78 -99 16 -77 -127 -49 -49 -107 -60 127 124 127 -45 -80 74 -65 47 38 16 -68 -6 -3 -79 -9 68 109 -50 -65 -114 -13 69 -10 -117 81 98 -32 -19 -38 9 60 6 39 39 -15 -10 -125 -17 -17 94 -120 20 -71 -39 39 -63 55 65 74 -15 -53 -25 -102 25 -124 -50 -123 46 15 -125 -76 -54 -41 -30 7 -52 9 -56 -8 28 -128 -10 -126 -9 127 18 -60 11 6 -74 -74 127 -34 -44 94 78 -37 37 -41 -19 127 -12 -12 -92 64 22 -28 37 6 8 -17 22 121 -34 -22 -5 39 -7 74 5 -14 55 -78 26 97 -72 -101 -99 93 100 100 38 -38 47 68 100 9 28 -5 116 115 63 113 28 -103 -55 -124 31 -65 -124 -116 -51 -31 65 -68 -13 -22 -62 38 41 87 7 -10 19 -23 -10 -47 -21 118 -25 -63 121 -42 126 -36 -46 56 -93 16 22 4 127 94 18 15 -115 43 124 89 -14 30 52 124 127 -57 71 84 -82 -45 56 10 -6 -46 85 -40 4 -66 -59 -126 6 127 33 -94 -56 -41 91 33 -73 77 -66 47 50 -40 -113 121 -60 59 126 4 -112 -66 105 -126 95 -61 -40 6 -29 84 21 -9 -117 -45 -90 -28 19 -18 -16 -21 -36 32 8 22 -115 41 27 61 -4 47 2 -18 1 -43 -35 -79 12 -103 127 89 68 26 52 31 5 77 5 99 22 -30 25 -126 -45 -2 -32 -46 -71 21 -6 -32 32 -125 -14 38 -49 -8 -17 -42 -21 -84 -49 -49 108 -2 -95 59 -3 7 -43 -49 -9 65 127 32 -128 2 -62 114 -99 -4 54 -35 -110 -18 49 -1 -64 121 -114 -117 -62 -27 -89 -99 18 127 12 30 -71 65 63 114 -82 67 34 -53 -123 15 -70 68 -49 -16 -13 -94 -28 -70 -34 -81 -127 -58 -46 25 -123 107 -25 8 -127 -29 78 -41 -12 71 28 -45 34 -8 -42 -96 116 12 103 -127 -117 25 -46 -124 -109 3 -114 13 -26 -59 -5 65 -39 -40 112 80 103 18 28 -47 -7 23 -77 32 122 103 -19 -24 -22 -101 55 -127 92 103 -4 13 -17 7 -104 36 -33 -80 95 -104 51 87 -12 -23 -59 -127 -58 -93 16 97 -44 -124 -124 -12 -67 50 -120 54 -7 -5 -83 95 -32 -107 24 -23 -124 -56 20 104 -106 20 -77 21 53 -126 -18 -33 93 127 -111 -62 39 -1 -87 -24 52 -120 -47 9 51 76 -21 -128 -50 126 -71 -25 89 24 -102 51 -76 16 -25 4 -65 19 74 -125 34 -101 -46 52 -33 -90 -45 -37 66 -120 -18 53 121 -93 127 -24 125 -24 12 127 18 21 73 79 21 61 -103 84 -78 67 -11 -63 -126 2 -5 97 -33 -49 -114 1 -69 0 -65 -26 61 16 -13 -38 -79 53 102 19 35 91 54 22 5 -7 -49 -16 -119 -5 -106 19 101 -8 102 68 -8 123 15 -52 -8 -110 -86 89 -5 -66 -56 107 -35 77 115 90 -63 -44 -22 -58 -62 -10 -44 -66 -80 -86 86 -44 -41 82 8 90 -80 -109 67 -87 127 56 24 -127 -33 -25 -127 -22 -52 -65 -5 -45 -73 -4 127 25 -106 20 -78 -31 -21 -47 -58 53 1 47 -87 76 113 82 -60 33 -107 -60 -62 -13 40 1 -3 -103 -65 -9 -46 1 -29 -70 -5 -51 -2 44 14 62 127 30 -107 -62 15 71 -88 95 -29 33 39 -52 -14 12 -27 27 -17 36 -60 2 -41 -74 6 -48 -46 42 -29 38 36 64 -22 0 60 10 -37 22 -24 3 1 -32 11 -16 -27 77 -71 63 8 93 5 -113 -67 -49 126 -64 14 -105 47 -89 -49 12 34 -73 -27 -16 -17 -53 27 12 -6 -4 -31 -84 9 -126 62 -113 -11 44 -114 -56 41 -14 -53 72 88 -61 92 26 -127 48 31 -24 44 -28 -12 50 -14 -12 -11 86 85 106 -32 31 -74 -34 -8 -27 34 1 -8 -125 -77 8 40 38 43 5 -33 -119 -6 -14 -27 -19 92 6 33 -69 -42 -8 -82 101 -5 34 -25 92 -88 24 -37 49 62 -12 90 38 -49 -3 -23 3 13 -39 -7 -115 98 58 -125 17 -39 56 -73 70 -13 -93 81 98 2 -2 26 64 -58 1 -35 -59 -41 -83 50 -9 -41 -16 -12 81 74 37 -49 99 53 -18 -36 -36 127 58 0 53 -25 124 -84 12 6 -56 23 55 67 -80 -43 -61 -14 33 33 70 109 29 49 -6 -14 47 -28 27 -121 2 -80 91 32 30 28 57 -86 42 0 -69 50 -8 -64 -19 27 -43 -11 42 39 78 119 120 -112 -19 -49 23 2 -52 8 -1 102 -46 -10 72 26 18 -10 -21 1 40 -45 14 27 45 77 -86 -102 -71 38 -36 9 -59 75 16 -86 58 -12 73 49 -30 -54 -128 72 9 75 46 -25 68 42 34 11 88 -56 -32 44 13 111 -70 51 54 -33 85 -55 24 102 -67 106 -74 -18 -76 121 -18 -32 1 -4 126 -70 79 -32 123 108 58 -8 25 -25 -37 -38 107 2 -47 -70 63 3 91 20 21 25 -33 -31 15 47 -1 -13 -3 -10 7 -8 -45 -3 11 33 -33 86 -22 42 -7 3 117 18 -23 -42 42 33 40 113 24 -40 23 29 -30 -47 32 -51 60 -14 5 25 -19 -34 2 -90 57 127 70 -33 -2 123 -44 -26 38 68 15 -15 -81 47 32 99 37 71 -2 44 110 127 -11 -50 77 19 21 36 -8 8 4 -1 -2 -96 -17 -60 105 29 48 14 -8 -121 -52 -2 118 51 13 -46 43 -33 82 0 -59 -49 21 63 -8 -36 -28 20 35 -73 65 -76 19 -19 -13 35 -119 127 -22 86 37 -57 85 -74 -35 -55 -90 -72 18 -67 -38 82 -17 -29 -114 5 78 -7 3 -18 -22 17 5 -63 -114 -109 127 10 -61 35 54 -59 -116 -45 7 56 85 -71 74 84 11 50 -114 27 7 84 -108 37 -22 56 22 76 15 -123 -7 -5 91 13 -27 109 22 72 68 -27 -86 -91 18 32 -30 0 27 51 -89 -76 74 -85 4 -30 -64 -24 14 -25 58 -18 -101 -102 51 -14 -66 15 -75 -9 127 -62 -95 -2 19 66 64 -15 -34 86 -94 30 -3 107 -12 81 -80 -1 71 -74 -61 -79 -124 -45 27 -10 -6 -102 -30 6 -38 -39 24 -23 37 -91 13 -34 -8 32 19 125 115 121 98 22 -10 47 8 40 -3 47 -20 21 23 -113 -118 -14 6 5 33 -11 -120 86 76 34 68 14 127 77 126 8 10 80 39 -22 -27 -21 -57 -44 -60 -42 -12 -14 -24 10 -24 37 29 -91 77 52 43 -80 106 -23 -70 -23 66 -82 -31 49 -43 -3 -92 -51 35 -30 -15 -8 126 98 17 -45 71 -38 72 27 55 -26 89 -18 -60 -16 87 40 36 -40 -115 -13 39 -49 -34 -117 3 -55 2 -17 60 -14 -70 -33 -38 -4 104 115 16 -61 -38 36 -4 5 35 -28 60 15 6 27 -3 63 -122 27 -7 11 -16 -45 10 30 -28 -20 0 104 33 53 -32 37 86 82 -16 14 46 32 -9 -55 87 -15 -87 5 -7 62 14 -61 41 20 -89 -20 -58 88 62 20 -60 51 125 -126 -53 -16 21 61 16 -11 -31 -44 24 -71 80 -104 -8 -75 -123 -70 -60 -70 29 22 -128 62 -23 17 -28 31 2 -36 -27 -21 111 4 127 32 -18 32 -125 70 -123 -25 46 -36 50 38 -20 85 -28 -26 35 16 -117 59 12 -52 -16 34 36 39 -6 127 8 -106 -26 -3 24 -1 -34 -28 -92 40 -63 -124 80 -15 27 -24 -36 -6 15 23 15 -52 -8 2 28 -105 -126 102 -9 -64 27 -36 93 31 -11 13 9 -47 23 35 8 16 -3 -11 -90 -40 -72 52 105 -23 -9 -105 9 61 127 63 -3 10 -18 -51 20 15 -28 84 73 43 -128 109 99 -126 -128 51 -71 77 -62 -63 74 79 26 -35 125 -14 -101 8 -109 31 -126 -126 -51 38 -52 -73 -3 31 -127 -80 -57 -67 8 -15 -29 -28 -12 13 125 -127 -2 63 24 127 -51 31 53 -91 -65 42 -127 -57 122 -62 -68 101 7 -63 -104 106 -102 81 24 -125 -42 1 82 54 -118 -1 -55 5 10 -122 -128 -125 -124 -123 -63 -20 22 62 44 28 -114 35 -128 -65 -127 -31 -41 127 124 95 126 61 127 -37 63 -125 127 -48 -76 6 -47 39 -82 6 127 6 -72 -91 -115 -22 127 -68 -125 28 -87 11 25 -126 79 -10 -102 -63 -47 53 16 10 -41 -28 44 127 -11 17 29 -30 -31 -78 32 73 85 -76 -128 -3 54 -125 -118 66 -56 105 44 -19 -71 53 77 27 40 47 95 -12 13 5 -99 26 -11 39 -74 -90 74 -3 -127 12 21 71 -23 -102 -52 16 103 -13 84 11 -69 26 13 18 87 40 -11 -119 -32 34 54 3 111 -24 -69 -2 104 -32 -35 80 -127 8 10 -124 72 6 -79 19 -80 -4 -92 -29 -10 0 -128 -125 -122 -115 14 -62 88 64 35 -90 0 6 -125 46 -52 47 4 115 22 52 126 79 127 0 -39 -125 127 -3 -69 -41 77 -42 -18 65 127 -69 -44 -30 -53 -123 -6 33 -24 -34 -108 -41 -21 -74 29 -37 -121 -78 23 -46 125 92 -38 -23 -11 32 20 -21 72 19 -14 -39 -34 -17 125 12 -74 -41 61 118 120 102 -106 104 -4 -124 -58 -30 126 85 -37 123 124 81 127 -71 28 11 108 44 21 127 36 102 127 29 7 93 127 -77 -121 127 40 -74 33 127 -38 25 -89 -57 18 57 -117 68 54 -41 127 120 20 62 -89 -65 99 22 -118 -85 -127 -7 67 126 -29 51 14 1 -123 29 -37 48 64 93 54 -11 127 121 98 -21 40 -31 -34 -28 119 17 73 96 121 92 45 -23 -83 -91 -67 115 123 -19 -124 64 -20 -103 10 46 46 -30 18 95 -66 90 13 54 77 15 -128 121 121 84 -30 -43 -15 127 -117 -124 62 -56 -36 -128 20 42 17 -54 -34 -125 71 -38 -46 14 11 127 -38 -14 103 35 127 58 9 123 72 -16 68 -61 -126 -128 16 -84 74 71 79 73 -12 76 -127 -5 126 77 -37 100 -41 -12 -9 114 29 -16 -126 -125 124 50 -15 17 -23 -85 39 105 105 10 5 113 127 60 -82 91 -27 12 -37 122 11 51 10 33 -73 44 -128 121 -77 -7 14 119 -21 -91 62 -22 -120 -62 -100 4 52 -42 -16 36 127 -3 73 -12 -124 33 11 20 65 127 109 71 -28 8 29 63 50 -75 -15 62 -127 45 -13 -8 -15 -58 -55 -3 -106 38 -113 -26 74 127 -30 -36 -52 10 109 82 -127 126 -6 43 -36 -4 -108 3 -7 -65 -125 127 -125 74 19 -122 28 46 57 -35 -66 -17 48 -21 5 15 86 -23 42 57 -44 -42 -58 -41 5 -90 120 -77 -128 -85 -49 62 25 -30 -55 2 -118 -82 50 106 -11 127 29 -44 -7 -27 -99 4 73 -34 121 -35 -69 28 75 -109 55 -72 122 -2 21 94 56 123 -95 114 -107 7 127 114 32 102 69 -16 -94 -30 69 127 -106 47 51 46 71 -112 48 -73 -42 -49 22 -43 62 -21 -6 -46 122 36 113 -109 -127 -111 70 40 101 127 123 -19 -8 -109 16 36 -45 16 -42 66 -128 52 -32 -42 -7 59 7 8 55 -20 -11 19 126 60 -19 -57 -45 -49 126 -42 -28 -43 62 77 58 -7 6 -71 3 -53 -34 13 -107 127 42 24 8 -81 -1 46 -4 41 99 -48 18 -98 6 -62 -60 -55 9 -16 22 122 16 62 -32 -33 47 -128 80 4 -57 4 -17 84 -36 -125 -73 -56 -3 33 -24 122 82 -126 -5 -39 -126 12 94 3 25 124 -67 -90 -59 -125 -8 -15 -69 5 -128 75 87 102 -91 -89 -70 5 34 37 64 -9 -126 -39 -68 63 -110 75 41 0 29 -98 94 -59 -33 0 -67 -21 47 -17 -19 6 127 66 80 1 -126 -59 26 91 21 82 42 -85 34 -65 -38 83 71 -1 83 -68 -128 3 -4 2 9 -31 37 -52 -121 -17 32 45 -26 -39 16 30 127 102 -24 49 57 -37 -67 -67 -14 56 -56 117 38 -107 -87 90 -71 -10 15 3 -14 -3 111 64 126 18 7 54 24 59 -75 87 -15 -61 77 60 -5 -64 -28 25 28 43 10 -28 25 -57 -1 -24 -36 71 -44 15 12 38 -48 1 -3 30 -14 23 6 93 -5 -61 67 10 22 -48 -47 23 -15 5 36 -24 -7 -24 37 -47 -10 83 -4 9 -17 -110 103 54 70 -2 -49 59 15 11 -92 51 70 81 38 -8 -75 -27 83 33 8 20 17 34 40 11 -26 -92 14 25 56 62 -43 11 -124 24 -81 25 81 5 7 53 -23 27 49 3 -11 -15 -111 -127 -24 18 -4 3 2 14 11 29 -49 26 16 -56 34 39 -40 7 8 -1 79 43 3 28 -11 -7 9 -128 8 -52 -55 30 35 36 -15 -31 -33 -38 -10 0 18 -17 4 13 19 2 -9 -33 -110 -65 7 -35 -10 61 32 21 63 8 -126 -41 -16 -12 -38 -121 27 -47 -123 26 -55 -6 21 53 -31 -13 -45 2 -8 21 -102 38 -95 -64 -1 15 -58 -53 -35 -19 8 -49 7 63 92 -15 -18 -58 -20 48 -15 24 -4 17 -73 -2 43 -21 38 -43 -109 -40 57 -63 99 5 -10 -81 -8 49 13 85 106 -15 -128 -72 42 30 -90 86 -4 -44 -108 17 -20 -43 -16 -13 8 103 18 20 -94 24 -47 -5 -27 -23 0 -8 -3 -5 -17 -8 -6 12 37 -29 6 -40 -77 -95 -10 5 -126 71 -29 36 41 24 -61 -18 -16 39 15 -62 11 -72 -5 31 33 45 -28 34 -45 25 8 -27 15 1 -22 -36 -43 8 -25 -42 -31 127 -51 -25 26 23 31 73 -36 -37 72 15 -2 -103 -56 -58 0 -15 -38 -45 -46 30 32 20 -1 -33 36 -78 44 4 12 -63 -95 40 -18 21 48 -26 -5 24 -29 82 -17 -21 44 41 -12 7 19 47 -38 -26 22 -60 57 -51 -36 83 47 -30 -11 -50 -14 66 -85 58 14 46 -18 8 6 -4 -42 21 7 74 8 -12 28 11 -94 0 -11 6 -12 10 -23 11 3 16 24 -29 -20 45 17 -4 -71 -97 -62 -26 -76 4 20 -61 43 20 -42 4 -9 81 -45 -55 -9 -62 61 -31 100 -11 4 -13 4 -21 -49 -15 77 -14 49 12 -30 -7 4 36 -73 -11 82 53 -45 8 42 125 106 75 70 -44 38 18 -41 -41 32 -33 -48 91 -104 -128 125 78 42 -64 -40 -101 64 76 -56 -28 -69 -36 -30 -37 31 28 -41 -120 -49 -61 7 -68 26 35 36 -15 -21 -58 -59 -6 27 80 16 0 40 -6 -38 -60 -60 -1 56 0 21 -55 -44 -88 38 81 47 18 63 14 67 2 22 36 -49 12 -26 35 1 -6 -64 12 -87 25 -46 24 38 -3 46 -74 27 -6 30 -8 -13 70 22 -30 -30 -85 -27 32 -33 19 -24 -14 -1 -124 33 -48 -70 -17 -38 13 -115 37 -42 -64 -19 40 -31 -8 -35 -16 -89 -17 -16 9 -85 36 59 -11 -4 14 6 47 66 3 -16 30 -75 33 -5 -92 51 9 118 -110 -45 -82 50 -65 -39 46 -7 15 68 -26 24 56 -126 24 42 -17 -12 5 26 -6 -113 -5 76 127 32 93 12 51 -6 14 84 126 52 -43 47 -6 48 20 -7 8 1 59 70 37 8 15 30 33 -6 -38 56 -65 37 -38 53 -58 -19 -5 -7 -32 22 1 113 -10 -66 -3 -37 125 -26 41 -102 -63 127 -64 -2 -24 -27 -9 -13 -3 -42 -105 99 75 72 -27 13 4 27 11 16 -36 36 -19 -112 -100 9 10 42 -30 36 -128 -26 -77 -6 -63 94 33 -37 43 75 -71 -11 -85 -7 -62 -73 67 -4 13 -2 70 -41 -20 4 -6 54 40 52 -32 117 -36 15 -13 6 -45 -71 30 27 43 18 35 -16 45 39 20 -33 38 55 -93 67 79 72 -8 -29 9 -9 -60 -18 47 21 127 90 -37 39 35 31 -10 54 1 39 48 -68 18 8 -64 -99 29 -40 80 101 -46 60 -47 -48 -47 52 -10 -2 102 21 -22 27 54 -6 -46 2 -46 -87 4 -30 -56 -47 1 51 -24 -17 15 -17 -15 7 -5 -60 28 -32 -67 -48 2 11 51 28 12 -95 11 29 -26 33 16 21 27 -10 -12 -15 -60 7 -85 -9 -1 -34 13 -47 -37 -31 7 -26 -13 13 32 10 12 1 -22 54 33 9 12 -47 11 -4 -20 90 -35 -17 34 -38 72 62 -62 -6 0 37 -117 40 -48 28 12 -15 -11 -76 -39 77 34 -2 49 89 -49 -15 56 -32 4 -39 -76 -44 -29 22 -12 10 -50 25 11 -55 14 83 -90 60 62 32 17 9 -10 78 28 50 31 4 -30 -30 -13 51 -10 -15 57 32 -124 57 -69 -43 -1 9 -51 57 -76 127 55 -53 24 42 46 -36 -26 6 -72 51 -41 -2 20 43 27 57 -51 -46 30 9 1 35 -18 -83 18 -2 66 7 15 -44 50 82 -32 35 -64 4 -11 -4 -4 -35 0 -61 -26 -45 -26 -20 -27 -12 45 -26 -94 -29 6 25 24 63 -44 -18 126 54 4 14 -35 45 -3 89 -23 11 -44 -29 -8 18 25 80 -24 15 41 0 -27 -40 1 17 -4 -29 -26 9 24 -33 5 -22 -40 20 29 20 89 40 18 -18 101 17 31 65 -39 -15 42 19 -46 36 -87 -80 4 -66 -28 16 87 -9 -50 51 -66 -102 -33 -26 -13 -7 -87 15 28 -14 -5 -69 3 -66 -17 -56 -11 71 22 72 -49 -39 -26 -60 32 18 76 24 -2 42 15 50 -45 -8 -19 -22 -75 63 23 -40 -44 -21 100 -88 -38 -51 13 19 -46 -6 14 -50 -11 -27 27 23 13 6 8 -6 82 -18 1 59 -34 62 -31 84 -60 53 8 -1 23 74 50 -44 -53 32 -7 20 -44 54 -39 -109 -127 2 -117 -61 -21 31 40 32 5 -10 -19 -7 -66 -127 45 -19 17 -126 -1 22 -16 35 -21 -73 -14 125 -18 -13 -35 75 63 87 -7 8 -11 -52 -30 -79 -48 -13 28 30 -79 -17 -56 10 -17 3 -30 -10 2 34 -45 -63 28 -37 39 -66 -9 58 -67 -18 15 -37 25 66 87 8 7 -111 53 -50 44 -36 111 22 72 67 -77 10 -7 42 22 -1 26 3 103 22 -65 -10 69 -48 -44 -30 -21 18 -82 2 -13 -43 1 8 87 -28 -56 66 -58 -10 5 23 -33 47 -48 -46 -46 63 22 -112 -58 -29 -22 -13 106 27 25 -31 21 71 -36 20 9 51 -19 -63 91 -38 -77 5 52 -20 78 27 20 22 -1 -12 -20 33 57 -25 9 39 -49 -28 39 -60 -15 74 35 -35 -14 9 -27 39 -127 -103 19 55 20 73 59 25 -29 42 10 -17 -11 -18 -29 21 40 12 53 -68 -27 -77 -68 67 111 -15 -2 -29 31 -20 5 -128 94 -11 43 37 -31 -35 34 73 33 46 41 85 -85 -42 19 37 -68 -2 5 -2 -3 11 -61 93 -63 23 -106 74 97 -48 -46 -27 -23 31 1 48 -8 33 54 -128 -90 37 -9 -63 44 127 -45 -35 7 -33 16 -2 19 -48 48 48 -71 -62 -63 -65 -38 -83 -5 -95 -32 23 -41 43 -11 50 11 -16 -78 -54 -12 -34 14 -27 57 -49 -18 -2 109 -10 -7 -30 30 -21 -126 -18 84 39 12 7 -38 -40 -34 -8 -16 71 32 -40 -8 74 -11 -47 44 12 14 0 96 33 -17 -51 -9 25 0 -13 42 27 -25 -88 -23 -38 32 -28 47 -3 28 13 80 14 -18 3 -15 4 19 -15 -12 12 -3 -114 -37 -72 13 -3 126 -62 -1 -99 41 56 11 -117 31 12 -12 -21 60 -6 87 13 110 -125 44 -75 5 -7 5 126 53 46 -27 5 2 -2 56 66 -20 -127 -58 21 -70 15 28 45 -25 84 -58 -114 16 -84 -42 -49 -64 92 51 56 36 -77 -53 12 -115 -5 -17 13 23 -25 -25 -14 -123 10 44 126 111 -53 1 -40 38 21 3 1 -107 45 9 69 -36 12 55 93 102 -20 -10 46 -75 24 66 21 7 48 122 19 9 59 69 -37 31 25 -43 -1 -23 30 -46 4 1 -6 -41 23 -93 79 60 77 -60 -77 -23 53 -31 2 -127 7 -25 28 74 8 17 14 -79 -14 -82 32 44 -124 -55 65 -41 -25 21 -56 40 -70 -19 -14 -15 -57 32 66 13 -19 -44 -18 2 -1 48 -22 1 -30 -29 -59 -11 44 -65 4 118 26 53 40 -31 -15 24 -36 24 13 -18 20 -5 -2 12 -36 14 118 10 43 31 -8 3 -28 2 -26 9 -48 89 24 -13 47 55 -48 11 61 -22 -25 45 15 -6 -94 14 37 19 6 46 9 -33 -27 -128 -15 -20 -126 13 -97 21 -45 7 14 37 94 -35 -48 -5 24 -36 -1 38 -93 -82 -39 95 10 8 -68 -27 5 62 8 37 -37 63 -79 -3 -88 -3 -108 -37 -16 45 67 23 -1 44 89 -56 -26 -66 -11 -32 80 -28 42 -31 -67 17 76 32 -50 -36 75 -36 -62 -86 8 12 -62 21 4 73 -15 17 -44 -13 -60 37 -5 1 -11 -8 53 -13 26 -31 101 39 9 -3 -59 1 -27 19 80 -7 39 -16 -15 54 60 -24 -53 106 -128 5 58 -8 53 -19 -16 -2 58 4 -3 40 9 -60 -29 -14 17 -91 -58 -21 -17 -1 -12 32 -94 42 38 18 -61 9 -7 11 38 -35 44 5 -22 42 -17 -18 -35 26 -9 61 80 -10 -5 39 34 44 -100 41 -10 28 103 -30 127 37 80 -31 -34 60 -8 -65 -121 -5 11 53 -30 -18 25 20 37 80 48 -21 -29 -44 -76 23 -15 -112 -88 -108 -53 -41 -116 -22 -2 18 -19 -75 49 22 -12 12 97 -32 -42 90 32 -53 2 42 64 -36 86 45 25 50 -81 32 -27 -15 -115 -8 -90 -6 -13 11 68 42 18 63 -26 40 24 -89 62 69 33 77 40 54 -44 50 49 -68 9 7 16 43 108 -58 -92 16 -15 -57 72 -56 33 9 -31 70 4 -52 -5 -72 -21 -19 -47 42 -30 -39 -24 49 -7 10 -15 25 -6 -68 49 98 -28 86 2 70 -1 75 32 31 4 -6 -91 -13 -59 52 -23 -13 37 68 45 -10 12 9 -22 38 35 38 -71 -24 27 -60 73 -37 28 46 38 -49 43 -120 -4 -70 -40 -75 42 -33 10 26 -78 5 9 -55 17 4 -75 -90 -2 -127 72 -47 -43 -40 -15 -11 -23 -49 -20 -9 -13 66 -8 46 -8 -8 -21 15 30 -111 13 -9 80 -2 -29 18 -38 24 28 63 -21 49 9 23 -14 68 4 14 27 53 -6 -14 25 -33 105 80 -29 78 27 64 -9 -1 38 -31 -10 2 88 -17 55 -91 -39 2 -7 -98 46 -62 -33 59 -71 -127 -47 -91 43 -19 50 2 -79 55 37 -113 26 -12 -17 -17 -23 25 61 3 52 -30 -22 -2 -13 33 -104 48 97 62 11 -32 31 55 14 26 57 53 71 3 -39 -8 -2 -29 -45 -72 21 10 -2 -95 -127 -43 -10 -2 19 -24 -13 -60 -12 14 47 124 -83 13 -34 37 -26 13 9 7 -14 -6 -80 -32 -104 55 9 -77 63 -19 -13 -25 92 -19 -15 70 7 0 -8 -29 -69 -15 18 -36 -11 65 -6 -24 -10 -37 0 -55 -17 27 21 59 -18 -18 -21 -60 -115 74 37 -3 12 -34 116 -12 -77 -57 -3 -95 -11 29 77 -29 -23 37 41 -26 8 -31 -42 -9 -43 40 -50 16 -19 -45 41 110 40 101 -44 -37 52 -18 1 -23 -23 50 -21 5 50 -125 125 0 -121 5 -24 8 -47 -42 58 -36 -96 27 17 9 -58 -20 -2 1 97 11 75 46 33 -15 70 -25 -9 27 1 -58 26 -18 32 29 -100 -25 -68 -42 -72 85 50 -19 -115 -91 -63 8 34 -11 2 -10 -84 -64 33 15 -22 40 -11 -28 67 -12 36 83 -61 -26 29 57 24 -5 30 20 -51 21 90 -98 -48 77 20 0 44 24 49 -113 -3 73 -33 122 10 -76 -1 92 -114 -42 49 -36 99 24 99 -51 -102 51 69 -107 74 90 2 67 9 -6 -48 -98 0 37 52 36 89 0 -39 -8 -58 -70 42 1 -46 42 21 59 -50 36 -15 -77 -32 83 70 -90 -56 -11 -71 1 70 5 22 52 64 51 40 -15 49 -29 -56 46 87 -29 -46 -70 41 -21 -21 -84 -86 43 23 35 -23 22 31 37 -46 37 36 -29 126 -22 30 -72 -22 20 9 50 23 4 46 -64 52 20 -98 22 39 40 50 24 34 -30 -16 65 17 11 -45 17 2 -28 84 46 -12 -13 -7 44 -39 -20 33 54 -6 82 85 55 5 54 53 -18 -108 106 10 11 42 56 -79 -47 -97 -36 -38 96 25 19 5 2 -14 -34 28 53 -46 73 24 -24 -43 28 -33 -9 -10 -18 47 80 38 13 -54 26 -3 61 51 2 4 -19 28 -22 4 -43 24 -34 -105 54 -111 -6 53 -45 76 85 60 -17 6 45 41 12 -48 39 8 64 -43 -23 14 -18 -28 58 -25 -38 -14 -85 81 -86 -15 -71 -46 -22 84 37 -6 17 7 4 -47 54 27 51 58 34 97 34 10 86 18 -46 -75 -30 -29 -15 6 42 -40 30 -34 -29 -46 -8 6 -5 117 -2 45 68 -3 -13 10 6 -16 -105 -128 16 40 -2 -18 77 -53 -18 -41 -44 -17 39 -25 17 -28 37 -19 -5 18 12 19 10 1 -51 -38 89 -61 7 -24 39 37 -29 -7 -88 -18 80 -126 21 49 -64 -44 44 7 -58 -124 -112 86 0 -16 83 -33 -42 -55 -24 -21 -15 -59 11 -44 19 123 -46 47 -25 124 -18 -31 89 -49 46 -29 51 -12 28 46 -14 -33 55 23 6 -37 7 -92 -1 12 -21 41 -8 11 -75 -8 -44 -61 23 -100 94 29 4 -26 32 -4 52 122 20 102 4 -60 29 6 -1 -24 17 27 18 -3 20 66 -7 41 -99 -50 13 -7 25 0 -2 70 -70 -72 36 41 29 -32 -28 114 -39 -22 25 8 -96 25 -19 20 38 -11 -15 27 -32 11 -36 32 -24 -2 -4 15 0 11 -53 21 -65 -1 -34 10 107 23 69 -91 2 -93 107 38 -3 3 13 -13 49 30 2 0 43 -61 25 -55 49 -59 85 -9 -66 -86 127 -47 60 -4 80 24 26 -52 35 -17 118 -81 27 107 1 4 -62 25 -30 18 -12 127 35 -17 -7 -115 63 -89 -2 0 -23 87 38 -7 -53 -30 7 7 -45 60 -80 -30 33 -28 -62 12 36 -10 68 -64 12 -85 9 19 38 20 36 -15 53 2 18 -25 -9 20 62 -27 -38 -13 -42 -53 -6 43 -58 -35 -33 -39 -22 -7 -44 44 -97 -34 -3 11 -76 23 3 8 -59 15 -35 38 -12 -79 8 60 -38 -17 -56 -107 16 -50 6 29 67 -21 -15 -30 72 -18 -29 37 -2 7 25 38 -21 3 -12 -53 -16 14 -58 -4 -121 84 -98 -125 -122 64 -22 2 -46 -64 84 -68 70 7 83 30 50 43 -13 -17 0 52 30 -34 79 60 -27 98 -4 63 72 -126 44 72 49 -28 47 78 73 47 7 87 23 -41 78 10 -47 40 77 -37 -2 115 22 -13 -37 -30 17 44 84 -52 117 8 2 -30 -18 98 50 112 -105 -57 44 -22 44 -8 35 -7 -1 56 26 31 24 26 8 4 49 36 -56 -9 1 45 49 41 -27 75 -33 42 -15 26 -39 39 16 -24 116 -73 17 82 72 -26 -34 12 -26 35 70 -15 -127 36 -48 31 -97 -20 -20 9 28 76 19 -127 95 49 -7 -17 9 19 43 -35 -18 -105 43 54 -95 37 -77 15 -38 11 -78 34 -14 -12 -13 -53 -115 86 -29 20 -33 -38 -113 -2 -98 33 43 54 18 -35 69 0 -15 -39 7 78 -41 29 13 1 72 -28 54 62 37 11 -44 -1 37 59 -127 45 -46 -68 6 68 26 12 97 -46 25 65 -34 53 -46 33 39 18 -76 -18 88 56 34 106 -37 23 -63 -13 11 49 45 14 2 46 -42 -127 28 53 13 22 47 21 30 -12 -69 36 36 13 5 17 -27 -47 46 0 -29 -22 -27 -9 44 -27 5 -15 72 -71 -23 -40 -2 20 18 -1 26 7 -13 -57 21 -46 -58 -8 61 121 -42 -16 -18 -3 43 -39 31 -16 5 4 19 2 46 76 -42 -80 0 49 -76 -127 45 16 -77 -11 -87 33 0 -81 20 18 68 -109 -12 25 -57 -64 -51 -3 76 -49 -68 41 14 -6 -64 65 47 -42 -8 -37 -101 -19 -76 14 -40 -47 -73 109 -32 -90 -55 -23 -17 60 -71 -79 -5 26 2 -10 -29 0 86 -27 70 13 -10 -23 -87 -22 -44 11 20 -54 -58 -92 7 105 3 -20 -53 -27 -10 -33 35 97 -71 20 -17 -37 12 13 61 -78 -12 -11 -10 -49 -1 -113 -3 -9 -46 -41 69 28 -72 -17 16 28 -50 46 45 -17 53 30 -91 24 -53 29 -18 4 32 -48 37 -37 -13 11 -12 47 -18 92 -16 -59 -61 81 17 2 1 -23 -30 -18 27 -13 42 -71 83 65 -5 -70 87 -19 -12 12 49 -41 -12 -20 -12 -88 -27 21 -67 21 29 115 -53 -9 84 -69 -23 -121 -13 -42 -31 -34 31 -123 44 3 13 -21 96 16 -24 53 -44 -45 42 -125 56 91 127 108 49 19 -8 123 26 126 37 -1 95 -77 -63 15 -2 -48 14 80 -25 -47 -26 -64 -18 40 15 -16 4 -32 -3 -54 -60 28 -4 -20 -51 29 7 39 99 -47 -17 -27 -42 30 0 -26 29 -9 2 -48 96 -37 -17 -22 -42 26 23 34 -14 108 -10 9 9 -36 -30 22 -3 56 31 -1 -50 -5 -17 2 -128 -50 -46 36 19 66 33 18 -39 -27 -77 -40 -40 -101 13 -39 -21 5 19 -27 -15 16 -97 22 -29 -55 -6 -7 -29 -8 52 -53 3 7 -19 -32 105 17 -58 -2 46 -43 46 -24 -50 88 -46 -8 94 -50 18 58 4 40 37 -119 -37 -28 -4 -14 8 58 -25 -56 -33 43 -22 18 0 26 -39 33 -39 45 -56 37 16 20 39 -9 65 11 -36 -18 -91 -32 21 -72 16 -31 -124 0 36 27 56 44 12 -59 26 60 -114 26 37 2 -66 32 110 8 23 19 37 -27 -106 -31 -26 -22 66 -13 -118 86 47 62 -13 68 37 50 -33 60 15 -61 -125 24 47 31 1 19 12 8 67 -57 40 -12 93 -27 65 -22 73 5 -70 -10 53 -21 -5 14 52 53 24 77 -40 39 34 -52 31 0 3 36 23 15 -40 124 57 -26 -33 22 73 8 -25 -30 68 -28 -80 62 119 -24 -40 72 -77 102 -54 -64 125 -77 77 65 24 -112 -16 -60 -33 6 -5 -9 95 55 -63 67 21 14 49 64 -4 13 -72 125 46 30 81 77 100 9 -74 72 -79 -33 119 -94 86 51 109 -78 -91 87 -5 3 35 -17 42 56 -27 -21 -111 42 -21 -51 -10 3 -100 7 -3 -72 -25 -31 11 -80 -53 16 -124 47 -3 -40 3 -17 -53 -121 -43 -93 -63 -25 -25 12 8 -10 118 109 82 -2 20 4 29 11 10 57 -24 19 10 -106 -58 46 52 60 16 -28 112 12 -33 -9 11 -33 -18 -125 9 10 26 -31 65 -126 -118 35 -5 -25 -10 56 -78 8 -13 58 -56 -38 44 -21 -71 -64 -73 0 -37 51 -106 -13 -49 -25 -6 -46 -52 -18 -8 -15 63 -75 -8 -2 78 -47 13 -80 18 -16 -33 -20 -14 -3 69 -44 -27 80 -5 0 79 48 -123 -109 -55 114 -49 -59 -33 83 -44 -128 -59 -51 -40 34 28 -121 49 2 39 83 -29 83 21 55 -71 -2 -5 -8 -82 -13 39 -18 -30 -3 -70 62 -14 12 -19 41 17 -44 43 -38 13 8 -27 39 -1 -22 5 4 4 -122 -37 -22 -4 -17 22 -55 78 18 -23 19 -41 14 -38 -42 -5 26 59 -4 -55 -61 -5 -34 -21 -21 14 -12 -11 -26 -4 45 -10 -32 -1 -90 47 2 -13 -14 -69 -38 75 49 -23 -70 -47 16 -73 -56 6 -7 22 -30 61 -8 -8 -58 -24 -6 -44 22 -6 -33 0 51 10 -36 -21 -17 -30 -40 -45 -80 12 70 -16 -60 -59 76 6 -53 -111 -8 4 -55 7 23 38 -25 6 -17 3 -72 -7 -7 53 14 -4 -48 25 65 -37 16 -76 30 -36 7 65 -65 12 -51 2 -48 -128 125 59 -43 -6 65 75 17 -67 -72 -5 -68 19 17 10 23 -32 67 -7 -8 -19 109 -22 37 -43 9 39 -2 -7 -24 -40 -23 9 28 -15 -25 -47 11 65 -5 20 -72 -48 17 69 -33 -18 -66 -41 46 -8 15 -13 -56 -38 -56 95 -45 -29 24 31 35 -28 41 -8 5 -24 11 -5 -107 23 -109 18 27 -59 -13 -14 -35 -59 -99 1 90 -1 -13 -8 16 46 14 3 23 51 -11 48 -25 0 -33 -36 19 -40 -26 -11 -26 60 -20 48 122 -13 11 -43 -1 65 35 4 23 65 72 84 -89 15 19 32 67 -67 -1 -68 54 -29 -8 -65 112 -49 -13 101 -9 42 -46 -7 -68 26 -9 14 -29 -75 -31 -36 5 15 -3 -41 4 38 -22 22 13 -2 -16 3 21 48 -24 -1 40 51 16 73 39 57 -8 -25 -12 -8 -5 -13 -15 22 -29 -86 -5 -39 125 -29 87 3 2 5 13 -84 37 23 35 -21 -88 -4 0 -3 2 19 29 -25 -32 -31 10 -35 53 -37 3 -37 31 -36 -21 -42 19 4 -31 -30 6 -33 -11 -126 33 -26 -52 -54 76 -63 -1 48 6 16 -43 29 1 -70 -32 45 111 -29 47 45 0 -99 92 25 -39 -21 42 -11 -6 -20 122 -122 75 67 72 -115 10 -17 8 73 31 74 7 23 12 103 40 -8 89 19 44 -20 12 23 18 -40 32 61 -5 -68 5 -106 21 -2 -10 96 -55 -78 -67 55 -5 -2 -13 -49 16 -71 113 40 -58 -14 -15 18 -63 18 -74 -55 59 -29 39 37 113 49 19 8 18 -22 6 68 -23 -37 53 16 23 15 -28 14 61 -35 -71 1 30 104 -75 -18 30 -126 -55 -109 -22 -17 -12 15 69 45 -72 -25 -99 -9 66 -16 61 -16 -70 7 -65 -8 41 3 13 38 -66 -41 78 -1 -12 -34 -32 49 -4 16 -37 -18 -9 -92 -24 51 -7 -100 11 -53 46 19 -53 -5 68 36 -31 5 49 8 127 10 -25 -47 -13 -47 -2 27 -8 26 -32 50 126 -22 -6 -66 -45 -52 54 117 57 -15 74 -56 35 21 9 0 -19 65 -31 75 10 39 68 18 -34 -118 66 -20 -29 0 13 25 112 -24 64 48 -64 -17 -4 7 33 -7 17 -45 -20 -33 89 -10 14 25 -55 -58 79 42 29 9 2 -66 18 -21 -22 126 16 -128 2 -12 45 0 31 -93 -45 22 1 50 26 18 22 -5 -94 114 -39 54 -73 -5 3 82 -21 -5 24 -24 -26 21 -21 -37 -9 -1 -21 -64 49 70 9 -80 74 -1 -10 -71 48 77 -30 34 20 -3 12 14 -7 1 -15 20 -15 -58 61 -3 -58 61 42 37 44 67 7 -47 -73 3 -40 -28 -117 67 -65 -3 -33 -65 -23 23 -10 -94 24 95 -80 68 50 -55 -104 59 23 -14 -27 30 50 27 80 -64 77 -59 -19 -28 -125 -19 17 16 -86 42 -37 26 31 36 -4 -68 -31 -106 -11 -47 22 24 -16 -18 -54 10 102 90 48 12 33 75 -2 -25 -94 51 49 25 5 -25 32 -40 12 -33 -11 39 -36 -40 52 -42 -2 -29 75 -53 -125 22 -53 -8 -55 5 -25 -78 -10 -6 22 73 -97 -126 54 -48 -29 59 -73 -58 20 -3 0 22 -48 7 -32 -16 36 -121 34 -32 52 -47 54 -42 -1 -14 -44 -31 22 1 17 -29 -29 -18 -68 -55 -32 -13 -48 -92 -19 24 -15 -66 55 -6 10 -79 -8 10 -103 -123 -83 49 65 52 -27 26 124 12 50 -123 12 -14 -25 -25 68 77 -1 103 55 78 62 -85 67 -8 -27 -34 121 -64 7 17 -52 58 -62 -46 43 0 -35 16 -89 -51 -43 -66 76 -51 35 -81 -112 4 30 -122 14 127 22 -64 19 23 -41 100 -20 54 5 2 -117 -59 -16 70 0 58 39 110 -2 -36 -86 42 40 -59 -41 -68 -45 -79 -80 15 30 79 39 35 -40 59 -87 -11 0 45 -13 66 53 8 -41 -47 -80 -8 23 0 10 25 27 16 -15 -52 -12 26 -40 -38 -44 -8 -8 -9 0 42 15 -15 48 59 74 -75 30 84 -7 -53 -68 -63 125 -29 -114 -34 35 48 -56 -54 -67 9 11 -107 19 8 20 49 -98 -24 31 -57 62 -33 11 22 -38 16 13 -45 -57 -45 -20 80 71 -116 -49 -42 61 -23 -107 -44 -2 -91 -5 -44 -27 -15 80 27 -32 -33 12 44 0 105 -1 13 -32 -1 -40 -40 -43 -101 -30 88 7 -48 -63 16 73 -19 89 -124 78 -48 -125 7 3 34 9 8 -69 -3 4 5 44 52 -108 -55 -75 -40 -6 23 -108 -20 -18 -60 -66 -50 -8 12 -58 40 -50 -37 -59 -41 29 9 -10 -18 -1 -38 15 22 -62 -82 -2 28 71 -49 -91 -108 -21 -4 -46 -38 -68 -8 -88 -25 -30 -72 -22 0 -28 10 -48 -7 15 -6 33 -96 -79 -72 33 14 -68 51 125 -10 -58 -92 -37 85 -101 -122 -1 35 -59 -21 16 -126 -70 58 106 -34 -49 127 51 -25 13 49 -18 -31 -36 -11 41 123 -3 47 57 20 -13 -50 30 14 89 -12 -3 10 15 0 -25 -21 -9 45 1 -38 -17 -82 4 -55 9 6 -15 -12 51 -14 86 -1 -19 10 36 25 68 26 74 60 -31 4 3 0 -10 24 105 21 20 63 13 -22 -85 31 28 -21 -121 46 39 -68 -14 26 16 -8 7 -49 -62 -5 -41 -128 34 -42 -32 15 18 -43 -16 -11 -64 -29 -32 3 13 19 -33 -23 -12 -5 39 52 17 -45 43 -28 24 -25 41 28 -8 8 -10 16 -16 -52 -6 11 18 38 55 85 55 82 63 -10 81 41 -7 -18 54 -66 20 -31 32 -12 29 -106 -17 -9 -74 75 -5 17 -23 75 80 62 58 24 -69 -65 -43 -56 -44 58 13 -36 -16 -64 0 -24 50 66 -43 49 -84 -81 -4 -40 -57 -49 3 -13 -45 44 18 -11 15 -48 35 -1 -32 -124 2 -1 -19 -8 -81 63 41 -85 -52 -43 69 15 4 -2 -13 42 0 34 10 33 -12 -48 -21 29 4 -15 35 -45 30 103 -26 -25 55 2 127 20 31 62 -39 -110 -10 -26 36 67 26 -9 -13 13 -109 -104 -11 -9 2 56 -2 81 -28 33 40 -10 10 22 62 -68 49 -44 48 -43 -122 10 33 -89 -46 -28 -62 -3 -35 61 96 15 34 3 -45 34 -4 44 -42 -45 125 10 34 21 -11 6 -42 -33 23 74 3 3 32 89 -27 -16 15 95 30 -38 4 29 28 -4 40 54 27 -2 7 0 84 0 104 -32 12 34 -3 66 -124 13 4 1 104 -15 -13 -22 -113 -49 16 -58 60 -86 -41 42 43 -94 105 44 14 121 -46 -9 62 37 81 36 86 -19 13 -36 -41 -2 -12 -5 61 50 42 -21 65 -5 32 -34 -111 32 -20 21 38 -5 25 34 -41 -113 19 1 -51 25 -94 5 -65 -15 22 2 -18 -59 -10 33 -12 26 -86 7 -32 -29 -10 -8 -54 22 -57 -85 -11 -14 -87 -24 -27 -22 -14 -57 -47 23 11 1 -121 -74 -122 -113 -25 -34 27 -30 -36 -43 27 35 22 -20 36 -94 58 9 -18 2 -13 -110 70 61 2 -38 4 84 5 -2 -54 69 82 0 24 -41 64 29 -74 87 127 -37 74 42 -18 4 70 -84 12 66 -94 121 16 -6 19 12 9 -67 -13 -11 -33 -125 23 64 -26 -31 -20 20 -4 -10 35 -5 47 -123 11 -59 -3 16 -4 46 34 60 43 -32 61 -24 -60 76 26 39 -114 -7 38 46 12 12 -10 -50 -19 -89 10 5 19 -96 -7 22 -19 18 -30 20 -64 -60 -40 -38 15 -17 -4 -6 7 22 -8 -23 9 0 -42 -41 -41 -70 -73 84 -19 -27 -45 -76 -67 -65 -11 -43 60 36 34 24 53 -63 28 -18 -62 49 16 -35 -61 -65 88 29 37 2 43 -13 -41 -19 44 -42 25 -50 -6 -3 -14 68 22 -44 54 63 40 64 11 24 71 9 -9 18 23 -45 36 27 127 -80 -45 -21 25 -69 -42 -39 40 -98 -30 56 -2 -21 -33 11 -27 -38 5 40 -35 33 -15 18 -44 -2 -23 -64 -11 42 31 -56 -35 16 -32 45 6 -1 44 25 88 -59 -46 -27 17 20 -33 -73 -31 -53 -74 -23 -18 1 48 44 7 -3 29 12 -27 0 -5 30 -44 17 -47 2 -30 -11 24 -38 -7 -77 -70 -13 46 -9 -6 7 -86 24 38 48 66 -29 25 42 75 16 -3 -2 -72 -25 -7 -39 47 -15 -4 -10 1 -43 -3 -23 25 5 10 -21 -21 -55 -8 -12 21 -18 32 -35 -102 38 54 63 14 30 -12 -65 -69 -28 -4 3 -56 30 -24 44 125 59 -7 -14 94 -12 -19 -44 46 -2 48 3 -4 -77 -21 17 54 3 30 -15 78 -79 52 32 32 -65 -86 -12 -6 -90 12 -103 -61 -15 -71 3 31 36 -56 -29 -11 11 8 1 6 19 15 -27 -1 -53 24 95 127 32 34 -32 -28 -32 -13 -22 9 -19 -43 -29 -25 -26 93 10 58 -18 -37 9 8 -125 -23 69 41 91 19 -6 69 53 32 -11 94 -18 -128 23 -14 60 -34 1 -44 -67 27 -9 15 20 -86 1 -46 -79 54 55 -24 -33 -36 18 17 -20 -64 -69 81 48 8 53 4 -45 -7 61 13 -16 27 20 9 7 0 36 2 -8 -97 45 14 -39 10 -5 -39 21 64 54 23 -39 -107 63 50 -42 22 35 28 -13 -47 -45 1 -30 -21 67 -69 -56 42 34 -52 -18 2 -32 18 -52 -15 -8 22 25 -5 -20 -16 -39 -102 -39 19 -126 44 34 -63 -40 38 -20 -73 33 28 87 84 -30 -128 -34 81 50 12 10 -8 -58 27 34 -71 47 -52 15 -8 59 73 24 -98 -86 -12 -44 -128 15 60 -75 -20 44 39 -55 61 1 24 -34 -112 -34 21 21 -19 -8 4 2 -126 -11 1 88 -19 -26 -40 33 11 77 9 -25 9 -126 -48 1 -16 50 30 55 -119 4 -74 44 55 49 28 46 17 -126 6 39 -52 23 41 -84 12 28 81 -12 10 0 54 -36 124 15 -87 -5 4 -105 -40 31 -2 36 -66 5 16 -61 43 0 1 50 83 58 102 -50 1 37 126 -15 -35 -33 12 12 106 -37 7 -31 28 18 -4 89 -38 63 67 -51 -17 65 17 -115 -41 -107 4 5 -12 -39 -22 7 50 26 32 -12 18 -7 -12 29 -4 12 51 83 -36 3 -19 6 -21 -18 -15 22 -16 -69 0 36 -1 -8 69 -58 38 34 -13 -29 -127 1 7 -26 4 -8 -113 -16 42 2 -8 37 -25 59 -10 45 -22 -29 -114 -15 49 22 -37 39 -1 94 -2 32 -18 13 -14 25 -18 -50 59 -36 12 -52 -60 -21 -35 -19 24 -77 -1 44 14 -114 -8 27 45 -105 -39 20 7 -49 62 -30 26 28 9 -34 -104 -101 -27 -63 82 -31 -29 52 20 -7 -30 -28 84 -28 23 -57 53 -20 -10 97 74 -60 -56 -80 -26 -73 9 -10 27 16 -9 -64 2 -59 -15 -72 83 21 10 79 -55 -13 -1 -66 -41 4 9 -55 -32 -102 59 -32 109 1 -43 -60 22 -52 2 -20 -37 80 -24 -36 22 2 -42 45 -66 29 13 37 -36 5 -19 -63 -7 -10 44 56 -33 -50 35 93 -17 62 8 -34 -18 -19 -29 -48 -58 -114 42 18 -73 -8 -11 -100 28 -26 28 69 -2 -2 -31 13 -17 -13 -8 11 0 -51 -24 -5 88 -32 23 0 16 -67 -7 -35 -48 -2 -48 -31 1 58 31 10 -9 11 51 80 17 -11 44 -40 16 2 -22 26 -47 -50 7 31 50 -8 42 44 49 11 -61 34 50 61 36 -24 -5 -124 -34 44 124 41 85 -64 47 -37 118 -113 -20 -79 -79 34 14 -25 -11 -42 -27 34 17 -6 -59 -79 -19 9 -45 -57 -28 -76 -43 58 24 -45 59 -78 23 -18 14 -13 21 45 -42 35 6 -14 -37 45 -13 8 -7 -43 -38 41 4 90 0 -82 -15 56 8 -41 9 45 -77 87 11 7 -49 4 -92 -8 63 -9 37 43 14 77 30 5 -55 -10 -73 69 44 -6 -30 -26 -56 8 4 -1 28 24 127 37 26 -71 37 67 -13 -7 -48 58 -18 -33 -43 28 46 -44 12 -86 -54 46 -60 -28 -125 60 -18 -5 -9 52 7 -2 -42 47 -38 -75 -52 31 12 -43 -67 32 60 -12 -17 27 -17 -9 0 -18 -55 -96 -36 39 50 31 126 -6 45 -27 44 19 53 -31 91 -8 -14 -6 -70 39 52 111 66 33 -13 40 83 -17 16 -54 -27 8 18 111 21 -41 -61 -23 2 79 122 -16 117 25 119 -55 63 13 17 -86 -1 32 31 6 -23 36 107 45 48 -26 -35 43 -18 -81 -18 68 39 -26 -69 -94 78 44 -83 56 2 -43 18 -29 19 -63 -56 54 16 -28 55 -32 66 1 29 -73 -11 -36 -65 31 -26 -76 32 33 3 38 13 18 -106 -33 81 17 -13 37 108 -37 -109 15 26 29 -3 62 17 117 -7 -31 -31 14 26 4 -81 44 -55 -25 53 51 -38 21 5 24 34 21 45 18 59 -19 -52 79 -2 106 -43 102 -34 -56 125 -84 -16 4 25 72 10 -60 -41 7 29 47 11 -78 104 -11 -56 -20 76 22 26 -26 -15 -3 -11 11 -25 -65 46 -13 33 5 -92 -21 -9 -10 -51 -8 4 50 -102 -35 26 26 110 -10 82 51 72 11 22 -26 12 -28 15 -74 -4 45 44 -6 -21 -37 30 36 40 42 18 -35 8 -106 59 75 -24 17 77 -9 -5 5 14 29 25 19 30 5 25 -49 -66 -23 21 -4 23 38 78 -24 85 -51 16 52 -6 55 31 -23 20 4 -15 30 36 -34 -48 48 -27 35 38 79 14 -46 55 30 -54 -45 -23 52 -100 52 -29 -68 7 -32 -23 34 -1 -18 20 14 1 -7 18 -1 25 119 -127 12 -35 -89 17 74 -37 -3 7 42 26 -56 -63 -26 16 43 -64 -23 28 -41 63 102 -116 29 1 -51 -28 -2 -38 -74 64 -33 60 -45 35 -37 23 -4 -29 -94 -27 -20 -72 -4 -32 0 -49 94 -3 -46 58 22 4 -10 89 12 11 -36 113 -25 -48 -7 -9 82 -17 -13 23 -49 70 -11 -24 -48 22 -14 22 37 29 4 116 -21 -52 12 -5 -36 123 -33 -61 -72 26 -6 -95 -18 -45 -24 -32 24 17 15 56 -58 79 2 -80 -1 34 1 -41 -44 -30 23 -8 -38 6 -38 48 -101 89 90 8 -41 22 4 -6 34 45 63 48 65 -39 -62 25 -5 71 31 -9 38 -1 95 -24 -54 -47 37 25 21 -9 87 50 -76 6 78 30 50 72 -2 -8 -3 -18 -87 -24 -58 12 -88 -29 7 -39 98 32 18 -8 43 -45 -28 -20 -81 -124 12 2 23 -23 -77 15 -8 5 37 -63 6 28 98 56 -16 -7 -73 7 -61 -47 -40 42 18 -87 -72 -74 -1 9 21 -54 64 -34 -87 -7 -59 -8 -17 15 -30 -57 0 58 30 85 82 -73 44 -48 -32 -8 -7 59 -93 -52 55 11 -3 -23 -13 -42 -31 54 -6 12 -70 30 -13 -48 21 -41 17 -26 120 16 -35 1 43 -21 -19 45 29 2 -62 -12 51 99 60 11 39 -8 8 -62 3 -32 37 -29 47 23 87 -19 85 36 -87 3 65 67 -2 92 -74 58 31 -24 -1 -78 -1 72 14 15 -69 -29 -21 6 30 57 -43 24 -16 7 41 53 -51 -22 -7 18 -6 14 12 -14 -128 -9 -64 -47 -37 16 -1 -29 31 34 -36 17 -84 -60 -53 -4 51 -28 -58 42 60 41 8 -55 -59 70 -19 66 29 9 -3 -43 -27 -78 -122 12 -12 26 30 -127 100 33 2 44 18 -2 -43 -6 -66 -11 10 16 64 2 10 49 -39 20 18 34 -25 -24 2 4 76 32 39 32 -24 -46 -18 -11 13 95 40 18 45 -51 31 -62 -34 20 42 -29 -97 -9 13 -4 -77 -109 -11 -19 -2 -22 13 27 39 -8 -23 -6 -15 30 -66 -10 7 13 84 40 -88 -8 71 47 -21 -75 6 11 46 -65 62 11 -43 -92 37 -9 43 100 -28 70 -23 -60 -44 -58 89 30 20 -89 12 18 127 62 -20 -1 76 -56 -18 -9 -75 -49 -59 -9 13 -90 -46 14 114 33 -78 -31 92 -17 50 -74 65 22 -29 31 -2 20 20 -41 -78 -18 -28 9 -113 4 25 -17 -24 80 -7 -92 -14 -51 -44 50 11 -77 -14 8 4 -6 41 -121 -76 -11 47 49 68 77 3 -12 4 44 -18 -56 20 -13 65 -34 34 -16 -39 -35 -31 39 33 -82 26 45 -10 63 57 89 11 -17 39 47 11 59 -101 75 41 -15 -66 44 -25 -98 39 -27 -87 -36 -41 -62 6 -27 34 92 -12 -10 -42 -4 -45 -27 59 51 23 38 101 41 61 30 47 7 -82 -12 -31 83 -54 78 94 108 127 50 -56 23 -5 45 5 -44 3 46 7 -17 -30 6 50 13 22 50 32 -13 -26 -6 -8 10 22 -5 54 25 -16 66 20 -22 0 22 -2 -7 13 -10 -37 -8 2 28 10 22 -27 -12 -61 -11 1 11 -77 1 4 -3 53 25 -1 37 24 -19 2 61 -29 21 74 8 -23 -34 18 10 9 -1 21 -17 42 34 -73 -2 -22 39 -42 -15 7 -9 -19 -19 -8 20 65 7 26 61 16 -6 -42 -6 -63 -11 51 -1 -48 -15 47 44 114 96 0 -22 7 -53 -8 -46 -41 27 53 49 -36 25 -42 36 33 20 -8 32 -16 49 2 26 -91 -37 -23 -26 -28 -22 -7 20 25 -15 -41 3 21 6 17 19 -9 -1 -25 37 -43 15 -74 6 -29 2 -8 2 0 -87 -17 -6 12 -14 -25 35 36 -24 19 -4 -14 -22 -18 15 13 -21 -83 56 -20 29 18 -22 -1 10 11 24 -1 23 17 -5 19 -38 -11 -21 -40 -21 18 25 12 -32 -18 -12 30 -40 9 -7 27 1 29 28 -29 -28 12 29 18 21 -8 40 -3 -55 35 -30 -6 -34 -6 14 51 20 -31 -1 41 7 -14 -6 -5 -4 -23 42 14 0 27 14 -30 -1 27 29 0 -40 -19 -22 48 26 12 10 39 34 28 -3 -19 -44 -18 -6 12 32 0 6 17 -15 -27 22 -2 -37 -34 15 35 22 52 -28 4 -44 -13 -15 12 -35 -44 -45 1 -51 1 -3 -3 -8 18 -11 -13 16 -4 -1 45 -38 -14 -19 -3 7 -2 -37 -16 -10 -10 23 -19 -25 4 16 38 2 54 -23 -3 12 -19 0 27 8 -18 -41 16 11 -9 -8 9 24 9 5 -25 9 8 -7 32 7 -5 15 2 16 19 6 0 17 14 -8 36 33 -15 -15 -11 -1 -49 2 -23 -6 -4 -19 2 -2 -3 -13 5 13 10 7 -1 -4 20 7 26 -22 -19 -1 2 -13 0 34 -19 -3 16 -7 0 -21 -17 37 -45 -7 13 10 -14 -10 29 -12 -14 -49 -11 -22 -19 5 8 25 30 28 -8 2 28 -1 21 -4 18 37 -27 -18 -14 0 -4 -10 -4 50 63 -4 -36 4 -1 -11 -29 50 38 6 18 11 -9 1 23 2 -34 5 -2 -6 -30 17 14 -12 48 -14 28 10 -6 78 5 20 -10 4 -5 14 -63 8 -23 0 44 18 16 7 1 -14 12 -7 8 -30 -14 -39 20 -15 39 13 -1 20 -14 -1 0 41 -8 -8 -48 11 48 -17 6 -49 -16 2 6 50 -9 -55 16 -5 -12 16 -15 -12 11 0 6 -13 25 13 -11 -2 -18 9 27 15 32 33 0 -18 -11 26 21 25 18 20 28 -45 20 38 -1 34 -13 -17 29 -23 2 -48 5 14 2 9 -18 -14 15 16 6 -16 23 -17 32 9 -1 44 5 3 6 -12 4 7 26 17 17 -6 -10 -25 5 10 -12 30 -27 -39 -4 6 11 7 -1 21 -14 10 -23 1 -23 5 -8 -3 -19 6 1 34 -8 -17 -4 18 -7 -27 18 23 27 10 -20 -12 -7 -11 -18 0 3 8 -7 -8 -28 18 10 -7 15 -10 50 -28 8 14 1 -13 -52 -2 2 -10 7 -14 22 16 19 -12 20 17 34 -7 -23 3 -39 -6 -27 13 1 -20 8 10 -12 -15 -18 -14 -10 6 -8 12 -11 0 -9 -1 14 3 21 -22 -21 -4 -15 -5 1 22 -1 12 2 -5 -5 -5 -37 24 -5 -21 5 -1 12 15 -4 -39 1 -4 19 81 -25 42 -11 -8 28 2 -34 46 21 14 13 -2 68 -22 16 -30 -23 34 12 -13 -25 39 -45 85 33 -5 40 -35 17 8 1 3 15 32 49 -13 64 -20 -32 -32 114 23 -6 1 -30 92 -10 -20 -9 -33 -25 9 -42 39 24 -24 -40 -17 4 -33 -8 -28 68 71 25 -14 11 3 48 20 29 -5 3 64 68 -7 2 16 -45 25 29 44 -39 -1 18 106 79 15 27 3 -2 22 -9 -11 -42 -7 -44 49 0 13 36 48 13 -14 20 39 -5 12 49 -9 49 -34 4 -31 48 10 20 50 10 -19 8 -16 -25 36 -3 -20 51 53 -1 -18 74 20 -22 -13 14 -13 7 21 -16 -21 17 -8 -36 -27 28 -24 -9 18 -48 14 -7 -2 -7 -31 -30 -19 20 20 3 9 42 -23 -26 17 -16 8 22 -19 10 22 -32 21 8 29 20 -33 43 33 -27 17 -43 -25 -8 15 -56 -39 -4 15 -9 -9 -37 7 52 3 -14 -33 -15 -38 29 8 -27 -18 -7 3 -2 -2 3 35 6 -17 26 -18 41 -22 22 7 28 -7 -3 14 -42 8 -15 -16 -15 14 -26 -4 27 -3 9 0 -39 -2 -23 -19 25 -4 7 -26 -12 -4 1 11 3 18 -12 -18 -40 30 6 -27 -5 -11 15 -20 11 -26 -31 7 -5 1 -5 -38 11 0 -28 -7 14 -12 11 50 -1 7 13 1 -26 12 -29 48 -7 10 -6 52 21 -33 -27 22 27 -21 -34 13 6 -42 10 6 17 2 28 27 -22 15 10 17 2 -20 -7 27 -9 29 -18 5 -3 -13 1 12 33 -41 41 37 -30 -6 -3 -32 -14 4 -1 1 -1 -8 -9 -29 31 12 -34 -14 8 -15 -12 -15 15 -36 -21 -2 6 -29 70 14 -23 -8 -8 -14 -19 -6 7 48 14 82 -9 -9 1 -38 -4 53 59 10 5 -21 -55 -4 -5 -7 -37 36 -18 11 3 -4 15 24 3 9 -30 13 -3 0 -6 13 39 -19 9 14 -7 -3 0 -23 -33 -11 -33 22 -10 20 -1 14 -1 -11 37 2 15 -4 25 -22 4 9 14 -3 34 0 4 -5 -6 27 -36 4 6 20 -4 -12 5 -12 -19 -15 25 -15 51 0 -10 27 -1 -3 2 -33 -21 -14 -2 -17 17 3 -25 2 0 -12 -14 14 20 6 -29 8 -1 -21 -14 0 -17 -15 -17 37 25 -7 1 -29 3 -21 -26 23 44 1 -21 -18 -13 18 2 13 -1 -26 3 -1 -2 13 -17 -9 -11 -19 20 -3 -8 2 -14 -19 27 8 13 -3 20 -7 -28 -23 -11 -11 -19 -15 4 29 2 5 19 -18 -30 9 18 0 0 24 -20 4 -1 -10 16 -9 -25 25 5 -3 10 16 -10 -20 -35 -7 9 1 -16 21 -5 -12 9 -23 -23 0 23 -6 -21 37 14 2 7 12 -9 -24 -21 20 -4 5 1 -10 -26 -16 1 -10 19 -14 -6 -13 -19 -19 -24 25 22 7 -80 30 6 -21 4 10 55 9 31 44 -11 9 4 20 18 -10 -45 -2 1 -21 12 18 -8 3 14 41 -20 -25 -5 -39 30 -27 -9 50 16 50 8 25 70 6 -31 14 26 43 48 -15 -2 -20 -20 9 28 -25 18 14 -4 -15 51 21 27 1 -23 -8 -10 -22 19 0 7 -17 21 9 14 -5 69 40 53 11 -22 -27 11 -7 -17 -10 -21 25 12 -36 49 1 -39 -27 21 9 -1 15 11 0 -16 -4 0 -28 1 11 -23 6 -7 -21 -24 2 -34 -21 25 -6 -1 47 -16 42 -8 -6 -34 14 37 -5 -20 39 10 16 15 -41 0 -19 -12 18 9 -32 23 34 -11 34 12 17 36 -42 3 13 -17 0 -9 -18 -5 -29 -9 -20 21 -37 18 -26 34 -16 1 66 16 20 20 -7 -43 -25 -15 -1 17 30 14 -3 13 -1 -2 -28 10 -26 -49 -6 17 -16 2 7 1 -11 17 13 10 14 11 13 -22 20 15 -22 -23 -14 32 -7 20 -9 2 19 -3 -25 -9 10 26 9 0 -3 -7 -14 11 -33 -3 2 11 -41 3 -42 3 -12 27 -26 -21 8 2 0 -8 14 7 2 14 35 -6 5 -37 14 -36 7 -20 26 -7 -22 10 -9 28 -2 -7 4 -5 -2 -15 -17 0 2 -3 -18 -9 10 4 11 -12 2 13 6 -20 -23 -7 10 -5 -23 -2 -16 -30 -4 26 15 -7 -49 -33 5 -28 -28 -29 5 0 11 48 -14 11 -21 5 57 17 -5 -22 -6 39 4 2 -12 -15 -64 -31 87 4 4 16 -23 -30 -10 -36 15 16 10 12 -51 -24 13 -31 -14 -6 -14 51 -7 -35 14 41 13 17 5 31 -22 26 -27 -1 -8 -2 3 -7 -7 -8 -21 -13 8 -3 51 -41 38 3 -42 -21 7 39 14 7 52 19 -6 17 22 -22 3 8 16 14 3 29 -7 -7 4 27 1 13 39 18 -14 -62 30 28 -5 -40 -44 -21 -21 -36 -19 34 12 -47 -8 -21 7 22 -10 33 -23 41 -13 5 3 24 -31 4 -17 1 37 13 8 -23 -12 -3 -9 22 -27 -15 -26 -9 23 -15 -9 -8 -20 -18 -15 -14 17 -24 28 -1 -35 -7 -20 22 -14 5 -18 28 -12 22 30 -4 -41 24 5 7 -28 8 8 -9 17 25 16 35 -9 -9 5 7 19 10 -18 -26 -39 -16 -8 -2 13 -49 -43 12 13 -1 22 5 24 -14 15 14 -4 2 13 20 -9 -12 -21 -5 0 -29 -7 17 1 26 4 13 -2 17 -18 -15 13 -12 9 13 17 6 8 8 1 -12 9 42 0 -17 1 -3 1 -28 -27 0 -12 -36 1 -2 -11 9 1 15 -5 9 19 6 -27 -9 9 -14 7 -12 29 7 1 -21 11 -9 11 -15 21 -3 -2 -3 6 9 -7 -6 21 31 19 -3 9 -6 23 12 6 -16 -36 -13 7 -10 -23 -2 -2 -8 -5 -11 -17 7 50 24 -18 -22 23 11 -19 -5 -14 12 7 12 13 16 -14 -7 -75 34 34 1 -2 45 27 61 15 17 16 -5 25 38 53 3 51 21 -5 39 21 -33 46 -59 23 25 13 13 11 58 50 23 24 -21 -24 -5 18 -49 -24 -13 11 -20 -8 23 6 -25 -28 57 -33 12 14 14 2 -10 -81 29 -13 -7 -92 6 22 77 -13 -3 16 16 15 65 4 -1 -19 -1 20 42 12 30 29 10 -7 4 -1 20 -1 10 15 -24 -16 28 13 27 29 34 24 20 -2 -8 8 -22 13 44 24 -6 22 4 -12 47 15 -4 -15 -15 -17 13 33 -25 7 -25 15 6 -21 40 -23 -8 -8 38 17 12 15 -2 -19 -8 -1 -6 51 -29 2 -32 -50 -4 12 -7 2 2 15 34 27 23 -42 17 -17 7 -24 -26 16 31 -13 -4 -26 3 -46 30 -16 2 8 18 -9 -22 -27 2 13 3 6 -21 -7 -14 -13 -4 3 11 -18 -35 18 29 -10 16 6 6 12 12 -10 15 -21 8 30 14 -19 -14 37 5 29 -5 -1 1 0 0 -19 -31 4 -16 21 8 -7 -8 -2 4 5 -19 -23 12 17 -25 -7 19 -15 -2 2 42 15 6 2 -18 25 -10 13 8 -11 15 26 18 -3 -10 -17 12 -18 -49 1 -32 -4 -13 14 -2 13 26 8 -2 19 -15 -25 -39 -8 6 30 -15 17 -3 20 54 -3 30 34 15 18 29 -27 22 43 32 2 -33 -74 -2 45 45 14 -41 9 -11 11 -5 -24 -30 -24 45 42 7 -3 -38 18 5 62 -2 -12 37 -2 -14 7 9 -29 32 14 -11 -24 18 70 -29 25 -13 49 -9 25 0 58 -23 0 -41 8 -14 -6 -28 15 -31 -5 41 -6 35 63 -13 -39 13 -7 10 -50 20 -32 10 41 22 -30 -16 -23 -14 3 -38 20 0 -6 -21 -25 -62 21 45 15 3 33 -12 15 -3 -38 12 37 44 -7 -9 28 -13 -3 14 -1 -1 41 -4 47 -7 14 35 -17 6 32 -30 17 -26 -9 21 23 10 10 -21 24 14 13 23 17 -6 52 44 -13 0 -8 -6 0 10 -2 8 19 -17 56 23 5 -39 11 -12 -10 17 51 -1 -24 -4 -34 -15 14 49 0 22 -2 -6 2 4 -7 -30 14 -25 15 25 -40 -19 22 12 -21 13 12 28 -11 -2 8 -2 -14 40 21 -1 18 16 11 -39 16 5 -42 8 28 19 7 -21 -1 8 -3 11 -18 1 12 -22 -27 23 0 -1 -7 -34 16 -47 1 16 -2 -13 4 -11 18 -8 -14 2 -4 -10 25 -16 -10 7 32 16 -34 -8 -18 9 -12 15 -20 2 22 -14 12 -5 16 -10 2 -3 15 4 -21 4 33 -18 12 3 -22 -16 2 37 42 -10 -5 9 -3 -28 24 -2 -15 -1 6 -3 -12 7 6 15 -5 1 -3 32 7 27 17 -1 0 -42 5 22 36 -55 -1 28 -1 -38 -21 -30 21 -2 -31 33 -33 7 -19 -37 49 -22 41 7 -10 10 3 28 -48 6 60 21 27 -18 14 0 -40 -2 35 -16 21 36 16 -22 -24 23 -1 -35 6 -39 -3 -7 -5 49 -2 43 -21 9 -24 0 15 -22 -5 -15 11 11 -26 7 6 3 72 37 17 8 -23 -11 -47 -7 31 45 27 44 -13 11 0 -5 1 -36 48 4 -21 16 42 5 0 -15 10 8 -43 48 -16 8 8 1 18 -5 -2 14 -14 -4 -12 22 1 2 -12 -19 3 -6 -5 -4 -2 12 3 -23 2 23 2 -42 -17 -38 12 -5 4 31 19 -20 -1 18 -15 26 -38 29 28 -7 -9 24 23 -19 11 9 -34 12 8 2 25 -20 19 30 -5 -17 21 -24 -6 23 -12 -23 13 0 22 15 -12 -3 -32 16 9 6 -21 3 11 0 -12 -3 31 4 -12 12 -18 -13 -6 -31 -57 -32 -14 5 -13 -4 0 1 -10 14 6 -6 -7 -13 -32 21 14 8 -13 14 -34 19 23 6 8 -1 -1 19 -27 -4 -16 13 20 -3 0 -8 23 -10 5 -7 -1 12 10 6 -4 -17 6 9 -11 -31 10 -1 -21 8 10 17 -37 13 3 -15 -16 -20 46 11 6 -16 15 13 -8 3 -14 9 -2 -36 -36 21 -15 1 -13 -28 -13 27 -1 -10 -1 -38 -22 1 0 8 19 11 6 0 -4 -70 -64 -2 5 57 23 -74 -85 -112 -39 -88 -11 7 34 9 13 0 -7 -36 -15 -10 36 -1 45 15 10 -8 -21 5 83 3 22 -42 -3 -24 26 -59 -54 16 -22 19 17 -21 34 -41 9 -25 5 -25 -19 11 -4 -54 1 6 -19 43 48 -20 34 -34 -10 32 18 78 58 36 17 -32 -43 0 12 42 11 36 35 11 -48 11 57 41 2 -46 -5 39 -24 11 73 -89 27 95 -9 -24 -22 40 30 -33 9 61 -5 45 -5 21 1 -46 -43 59 10 -9 19 62 38 5 -42 -15 -12 37 106 -10 40 -16 -10 -4 4 -30 4 -4 44 -2 13 75 -23 24 12 16 -12 -12 21 -10 59 48 -42 -24 26 -27 4 -50 -14 -24 -7 -49 -33 19 7 -36 71 -58 -21 -9 -26 28 46 31 -66 -5 -79 -49 17 3 24 -13 30 -16 -4 43 4 -7 59 33 3 2 38 16 23 -11 23 -43 22 16 -22 -25 26 2 -31 -9 12 -48 -11 -34 -25 -47 7 -43 -4 1 14 -23 -4 -9 -7 -3 -8 -3 8 12 15 6 -19 -18 -6 40 -17 -14 2 23 -23 4 -19 28 -3 15 7 -30 -8 -6 11 8 -11 7 -4 -16 8 35 14 -17 -14 15 7 -5 -2 -9 40 -18 -25 12 21 17 -6 -16 12 -28 61 -45 -28 31 0 12 2 1 26 4 -8 -4 17 32 -79 -3 -1 10 13 32 -63 32 28 0 -32 8 -35 38 -11 -6 1 8 -42 -7 31 62 17 6 26 -5 -46 11 -5 20 -4 40 31 -24 5 -8 66 -14 -40 -7 -36 23 67 -9 -40 2 34 -34 18 -21 19 40 -60 70 36 -54 -31 -5 -29 -7 -14 15 -7 -22 -119 1 -20 7 1 -15 31 34 31 0 29 -25 -48 -15 -53 27 0 5 41 18 51 67 2 -36 121 -15 36 67 -4 16 -8 -32 -8 -17 -18 50 6 66 -8 -23 80 -9 69 -2 42 62 3 -13 -65 7 -3 -21 -13 45 49 26 22 -10 30 4 66 -50 -17 -47 5 -5 -56 -19 -15 30 11 -8 40 3 32 8 -10 -72 6 -15 18 -52 21 26 -19 8 34 20 -31 28 1 20 -59 8 17 18 57 10 -14 57 -27 35 -28 12 8 1 15 19 35 -18 24 14 22 8 49 3 -39 31 49 32 1 16 -34 17 43 20 -9 10 -42 -45 10 -62 -19 -52 -7 -8 31 -59 13 -56 -4 -7 -11 12 18 29 -19 -4 -34 -29 -40 -3 -16 -13 -5 -17 13 -5 -15 32 2 23 -38 -48 -6 -15 19 -10 -6 10 28 -2 -29 -9 21 15 11 -3 -8 1 31 -18 -26 -11 -34 3 -12 6 15 42 -34 -5 12 -14 5 -6 -7 1 -22 13 -7 -15 14 2 9 -9 16 14 -46 11 -3 -29 -58 -29 21 23 -20 -10 3 0 -13 -12 7 12 3 -9 31 -26 -8 23 -4 -22 -4 17 -5 -9 13 1 6 -28 20 56 -43 57 -22 -2 2 6 10 -19 46 8 51 36 23 38 13 7 26 6 -50 -35 89 24 -2 8 -50 -49 -20 30 12 22 -55 -62 -51 22 -56 -49 47 19 -17 30 3 -12 49 -58 10 -63 16 30 -75 -48 46 -20 -30 -33 20 48 -63 -21 12 72 -69 51 -2 53 41 -22 -43 -33 41 37 -34 -6 4 -22 -9 -1 29 -6 14 49 -11 -97 -11 59 21 -72 -93 -64 -25 -19 -19 73 -41 -29 -23 6 -86 3 -22 -19 -44 -63 -2 81 -37 6 -5 40 -11 -20 -32 65 53 20 -49 -8 89 -64 56 -50 32 -85 -21 -7 10 -55 -23 -11 41 -17 63 1 -22 42 -14 47 20 16 -8 10 4 65 44 10 -38 47 39 28 -35 80 -26 20 -1 -20 51 -36 -3 -50 -4 58 37 29 20 53 2 -25 -56 25 -7 26 -17 63 -29 -17 45 37 51 -10 -11 29 36 18 9 58 22 25 -14 -14 -33 11 26 -17 -23 30 -3 23 -52 29 -21 -12 -32 -36 -5 -12 8 5 -37 2 5 14 -3 23 -27 -19 11 -32 -4 22 15 -18 -16 6 -26 -32 32 -17 -25 -33 -1 -14 13 -18 -32 21 20 -1 -7 -16 -15 -20 4 -2 -2 -12 -12 3 2 2 4 -23 38 -36 2 14 -23 -14 4 -3 50 5 -14 -11 24 11 23 22 -10 -7 28 22 -17 4 -39 -74 17 -11 66 -2 -46 -4 27 -10 -2 14 -21 -6 -36 52 48 37 -72 41 11 5 45 2 2 36 13 32 -19 -35 -11 -24 -40 -27 -14 17 -7 10 23 22 -15 -25 -13 36 21 -8 46 9 36 55 -13 19 -113 -25 -63 -1 45 -84 5 -26 -6 13 -40 -1 68 -63 -15 -56 -56 -33 -61 -42 -8 11 -20 70 -32 64 30 49 0 -25 -18 53 2 -88 38 1 -1 11 -10 50 -15 -27 -11 8 -41 7 -2 -13 89 32 30 53 37 14 -22 -4 41 -29 -30 -25 -13 -16 -27 43 56 48 40 -46 8 -51 -24 -7 -8 -13 -34 41 -34 35 8 4 81 59 -47 -24 24 31 15 61 -17 -61 44 32 -15 17 37 20 -21 -50 3 -20 -2 16 -37 -4 4 6 -22 7 42 37 32 19 -50 9 -29 11 -5 -69 17 -22 -38 33 44 29 -2 37 -32 25 32 -24 4 49 10 -7 -21 32 -8 12 -70 14 92 8 -31 28 -15 87 -59 -6 3 20 -17 -9 8 -29 -6 41 7 33 -13 41 -30 42 3 15 -53 3 3 11 -1 0 14 -28 -26 -34 -25 26 -24 4 27 30 1 -6 0 -40 -31 -18 -28 -17 24 26 -32 12 -10 0 10 -38 22 26 -28 29 10 -9 -18 48 5 -23 46 -26 28 -5 -6 10 -15 -24 13 -5 -20 -1 -40 -4 -2 41 8 -12 -8 -53 20 17 2 -7 -43 -36 -8 15 24 3 35 11 35 -13 55 -42 -23 -21 12 -27 -19 15 -6 13 -12 23 29 -57 58 10 -15 55 3 36 -20 -21 -56 -35 -43 13 11 -33 -36 19 -20 -4 -16 36 7 124 10 7 57 -8 -79 9 -16 -23 46 -7 -23 -8 38 69 12 -31 -64 -7 -8 -36 27 13 -52 8 -11 19 11 -56 63 -33 18 14 -18 -23 -9 -59 -15 -27 -79 31 -36 1 46 9 58 -32 6 -10 -18 -77 -24 -5 -69 16 10 -52 21 45 -37 23 64 -20 3 -6 46 -39 -36 17 46 7 -8 -90 -9 -12 62 14 5 -4 39 -9 14 54 37 -27 42 -17 -9 -13 -39 18 47 12 57 39 23 20 13 -5 17 -55 -76 7 24 27 11 -63 5 7 0 -28 11 -6 24 32 -3 1 -3 37 8 11 -74 16 -3 20 5 -32 24 14 10 -9 36 27 -59 11 42 -9 -20 4 39 58 1 49 19 -22 23 5 4 -7 -14 33 11 -49 12 -36 -28 12 -20 -5 41 -57 99 -45 -3 -17 29 -23 8 19 -5 24 48 24 -34 35 5 -16 7 -10 -25 14 12 13 15 17 -41 -11 1 -11 12 -50 3 12 0 8 -41 -8 39 19 5 -35 -50 -5 10 -25 -10 -19 14 -25 14 13 -13 -1 -16 45 4 32 19 42 10 -3 -36 37 -1 -16 4 -33 -15 -34 -1 1 -32 47 26 19 22 -34 8 4 6 -6 9 -14 -12 -41 -18 -14 0 6 9 -16 -26 36 16 26 28 -1 -13 -1 -5 -20 -3 17 -29 15 -6 13 24 -26 -42 -9 0 20 11 -2 -26 -3 13 -6 -31 -5 27 5 0 -16 10 -10 42 23 2 20 81 -14 14 22 31 28 24 22 36 -5 5 11 26 -2 -3 9 9 34 27 22 40 14 -18 4 11 9 -9 -4 14 14 0 24 13 31 20 20 15 26 2 48 -59 6 -28 -9 -20 -12 14 -3 -21 -8 -17 50 -3 55 -7 4 15 -5 -20 10 -14 -15 -4 -27 -26 15 -31 -8 5 39 0 19 2 -10 -1 -5 13 -20 41 -19 4 14 10 -22 37 25 8 -28 4 -1 0 5 1 -15 -5 16 -14 -16 -1 15 -32 17 -24 -10 -17 2 -13 -12 -2 -19 -22 -10 37 -7 9 13 -13 3 12 -12 -4 1 8 -19 23 -2 -4 4 6 15 8 -13 -19 -18 -33 -9 30 33 -6 -9 42 6 6 13 26 15 4 9 20 22 -36 26 -21 0 14 28 -12 17 45 20 -9 36 -35 -1 -5 -24 -5 10 20 17 18 7 11 -4 1 -10 16 -16 -30 23 8 3 4 -34 -7 5 1 -12 1 -9 -2 -14 -25 0 13 -12 30 12 22 17 22 3 4 -9 -24 -14 -3 3 -24 2 17 42 -22 -15 3 6 -14 8 -10 -10 -18 1 -14 11 27 -3 -12 2 12 27 -7 9 37 9 -23 -1 -29 19 9 -8 -13 -8 -20 -17 -7 -18 -12 3 24 -9 -20 -2 -20 -33 28 2 10 11 -6 -13 16 -48 -6 4 33 -32 8 -1 11 -38 -40 -29 19 65 -75 -7 3 30 -48 -34 -15 -1 37 21 -20 16 23 13 -38 -21 40 10 75 5 30 22 -14 -21 -10 41 -19 28 -26 -59 -43 -26 -25 -2 -13 -45 -20 -15 -11 3 5 1 -24 -13 -22 -2 -35 19 -19 45 13 -16 -25 -9 29 -26 -29 -5 -8 -16 -17 0 -3 -41 29 2 19 20 0 -28 -14 20 60 -11 6 -18 -9 -7 -47 30 9 -32 -29 9 -12 6 7 7 -42 -8 37 44 26 -1 20 -34 45 73 -11 4 -37 6 52 24 11 2 28 16 10 3 -47 6 30 -24 -33 3 0 3 24 -6 -30 -21 -15 -31 -23 -2 -42 -7 -1 -23 -1 19 3 -32 25 -1 -35 32 0 -17 -4 -3 -15 35 19 21 5 7 5 5 -32 -8 -60 -34 -14 -20 6 -5 -12 -18 -16 -22 12 -31 0 14 -32 38 28 10 47 3 0 27 -14 -5 -27 -22 -37 24 -7 38 3 -26 22 -10 -8 11 6 0 -14 -6 20 4 -4 16 4 -2 -23 29 3 9 -11 16 -17 -10 -10 -10 9 18 -9 7 18 38 -11 3 -9 5 -12 -12 -14 6 -16 -2 19 -17 -18 19 7 -33 -4 1 14 1 -22 -5 -9 12 28 -2 -40 24 6 12 15 38 -24 12 -14 -25 -18 -7 2 11 -13 14 0 6 -21 -14 10 2 -29 2 43 20 -18 -33 32 20 22 11 26 -26 13 -8 -4 13 0 46 -5 7 11 4 17 -32 -19 10 21 29 14 -10 28 50 41 21 -33 -1 -1 -7 5 15 21 -22 -7 24 1 -4 11 -20 14 31 2 22 -32 -14 -3 -21 -36 5 -11 6 24 6 31 35 7 28 -4 2 10 24 11 -16 -9 -35 12 2 1 6 29 34 7 -28 -28 -18 22 -10 -15 -26 10 -26 6 -13 36 34 13 -10 -10 27 -34 -37 37 -56 -31 28 16 -26 12 -1 -2 37 3 6 -32 -15 -28 4 -24 16 -2 34 -1 -24 -27 -7 0 4 23 -32 -28 -29 -20 -4 22 -9 10 -6 3 8 -7 28 -16 5 -27 -24 -11 15 8 39 -20 6 -15 16 22 -8 -35 -34 26 19 -41 -17 -4 29 -3 11 45 -12 36 -8 -1 26 -13 -26 -5 -29 1 -30 -15 -30 1 17 1 -16 16 17 -7 -25 42 12 17 34 -10 22 0 34 -4 -9 36 21 20 0 10 -1 18 16 11 -15 0 -2 9 -6 16 -38 5 -17 -13 -7 5 -6 5 -12 -9 -3 21 -23 30 5 -8 19 -8 -31 -1 31 4 25 -1 -7 4 6 -17 4 -2 31 -2 -7 -7 -15 6 -3 10 -2 -11 21 -10 10 -2 -17 -7 -23 -18 -16 -22 5 7 -10 3 -23 10 -1 0 16 5 -25 -30 -9 -11 19 22 -11 20 24 10 19 -3 11 -20 -5 6 -15 -13 13 14 -3 -26 11 9 -31 -3 -3 3 -42 1 37 -74 14 -4 68 -6 1 7 19 -55 30 -10 -38 17 16 -14 -28 -29 -2 -2 -35 -84 -12 1 -21 6 33 -8 14 -24 20 -49 0 -38 -12 -30 -20 3 -26 54 -27 57 -12 -13 4 -47 -27 17 24 -14 68 -45 -31 22 -7 34 7 6 -7 3 -16 5 -5 37 -50 28 36 37 26 -28 1 -22 -50 -41 35 19 -11 51 -16 3 -84 6 38 -16 6 -52 23 -7 -2 2 33 -32 -15 9 24 -4 -16 71 24 -6 -26 -2 -14 -49 -26 51 12 19 13 43 -51 -3 -2 21 48 12 -49 0 10 29 -6 -10 0 -46 -58 13 -36 -8 -13 -40 -30 -26 -53 28 54 -77 -23 38 -26 -11 10 -27 -13 4 -11 20 29 6 38 21 -4 -46 10 22 -3 -36 4 -5 18 8 -58 15 39 -44 0 -29 -31 22 -1 -12 -4 3 37 -18 -39 21 -25 -16 8 16 -6 -17 14 6 -18 6 -26 -13 -2 30 44 6 -26 -17 -11 5 15 27 1 6 -17 11 15 21 -3 19 10 12 2 -12 -22 25 -30 -10 2 25 9 -13 -30 7 -12 11 -11 37 -17 -12 48 -6 -6 16 36 -5 35 -38 -33 5 18 24 0 6 12 2 20 -1 17 24 -22 11 -5 10 28 13 10 3 -22 8 -18 5 12 -1 -17 3 -15 26 -15 0 -15 -3 23 -5 -5 29 29 -11 24 38 -37 -14 -24 -37 11 -7 -12 -10 -3 -63 31 53 43 48 -36 5 4 1 -6 -39 -25 -44 10 -22 54 63 -13 9 2 24 -10 52 36 71 26 35 -4 52 23 49 10 34 62 52 23 61 16 -12 8 29 -83 5 66 -8 15 0 -13 1 73 -68 -92 12 10 -84 44 5 80 0 -3 33 1 13 39 -49 28 -45 34 29 8 -56 -20 6 50 -2 -12 1 -12 44 -34 72 22 32 95 12 -39 -13 -17 -27 -9 -1 -31 21 -4 21 -53 -13 -31 -2 -5 -30 -11 -1 38 -70 -69 58 10 -25 38 -57 -45 -36 7 17 21 -43 -1 11 -68 18 27 -10 1 -27 22 -19 -1 19 -6 62 12 -38 4 22 31 48 -15 16 39 -42 -14 3 1 3 -14 -43 -6 7 -4 24 -8 26 13 10 13 -21 45 -9 8 -35 7 -2 60 -7 -35 24 -30 -42 -64 0 10 -36 17 -14 -21 23 18 11 18 27 7 16 15 -28 -42 28 37 30 25 -21 16 -16 -27 -14 17 3 16 -6 8 3 -1 -11 23 7 15 -12 -17 -11 -7 30 -11 -29 -15 1 -5 20 8 23 18 18 -3 0 16 4 4 -36 44 -11 -23 -33 11 3 9 -23 -16 9 17 -31 -31 36 -39 14 6 1 -25 32 7 -9 -15 -8 14 -48 11 5 -3 -41 -19 18 -1 3 -35 18 -6 -19 -53 -14 14 11 13 -25 -13 9 -7 3 -29 -19 -55 -26 11 22 21 31 -32 24 16 40 -30 -23 12 37 1 101 53 -3 -96 18 -7 -22 47 -13 -24 24 15 -2 -48 -58 5 -48 -29 -1 -18 9 -2 63 19 -3 -1 47 -2 -23 -10 -6 56 -37 47 -54 37 38 15 26 102 -42 -24 76 -3 25 -27 -59 23 22 -26 127 54 55 6 45 -1 -6 -5 5 19 -56 -74 -9 -40 -47 56 11 -16 -9 23 40 -22 55 19 62 24 -40 -2 -35 -4 -23 -29 -4 19 4 13 33 -42 20 18 -32 -35 23 -13 41 73 9 -14 -29 -60 -18 76 -28 -48 -22 -20 65 -52 -44 -28 22 -37 54 -39 21 20 -15 9 -1 10 -9 28 -7 24 24 -14 -4 18 -75 10 14 -16 -12 -20 73 -14 3 -9 -23 -33 3 28 -47 10 -11 -26 16 -33 -2 4 -22 -1 -2 31 -67 2 -75 12 -28 -53 -3 -1 -37 -22 39 15 44 -23 27 35 49 -13 20 -48 -22 -68 -14 -27 -30 -23 23 -5 20 28 -26 -21 4 -18 -23 4 -5 29 49 -27 91 1 34 31 20 -2 5 2 1 -27 31 15 1 8 -34 -30 -24 1 7 -47 -1 9 -18 -18 -2 2 14 35 16 11 25 1 47 27 9 -11 25 -11 -22 33 6 -39 18 -25 -6 -21 -5 17 15 -4 7 -24 35 -10 23 3 44 -11 9 -11 15 -16 -1 3 -30 45 8 25 -6 -23 9 -10 3 -18 19 -11 -26 36 -18 14 32 0 -49 -5 11 -4 -34 12 17 23 11 -16 5 40 -8 -41 -18 26 -22 23 70 18 2 40 -14 -15 9 30 -7 -47 46 20 21 14 10 31 35 0 13 18 -21 25 -19 -14 11 21 6 -24 47 41 5 -20 -13 31 -11 -48 -2 -2 50 48 12 -23 9 -19 8 -8 -17 43 14 53 18 92 -11 -23 7 -4 -19 61 2 44 -9 29 40 -25 66 7 15 12 8 -12 16 1 -14 -22 17 4 21 -36 7 40 39 37 5 -60 16 -5 27 1 -27 8 -14 12 -6 17 -19 -10 20 8 -29 15 0 30 -28 -39 10 -32 0 1 -18 -42 -5 20 29 -7 -11 -14 -28 -19 -10 10 41 24 -45 23 -35 20 22 23 -7 25 -22 5 -6 9 -33 -28 -7 10 -6 42 -2 18 0 -15 11 44 -51 16 2 -30 -44 -24 13 24 55 -22 21 -45 44 5 -2 40 6 -25 9 -14 -8 -4 -2 1 36 28 32 -12 3 8 -7 29 1 -11 -7 7 -15 2 3 -6 1 0 7 1 -38 -27 -11 34 -20 -14 16 4 21 -2 34 -3 -21 29 26 -8 -16 -21 -30 -17 9 11 -25 -12 3 -1 15 20 -21 2 14 29 4 24 6 -17 -21 8 14 27 39 -12 -2 -1 7 -9 10 -12 -9 -12 -18 -13 23 2 -36 15 19 -9 4 24 -6 -34 -12 1 -5 -13 8 -3 4 17 -1 37 1 -23 14 -4 -10 10 5 -14 41 -6 1 -19 11 -12 9 11 -26 -22 8 -7 -44 16 -26 -11 7 0 10 19 -7 -5 -29 -13 25 9 -12 -40 18 17 -38 28 1 1 -25 22 28 -8 -11 10 -56 16 8 -21 12 -42 -52 -19 29 -34 15 -29 -23 22 -41 -21 6 18 -19 1 22 30 -51 -10 -3 -47 29 8 1 5 -11 12 -3 -4 -44 -7 -9 9 17 -35 27 -28 -20 -7 -30 6 47 -19 -49 12 3 -41 23 -17 -1 12 30 68 2 21 -6 18 27 -54 -25 -29 -11 5 4 19 -42 -26 -6 -7 -28 18 -27 34 30 -19 -25 -18 14 -14 38 2 -25 -29 -5 -34 1 32 12 -34 -5 27 0 -9 -26 -44 -57 -27 1 -24 31 -11 -17 -15 11 2 -16 -21 -16 24 20 -5 -52 -23 -28 -28 1 12 3 38 -10 16 31 2 -5 -30 17 25 27 -16 5 -37 15 -15 -20 48 -15 9 -19 -2 -15 5 9 -8 15 -23 -4 -24 -4 -49 -46 31 -29 -12 11 -11 7 -27 23 -9 17 6 15 22 2 -10 2 26 -17 -15 19 -4 12 -4 -10 -28 5 22 -3 -13 0 -25 -5 18 7 11 44 4 0 -5 37 18 25 15 13 -33 8 -10 -3 12 -1 21 29 -30 -7 -19 -2 -9 12 51 -19 7 -9 0 -4 -19 29 -32 -5 -8 -5 -29 7 -11 -1 -20 9 -6 7 -11 -37 -30 7 23 11 7 44 8 2 1 18 -12 16 1 36 9 27 4 -18 -7 -32 34 -26 35 -16 -7 -19 -29 12 -64 -33 -8 29 -26 -6 8 27 -30 31 49 22 -56 7 23 -2 31 17 -15 37 4 20 1 12 -14 34 -20 54 -9 -6 -24 -3 -6 12 15 36 -26 -8 8 13 14 21 44 4 64 -5 -15 -8 38 20 -11 38 -8 -29 23 11 -8 31 -10 49 2 38 4 6 26 -14 23 4 39 16 28 -12 -12 19 16 -15 -2 38 40 15 56 -23 48 16 -4 2 1 -19 3 11 14 -36 15 10 17 10 -16 48 42 2 -42 -1 11 14 -9 14 14 -13 19 23 -13 20 21 20 -5 22 12 -22 -19 -32 -15 -3 2 9 27 -30 17 23 9 -12 23 4 33 10 22 28 8 31 7 33 -12 3 -41 23 24 -6 -19 22 18 -26 -28 -26 -11 22 -33 -6 14 -28 26 -3 -20 -12 -5 22 31 8 -3 1 -16 -36 -8 -2 17 -26 -1 -24 -34 -6 14 -2 -24 -10 15 -7 -7 -18 -2 24 -24 27 8 15 28 -38 -8 -8 -3 10 13 -14 -4 -19 7 -29 -17 26 -17 -16 11 9 -8 -6 -7 3 26 -18 14 -23 -8 26 20 33 10 -10 -23 -9 -14 -17 12 0 16 -23 19 7 2 -24 -7 6 4 -5 -22 -5 -12 -25 19 -48 -16 5 -8 -30 -17 4 17 19 8 8 11 10 17 -2 32 21 21 -34 -36 1 19 -35 -29 12 36 5 -1 37 -10 -28 6 15 5 -8 -76 40 -49 -7 -50 17 23 13 43 10 13 -48 8 10 -36 -45 24 -74 7 4 7 -15 -18 21 -43 -27 -5 -24 33 -22 13 -27 -16 51 28 2 -4 0 -14 23 19 48 8 22 58 -40 -12 -79 9 -30 58 53 -47 -23 -11 11 -12 -3 -19 -45 22 -32 -9 -70 80 -7 23 6 -6 31 -14 8 -1 -4 1 16 -39 25 -66 -61 -41 34 37 -6 64 -9 24 -11 -24 -35 -53 15 21 -39 50 50 -4 -12 -15 -20 -40 -18 2 -54 2 -12 23 -1 25 -10 -6 -35 -6 -10 71 -34 -1 -26 8 -17 1 -50 26 26 17 -60 -12 0 -16 -9 -58 -49 -34 21 -9 -33 -16 0 -34 -2 27 -23 -22 -37 -29 40 32 26 33 10 -30 5 0 -28 38 1 16 2 -34 13 23 -19 -19 -25 4 -15 3 -48 -38 -19 -5 -12 -30 -2 -9 5 -24 17 -23 42 -18 26 -29 -21 18 4 -18 -18 5 -5 0 -10 -17 3 -5 -8 7 -13 -5 49 -12 24 -3 1 -27 34 -9 27 8 14 -29 22 -3 -2 4 -11 35 12 -50 15 22 -28 16 -1 35 -18 -7 -14 9 -19 -14 1 0 -17 -18 -14 -17 -31 12 -18 -1 -24 -10 -1 20 -73 7 -9 13 -45 14 -20 -32 -45 -3 49 16 -22 -7 -1 13 21 -9 10 -15 -39 -16 3 16 20 -26 7 4 -7 5 11 -4 -37 26 -5 -20 6 -18 14 -9 -25 -13 -37 -22 0 -20 -52 -77 -48 -63 -6 -13 -14 33 52 -44 3 19 10 -63 -8 23 5 -61 -21 -37 13 33 -66 52 -43 5 48 -57 -29 -21 -83 -56 24 -54 5 50 42 -56 28 38 -17 47 -33 39 -23 115 -15 -7 -73 -72 50 1 -106 -48 83 -31 10 -17 9 -96 33 -20 -17 -70 -2 -40 -89 24 37 -24 -28 -30 43 3 -49 63 7 76 19 -9 2 21 -52 30 25 -26 47 20 9 -48 -3 16 -15 -18 -12 4 -43 17 35 41 23 -32 -6 9 4 -9 -49 17 8 -31 -20 43 -21 28 38 -5 4 45 85 4 -3 8 -10 -41 -31 10 -2 33 -33 -55 69 -10 -23 22 -1 -42 -25 -6 44 33 -10 -19 8 -60 63 22 -3 82 7 14 5 -19 -16 9 16 31 10 20 19 45 -42 -9 11 -34 -44 24 -24 -17 -22 1 14 16 -50 -21 55 31 9 29 -59 -22 25 23 -35 -1 -12 -34 -19 35 9 3 -6 10 2 -20 -2 -29 36 36 -6 -17 10 48 41 18 6 -13 0 -15 -39 -17 -15 -30 -4 -16 -23 -2 -10 7 -32 16 -22 -14 -12 11 34 2 0 79 39 21 -8 -6 14 18 -3 12 6 9 30 26 -2 3 -11 13 -11 6 -50 -19 34 46 7 -27 51 -22 44 1 -17 -57 17 -4 14 -50 -17 18 -35 -18 18 -11 13 -50 -6 32 -17 -2 -15 61 6 -32 17 3 -9 -9 -5 39 83 -20 24 -97 -56 -17 -53 -25 19 33 -24 25 -25 62 13 55 9 -91 42 5 51 -62 42 14 66 5 -57 74 -48 -15 -35 14 55 -60 45 -87 -66 6 19 23 -52 1 -89 -81 39 -11 -32 82 -47 31 53 -61 10 44 113 -42 -30 -124 108 66 33 -38 46 -110 0 84 -41 -97 16 -24 79 -28 -36 -63 84 23 -10 -6 -8 6 98 81 61 102 22 -126 -50 -36 19 1 51 -14 1 -59 -55 97 65 -19 -7 -2 -12 43 -16 33 -10 -42 43 8 -92 -106 -89 3 -21 25 -39 -29 -5 -31 2 78 1 26 -15 -12 -9 -61 -93 11 17 -40 -46 10 -41 45 50 66 -19 -10 -6 -13 -33 -52 59 29 -36 2 69 43 -59 -50 2 73 78 -33 10 39 11 47 23 -57 22 30 35 59 -127 -8 33 19 25 10 -94 27 1 -20 13 7 49 15 25 53 -86 -73 13 28 28 -35 39 -21 53 -106 -6 97 -16 54 97 41 -39 -13 43 13 -24 90 73 -45 49 17 40 -14 -37 -13 21 -19 34 -52 -64 15 36 -30 9 -2 -70 -7 -25 50 3 -64 -19 17 94 0 -27 36 -16 -22 -9 -30 -69 61 -22 -10 -30 -8 64 24 12 6 33 76 -87 -51 7 -24 18 39 127 -31 -30 18 49 79 -11 -17 -1 -3 -7 -20 -16 -9 -27 -87 8 -14 -3 7 -16 -38 -36 -36 -12 7 35 -1 -55 -3 -4 -2 -4 13 -3 -2 -7 0 16 48 -19 -60 -29 -13 -77 41 40 12 -84 -1 -35 -35 -41 -17 13 -41 -5 115 7 -17 -127 41 -4 48 108 58 49 53 -111 -67 -19 -47 -17 -38 63 6 72 3 15 7 100 27 16 8 -27 34 -7 -127 36 -47 9 -13 -3 24 67 42 54 64 53 -48 -26 -8 8 4 58 -31 -51 -14 9 -33 98 28 -123 74 -4 -5 -23 38 34 -37 45 41 12 34 44 34 -3 6 9 26 56 50 -54 2 -21 6 20 0 -8 85 -64 13 8 41 -36 -24 35 -10 0 46 3 22 116 -41 6 60 75 39 80 40 28 -3 -30 -78 33 -28 3 -55 124 39 51 -46 75 -84 -17 -48 -53 -81 -7 64 -15 8 -51 -95 -109 41 -12 96 -73 70 29 15 89 -66 60 16 -3 -1 31 10 13 -20 -48 72 70 15 -7 -22 -63 -119 20 32 -82 53 7 29 -61 -23 15 -35 29 16 -28 64 22 127 29 -30 33 -40 -28 6 31 -1 -11 37 -17 16 7 26 -46 2 7 19 -3 -7 -20 -8 -12 5 9 -2 -13 -38 10 6 40 6 28 40 13 -37 22 -50 2 -27 -21 45 21 -27 -3 -14 -12 2 -24 26 -13 -17 -30 -97 68 6 1 22 20 28 -57 28 33 46 55 4 7 8 -2 77 2 30 23 18 -11 16 16 29 48 -33 -22 45 72 -11 -12 -19 12 3 18 -21 38 -5 21 29 0 -17 33 6 2 29 27 65 -7 26 -23 -5 53 19 31 6 -18 77 15 23 -19 6 -30 8 11 17 19 80 -93 -21 2 -1 3 38 -21 -5 -11 -12 -39 -6 78 122 11 35 -31 10 32 34 8 -5 -29 -47 -22 45 67 -35 4 55 -31 46 50 38 -26 -34 -44 37 35 29 -12 -2 -51 -72 20 39 41 68 30 118 21 25 23 -2 -12 79 78 -63 29 -32 47 12 47 26 46 -31 31 -4 15 48 -56 -1 -32 37 -77 -5 -11 90 64 19 55 22 38 -1 -27 33 -17 35 46 62 10 7 18 65 -116 -21 7 -51 49 44 10 8 37 2 4 -38 -4 -55 -19 34 21 -28 -18 0 -5 -21 -1 7 -27 3 -5 6 -2 12 37 45 -29 19 44 1 -13 -65 82 7 46 46 -54 -22 1 11 40 -52 7 73 5 -13 24 -12 -5 10 -34 47 2 -43 2 35 -15 -34 1 43 4 20 69 31 20 -28 29 -2 -14 11 2 -14 -33 2 30 22 35 18 -3 7 3 -16 -20 9 -29 15 -2 -1 -31 -15 -56 17 30 3 59 49 26 20 31 -17 -1 4 -11 24 -23 75 23 -24 -2 -12 -3 -15 13 21 -55 51 37 -25 8 31 4 17 30 15 14 44 16 -35 62 42 28 2 6 -20 0 12 9 -19 27 3 19 -5 -20 15 2 13 2 -10 -25 -30 -16 5 0 -1 15 -3 -15 6 3 -3 19 0 27 27 28 34 55 60 5 -12 21 -21 68 69 -56 39 17 49 33 42 32 25 27 11 40 21 52 33 -81 -32 30 38 -27 22 -46 27 2 33 7 5 122 103 41 86 28 48 3 -5 54 -15 81 97 -46 17 -18 62 33 13 -26 122 -54 16 -90 -2 21 77 -44 -33 6 -73 35 81 8 127 2 83 -4 15 91 -24 -3 -3 -14 20 -25 -6 2 42 19 -12 -3 4 -8 13 29 59 56 -16 31 46 -91 22 -51 -10 -17 -11 55 30 -1 4 17 30 -26 100 7 -46 20 19 -4 31 -8 60 -27 20 8 1 90 41 42 -30 -6 -36 -35 54 38 -32 47 -11 29 57 37 -7 -50 43 -26 4 -43 -9 -10 14 40 7 59 -4 -65 3 -43 24 -7 44 -41 -12 -8 -49 23 -18 29 -4 37 3 40 28 -8 -2 15 53 -28 -17 -9 -66 37 46 -14 54 12 20 -31 -88 9 8 59 63 -32 29 37 -12 -47 -9 -16 3 -27 37 29 -5 -22 -5 10 30 -20 -1 -2 17 -27 13 8 -7 0 5 -8 36 -5 -15 7 2 15 -18 21 21 17 16 -28 14 -24 -1 14 5 12 4 -6 -14 -16 -35 -62 10 -28 7 4 -8 -26 -23 23 90 -25 -15 -16 19 -2 18 -8 17 -11 -9 -14 20 24 -44 11 8 30 -30 25 16 11 -9 7 -47 7 -11 -2 34 -8 2 -2 -20 63 -22 17 39 61 -42 -14 -21 8 -29 -31 35 -90 7 -9 -27 15 -51 -81 27 -2 19 -16 -118 -122 52 18 -40 3 -12 -76 4 -33 53 -12 3 33 -40 34 40 -119 -115 -16 -47 8 -33 -57 -40 -28 68 -12 -108 7 -55 -83 117 100 -35 -28 48 35 21 -23 -32 -34 50 107 8 1 31 13 56 41 -66 18 -13 47 -11 -3 -42 69 -18 -128 -1 -82 -121 39 18 5 6 31 -120 -72 -42 -12 48 -83 36 36 25 -69 115 6 12 -75 -16 -84 -14 -19 -15 -68 68 31 -23 43 23 -8 46 -1 1 -67 10 -9 12 127 35 -31 31 -87 -19 -33 25 -22 -86 -32 -53 1 11 -54 3 81 33 -13 -47 6 -100 -34 -33 -23 -33 -7 51 42 60 -30 -13 28 51 -23 27 -12 55 14 32 95 36 46 -23 29 40 -101 -8 1 -29 -41 26 -66 5 -12 36 77 -1 -23 29 -1 73 60 -17 78 61 27 1 -19 22 62 46 0 26 -85 15 25 -18 -23 -38 8 59 -49 19 33 16 13 -30 41 -34 17 -28 -16 -24 10 -17 30 -15 52 -22 -42 74 -41 -47 -67 7 24 -50 -47 17 80 -7 24 93 0 -19 8 -35 -106 66 -7 -29 25 6 9 6 7 -40 11 60 -86 -55 30 74 -91 69 43 -24 -4 50 0 56 -16 -43 8 -2 36 6 16 31 15 7 -1 -5 60 0 -37 -38 15 6 -29 -25 24 4 37 19 -77 -43 -33 96 36 2 88 11 83 29 -64 -57 -4 -15 -17 32 -73 39 -73 30 38 66 21 -9 0 63 45 31 39 54 -86 -9 27 -52 -38 13 11 -16 -29 74 -23 -5 21 110 63 16 -24 -25 10 -39 104 -5 -34 32 60 125 30 -9 18 -67 64 55 -33 -6 -42 19 56 28 -13 -18 16 -37 41 -7 -53 61 109 47 -52 -73 74 -7 -8 13 23 -43 10 -17 22 5 1 -10 7 -7 69 1 35 37 62 70 -21 -48 -3 26 34 10 -51 35 -28 -19 2 59 4 46 -29 -7 2 17 -22 -54 -33 -19 23 -49 -15 -9 -37 46 -67 18 32 58 17 -93 1 9 6 -12 40 3 40 -48 -23 71 2 4 35 22 18 59 80 -26 77 32 -31 -125 66 -40 30 42 9 76 123 -79 4 -63 45 76 -55 24 39 59 -37 -37 34 -75 17 31 23 -48 -31 -40 44 -3 58 -5 74 5 108 -59 -24 -37 10 4 18 0 -13 23 73 4 -10 32 -31 7 -13 -14 45 2 5 3 3 30 -16 19 12 0 -20 -9 24 10 -10 24 -19 -58 -5 -13 -5 30 30 -23 -10 24 46 -29 19 -11 4 -17 1 7 14 -13 -16 -10 7 -44 22 11 -5 33 6 -19 12 -4 1 -19 -11 7 28 19 -3 19 52 23 42 52 6 14 -48 12 27 -31 -16 -21 -7 17 -1 15 -4 -20 17 37 14 12 28 -34 -15 -27 7 6 19 -2 8 73 1 8 -27 -13 -50 -18 27 12 73 -31 2 57 6 2 -20 55 -33 -9 -5 13 57 42 10 57 -30 -15 -98 -18 44 12 26 16 -18 -22 35 -1 -18 15 16 -16 79 -71 5 -4 -23 -47 19 64 -15 -7 -40 0 30 38 -12 72 23 121 -33 -38 0 25 -9 -50 45 -109 51 -11 -90 17 -74 66 -15 -31 -2 12 14 74 -4 87 33 -45 -25 39 -7 16 30 -8 4 -105 38 35 -25 33 -26 -2 12 -6 16 32 -16 2 27 -6 -41 52 -23 66 -43 28 -32 -6 -10 -9 44 76 15 52 -34 12 17 1 12 -56 42 -16 65 40 71 -8 81 -93 -52 -58 -4 54 -28 64 47 19 112 21 24 9 -51 -6 46 -30 -21 2 53 33 72 44 23 0 -11 -25 -18 -75 40 52 21 3 55 -16 16 -17 33 -75 -18 -17 19 -53 -71 3 -21 20 29 -10 -19 14 38 -49 92 3 24 27 -44 3 15 5 -12 -7 -7 49 -40 46 15 9 -5 35 10 -24 -11 -44 6 -16 13 16 -3 3 21 -80 17 -2 4 33 29 -26 -10 -20 -10 13 -26 -32 5 2 -3 -15 -37 -3 0 26 1 23 17 -38 14 25 -5 42 1 -20 50 16 5 -42 23 7 -25 -15 -28 -22 -13 8 53 5 24 -24 1 -14 -5 -50 26 27 -5 33 41 13 19 -5 49 1 0 -37 -41 -27 29 1 9 7 -6 34 2 -40 -22 25 -4 16 -5 -31 -43 -78 -41 13 9 -31 50 -38 -7 9 27 -21 -118 -11 -10 1 -11 -44 13 -35 -26 -46 -44 75 8 5 -40 -30 72 52 62 -4 -9 -51 -3 -41 -68 12 12 72 12 26 -39 -46 -28 41 -82 7 93 39 -53 8 49 29 33 46 11 64 26 8 -35 -18 -64 56 -12 45 -6 31 -9 11 31 1 -60 -65 33 -19 43 -20 63 -4 -6 -23 -28 36 46 -30 -46 -18 9 2 18 -98 37 -41 40 28 73 33 -43 21 -1 -6 96 -40 62 -48 -33 65 -7 88 22 1 -28 -29 -45 8 11 -13 -36 -19 18 35 18 -48 -6 80 -64 -50 33 32 -20 17 -102 -15 -1 66 -25 -2 -12 -57 24 43 107 42 -24 5 -29 -13 27 -9 -90 -57 1 22 -71 -14 69 7 35 -10 78 -42 -35 7 -9 -38 -17 -36 7 -65 40 67 22 57 0 63 -27 -5 -18 -44 -17 -93 -37 -10 -38 -19 -23 30 -40 -9 9 40 -18 41 -36 22 26 -19 21 -53 -25 48 -4 5 -25 -19 -3 20 1 3 -45 21 -1 -14 -19 23 -34 -6 -20 -68 33 -17 -2 -6 97 -13 5 35 18 11 -34 -41 53 -70 2 39 29 3 44 -1 -7 5 31 -4 -27 26 -1 -26 -2 31 -23 -9 -28 9 -15 29 7 -16 -23 1 8 -12 -66 55 31 20 -17 -7 -34 -66 16 15 10 6 46 45 28 13 11 -19 15 18 -16 13 -52 -19 1 -72 -19 -19 61 -49 19 17 7 -9 16 -1 -46 -18 -52 8 -35 17 98 -35 -32 28 8 0 -22 0 38 -29 -58 34 27 -65 -8 35 -13 4 75 18 -15 -1 58 37 8 -32 -54 -13 14 -15 -25 -9 -5 40 38 9 -38 22 -21 74 67 14 -1 4 81 26 -65 58 -70 -24 -32 -41 -88 -13 19 -7 -1 -27 31 56 110 -19 -39 -31 12 48 -25 -11 62 -2 5 41 -22 1 26 -74 -19 -6 22 12 -50 75 14 2 -43 58 8 -1 22 26 -8 -19 24 10 44 105 -71 52 9 -3 1 -21 26 -2 40 -20 -50 40 -57 7 85 -2 44 -7 -56 8 44 18 10 -69 -39 -15 -26 -42 -28 -39 -14 13 36 -30 1 33 14 13 17 -4 -9 0 -74 -38 2 -27 38 -44 -78 -4 65 35 -7 28 -29 -85 14 3 -39 11 22 5 -52 -12 44 -5 34 -42 -50 -4 25 -15 1 -22 18 10 4 12 13 9 29 8 6 -12 -37 21 26 53 61 20 -12 -5 7 27 -9 -6 63 4 16 7 28 5 8 -14 -58 -14 -20 15 -8 -72 -3 16 -8 13 14 15 -2 20 26 -18 8 7 11 4 6 34 48 -17 -22 41 -31 5 -52 -7 25 -5 22 48 26 -43 -71 -3 -9 13 -17 17 -18 20 11 16 -16 -57 12 20 7 9 -20 -8 -13 -3 16 -4 4 17 -25 12 -27 -5 -44 -20 50 -19 -41 24 11 -40 19 55 4 -46 0 -11 7 31 10 55 -56 2 15 -89 24 0 -19 21 62 50 6 11 16 -50 -20 27 -14 5 -33 -9 -1 -7 -14 -27 12 87 49 -13 -8 -45 20 -73 -77 44 -8 99 6 -20 43 56 -97 39 3 13 -4 -2 -10 -91 -46 -35 13 2 18 -49 -100 18 43 -23 71 95 -57 42 15 -56 2 11 29 -24 -50 -1 -49 58 -9 2 13 -79 27 31 53 59 -15 -127 47 29 23 -69 -14 57 -52 3 -31 37 34 -9 62 -1 -13 -33 28 -2 -8 -32 48 25 -40 27 -15 -59 -25 69 59 64 -30 51 -46 -56 66 -16 70 13 45 23 -48 -1 13 4 5 52 23 32 1 9 -98 10 24 -7 34 23 44 -49 -6 15 3 -7 2 -15 -56 5 38 49 -24 85 7 -7 31 -88 50 7 -85 30 -95 -31 -22 -65 16 -56 70 -38 50 35 38 20 -44 -19 9 -6 14 26 9 23 2 34 -14 -3 22 -39 32 -5 -22 11 15 14 -16 1 16 -4 -24 5 28 -62 36 27 40 14 25 14 44 1 -2 4 -4 9 27 -6 -35 -27 -23 15 -5 21 -9 -14 19 7 8 57 9 -40 2 19 -52 22 0 5 -20 9 6 -41 2 41 -30 6 10 -12 -12 -3 -23 19 -28 -118 4 9 56 -40 -26 18 -33 -37 -24 15 25 -6 42 1 -20 -1 -21 -31 -7 7 20 3 52 -74 -8 29 -52 -20 10 -127 56 4 -28 -8 -62 37 -5 29 9 36 -58 -73 -34 31 -2 -27 19 -13 -42 -82 -77 -25 27 -33 60 13 90 36 5 -84 3 32 3 35 -81 -23 81 -110 20 56 -10 2 -59 34 -57 -31 -61 -22 -56 26 -17 -14 -42 -38 -28 -2 12 -62 55 -20 -18 -11 -8 87 -1 55 14 -10 45 37 -83 35 -42 -68 -73 21 -56 34 -59 88 6 13 -43 29 79 2 -28 -44 40 23 70 30 8 -2 51 -14 -23 6 22 20 32 -31 -97 55 -20 -24 29 99 37 -50 13 2 -46 13 5 -58 -2 46 58 78 -18 44 -28 2 -16 -9 -26 -19 -5 8 18 -28 44 -67 63 -84 11 8 23 86 -70 -83 54 -13 -4 -22 55 40 21 -19 68 65 -11 -50 -19 -19 -6 84 -59 -5 27 50 40 114 44 -49 -111 -35 -17 -28 -26 -79 -3 19 -21 -31 30 -37 -32 -60 7 25 64 104 1 14 -58 -58 -8 -51 -48 -31 -18 -8 -36 25 15 -26 -12 -18 -6 31 7 -11 -26 0 -3 13 3 -31 -16 -19 -27 -13 11 18 19 -24 0 27 3 -7 -57 -46 -6 -33 20 51 -16 -24 -44 -18 -50 23 -12 67 -39 26 31 -29 7 -19 33 -8 -15 22 7 10 -59 23 -4 -42 -14 -23 0 -109 -57 -40 19 14 8 8 26 -46 -14 -27 -8 6 -14 -23 12 -59 33 2 -13 4 42 -48 -5 5 -24 -47 3 33 -15 -13 52 37 -61 80 -28 13 4 51 69 84 -10 28 -17 -6 -13 87 93 0 62 43 23 -17 3 -11 39 32 17 8 102 11 -23 24 84 4 51 23 99 -4 -22 -12 30 55 39 64 -9 -29 -2 -24 70 -30 49 41 -65 28 -11 30 22 -31 79 14 -15 58 1 -34 7 50 -16 17 -32 8 14 19 12 25 17 65 29 71 25 18 9 20 43 61 38 -24 -4 19 12 -57 17 -53 17 17 -88 -22 -14 -38 35 -63 -18 1 -24 -41 -82 42 1 -36 -2 -12 -4 -42 -11 -14 -4 14 -10 16 41 85 13 -70 -22 8 -17 -8 -36 -38 -6 -26 51 10 -35 -50 2 -31 -26 22 20 15 23 -12 4 -19 -25 0 -18 42 -75 56 -56 -29 -38 2 -15 -47 5 -48 14 42 43 -5 34 23 15 -88 22 41 -117 -16 -7 -59 16 23 -5 -47 9 -20 58 2 71 -104 -31 31 12 58 30 14 -11 -27 -9 10 -34 -14 5 9 -5 -24 0 14 -7 -34 -5 38 -16 20 11 -7 -2 -12 26 42 26 -15 48 20 34 10 -17 72 27 22 5 -10 -20 -63 -40 -56 -17 31 -9 8 -10 -3 -33 7 -3 7 -1 -16 -9 -39 33 32 -35 61 -20 16 3 3 19 -16 10 -47 -13 30 13 -7 -20 24 5 -10 -15 20 22 18 -6 -26 13 15 -15 -13 4 -2 -47 28 1 5 8 -3 -4 17 -64 -18 -16 -28 -32 -23 -126 68 32 77 -9 58 -92 -14 5 37 22 -32 -53 -18 0 11 -60 37 12 -10 -54 1 22 -44 -54 -33 12 15 -22 -7 -80 -9 -78 -51 -114 -26 -51 -36 -26 -83 -10 -39 -101 20 -49 -64 30 14 -18 -10 -25 -85 30 6 7 -17 34 -46 62 -74 14 -26 4 -110 -6 -30 -123 -52 52 -91 -10 -44 19 -23 -50 24 33 39 5 -105 -10 -7 -18 12 22 -36 81 1 -34 76 -48 -32 -36 34 -39 -21 -13 -17 -10 -30 -5 54 13 -4 -13 -33 75 -4 112 -42 -34 -6 91 33 -55 -20 -31 -25 6 30 -49 -51 67 -38 -10 -37 -105 -44 -16 5 -22 35 -3 -80 -67 40 34 -23 67 38 -12 -59 -54 -27 -17 36 22 4 49 21 -30 45 127 54 0 -49 5 -36 -62 17 12 -66 2 35 20 -38 67 10 -20 2 53 -5 3 31 11 2 -26 21 86 -27 14 -68 -16 -40 33 52 -10 -12 30 0 30 -34 8 -2 -11 -13 -67 108 -9 12 18 -13 15 -29 19 -8 -14 -27 7 -13 -5 -5 14 -12 -13 -10 13 -18 1 26 1 25 10 28 4 5 -18 -19 11 -28 -20 31 -23 12 47 -14 -45 8 35 -17 31 59 -19 -54 34 86 48 0 127 7 -19 -21 -17 -4 29 10 2 29 23 -7 -4 15 -24 -20 18 11 1 -11 20 23 46 -48 -15 24 16 2 -24 18 -19 -54 -19 26 12 -44 -3 61 -2 29 12 18 59 -35 49 110 -39 -13 -64 21 -37 76 -24 0 -9 71 21 38 49 87 12 28 36 32 124 67 -55 49 103 29 31 71 37 -50 116 39 28 61 -26 50 48 -23 67 32 55 60 51 -19 66 16 44 38 46 -33 -5 -35 34 50 3 2 13 25 -80 48 -12 23 92 82 -34 -40 0 6 27 -57 -14 -19 -38 41 62 6 16 27 26 -48 32 21 0 102 33 -39 -16 116 -19 9 94 12 54 55 -10 -89 -42 -18 -7 -33 19 19 -84 -21 16 38 -78 -25 57 64 29 85 -53 3 -74 9 -5 47 7 -21 -19 114 -40 -60 -24 -35 72 28 -35 -21 -26 68 57 38 1 3 -19 -38 19 54 8 106 28 65 72 13 32 55 -10 -3 -24 17 35 -26 -59 20 -24 -25 -100 37 -6 -42 12 83 -39 -69 -30 -61 18 43 15 12 -72 -38 2 -11 30 -40 2 29 106 -94 -42 14 9 -30 4 -73 10 17 24 19 -4 -49 -25 37 -29 11 -10 45 -30 -6 20 -12 -54 16 4 38 -29 -3 -24 -12 -3 -62 18 -7 -37 13 -26 9 -11 25 26 20 -6 -37 -39 -23 -49 28 16 -8 25 18 -2 -14 74 43 45 32 8 -44 13 23 -34 28 -9 18 -4 -50 -4 -12 -17 -23 29 -31 7 -6 -2 -13 0 -10 18 -21 8 28 38 46 4 10 -71 4 35 -21 -8 6 56 22 -23 -91 127 61 -28 -19 -26 15 -64 -21 -20 11 -69 38 -68 -10 -70 44 -5 -5 -40 105 33 17 -26 51 27 2 19 8 120 34 -35 -18 10 -18 92 -60 61 32 -11 32 2 -24 6 64 -17 71 -11 21 62 26 -47 -2 -39 -53 34 127 48 58 35 8 29 12 1 1 61 -7 25 13 53 23 81 -7 -86 -35 64 33 -50 22 10 -6 -1 -23 41 6 3 -6 5 -28 -50 13 71 74 13 -67 31 -9 -28 -36 12 5 -104 111 -54 -50 -94 13 -56 -26 -20 38 -90 -1 -28 40 -69 -23 28 -31 20 49 -102 42 39 40 16 57 -3 -76 63 -8 -17 18 3 -53 -3 -11 -80 30 44 116 125 -24 81 49 31 -32 77 -26 50 -8 82 -31 10 8 70 35 -23 15 0 -33 27 75 -80 -26 16 -5 -3 -20 -45 -1 -26 62 41 18 17 3 33 10 72 -14 -39 33 64 29 12 -17 -23 62 6 6 -22 7 7 17 -30 44 -14 20 -6 -6 32 21 10 -8 -25 -52 19 -18 -6 -28 -21 37 6 9 29 70 -32 -6 -44 -39 -36 6 -72 -40 -34 20 17 -2 24 10 40 20 12 -12 -3 0 0 -21 -5 66 -19 -14 -1 -27 16 -44 3 -8 29 38 -23 15 25 40 -14 22 -28 15 1 23 20 -11 6 9 12 2 -53 11 6 -9 48 -14 22 -17 -6 39 -20 18 -21 -51 3 11 -27 -53 50 -35 -42 32 0 23 75 46 12 -14 -4 33 88 12 -75 57 20 64 3 23 39 45 -10 -28 6 -57 -49 -67 25 -75 -18 122 -42 11 47 2 -17 2 -29 54 -29 -9 -35 28 8 15 -17 118 42 -68 34 -42 15 100 67 45 24 28 30 64 121 21 -8 33 -5 46 -17 -33 -29 27 2 72 2 12 -1 43 24 55 52 55 -12 -24 -44 -49 48 3 55 21 6 -63 26 -43 66 19 85 4 73 8 6 2 -62 -6 -28 20 -15 -24 88 -52 18 5 99 -58 -26 83 1 8 -75 39 -13 9 0 35 5 47 -55 -59 43 -12 0 8 -13 -9 31 73 28 -38 57 12 -43 -44 57 -29 51 -51 -6 -68 34 33 16 16 20 -21 40 40 2 -16 24 30 -9 -42 -27 5 -49 52 84 -41 20 -21 -15 -29 36 -18 32 -25 -12 -1 -9 56 73 -19 95 22 13 26 -64 12 16 25 -25 10 -30 53 25 14 8 -4 9 -11 1 10 -1 -2 6 0 -77 35 3 24 -17 -26 6 7 17 8 34 -10 2 -23 17 -10 7 4 9 44 21 13 -12 21 7 -6 -16 21 0 -22 37 10 -13 -38 -43 -12 -31 -16 -15 11 -7 -50 -12 12 -32 -1 13 67 -16 12 5 4 22 15 69 -6 -8 5 26 60 -37 -23 23 21 -2 -8 34 34 -1 1 -7 -33 -19 17 -41 23 24 -21 37 5 17 -41 45 -8 11 6 26 21 -12 9 17 8 -12 26 -24 31 21 1 5 13 -24 18 17 47 -26 -19 -2 55 -51 -5 7 85 36 -19 -49 6 124 39 -20 40 85 30 83 -18 -9 38 36 31 28 37 10 -12 -15 -8 -2 44 37 127 -91 40 22 54 -25 98 -9 18 -66 -23 28 46 -2 -11 -33 89 19 18 -30 28 4 19 -24 -21 -52 3 -10 22 -73 4 -7 -28 28 59 3 -7 40 13 79 -65 120 52 41 4 3 33 31 -45 44 33 -18 25 -57 -3 57 8 35 -28 -46 5 88 10 1 -26 -8 -6 -5 -7 -3 -41 -46 27 -44 -20 -42 -57 6 11 7 15 -44 -14 15 19 -15 -6 -9 32 44 3 -79 1 21 -65 -55 15 68 14 -15 99 -57 52 30 8 42 1 -25 -10 8 73 24 -73 -46 28 24 -6 -40 -20 57 45 44 10 72 47 8 -36 27 -43 -26 -57 -16 16 -29 -26 16 -3 53 21 76 77 4 -46 -20 0 27 -13 -17 7 57 -18 -12 -16 -9 -5 -8 42 26 -16 -6 -1 -5 7 69 -40 -37 10 -6 -4 21 57 -20 14 -25 29 14 -10 14 -5 -5 38 27 9 -8 -11 1 -20 -11 -19 -5 10 -12 19 -20 -19 -22 37 48 45 -6 58 -7 -29 -20 -8 9 0 18 -29 40 10 -16 -21 46 -4 -11 -25 9 4 29 -4 16 10 6 -4 -50 33 -30 15 -34 11 -1 3 -95 -18 5 -17 5 44 65 59 37 88 23 -5 45 17 -60 64 -6 -52 0 0 -38 -4 -45 17 0 28 -34 16 13 27 -14 -1 -7 31 49 27 -13 -31 5 -8 35 -88 76 -5 -35 71 33 -10 54 28 2 45 30 120 -12 121 39 -14 10 -16 11 74 47 50 24 73 16 -47 10 -11 -13 7 42 54 8 111 35 43 -9 53 64 -11 -6 -1 -26 -4 36 57 22 57 -6 115 -11 49 -21 43 86 8 2 75 33 -27 -17 66 -29 -10 2 2 7 43 -21 -11 -46 -13 86 32 -27 19 35 -21 28 -20 23 -10 75 76 23 20 -5 20 -21 37 -7 11 -24 0 -33 -6 -53 18 -3 -16 55 32 25 55 73 0 27 -17 48 72 8 36 -4 -14 -1 33 20 53 26 -69 -47 13 31 -34 54 27 -37 15 49 10 83 56 -12 10 20 -4 44 77 107 -29 9 23 29 33 -17 -17 7 47 -11 -25 6 28 63 54 -7 15 -6 -31 -13 -20 33 16 12 -14 8 -21 12 21 16 -21 -22 3 -13 18 2 22 -17 8 43 -31 -6 -2 -3 20 7 -37 36 22 22 1 8 28 -26 3 -49 54 -19 14 -12 -20 5 -31 -36 30 27 42 17 4 3 -22 4 -2 9 -4 24 15 36 69 53 -5 -5 -6 27 -11 1 19 -11 -20 -13 -3 -21 -26 -10 19 -9 31 -36 -25 -52 6 7 35 0 -11 40 -12 1 1 -3 -2 -3 41 -3 -5 -14 31 -8 45 -24 27 -14 -16 -25 38 -39 -22 -5 -1 -25 6 14 6 45 -8 -43 17 -66 -15 -18 -59 52 -52 -9 -7 -46 -8 60 -40 -75 -8 45 -44 70 -75 -25 -37 14 95 -86 23 -42 0 35 -3 -43 74 54 41 -21 2 17 -46 -28 -6 27 4 19 -16 6 -100 31 -92 -86 -23 2 -50 -8 15 -18 2 28 65 57 9 53 -43 -30 -66 12 -56 30 -52 67 -6 -105 69 59 -67 -1 21 -11 -8 -16 -2 -7 42 35 -2 11 59 20 2 -10 -22 2 42 8 29 -2 5 -26 11 -44 -18 -17 -11 -27 -9 12 31 2 9 -81 -32 -12 -60 -13 73 25 19 26 53 50 -46 -18 -37 13 16 27 23 -33 20 18 -35 37 15 -67 17 -25 84 -20 -53 66 43 -47 0 -3 -55 -24 -49 -41 3 -31 -22 22 31 74 15 -17 -27 -8 23 -43 34 7 -75 61 -15 14 3 -101 12 6 0 17 7 -8 -18 0 -39 0 10 1 37 16 3 37 -22 1 -8 10 -34 -40 -42 -29 -18 -3 -39 5 13 12 -7 -32 20 21 11 -8 19 -44 36 -5 82 -4 16 5 -8 6 -18 4 -30 28 -38 34 15 2 -40 -32 18 -34 -42 -7 -6 31 19 8 35 8 9 3 6 32 -22 -17 53 45 34 25 -3 27 -24 3 31 3 -15 -20 -3 3 7 -40 0 -30 -24 -33 17 -3 -21 -8 31 -29 -46 0 22 16 4 -16 13 -43 -17 11 49 27 -6 3 -57 29 -8 47 -6 8 25 48 7 26 -36 22 -65 46 -87 -47 44 -93 -52 -7 13 0 -67 -73 8 -15 -42 -53 -39 27 -30 2 22 -77 127 37 5 59 -19 18 20 -22 0 127 35 -58 33 -5 -20 31 -2 13 -10 15 -39 -63 -26 -3 -22 23 15 -7 5 14 -118 -58 -4 25 -34 21 9 -38 65 78 -89 -2 -22 -1 -23 36 44 -60 18 9 -90 -36 96 64 72 -10 40 74 -110 47 -62 21 -22 64 49 -97 -23 44 63 5 -8 14 -37 46 1 -107 -6 -1 60 -5 22 -24 35 2 12 -106 7 -56 -46 77 -30 42 -31 -107 -16 42 8 -44 -44 -47 -29 26 -58 -72 -3 54 24 -44 66 -5 -47 1 76 61 -35 -24 -52 -4 -39 36 10 18 4 10 6 -9 28 -20 80 66 -56 -33 21 -61 -59 -92 -60 54 -4 -5 -41 -64 20 3 14 -7 -1 -14 -61 59 -18 -9 -15 -86 33 1 -45 17 -32 0 -17 44 4 -35 -7 61 23 59 -40 -4 -83 2 10 -24 48 -15 -19 27 4 8 66 -34 66 -33 -28 -39 8 5 -22 -24 -9 -21 -36 15 -39 6 17 -2 2 6 -48 27 1 21 45 20 -34 -3 -10 -18 -37 65 -3 -20 -14 47 -31 -15 -9 -112 -3 38 -10 -19 7 -31 28 -17 18 5 -10 42 -30 21 -26 10 -53 -18 21 8 58 39 -1 4 64 9 3 106 -18 31 15 -32 -38 -7 70 -27 -6 -96 -17 46 -19 54 40 -7 -14 -20 93 -23 -7 62 -2 -39 -16 100 60 23 -14 88 36 63 48 6 27 19 -10 1 98 54 31 -41 49 -22 -35 29 31 39 91 53 1 87 -15 50 14 70 -11 30 -2 -15 -41 3 91 -16 12 -3 -12 101 28 -29 37 34 -10 73 -44 -3 34 -3 48 77 16 -44 91 83 18 -45 59 10 6 45 -37 10 -2 40 -15 5 17 -19 -30 -17 9 2 -1 -17 65 -35 51 57 63 -4 0 -39 11 -50 -27 -1 33 -23 -9 4 33 -9 32 20 -18 41 -25 56 -10 35 28 31 30 5 9 -10 -33 -6 16 94 -17 -25 -7 53 -31 39 35 35 -18 -4 -19 12 62 35 12 -32 8 22 8 21 3 -54 -4 28 -21 95 -53 42 11 -5 -18 3 32 -47 -10 -32 -18 -16 7 3 -28 -22 56 22 -14 -72 -3 23 -13 30 -26 7 4 6 0 4 -49 20 54 15 5 18 -3 -15 -4 15 9 -51 -9 -5 7 2 -25 13 33 14 8 -16 10 -34 3 -37 13 23 -33 4 19 -27 -4 -23 -30 25 -23 -6 17 6 -40 7 0 -25 52 1 2 12 13 0 -24 -8 16 29 44 -12 10 12 -90 7 -16 -21 16 -59 22 10 15 -2 -11 28 -11 -21 -8 -24 11 -6 -6 12 21 -23 25 9 -11 -8 38 8 5 26 43 -17 27 46 -31 -30 43 -15 32 -36 42 24 26 -37 -8 -10 15 -22 17 -3 -58 -14 37 0 -46 52 2 22 -4 64 12 -22 29 107 -36 50 -13 86 -33 7 19 31 -15 1 54 14 66 -14 -33 31 4 18 -7 26 3 -11 -26 38 -20 15 -27 -13 -26 57 13 44 -19 -37 22 -28 27 32 0 -3 -67 -13 44 24 37 23 1 58 -14 -33 -4 35 -8 52 -13 57 49 19 -64 43 37 -30 -11 37 -1 -93 4 -3 95 16 28 55 51 7 -33 1 12 -57 2 3 47 3 -25 -42 -1 48 107 -70 -38 75 30 72 28 31 4 -5 23 86 -3 -27 -57 54 42 -22 -5 -22 57 -16 43 -24 -43 68 58 -25 34 38 26 -70 69 58 83 45 -63 31 14 27 54 -15 18 -88 -111 28 -64 9 5 -27 -32 -74 33 -28 -4 59 -11 69 22 49 -20 18 -28 55 109 -15 7 -11 -13 -8 28 -18 -13 16 31 70 8 67 -58 19 16 17 -19 -16 0 -29 -15 -8 -11 -11 -11 10 8 20 -17 26 -62 2 -8 24 3 -23 15 -33 6 25 31 -11 -44 34 7 -7 -3 21 9 11 -45 27 8 4 27 -54 8 -7 -29 26 3 4 -11 13 59 -41 -9 -33 -2 46 -40 8 -4 -32 2 -4 -5 9 6 43 22 23 -66 -9 -30 -7 -14 -19 1 2 -12 -9 45 -32 17 2 41 78 51 63 -1 19 7 9 -12 33 24 16 -13 -73 28 -8 5 1 35 11 52 14 20 32 72 42 120 -14 84 25 34 2 22 13 11 -88 21 35 -9 96 39 107 41 -6 -37 54 -6 25 -20 -16 28 23 75 -43 8 66 68 5 52 -1 75 101 -15 91 -79 99 1 24 28 86 -16 -17 68 71 127 21 5 24 41 6 20 111 90 8 33 55 -35 -37 5 40 118 12 72 11 41 1 49 -48 -18 -34 12 -52 -10 -21 37 7 -35 -20 45 10 -66 -8 -37 10 78 14 16 -10 13 34 43 -18 32 6 27 65 -41 -35 -36 -39 13 33 72 -19 40 23 -26 30 -6 6 3 -48 -69 89 -5 -32 -13 -31 -9 15 -37 -87 25 -12 -43 -21 25 -7 -5 41 -24 70 11 -60 11 -89 -42 -9 -16 57 -28 98 -62 -9 40 -9 17 -64 10 45 11 -7 -8 -4 13 12 15 11 -42 -21 25 -40 39 -22 7 -9 36 -24 -19 17 -16 -5 -10 -56 -6 -8 13 -3 -7 13 -2 0 -46 -20 -10 3 57 -27 -17 -27 13 -25 -7 8 15 -23 -34 -9 -8 -22 -23 30 -12 8 28 27 9 -11 19 41 -4 10 39 7 17 -13 -21 20 -14 -29 -27 18 -20 -14 15 -10 55 -18 5 16 18 7 -29 -27 7 13 10 22 42 -3 -2 -19 -4 7 7 -11 17 44 28 2 -43 36 22 -1 -28 -7 25 -3 10 -35 -13 17 57 11 35 47 -55 15 5 39 -56 -7 28 37 -57 15 -4 -16 17 13 -44 39 45 -16 47 -33 51 40 26 10 -15 -57 60 -30 31 3 8 -4 67 26 58 -20 -8 8 -9 -4 -29 -61 4 -7 53 34 55 -20 18 -41 -3 60 -7 -11 30 -3 28 33 -9 13 -32 -22 -31 0 -6 -40 -14 72 -39 85 27 10 -69 29 47 -3 -40 36 -26 -26 -4 -17 -36 3 17 1 21 37 11 25 0 4 -48 18 14 -2 48 23 38 -84 -3 -26 -28 -10 29 -18 -18 -1 -5 15 -33 -45 66 103 -3 15 11 17 98 -18 14 -8 -44 -17 -20 5 40 4 52 -59 -31 -28 -30 -22 -22 -46 -52 -96 -24 44 4 -3 -30 -70 88 -53 44 -38 -16 -111 1 -64 82 -54 -58 71 7 -33 -61 -7 -43 5 67 -74 22 0 -6 24 -25 -32 78 25 -19 47 45 35 -90 -15 45 33 43 -5 69 1 89 -16 14 -57 -17 13 33 18 32 -9 -35 40 -10 -7 25 23 19 4 23 24 27 6 10 12 -25 8 6 8 34 -38 27 21 46 -20 -18 0 21 -70 23 76 -15 7 60 -15 24 -9 -9 -45 8 -8 -40 -5 0 39 -36 -55 -28 12 -27 -27 11 -44 -26 14 37 7 -48 4 18 17 20 13 17 1 46 10 -52 -8 12 -17 1 -34 3 19 -8 -17 32 -8 0 14 -14 0 -25 14 11 12 -17 -67 56 -14 -79 34 -18 26 -66 -12 -32 -38 19 -72 65 -27 -42 26 -22 -58 14 9 -14 24 -71 -14 15 -28 -104 -2 16 -110 3 -7 11 3 59 56 -66 -15 0 -75 -55 -30 23 27 -38 33 -3 10 -65 -41 61 -20 -30 16 31 -3 -31 42 38 23 -65 2 32 19 -6 -4 47 -26 -15 3 19 6 42 -17 -79 -70 22 34 37 -37 -69 -66 -55 -24 3 8 50 37 -63 -35 20 -10 -82 76 51 59 20 15 -10 52 81 9 0 92 39 -86 42 46 -50 -10 -7 -8 14 17 -3 34 88 -63 -34 35 -112 -13 -26 -50 -2 -17 -26 53 83 -11 127 30 -49 3 -39 -86 -66 14 59 36 40 23 18 -22 -63 -14 20 -48 46 -17 50 -3 -73 -35 -36 -62 -19 -34 71 -47 -17 9 33 73 -9 42 47 -24 23 -40 -47 -12 -99 -3 13 27 -38 20 13 5 31 -2 36 -5 -89 -91 8 4 45 52 106 -19 20 -10 5 41 0 6 39 63 20 -76 0 9 -30 23 -3 -6 -3 12 16 11 7 -32 2 1 69 4 59 5 42 -7 24 -20 -30 25 -22 -3 -7 -27 -13 25 16 34 17 30 0 8 -4 -27 -3 -2 -20 10 6 61 20 7 71 -16 1 9 -15 0 5 -2 -36 -32 -30 4 14 -19 -22 -3 -25 -9 3 -14 4 -25 -6 -13 1 3 -33 -38 17 16 -4 4 12 -28 22 -42 -2 -22 22 -39 -11 9 32 70 46 -24 -14 -21 -3 81 49 -25 48 -5 -6 45 21 6 -20 -8 69 55 66 17 33 -8 -68 20 22 13 61 -1 7 -14 56 121 -36 19 68 86 47 -17 36 -16 17 -2 -68 50 42 -34 3 27 23 31 29 11 68 -10 -25 -27 -29 -38 -2 34 -90 3 46 -5 12 -11 127 83 -54 -62 2 58 11 -10 -9 12 -52 47 58 -35 60 52 27 30 20 32 -47 -9 67 38 -16 63 31 15 -45 4 1 20 -10 -7 -18 32 53 9 2 27 -19 -18 -38 -24 -50 -23 -4 -53 3 17 -35 -68 -59 41 30 -23 -29 52 8 26 47 -22 -9 62 11 -38 -29 -29 57 12 -75 4 -46 -36 13 22 47 25 8 -40 27 1 44 -63 18 14 13 -16 14 -29 18 -14 -4 -16 31 -67 0 -61 -56 28 -23 -4 29 10 -9 13 -26 44 3 37 10 49 -18 46 26 -9 16 37 60 24 46 34 -19 -37 2 -18 4 -3 -6 -26 -19 -17 0 0 -4 17 0 8 11 -37 -25 1 26 6 23 -25 -19 12 26 -4 7 -4 23 3 -6 5 -7 -1 17 -12 -5 26 23 14 13 -2 -28 -21 30 -29 18 -40 31 1 0 -12 -30 22 10 17 -29 -8 -10 -42 49 16 18 33 -3 0 -20 0 -54 -70 -10 21 -4 -9 -21 -4 -13 -18 60 12 -41 -4 51 -10 18 -29 -56 -13 -5 -10 -13 47 -5 -30 -67 -27 23 30 41 10 48 -20 51 57 3 98 88 2 37 -81 -12 26 -28 -67 16 5 -3 59 6 4 74 -12 28 4 28 38 20 30 8 24 -35 32 3 33 2 -62 46 19 -28 -50 65 -2 50 -38 27 5 -36 80 63 10 47 -32 -50 21 15 72 -31 51 0 -40 -23 29 18 -47 42 24 -41 36 -3 30 -5 31 -60 28 16 14 -44 87 -28 41 51 26 -13 41 -45 -26 12 -7 85 21 -16 8 40 27 59 78 0 -31 27 18 -82 88 -37 3 5 -8 110 -17 45 -17 35 -53 -17 -11 -56 30 -59 -15 36 -2 21 -25 -46 -25 -57 6 79 119 60 40 -43 21 -56 -20 -53 -30 11 -13 29 -8 -21 -26 -22 -52 9 -53 32 -49 7 11 13 6 52 6 -22 -38 32 1 75 32 48 21 22 -38 23 25 23 -75 -73 -73 26 27 -10 -46 -3 -6 -69 -77 -13 -5 86 14 -64 11 15 22 10 -29 -2 -4 -19 -24 -26 8 -27 -1 24 14 30 -12 30 -13 5 -1 -8 14 -4 20 1 -38 43 26 -14 1 8 4 -16 -12 31 42 -13 -21 -26 -30 2 -11 24 -39 14 -15 -23 -25 19 -39 -2 27 21 -17 4 14 42 25 7 -9 10 -1 10 -1 16 -17 -3 -3 -46 -12 20 -13 -27 0 -32 7 33 -33 -12 -9 12 -28 26 -24 8 -5 26 15 20 -23 23 45 19 9 17 37 -22 43 -14 9 23 -41 -15 -46 43 82 30 -19 64 -55 87 11 32 -54 -14 31 -6 69 -14 31 43 21 20 -128 -14 -55 29 -23 -35 -32 15 90 -22 -6 -63 81 -24 6 2 67 8 -17 0 -15 28 -15 -23 -52 73 -27 11 58 36 -29 -51 67 -4 24 -10 69 15 36 -44 45 13 72 4 32 12 38 46 7 19 44 32 63 10 -8 53 29 39 72 4 -38 14 -54 -13 -46 9 36 39 15 85 0 -47 -37 23 -32 -87 -26 16 105 -30 -33 -11 2 15 40 92 -25 49 60 42 -33 -17 10 42 -6 79 -33 -37 70 -36 43 38 -14 -3 25 21 5 16 1 -25 57 73 -8 4 -34 -5 28 -2 9 -1 8 -10 -65 -13 58 -7 -11 17 24 31 10 55 42 52 -62 -80 22 3 40 9 -4 35 -24 8 34 -74 13 48 -8 34 -45 -47 28 0 62 57 -28 28 64 -50 33 -21 -14 -55 25 -24 2 7 9 10 6 -27 -33 -4 -39 48 22 21 -34 51 -33 21 8 4 -3 1 -33 4 -3 -12 0 -11 9 63 -7 -19 1 16 12 -23 6 -2 0 7 2 14 -28 -17 15 5 -7 13 -16 -40 -17 0 23 30 8 7 -15 -4 -10 -11 -6 -14 6 5 8 -28 9 5 -31 10 -23 -21 0 44 0 32 -4 20 8 -26 -10 21 -11 -12 -31 -8 -10 -10 23 -19 35 21 -12 3 -35 31 0 -4 31 -3 -8 29 -49 15 -73 9 46 15 -24 -4 -7 17 -24 18 -44 -55 -10 -51 41 23 17 44 49 12 -12 25 -14 -33 -26 20 1 26 -54 -32 79 6 2 49 110 115 -50 -5 -36 -25 47 62 -26 28 33 40 -85 29 30 -12 -9 81 -39 -16 -5 -28 49 -34 -31 -52 29 -66 64 -6 10 -25 66 -3 -54 -23 95 20 -2 21 1 -2 -31 -13 63 -71 -31 -13 29 92 48 64 106 76 -18 -14 4 -33 36 48 -17 21 1 -18 26 1 79 28 0 80 -57 40 -7 -12 -71 19 55 -13 -20 -12 -15 12 -54 8 37 51 32 17 26 18 45 68 12 6 -4 -22 -82 34 30 3 -19 -81 13 -25 -22 -17 23 -37 0 -42 -11 9 -16 25 -16 10 25 -27 28 12 57 8 -32 11 46 11 55 2 -104 40 15 11 12 7 -25 -6 -1 24 32 -43 -19 -13 42 35 -33 -6 6 22 -24 99 -34 18 12 -31 -27 -18 -30 -9 -13 16 12 -23 -45 -17 8 -18 5 11 17 4 4 -18 9 33 -1 38 12 -19 -4 -26 -18 22 10 -12 -4 21 14 -18 8 -6 -67 17 -2 -1 14 -23 33 -21 2 4 -11 88 4 55 3 3 6 -22 16 57 2 -1 -2 -36 -25 -17 -23 -9 10 -16 -21 4 -3 -28 -30 40 -3 -18 0 10 6 -2 -6 30 -18 -21 25 47 3 6 2 18 8 1 31 51 17 -10 45 12 31 -20 -19 -11 78 13 23 3 47 44 -23 -53 12 26 -19 30 -59 -41 3 70 -2 3 50 -25 31 9 -14 7 -1 62 24 -45 -24 -27 51 -30 73 54 -10 1 -63 -40 50 -22 -38 49 -20 19 -36 2 -46 44 17 46 -33 28 67 6 -47 10 7 28 -38 -93 6 -15 -9 -18 6 59 87 68 -42 68 -26 2 -19 31 -42 31 12 28 9 19 -1 -27 9 25 -69 1 61 56 -21 -3 -12 75 62 51 -31 -71 28 -13 18 42 39 12 -19 67 43 25 33 33 58 9 37 62 -34 42 -32 -35 -83 46 60 24 45 -36 28 -41 -71 4 -75 28 57 4 -23 39 -104 -30 52 -21 -78 16 51 -19 39 -54 -44 18 12 26 -2 37 -41 11 -22 -43 -19 73 -24 14 13 -15 56 -64 -43 -6 31 84 56 -46 -13 -12 -35 46 -47 -82 36 -47 14 5 44 77 56 23 24 -13 -34 97 -30 54 2 43 30 -36 -48 -38 -66 18 31 7 86 2 33 -3 2 -8 -44 -1 -49 17 24 27 -28 -25 -11 -18 43 -96 82 19 -21 37 -27 23 38 1 14 -1 27 6 20 42 -50 3 24 -34 8 -7 -92 -26 3 28 17 27 -18 -37 39 29 -15 33 -23 7 23 56 18 -25 12 -37 -7 -17 -15 4 -15 70 17 -21 32 -16 23 9 1 1 -31 25 24 79 -4 7 -1 -37 23 7 3 23 45 22 8 -34 4 -12 -20 57 30 -30 -49 32 -52 -11 74 -76 10 1 30 -22 -25 30 47 -30 -1 20 -34 -8 -54 28 -45 -11 7 -24 17 -29 26 15 -84 -61 3 -67 -126 26 -126 23 12 17 16 -97 0 -42 21 -12 93 42 71 101 46 -58 57 57 -36 48 85 1 59 3 12 25 -85 24 -127 20 -11 -39 9 12 -62 -19 27 -127 21 -50 -10 26 94 -4 -6 39 17 30 -26 -57 32 -90 37 83 -124 29 -7 36 34 55 124 -7 -1 39 -58 -66 -84 -112 34 -37 47 10 6 77 63 113 -90 19 -32 15 -31 59 -59 -60 -33 34 -15 60 -32 6 -17 54 40 -43 5 39 71 -10 37 -15 -99 -114 -76 -39 -23 53 29 -63 -91 -18 -40 -24 33 -70 -78 1 -19 -37 13 -36 -29 -65 29 -86 3 68 -7 -54 -17 76 46 -19 17 -33 50 25 -47 15 -35 -23 42 -86 -39 -62 15 47 15 -71 17 -32 2 -9 21 17 -8 44 2 13 -19 -8 11 -48 17 -57 -11 44 14 4 21 33 -4 13 17 -18 -22 -72 15 -21 21 -5 -30 -23 -23 28 62 -17 4 23 -10 40 22 -50 -8 24 18 24 -1 3 -10 -24 10 11 12 -99 55 67 -13 -14 -50 -26 66 16 -4 -36 -76 -5 -4 -13 -60 4 21 5 -17 55 1 0 25 6 17 -3 21 -4 -23 10 1 10 -19 26 31 11 60 -4 19 -21 -37 16 -7 17 -9 -14 0 -4 79 -45 -73 84 -34 99 -35 -83 40 20 7 -25 -83 -40 44 0 83 89 26 54 -55 26 -54 -90 -82 13 -21 -20 68 12 54 -93 50 -2 -35 -19 -26 -72 -10 -7 4 -53 -87 -5 -69 5 -6 -40 51 92 -89 41 42 93 -7 66 69 46 79 -21 5 5 -76 -28 -64 -11 -58 -47 6 48 22 -32 -1 -105 5 22 37 -1 58 -27 -40 7 -34 -17 15 -20 -12 -57 -11 -57 -23 -19 59 40 30 20 48 3 28 32 -49 29 82 -68 -40 -2 -9 65 42 -51 -12 -15 -75 -13 26 11 -21 -17 20 -4 17 -20 21 4 -35 14 52 -6 116 72 -45 -33 41 26 28 -37 44 8 0 -47 3 -42 -22 16 -13 -42 -23 24 -38 -47 -24 -32 -28 -42 -24 6 28 19 13 -19 -26 43 -26 42 -23 37 1 -24 13 2 50 -43 -10 55 -9 16 20 -35 -3 48 -6 -12 -40 -50 -7 -2 9 4 -6 37 40 3 0 15 13 -1 -3 -65 -33 -6 -5 -31 -28 -2 24 12 -3 2 -8 -31 20 -23 40 21 13 56 5 -4 -7 1 45 1 16 -8 20 -30 -46 51 -17 30 8 -40 -22 24 -10 8 25 -2 65 -7 4 -18 10 -30 -15 13 -22 -22 31 -53 -6 -25 17 -25 12 0 -3 39 -25 -33 -5 -23 34 -71 7 14 -8 72 -9 -8 -27 19 -11 8 -2 23 48 7 -3 47 11 -8 52 -72 10 -13 60 -28 -21 25 -53 63 60 -1 15 -22 -3 109 3 -50 -52 -7 61 -5 48 3 42 21 -73 45 2 -46 -44 24 -12 -1 5 -6 -21 2 -43 -31 -35 -19 -25 -36 55 -60 5 -11 43 0 -29 -19 1 -1 50 35 -112 -25 -17 -38 -12 94 -27 -109 26 -29 23 -49 1 -77 28 -3 9 5 -43 38 -39 58 41 -4 -47 125 0 56 -35 53 -4 -6 35 -16 4 -52 -61 -50 21 74 -109 -21 -80 -2 -94 20 33 18 17 75 4 -41 -2 6 -2 -26 -8 26 32 -91 -8 2 7 8 -53 -50 -38 -104 12 -18 -6 -106 47 21 -10 28 51 -27 127 0 -4 -14 42 -22 -70 28 -125 13 17 2 37 8 13 1 20 -16 -26 51 -51 71 -60 -42 30 8 8 -63 -4 -92 67 -18 -9 -17 -44 -40 -16 -11 -9 36 -1 45 -40 54 18 21 -5 -20 -59 21 15 -13 37 9 -32 1 -32 24 -36 -10 35 21 -20 -39 -17 49 -20 -39 39 -24 -49 -14 -10 -16 10 -3 -6 -4 -2 -38 16 -23 -43 -10 18 53 29 4 11 34 -7 44 86 -26 34 -7 12 74 6 -16 -4 -11 -17 10 22 11 -5 -7 3 -24 -1 -6 -54 24 22 -33 40 60 25 -10 58 -12 14 -26 2 -71 10 9 1 -21 9 21 -36 12 -14 -29 -2 20 18 -40 16 -4 -29 -3 10 -27 3 11 58 38 21 -25 -19 0 -49 -12 -19 -48 -47 21 -47 -60 -76 51 32 15 0 -69 -38 93 7 4 -24 -19 5 30 33 -45 16 32 -26 -75 -38 -40 -13 31 8 3 -2 36 48 84 -66 -75 18 11 -3 -20 43 31 -24 29 -64 67 0 -57 -43 22 -50 11 -38 -127 43 7 -22 53 11 -7 -22 -27 -40 -53 -74 -59 -62 -49 -23 -20 -27 -29 -36 26 44 20 -23 -41 -5 24 -7 -62 56 -32 36 -61 19 14 -3 81 -23 26 -13 -43 43 27 33 20 30 30 -72 -25 -1 -5 -32 71 -23 17 14 8 -4 -5 -35 13 4 27 -38 75 -40 -44 25 8 -40 17 -14 -12 -13 86 -48 -39 -36 16 -47 -36 -4 -8 -7 -49 -13 -11 -46 -67 -17 -79 29 -29 40 43 -3 -16 13 -48 23 -57 -23 62 -33 -25 3 59 -13 -41 5 -55 -8 12 3 -70 -64 -65 -9 18 -48 -26 41 22 -14 20 -24 -46 47 -15 51 -66 -31 -7 -39 67 10 8 8 4 -15 -51 37 17 32 -40 -12 -24 -2 26 28 31 11 -8 2 8 -6 17 26 38 17 -23 5 -23 17 5 -59 -5 4 0 -17 18 28 23 37 -13 -32 -28 5 26 -7 46 -51 -3 2 -2 -27 15 15 -55 -4 -5 8 8 -37 9 0 -13 18 46 43 1 21 -5 19 17 -10 -35 -55 -17 13 18 17 -19 20 15 2 17 11 -8 -34 9 -36 56 -18 8 -8 30 10 20 3 28 -13 18 39 -19 -1 15 -49 63 31 -21 28 74 -7 12 23 60 -40 -11 -25 -29 -10 2 37 -13 11 15 -39 -22 17 -3 30 -2 19 -9 -57 40 -7 -9 49 39 42 66 126 26 -5 -26 45 67 20 35 -48 43 -28 -75 71 47 28 -2 92 -32 27 -8 91 2 30 -85 51 -14 33 -72 11 7 47 -4 -16 -23 50 26 -19 -42 -7 79 38 50 18 99 -7 -5 74 -5 60 10 32 70 29 34 18 20 35 7 17 46 -32 64 35 13 -56 -19 26 2 23 22 -52 -5 -2 56 -5 -26 4 2 17 23 -34 -67 48 22 -51 40 6 -15 -12 26 -10 -41 23 -40 -26 29 32 -38 -18 -11 75 -8 -11 -35 -19 66 16 -14 -63 -21 -7 -50 14 -16 15 -37 22 28 -37 19 79 -9 -69 -24 -39 -4 1 69 -4 -10 18 -10 22 -1 6 2 40 -2 -21 7 -8 -23 -11 -5 -27 -11 100 47 -15 54 -5 53 9 -25 -46 -25 -20 -42 11 -4 35 -7 7 16 -9 -30 21 12 -32 -19 -37 46 17 27 2 14 71 -30 45 63 -35 -18 -13 11 34 20 4 -3 -24 44 -19 -10 45 21 -26 34 -7 -6 -24 16 26 -3 22 -6 -22 8 5 -43 -48 13 -28 -30 1 13 -14 -2 -47 -21 40 7 4 2 5 40 -16 29 -17 6 20 14 35 21 -44 -13 -3 -6 -1 19 -38 12 -5 29 30 9 -18 41 31 -53 56 26 25 -12 -13 44 16 -51 -32 43 -5 -35 59 -16 -3 32 38 -12 -25 47 83 -7 23 67 14 -60 30 39 84 46 -68 63 12 29 65 -12 89 40 -24 76 -89 26 54 34 3 -3 44 19 -17 103 -31 -62 33 14 -17 27 95 37 -23 34 37 2 -6 -2 -25 8 -28 15 6 27 82 -43 -15 119 43 -37 37 -69 2 59 44 -1 66 3 63 12 50 48 15 -70 15 -14 -20 49 28 11 -3 -42 -18 7 27 31 45 -49 58 -30 61 20 -49 -15 -16 81 24 90 -15 -21 -110 19 -44 61 48 50 52 46 -14 -10 -11 30 -42 38 -1 -30 0 21 -2 -13 -48 -39 0 -127 -31 -14 -69 27 -76 -52 -66 -51 40 -5 -1 45 0 -3 28 -11 -7 8 -22 -29 -42 20 29 -35 37 25 21 -9 -12 37 -10 57 -31 -73 -36 11 -20 -29 -32 -60 47 -43 23 -56 42 50 -52 -4 11 1 -20 -11 -103 -12 16 78 -42 25 3 10 -31 54 -16 -21 -18 32 -11 -9 -53 15 6 13 -28 20 12 22 32 9 26 39 16 39 46 24 65 5 -16 37 -10 -36 10 -28 -27 28 -6 -27 -47 1 -66 -24 9 8 46 -32 -46 9 26 -32 -50 -2 -14 -8 5 38 34 -17 -29 -46 -33 36 18 -39 1 -25 -1 -15 -10 -19 16 25 -5 -12 -30 -13 -25 44 20 14 5 9 26 7 -8 -30 -4 24 -15 -22 4 31 38 65 3 -28 40 -1 -14 37 -51 -12 -48 -18 13 54 -49 -13 15 -7 -39 21 39 -3 -114 61 -22 34 41 6 -3 -15 -17 -45 81 32 11 2 -27 53 -28 3 49 -7 -22 32 -11 69 -2 38 54 15 59 -17 10 -13 13 -32 -47 -19 72 5 24 50 18 9 37 7 -10 9 -17 17 47 7 106 7 7 -41 -42 41 54 -5 -3 1 -8 -16 39 30 0 20 -1 18 -10 40 19 26 -52 -19 -49 53 5 16 69 -3 -72 -57 100 -80 38 -9 24 38 28 -51 9 -5 15 10 -15 67 -11 25 -32 47 4 -2 22 14 11 -3 -29 -52 -1 14 -13 4 17 7 -17 1 9 18 2 -64 -26 25 -15 6 -52 -24 7 -29 -16 -7 96 -31 48 21 3 1 13 0 -19 37 -90 27 42 25 -28 24 62 13 14 3 -10 -12 23 16 2 -2 -33 -36 -32 77 -47 14 -4 -34 -13 64 12 22 7 17 -37 2 17 -1 0 -13 34 11 6 -39 -5 38 -32 27 -16 10 10 20 15 -7 22 -14 11 -25 -11 57 32 5 -5 -22 42 -3 34 4 -16 28 -51 49 -4 8 -19 -23 -27 -35 -5 14 14 73 2 9 9 -21 -1 13 12 7 3 7 33 -16 -8 -12 -12 -16 16 -7 20 3 14 -22 -36 7 16 -19 -3 20 -24 10 -26 -33 30 25 -4 34 -25 35 -37 16 49 18 4 5 3 -31 14 -54 -9 19 -45 88 15 1 -3 19 -22 24 -74 -33 -42 21 -9 -84 -23 19 23 28 41 75 7 -48 -25 -19 3 32 37 19 5 69 25 33 101 125 35 64 2 13 -23 -79 52 -126 0 35 -119 37 27 -4 -3 -2 -44 88 87 33 -17 -41 2 25 -21 -12 5 -1 -31 -38 -35 -52 72 119 -2 25 2 80 45 -7 -48 37 102 -4 35 47 9 41 -29 33 12 -128 -18 46 -11 10 25 -61 29 87 -84 -52 -54 77 29 64 117 -8 6 39 10 1 37 -119 45 11 -12 -21 -34 -17 25 -6 -1 26 -23 73 9 36 73 -76 -94 -17 29 -59 60 118 -13 13 -4 -36 -2 11 -37 -27 20 4 54 -37 -47 -10 -22 -10 23 13 6 8 20 3 18 3 -27 61 -28 47 27 24 25 -5 -61 39 -27 -23 -27 84 -84 64 -115 -9 49 14 -26 -16 -25 74 126 56 0 70 -37 4 87 -11 -29 -29 -61 6 -16 54 -33 74 14 16 54 -28 31 -8 -2 -13 -12 7 -21 5 25 -6 -15 11 -60 -11 55 41 69 -7 -25 28 -27 38 55 19 18 -27 -72 74 -27 61 -22 12 36 -11 23 -45 -19 6 18 16 17 27 20 37 28 -40 -4 58 15 -19 106 13 -14 -9 53 -49 13 42 -23 19 -8 12 14 -87 9 6 -10 1 -20 3 19 11 -8 12 32 24 -5 -6 -4 26 -26 -11 66 10 -36 6 13 8 34 35 35 0 -11 -45 115 16 -72 36 -88 53 -14 -12 -3 -51 20 42 44 -38 17 41 -49 43 1 -6 -24 50 -49 5 -69 37 -17 13 80 36 -16 -2 30 17 -21 -26 -35 -12 29 -26 -50 97 18 -27 48 -23 -38 39 11 -5 49 -18 10 -25 -7 12 -45 -20 -21 8 -24 -8 69 4 -3 -57 73 7 5 7 -13 -29 5 -31 -14 10 -1 22 6 101 70 -38 104 1 14 13 -72 -6 -21 -16 -23 20 -8 3 -23 41 50 60 -45 -15 5 -17 -47 21 -22 -38 -6 17 -54 -52 -5 2 -11 24 -76 36 16 -90 32 -39 23 -10 21 -11 22 27 -5 28 -53 4 -4 -58 3 30 23 9 10 -12 11 -25 -30 -59 3 43 -51 33 -28 -14 -5 -7 -6 36 -27 5 -9 61 11 -37 -7 34 18 -38 24 41 -5 22 59 -15 -16 -42 -12 38 69 -12 48 -2 -17 9 38 12 17 -10 22 -4 -34 -25 -31 0 -9 -7 1 -18 6 -23 -8 28 -22 45 -26 20 0 -16 8 26 -13 22 11 -10 21 43 2 13 18 48 -2 27 19 -2 13 20 25 30 -1 15 7 12 25 -27 -15 -20 -25 -9 25 16 7 -12 -1 -30 38 28 -8 16 -5 3 12 55 24 -8 -24 -21 -15 34 -2 -11 39 19 1 -59 26 17 11 14 -15 4 -30 15 37 18 7 27 -29 2 11 11 11 -14 55 0 -48 -41 3 -3 10 -51 6 54 10 -5 25 -20 -74 -7 -10 8 -19 -33 2 -24 35 -47 -13 -10 97 -31 -126 -66 -6 68 36 -20 -42 -22 31 43 -27 43 -26 5 -67 23 32 61 -23 -60 14 24 48 30 -15 14 -3 30 78 38 -84 3 25 23 2 -59 53 -25 52 12 -49 -125 2 -57 -47 8 22 -17 11 6 44 21 -78 7 12 47 111 -87 38 24 19 95 -45 41 -16 -61 59 50 -26 29 46 -12 59 -26 -3 -3 27 18 -42 53 -40 -2 -52 -25 17 45 -60 -28 12 -16 42 37 -18 25 10 -57 -4 -86 -5 102 -2 61 26 -21 -79 -4 -3 -48 58 4 -47 17 -69 -33 -69 -50 11 50 -44 5 51 27 2 38 -105 -22 16 -8 34 -59 67 2 7 15 17 29 -14 -6 -4 -19 25 25 23 3 -42 -25 -26 -16 -55 32 17 47 14 26 14 12 69 -31 58 69 34 -33 25 2 17 17 -15 47 66 1 -6 -25 -46 -20 16 19 41 22 1 13 22 6 -13 -10 14 17 -4 -15 -16 5 10 -11 23 16 -4 14 -13 20 8 14 35 25 32 8 -29 26 -42 14 33 9 57 14 -16 -43 -29 2 -29 13 18 48 -51 16 17 -3 5 -33 22 -26 -24 -7 3 -3 -17 -66 7 -15 -15 -24 24 -22 -15 -10 21 -13 34 -10 -36 -24 -48 45 23 18 36 30 -2 18 -11 -7 23 -33 26 24 -26 12 2 30 -6 37 61 21 17 -8 -5 36 -55 56 -4 87 22 42 -2 31 -2 3 -38 70 9 29 -30 34 -60 25 3 22 -10 -56 -91 -14 -15 -9 64 35 -7 -58 35 -26 -37 -42 55 12 1 64 -80 79 4 -33 22 31 -16 35 38 -14 1 19 81 10 7 -41 -27 -24 -14 -60 26 5 -4 107 -1 16 98 17 8 -22 43 -26 -11 90 51 21 -48 -71 24 -26 61 11 74 53 -11 51 20 -71 -1 -2 20 -6 -16 -35 -25 62 14 1 62 89 27 53 9 58 -30 3 -9 -13 -12 -13 82 -29 -16 -34 21 37 -69 26 -21 -95 18 -53 1 56 74 -17 25 -6 -58 -14 -46 24 -56 2 -13 64 27 -18 -18 -42 -3 -55 16 -47 10 -6 92 -4 38 35 14 3 -55 10 38 -36 -99 57 -70 23 -58 3 -5 11 -54 24 41 5 29 10 41 31 44 6 75 90 -42 3 16 -2 -59 54 -3 -1 -38 12 -45 -25 18 7 -9 -11 17 26 23 -8 -12 -19 -4 -18 -21 6 -2 -3 20 40 -45 27 -7 -3 -10 -38 -9 12 -3 -7 -10 -34 -13 7 -36 55 -8 -11 2 1 -8 -22 -2 10 -3 -3 5 25 3 -37 8 -35 -17 10 17 6 -2 2 20 37 -8 -2 0 21 13 -42 15 -11 -20 20 0 1 -23 -15 6 4 -9 31 -16 3 -20 9 4 25 2 -4 -45 8 -17 -15 -5 26 28 71 63 25 16 23 8 -48 43 -20 -67 65 40 -16 94 95 -11 -1 -32 54 -6 14 12 -2 12 11 -10 17 17 16 3 24 78 31 34 8 8 75 27 -61 48 63 20 -52 28 -3 10 -12 26 59 -51 29 65 -20 102 79 -56 -9 121 -16 21 57 65 13 -65 9 -28 27 -101 -1 1 -22 -2 82 14 5 55 14 0 -89 -43 74 106 35 71 36 54 74 -25 26 32 -11 -25 -40 -15 46 -29 62 -127 -27 17 -1 -52 -8 -58 67 -34 -33 41 33 0 47 -47 -5 39 47 -33 25 13 9 0 -6 -37 18 18 -3 28 12 74 13 71 -15 56 -67 3 97 -3 5 -66 -46 72 51 111 -92 -101 -64 -40 86 42 67 -37 34 9 -8 35 -33 -34 -56 43 84 -31 -33 23 -11 99 19 44 95 3 -40 -106 -42 -25 -36 19 -27 -21 -58 12 94 -5 -49 98 -127 -66 -115 -127 -8 38 45 31 -110 22 3 -7 -17 42 33 21 69 11 10 -20 46 10 -24 62 -8 -10 -18 -6 33 2 38 18 20 18 -37 38 -19 25 36 -1 3 -28 38 27 -31 -32 69 3 38 67 16 -36 22 23 -32 4 65 -25 -13 -2 -32 52 -11 -4 24 23 -26 -79 -20 48 14 45 -8 4 -47 -37 -12 10 -4 -30 25 0 -7 -12 4 34 -36 31 7 -37 21 -66 -21 13 8 34 7 -11 43 31 8 18 -22 -31 56 3 37 20 71 13 23 36 52 79 40 5 31 26 10 83 -5 -14 7 6 -7 14 -7 46 88 29 48 -36 54 8 -6 -3 8 13 37 18 33 43 40 13 76 32 -44 -13 -8 22 -15 24 -3 3 20 39 82 52 26 36 37 -14 12 60 32 -12 2 44 -28 -6 35 84 21 45 -53 -46 32 33 19 79 18 -19 8 -8 24 61 6 5 33 40 27 21 22 -35 120 108 24 -30 22 23 55 34 -3 9 -5 -4 21 4 -13 -6 8 22 1 33 26 2 34 12 15 12 60 -6 22 -22 19 -8 78 109 -56 45 -34 42 1 -14 46 -39 56 22 -52 -14 -35 27 4 22 -1 -10 -31 13 -34 25 -2 42 -7 -40 -5 20 -7 54 26 9 55 48 -70 -4 -15 -31 -19 72 -34 8 9 70 -15 -3 91 4 58 -28 45 -12 -42 -2 17 -37 -11 -9 43 10 5 20 -8 10 -5 -52 -16 38 47 -27 -2 -3 -3 -1 11 33 25 32 41 -61 39 18 -5 -36 9 -16 -23 11 -7 4 -41 -14 -5 4 34 -19 -20 -7 51 -16 5 46 -46 4 20 1 -1 -42 -3 14 6 -38 30 -11 1 -2 -6 22 3 -1 16 -17 -14 -1 -8 21 5 68 -10 15 -10 -1 -33 -8 -9 -8 -4 -13 9 6 1 -9 -4 0 2 49 -7 7 5 -41 -10 23 -3 31 18 4 -9 13 6 -20 3 -16 22 20 10 65 0 26 -36 -34 108 -40 -9 -1 18 -12 9 -41 -5 61 31 -56 -5 -55 -7 3 -31 -3 2 -36 31 -2 39 -47 -58 -16 55 65 21 -44 -90 -17 -11 51 28 26 -29 -16 -60 17 -115 4 17 41 10 -24 12 43 -27 -31 20 -54 -35 109 -65 19 13 25 -28 -6 26 13 0 37 -21 29 28 -46 10 21 -54 50 21 -24 -55 -35 -11 38 -42 52 -17 -2 56 4 -49 -7 5 -11 -22 -61 -34 -10 -39 -47 -54 -18 14 -7 -17 -48 -107 -28 -17 22 -44 -10 -10 -44 13 17 58 -1 -27 57 22 -37 -58 -21 -14 47 -32 -15 13 1 -4 0 16 -10 -8 75 -43 36 -49 48 -53 -5 55 -31 -36 15 45 65 3 6 21 46 -16 79 -21 20 21 0 40 48 -22 35 24 32 20 45 -19 28 1 10 -39 32 9 -74 42 2 -13 13 -25 22 38 11 12 -20 25 -13 -5 -46 7 -25 21 53 -19 0 14 45 15 -6 28 -15 -19 18 -1 -47 -2 17 24 19 23 12 -12 12 -3 -21 -38 19 -18 34 26 -20 69 -20 -18 -3 -11 9 -35 -31 26 58 -31 -11 18 -8 26 8 -42 1 -16 19 -52 31 0 -21 -10 -3 -17 34 -9 -12 3 26 -13 20 0 -54 -39 6 0 5 4 -3 -12 -19 -42 17 -26 15 23 -12 1 -31 21 23 -32 -18 -5 -4 -26 29 -9 20 -26 26 24 57 31 -31 -21 35 -11 41 66 -2 45 -8 36 66 56 -72 13 -38 85 -81 125 11 24 62 27 13 39 43 127 63 -56 -48 87 -21 1 16 -4 21 9 77 12 -8 52 108 38 110 78 -109 27 -20 -22 34 1 8 86 12 17 24 -2 112 -5 50 42 65 -35 -10 -37 -70 -29 -10 -22 65 -11 -4 -19 126 28 -60 120 37 17 75 49 24 37 29 15 25 -19 49 30 70 13 34 -52 0 -13 35 -42 -15 113 99 53 67 69 -2 2 54 -28 -62 37 8 16 24 -12 -88 -19 15 -32 35 95 46 50 -11 -22 -19 42 -3 91 17 33 52 60 -6 -16 -13 -37 -16 28 123 -25 63 29 -11 1 -33 8 -15 3 68 65 -69 89 56 -47 -66 54 -23 18 45 -9 -30 61 -31 12 -2 -89 -87 -4 8 67 -6 18 14 27 -4 24 43 -9 -61 -51 -36 -61 29 22 -16 11 -14 44 -22 -25 -34 -13 23 -30 3 32 4 16 -90 -1 9 -2 -27 -5 -14 2 65 22 -15 -49 3 -84 -10 29 8 21 -6 39 -3 -71 -9 -10 -2 -20 -13 -10 6 -1 3 18 15 53 30 -34 -47 14 -32 8 32 19 -44 26 -28 13 0 24 -22 38 7 -6 50 -23 31 21 54 21 2 -9 -16 -13 -37 -18 -25 -44 -55 11 29 -5 36 -48 -1 -23 -6 -26 30 -14 -15 -26 -5 23 -28 16 17 72 -3 -99 -42 14 51 -16 0 9 -6 43 35 60 35 120 -38 38 126 -56 -21 19 25 0 96 17 26 -4 45 -39 30 -38 54 24 -24 36 -67 94 -6 25 -39 31 6 39 -29 23 11 26 84 71 22 -5 -23 31 -32 36 109 -45 48 -32 21 50 30 31 25 43 -13 2 49 12 29 17 41 8 60 9 49 11 -27 -1 -14 27 5 122 -5 -48 -19 13 11 -37 40 88 -29 4 71 2 -40 15 -83 1 62 26 -31 76 14 47 52 34 -40 -11 31 29 44 49 38 -77 46 -22 68 29 81 20 22 65 -36 40 28 -41 -92 6 31 -60 4 -15 -30 -12 90 -30 -18 19 -74 -60 70 19 39 5 -64 3 -32 36 14 -8 4 -10 -48 37 21 6 -68 46 46 0 52 10 -22 40 1 -35 -27 6 -28 1 -19 -49 121 10 -2 8 67 -33 -25 52 -5 36 43 52 20 52 -63 7 41 15 56 -39 15 -30 -53 60 -103 11 49 -52 -13 -44 -21 33 -2 41 -41 53 9 11 -39 24 -1 -16 -49 8 -12 -32 -21 9 -3 -17 -11 27 18 22 -25 43 -9 -31 11 26 -26 -35 7 -49 18 30 13 47 42 30 -13 -6 -12 2 122 -48 5 9 23 26 29 -2 21 4 16 10 -28 0 9 -26 5 -25 -37 -21 23 18 -43 17 -4 30 -17 -43 -45 -32 -13 -27 -16 -8 -2 3 -18 -26 40 -2 11 15 -7 1 3 -6 -43 -17 26 2 -68 -11 53 -63 44 -17 -63 19 -39 3 -28 57 19 -30 14 -54 -54 15 -64 -21 -13 -26 11 -74 -28 15 -20 13 -54 -66 7 21 -10 9 -126 -14 -50 -64 -126 -76 -18 20 21 -29 66 -122 -42 -14 69 35 -25 22 -11 -46 -20 26 -30 -122 11 37 19 -24 116 11 32 -80 25 33 -28 124 -16 22 68 -46 -108 -107 54 19 20 -30 -11 45 -6 43 -11 47 -21 66 -11 -4 -23 -58 -63 10 -43 72 -31 -22 -43 3 -31 21 -11 40 -81 -62 -8 -36 -23 64 -19 -9 25 21 -54 -48 12 -36 3 -68 10 -27 40 -79 -7 -8 55 -36 53 67 -96 78 -52 -32 23 14 28 16 -74 38 116 -33 27 23 45 12 -81 -70 1 -12 34 36 -56 13 34 -67 -2 26 -4 35 33 0 60 -81 36 -14 -27 53 9 -24 16 -25 33 -42 -27 -44 -8 14 21 -41 1 -70 -76 29 35 80 37 6 -37 19 -71 -38 -1 1 42 61 -1 -22 -25 31 -115 -24 32 21 25 -19 17 -6 6 -9 34 4 -43 -38 50 -9 38 -82 -6 9 -42 -55 -21 29 -43 -26 2 -5 26 -2 -2 1 24 3 3 18 -40 -16 -82 -12 53 -55 50 -25 35 32 -56 35 -43 -42 -22 28 -16 29 110 -23 -40 30 24 -50 -15 -41 0 6 15 -26 5 8 -26 -82 21 -1 22 35 -19 30 -16 -16 11 -4 -8 -62 5 -17 -49 -6 25 4 3 4 -3 10 8 9 0 1 1 11 -7 -7 14 6 8 -13 3 5 6 5 -1 -3 4 10 -7 5 36 7 0 24 -16 1 1 8 5 0 0 5 -2 3 -15 -12 -21 2 -11 1 4 -13 7 -21 7 -1 7 10 -7 -5 -3 -6 -14 3 -9 -5 -6 -2 -1 8 1 11 3 11 3 1 -2 2 10 -3 -16 -4 2 3 1 -1 -11 -5 10 -12 -3 -2 -24 9 19 -8 -19 -10 4 -6 1 11 -10 -8 0 -17 5 -16 -22 3 26 -13 8 -1 2 -2 -4 6 1 -3 8 -3 -25 24 -1 -4 23 1 -5 -1 25 -9 -8 12 -8 -19 20 16 -10 -1 5 -1 -17 7 4 -5 5 12 2 18 9 23 -5 9 14 8 14 15 0 6 1 15 -3 -7 9 -6 -22 -11 31 14 8 16 2 -21 3 16 -4 12 2 1 3 13 -14 4 1 -3 4 8 -4 16 1 18 -25 -7 8 -9 -6 -13 -1 0 7 23 0 12 -8 9 -21 12 -1 -10 -13 2 -6 -5 7 4 8 -13 -6 -24 -2 10 -14 12 -9 -4 11 8 2 -12 -2 -6 -5 -4 14 0 2 4 -11 -3 3 -6 17 5 2 1 -6 -22 -7 6 10 0 4 6 12 1 3 -4 -5 -17 -11 -4 11 7 -15 5 -4 8 1 -18 -2 -9 3 3 -5 -6 -10 -8 3 -2 6 3 0 -10 5 -5 14 -12 -2 -2 2 -10 2 26 -7 -4 10 -9 -41 28 14 19 -8 -1 18 -20 4 -2 -6 -21 -15 9 24 -15 15 1 -26 20 32 1 -4 -1 -13 -22 -33 0 23 14 -19 22 3 1 -23 -3 -10 3 -10 1 13 -19 1 -16 -20 1 0 9 -30 -11 -11 -15 34 14 4 16 -16 -4 -14 0 4 7 -15 -2 -12 -14 -33 19 21 -17 0 5 -11 -10 -1 18 36 -26 20 3 11 16 -31 -29 -22 -1 -8 -17 -6 -6 14 17 0 -10 -9 -19 -17 20 5 48 6 12 -5 33 10 -15 -34 -19 20 6 -33 34 -8 72 12 8 20 23 18 -39 -11 -21 16 0 -8 22 32 -38 -2 16 0 7 5 -2 32 5 45 -34 -17 12 -18 -6 -8 -25 -31 16 3 21 36 2 -7 11 2 -15 -16 -4 23 -21 31 18 -15 -7 23 -28 30 -15 1 -13 23 -23 37 -25 -16 5 29 28 -21 -22 -9 -16 -15 -19 -5 -4 3 -5 3 -15 8 7 21 6 -9 29 -31 -1 -5 8 -9 -5 -8 2 -1 -20 12 -2 -5 -18 -18 -11 21 -21 -5 -4 -6 -2 -6 30 -1 -7 -1 4 3 3 5 8 -9 -13 3 25 12 -3 7 -24 9 -16 25 -42 22 -6 -11 19 -5 -10 -5 12 13 -11 19 -24 -18 -12 -28 14 10 2 14 15 14 -30 -11 -17 -6 -14 6 30 -23 -12 -19 -4 25 -10 10 -1 23 8 -6 0 -13 7 -17 30 -7 -2 -27 -14 11 -43 -43 18 19 7 4 -24 -26 13 -2 0 -18 -1 5 -3 9 8 13 -1 -18 30 0 3 2 15 10 -13 -36 2 23 15 -25 4 14 27 -8 -21 6 29 0 -17 -15 3 17 -7 -11 -16 -17 -15 -11 -16 -10 -14 -43 3 2 23 -20 1 23 11 -13 -12 8 -13 -8 -25 -17 3 11 -19 7 12 -3 -12 17 -7 35 -31 9 11 17 -2 -18 48 6 -20 8 -37 -35 -20 -46 -7 -10 13 -28 10 2 26 22 23 33 -13 -19 -5 -27 -29 -43 5 -11 -10 -21 31 9 -6 4 -3 23 -14 31 -32 -86 -43 31 -16 -5 32 -5 4 -4 8 12 -1 -8 -16 17 2 -18 38 -16 18 -67 12 4 -52 -28 0 -13 34 -33 21 -11 24 6 7 -3 1 -17 -52 -20 18 38 -12 -9 -17 -1 -38 -21 13 -37 7 1 -15 -31 -28 1 24 -48 -6 4 -19 22 12 41 -9 -21 -3 16 -30 11 11 13 -30 -16 -6 -9 -18 -13 -19 -4 1 4 -8 -4 -31 9 -14 8 -34 -8 -30 -8 -10 3 -3 -4 -12 -18 34 9 16 13 16 19 -21 -19 -1 -12 -36 -3 32 -7 15 -35 15 10 -10 51 -32 -1 -9 -20 37 -17 -6 20 28 -19 -5 20 -30 -41 -7 -28 -2 22 3 -38 8 33 -24 8 -23 -6 -2 3 6 -11 -13 -5 26 5 -24 -2 1 0 -10 24 27 -28 -21 -1 20 -25 -20 -25 -7 -8 -5 -18 -7 -21 -14 7 -7 -9 -13 -18 2 -22 13 -25 -14 -1 34 14 10 -18 30 -21 -5 19 3 16 18 1 15 8 9 26 7 -15 -5 -5 9 -28 4 -3 0 -17 -17 23 19 16 15 3 14 -17 21 -10 17 30 -9 -14 17 24 21 14 5 9 -31 -3 -2 2 -2 -23 36 3 -13 13 -1 10 24 -7 -18 -31 -32 33 20 -9 -10 23 -6 -33 -9 2 -1 -28 16 25 -16 0 -2 6 25 51 39 0 -62 35 -36 -4 3 -24 -26 -21 -31 -37 12 12 22 2 50 -9 6 -14 -22 4 -7 -28 -16 41 20 -19 -32 -16 12 15 12 -6 -2 0 56 61 -25 10 -26 31 -13 -82 21 13 52 37 44 -5 17 6 29 -19 28 -18 -8 -4 -17 -7 -69 -57 77 -23 -2 6 -13 -11 -8 -32 38 -34 49 -1 11 10 -29 -7 11 -11 -28 -42 27 -28 -20 -4 9 -34 12 9 -5 -9 -11 2 4 9 -2 -34 -4 -23 -8 -19 -3 -26 -2 -4 -12 -3 -11 12 -16 -5 30 1 17 -16 0 -14 -11 -18 -18 2 23 11 -3 8 -5 23 8 -3 4 -13 -9 3 37 -28 -9 -1 -14 7 -16 -14 -6 -5 38 -10 13 0 -9 -24 5 -4 -5 14 -10 47 -34 -27 9 38 -12 26 3 13 -2 5 -4 -13 -25 19 -12 31 45 -16 0 -22 -4 -8 0 -4 12 -5 -11 12 -50 -26 -21 5 13 15 6 12 -24 30 -6 -42 -16 -2 31 6 -18 4 18 0 -14 -13 44 6 31 -44 26 -59 23 -9 -2 5 24 42 0 -35 -2 36 2 53 -14 6 4 -34 -27 -26 12 10 8 12 7 -22 32 4 -9 27 -5 -1 -1 18 -9 -10 -5 39 -11 16 27 13 24 -14 -39 17 16 -41 23 33 -3 9 3 -19 -34 -12 -26 -14 -32 -10 6 -25 22 16 -35 16 16 -16 11 -4 1 -13 -31 8 -21 -13 32 5 -2 -8 -81 48 11 -16 13 -28 20 -49 4 -25 -14 44 -1 28 -10 47 28 -1 14 13 19 9 -55 6 47 19 -1 12 -64 -32 -25 8 0 13 73 22 -14 28 -10 18 1 11 3 -7 76 -17 50 48 21 31 12 6 17 -20 1 -7 -4 18 -51 -21 12 34 2 6 5 -56 60 -30 22 32 -83 -7 34 18 1 19 -57 12 -14 46 -93 27 -26 -16 -42 21 -6 10 9 4 -12 10 1 10 -8 6 28 9 21 -19 -12 14 -9 -20 8 -6 -6 7 -11 -12 14 16 22 -1 -7 1 1 -18 -62 14 8 7 0 -20 -5 -12 20 1 16 -3 -65 -5 -5 22 -19 -1 -4 -26 -7 4 21 -2 27 0 -2 13 -23 29 -2 -56 -5 -5 6 6 -26 -10 -2 -50 23 28 -17 11 8 11 -7 -13 30 72 -27 -4 35 9 24 4 6 -19 37 15 -10 1 -20 -14 -31 -13 17 -11 14 33 8 1 4 -1 32 3 -5 57 10 1 -24 9 14 14 12 -7 12 10 4 -10 45 51 8 -11 -3 -50 30 34 -23 -39 -1 4 -3 34 -15 30 26 -26 0 -24 11 3 19 17 17 -67 0 35 11 17 -13 -11 14 -76 -3 2 -3 29 -11 -8 -19 -19 63 3 -1 18 10 -31 22 51 -9 -13 -19 -21 11 -35 10 30 -45 -30 -33 4 13 4 44 -3 2 -27 -10 30 -15 -18 26 6 -73 -3 -7 -22 -40 20 13 -2 16 21 -25 -55 -13 -55 -15 20 -34 12 26 -7 83 75 48 17 -29 -37 -23 22 -91 -18 -7 12 10 22 28 3 23 28 -22 65 -49 57 -45 58 70 -30 -15 78 27 3 -46 -15 54 15 2 -68 -12 48 -4 -44 24 -10 1 -26 -17 -3 -45 -56 -18 15 -9 -9 -7 -13 -34 -4 -26 28 -49 -56 19 -19 -36 -20 -9 4 97 63 21 -18 -10 70 42 -4 -4 -7 8 15 -7 -16 -9 -2 30 10 -3 10 19 -14 24 -27 19 16 -2 -9 0 4 -10 -21 -3 9 -2 14 14 -23 -63 -9 -29 -1 14 -27 -11 4 9 -8 13 -3 -42 58 -15 35 53 2 -9 -46 -3 14 -14 45 28 13 -33 -9 -26 11 4 -31 6 -5 27 -37 6 -14 -16 46 7 42 -30 -26 -7 5 -14 30 -8 37 21 -18 -1 44 26 31 6 -9 -21 -15 -13 -23 9 -20 13 -80 -12 53 41 75 -13 7 64 59 24 -89 7 -64 -126 99 9 88 118 118 28 -81 114 -12 -38 44 8 14 -126 -111 31 58 -27 101 -49 116 -13 -73 59 61 4 -9 121 -31 -15 -3 34 33 12 13 106 20 -29 110 -105 -118 -50 34 37 127 91 -119 74 -50 -64 26 71 -73 127 -105 7 34 -6 76 69 124 101 -67 -15 -8 127 -81 -117 37 -100 -33 -116 8 11 -58 -69 -5 -27 -27 0 65 -2 91 16 -43 -39 123 -1 126 -72 -127 -13 -33 -118 -4 30 2 5 -127 127 -33 84 -2 89 -10 -101 -44 78 -40 53 -127 -70 127 -28 4 -127 94 -39 -58 17 -64 -45 -109 45 44 -128 122 -93 -28 -128 -3 8 78 127 56 -124 127 127 -118 -44 127 -104 -89 -16 -126 -54 -1 126 96 -43 30 87 77 -120 51 31 -104 48 2 -36 -114 126 40 -42 -10 -38 -25 -2 -58 -24 33 -45 -127 -19 14 -34 22 47 -45 3 -53 24 -20 -14 -128 5 101 93 19 -44 38 41 38 -6 -124 123 49 27 -64 46 13 69 -6 8 85 40 4 44 48 -41 48 55 17 15 -89 59 -20 19 19 50 -34 127 127 47 28 -66 -59 78 -127 44 -1 -16 -73 10 103 -25 -56 -31 -68 -9 -109 -8 7 90 -104 51 -15 35 -125 8 33 67 55 10 85 15 50 -89 -86 20 25 -101 -49 71 42 -51 -45 35 5 -50 11 -15 75 -21 61 -9 73 31 1 -34 124 -50 37 -51 44 -78 -25 2 62 -8 11 85 59 -50 -27 103 -14 -128 18 -52 92 36 122 2 21 -127 68 -82 112 74 -67 -54 -100 -28 25 53 -118 -107 67 36 -81 -125 20 3 83 45 -58 -4 126 -35 -55 91 -108 127 4 -124 67 -54 75 -54 -3 8 118 43 50 76 74 74 91 45 -125 -27 87 -97 39 -34 12 -7 0 -113 -54 127 27 -18 127 -8 25 49 54 -37 127 -82 -121 -66 76 53 121 -59 58 -88 -49 127 -77 71 -93 -57 -127 -37 -127 60 98 80 52 -2 126 18 -45 -43 -126 -55 -56 97 -6 -13 -57 91 64 -69 72 -20 71 6 -117 -100 2 37 73 127 83 -61 28 -95 22 127 -127 124 2 -60 -105 -127 -13 -34 -60 -50 123 32 -8 79 -11 50 117 21 -100 -57 -114 70 -46 -6 4 -125 30 -47 -105 21 44 93 -73 -114 127 -7 127 127 3 -4 -126 -127 -100 27 20 -13 -81 -36 4 -90 -127 -40 44 -9 126 -48 -120 31 -87 127 -10 -55 -85 76 -2 -30 -51 32 -5 0 15 23 9 80 125 50 4 27 -37 -36 22 -51 -25 29 35 127 106 -31 -98 113 -32 7 -125 50 13 93 38 0 66 -78 68 -82 -34 6 -60 -19 -127 14 107 50 -6 11 82 -20 18 11 127 37 51 57 -28 110 -11 -106 33 -92 46 74 -63 82 -56 11 54 -36 49 31 35 32 127 -81 54 97 31 -33 61 -47 -49 -27 13 107 -17 -19 -56 1 45 13 37 3 35 44 63 -37 51 25 41 -126 56 63 54 -5 40 60 -45 -5 -97 -38 -65 89 21 -43 58 50 -87 17 -101 -43 44 43 127 50 75 -128 19 -47 -3 41 93 54 -22 3 12 -5 -108 5 12 -83 -69 -62 63 4 -83 45 -96 16 -106 32 44 -36 25 -63 79 65 -51 -83 32 -87 24 -48 -96 -50 -64 87 -2 13 117 0 -71 58 -2 21 -58 47 29 -123 -44 -126 -30 -115 -123 11 -99 -82 -76 41 13 51 -7 41 103 -1 -60 -34 -93 112 -3 24 -29 -38 90 75 8 9 -63 5 6 2 126 127 56 103 -2 -127 -12 -4 -16 -51 -53 89 48 110 -45 -20 -64 -102 60 -78 -52 48 -121 5 -45 17 13 56 -127 -91 58 46 -71 -1 -88 -31 80 105 30 5 42 -46 -28 11 -4 -55 57 82 -64 11 -5 -2 -14 26 -23 28 -20 -17 -127 45 -12 23 -40 -69 3 -21 19 15 -43 7 -111 125 -125 56 -41 36 7 82 -34 -25 61 -123 75 38 20 3 72 6 67 36 -74 17 -38 11 26 107 9 -21 -17 -52 -67 29 -23 4 -81 -8 22 -1 62 10 60 4 -24 -45 28 25 -33 60 80 -73 -30 -82 49 37 46 23 53 16 127 -33 75 36 -11 -47 -34 57 -7 -61 -49 64 19 -85 -11 18 27 18 13 -29 8 -20 112 10 54 -24 39 29 -15 106 3 -127 92 -38 8 22 -66 54 85 90 -83 41 71 90 -38 -11 -20 36 36 -125 -42 27 -16 9 67 74 -12 33 26 41 0 45 -64 -95 84 116 -109 35 54 125 -47 28 73 63 15 7 -126 -58 -13 74 55 -41 -63 125 -124 36 90 -61 7 -127 104 -108 -92 33 -36 -79 -15 22 -128 4 -79 111 15 -13 4 104 -31 -125 37 -29 57 -45 55 -29 -78 93 31 33 122 -117 -11 -91 -111 -61 -123 -23 40 -38 -76 127 -127 89 -58 78 -85 61 114 126 7 -15 -35 -1 127 52 51 25 51 -126 -58 127 -19 -85 21 19 122 -51 125 24 -127 -128 -125 108 63 -122 87 26 70 -10 41 -46 -80 -60 6 120 73 -75 127 120 -59 -94 -120 59 125 113 -62 -71 69 20 127 67 16 -128 -92 125 -128 -101 -25 -127 44 -75 -109 -80 28 2 -30 -61 4 -50 86 57 -23 -28 45 23 -25 1 9 -18 -127 65 13 32 -72 -107 -28 -93 9 -106 -25 -3 -103 65 -116 111 -84 77 68 -8 -1 -21 -7 27 38 38 -6 -4 -56 -127 -37 83 -98 -1 4 126 48 126 20 -128 -26 -46 3 92 -42 -22 100 68 -31 -3 -44 -103 5 -75 21 6 -16 78 19 18 -110 29 -11 -49 -45 -1 -127 3 -73 -11 127 53 126 28 53 -43 68 -67 -14 -65 24 70 4 2 58 20 -107 -16 -27 38 -32 15 98 -14 -126 -39 -39 -69 -44 -56 90 -26 11 -25 10 -86 -121 74 -71 102 -125 -16 86 -32 -74 81 -65 43 30 1 41 101 39 -97 -82 38 61 7 71 -15 -112 0 -86 75 -127 -46 40 127 104 -79 17 118 122 -68 -69 -12 127 -126 -23 -114 -77 -108 62 40 -47 -42 -102 -86 41 58 -53 -111 -47 -63 127 -41 127 37 116 17 6 -27 -31 -115 -10 112 -34 -123 74 125 36 127 -105 -7 117 53 -59 70 78 -13 111 -103 103 40 -82 127 114 -3 -127 -48 109 -121 -126 -127 -128 83 68 -38 40 -127 37 -24 127 82 49 -127 -113 8 66 117 125 -56 127 -81 84 -21 -86 61 -121 -127 127 26 -82 -121 -112 115 127 -34 127 -66 -18 -78 -60 102 -6 -102 -120 127 -124 -1 36 -126 -121 -28 -103 90 -72 -53 -128 -59 -52 69 -31 95 -128 -78 -126 -45 -32 113 -1 -117 79 127 -126 -119 -68 -58 2 17 123 -88 125 -87 -28 15 126 -58 -127 -13 11 -110 -79 -105 -35 -128 -27 30 -122 38 -26 17 -125 77 -74 91 26 65 -39 -34 -27 25 -62 -66 -58 74 -128 -82 -93 127 -94 -125 -72 -81 71 127 47 -124 28 -128 67 31 -22 44 127 -42 -47 -52 72 -125 -3 47 127 -23 -88 35 46 -29 18 67 -68 125 87 5 127 25 -52 -82 79 87 13 46 -29 -9 -12 -128 42 -38 12 55 -72 127 46 -21 -68 -52 -31 68 -18 -53 120 -34 -22 -45 -77 2 127 -122 -88 -58 -126 30 -5 6 91 23 30 127 8 88 80 -60 -28 10 56 2 123 -37 -34 97 12 -3 44 100 122 60 -10 55 -60 47 -120 -70 8 -122 4 -52 50 27 100 14 29 54 98 -126 -127 -89 -11 -91 80 -66 18 90 -54 -30 37 54 -1 102 3 4 -30 -11 123 -20 118 120 -10 -58 56 6 -50 37 72 127 -1 74 109 -125 -105 -86 -15 -98 63 57 7 22 -55 2 -126 17 -126 66 41 53 24 125 -120 39 33 126 74 40 -125 108 84 85 -16 123 -13 112 -26 -2 -57 127 84 105 -87 125 37 -93 -104 -116 29 -14 124 -57 -86 116 -61 -127 -43 125 43 -127 -126 -29 125 40 90 -105 -12 127 42 -123 71 60 -38 -122 -127 -62 127 -57 125 16 91 125 127 100 -70 -124 -111 -84 124 72 57 -115 42 -57 -4 36 -3 -31 65 50 96 38 -124 82 12 110 111 -24 127 -18 -70 15 -93 -25 -40 51 -3 -95 121 -22 0 13 -40 -10 -32 34 -127 127 10 83 96 7 63 17 98 -77 -65 27 -70 -32 -49 -65 -83 9 -52 100 36 -53 40 -80 -53 126 23 -128 46 -24 -44 -2 35 94 12 45 -40 -91 4 60 -118 12 -69 30 -20 55 -123 9 35 108 9 -27 -127 74 -66 5 -76 -41 -127 -81 -61 25 -46 65 -70 -67 -16 -32 -116 -128 -12 47 -9 6 -35 29 22 43 16 -53 110 -43 -86 -29 -115 -68 118 -93 -7 -20 122 109 -116 -31 -42 -19 -127 44 -59 -28 -120 -128 -52 18 59 81 33 -34 108 -67 43 19 -28 -12 122 -13 106 58 -51 -127 -23 -19 24 8 -15 82 101 32 13 39 -52 -8 78 -128 34 -12 -121 -124 62 111 -52 -106 -102 -29 -37 -32 127 -19 -97 -38 11 -51 -50 -11 -110 -95 0 91 -39 46 -97 127 -80 51 11 -26 -50 119 45 -27 -105 3 -3 -118 -122 -86 -10 -21 -128 19 126 -1 60 -115 -106 -30 -20 -17 -126 54 -126 -112 126 -31 -14 49 126 36 126 14 121 65 90 -126 -55 72 127 52 -125 -75 -125 37 -105 -59 39 -127 123 -128 21 -24 -126 126 127 -17 119 -63 -125 37 53 15 18 37 14 124 -125 -119 120 -81 -119 -25 -125 -73 -15 -22 -127 32 115 -71 73 99 -115 8 127 -128 60 -10 -32 -13 58 -5 -36 -126 48 -22 13 32 93 -79 32 4 127 -74 21 37 -121 -92 67 -114 -71 2 4 -4 54 -52 -63 -18 24 -55 -128 50 -70 67 78 15 -35 -32 -11 -2 -105 -21 -91 106 -22 -83 -87 -13 81 -127 -56 -54 96 57 65 103 -5 13 -100 55 101 -20 -63 -25 -71 -81 -21 -109 -34 24 127 -10 -89 75 -20 38 -111 91 33 25 84 -120 127 -50 -18 -11 -65 -37 -7 37 58 -29 28 -37 45 78 47 -20 -109 82 -25 -40 2 5 -3 95 -60 -57 -62 -26 -63 57 -108 122 42 -99 60 -125 24 8 3 -20 60 -125 -86 6 -105 55 -18 77 -58 122 99 -43 -17 94 35 15 62 -127 24 78 -2 -6 117 -22 40 14 -117 88 -59 127 75 -128 14 19 -9 56 6 -126 -80 87 -124 -104 -1 -100 -8 -127 127 89 -48 -77 -128 -98 18 -128 -60 93 59 40 -41 0 11 -22 123 -84 -80 -100 54 -16 33 110 -61 84 9 62 -39 27 -82 -14 -34 52 101 -52 -78 -127 73 11 -49 102 124 -110 35 -123 -20 -124 49 33 127 -126 -127 124 120 15 90 48 1 126 34 127 104 -61 118 -42 24 -30 117 122 -72 127 45 126 -79 54 125 80 63 -115 -99 -126 25 -85 31 43 58 127 -25 126 21 91 106 -59 -54 111 -80 -33 -125 -79 -5 -1 60 -49 127 118 71 -43 127 47 -43 70 -126 23 33 120 127 -118 -73 -67 -78 127 -117 -122 -1 9 -75 44 -118 -110 11 55 127 54 112 23 -73 -2 -56 109 -19 104 38 8 21 -13 126 113 60 -61 -128 86 -116 86 86 25 37 -127 47 21 6 0 -35 117 64 -21 16 -106 28 95 95 73 -56 83 -53 87 13 99 -89 -50 3 32 -100 -55 -24 -21 41 -117 -42 41 -78 47 -43 127 17 -79 -2 99 -36 -22 20 -124 -128 -83 96 -12 -73 -14 36 -50 54 -23 -62 13 -4 97 -46 -49 12 47 -40 103 127 31 126 118 -101 32 -18 124 -33 -11 -126 -62 69 -125 127 115 -124 69 -61 -38 -123 -45 -80 29 -113 -126 43 -46 -126 -28 126 -1 -16 124 -44 116 127 -44 -40 -10 -117 -52 127 -68 89 114 126 -121 127 27 125 -127 37 127 -117 -77 -47 -54 -61 118 -128 -29 -31 106 -126 -49 107 126 -7 114 -88 -52 -38 -128 -125 -75 -128 -58 -14 -87 -69 -32 -63 99 -66 100 56 -76 -124 127 68 82 -126 28 -50 -50 -92 -22 123 -8 -8 41 -100 -105 126 104 -13 -9 124 -127 127 43 -15 127 -120 67 -81 -60 -123 127 23 126 72 -126 95 -6 125 127 97 74 49 -12 83 53 -61 83 -35 127 74 -35 13 75 -17 127 -113 1 25 52 63 -52 -93 28 117 -6 14 -8 29 114 -15 -97 -24 61 -37 -51 -98 -22 126 68 -85 127 120 -69 -91 75 -75 -111 123 112 -80 -47 -91 -70 69 -106 -124 -1 125 104 -20 -87 9 -73 -23 59 36 64 -123 -127 125 13 -127 -29 -24 -25 55 7 -48 118 73 124 125 13 -48 -6 88 39 -128 -97 -13 -3 72 50 -36 -121 -12 -34 21 -82 78 105 26 -43 -56 -124 23 -26 -64 -4 26 0 -14 -124 22 -2 41 32 -2 64 -81 1 11 23 -50 13 -48 -35 76 60 -66 125 -120 -68 -87 -10 51 -76 22 -20 119 13 -125 -56 -68 -14 64 11 -32 -108 34 -40 36 61 -44 -128 -39 96 0 103 -127 -48 108 49 -88 67 -25 78 73 -106 -66 -127 -125 -57 -100 127 72 -113 111 44 -55 -80 46 -43 -62 20 -48 1 -125 12 12 -27 75 122 -120 -97 -125 10 -76 -127 -114 -78 99 51 92 125 78 -126 11 -126 -33 127 -49 19 -15 57 32 26 -74 64 126 -120 127 35 4 -115 -40 89 -76 -14 12 -6 -102 -127 -5 -15 126 66 -128 4 -7 119 -122 -23 71 -18 50 124 68 76 76 111 -125 -93 12 33 -64 -54 60 125 111 38 -127 -127 127 -97 -118 26 -126 -59 -64 -127 -23 22 -122 -122 -71 -25 52 127 -66 126 -32 90 34 -71 4 -105 127 40 37 2 126 -7 -19 -9 95 -27 -72 23 116 85 -127 -2 40 127 5 -124 103 126 -75 114 -37 40 -2 -84 -28 44 93 -127 -66 58 -49 1 127 45 80 -73 125 79 -19 -84 120 127 83 -128 127 70 -1 -35 -70 -121 -32 74 11 5 45 -125 120 114 120 88 45 44 -15 112 -127 127 35 123 6 21 45 -51 80 81 -107 32 16 -45 127 118 68 -72 90 -42 -2 -73 -85 -65 -5 -59 68 103 -70 69 67 -26 4 48 9 -39 -61 -124 -30 -125 127 -54 7 58 -75 -127 -126 -44 -52 46 -39 59 6 -43 5 -115 65 -3 -107 -39 34 -9 -92 61 13 40 -53 21 -75 -64 32 -15 -23 20 -69 125 -76 77 103 -12 44 0 37 -96 13 127 81 44 76 -1 74 -11 124 30 -99 15 -73 -78 -128 110 77 -127 -72 11 114 -118 -27 -90 -109 20 28 -29 -96 -81 81 -66 -121 73 -3 -42 -89 -93 127 42 38 54 -90 127 -39 -6 -13 -19 -42 -119 124 -128 127 -22 -60 14 121 -19 -22 123 -115 113 -53 56 42 -48 -126 20 -119 55 -38 -101 -21 29 28 46 -126 110 -83 -52 -126 -83 -126 39 -68 -59 -4 -128 41 71 23 -39 111 -45 28 83 -55 25 39 94 -52 127 125 -102 27 127 86 33 -65 76 110 -32 127 -45 -124 -62 104 -54 25 -92 127 105 -127 127 123 127 118 124 -18 57 42 52 -94 108 121 82 126 9 117 -122 76 -128 54 -46 -107 52 -99 127 -126 114 -40 25 13 70 74 125 110 -122 -43 80 -128 -2 -127 -126 -15 68 46 -7 10 44 -44 -91 -94 -49 -99 -97 -18 17 -44 -70 -6 -115 124 56 127 65 -46 72 92 127 126 -114 -72 119 -110 -65 6 -59 -64 -5 -116 -121 29 -50 -119 -126 25 107 -14 -2 -75 6 -79 33 -73 38 -22 -8 91 -4 -73 83 88 -66 92 -39 -23 -81 59 122 106 75 -7 -76 121 18 18 14 -47 52 -68 -128 34 72 24 20 -11 127 -122 92 -93 73 -29 23 86 37 127 21 109 42 68 -23 -1 52 106 -33 -32 -9 112 44 -49 25 -96 -34 -91 -102 61 -5 19 -21 -126 -50 69 -53 51 -99 52 28 -15 -59 -115 -119 67 -118 33 -29 -76 64 -48 83 -3 79 -128 67 -49 -6 -115 4 20 -127 127 -106 -127 120 27 -105 -124 64 -3 50 71 -78 64 127 -119 79 127 -62 -4 40 -63 -57 29 29 48 78 41 -89 127 9 17 -113 -3 9 22 80 -14 24 -87 -15 20 55 50 118 19 83 27 52 41 -5 46 113 -46 -33 -128 27 5 -106 115 78 -77 7 94 126 -104 127 -104 29 102 -110 -8 66 -116 -11 -40 21 -127 127 -78 69 71 66 -35 50 77 34 -74 61 71 -127 -44 -105 -72 118 125 -127 82 -125 -6 73 -14 -128 127 -123 -10 119 -128 -81 -84 127 127 -54 110 127 127 -72 125 -66 -84 -109 -109 115 63 61 11 -100 109 -19 127 -108 -92 -124 40 15 -57 126 65 114 -115 65 126 127 -70 18 16 -6 80 92 79 19 -61 -80 -11 -126 -97 103 -36 -25 -94 49 81 64 125 122 -128 89 116 -81 60 -18 -23 34 112 126 -82 -127 1 -14 28 123 -109 -30 -89 27 35 8 125 35 -25 9 -117 63 28 -30 26 -115 85 -5 4 -36 127 -17 126 61 -2 112 2 25 126 -124 -87 -40 111 -27 -22 110 1 114 50 -89 84 -95 111 -105 -90 89 -63 123 -128 -48 -103 -35 75 17 76 -4 -125 26 -17 32 -117 -2 -32 -70 -50 104 106 -25 30 76 72 -28 50 -128 22 -53 -5 13 -82 112 76 51 -1 8 106 -44 49 -86 -47 -72 -47 67 31 -30 -30 44 -89 -65 -64 -83 -114 -55 24 64 -92 -37 -126 99 49 -89 15 -42 65 -92 93 -10 -10 -6 122 -32 -82 91 -30 -87 126 -14 55 -91 -111 102 -83 44 16 -97 -26 100 43 -46 54 -110 60 -93 -34 -116 -48 -66 -33 88 -109 -121 115 -69 -116 46 99 77 8 -103 -127 31 -118 -126 127 31 -11 -124 -7 -126 -8 -13 -110 -128 109 65 -126 120 -45 -34 -47 -15 53 109 20 -123 -10 127 7 120 31 73 -73 -33 -94 86 -127 -46 -9 -63 98 82 -82 127 55 -8 122 -17 51 -14 127 -115 45 79 60 -49 -126 -50 11 38 -63 -46 87 81 -2 -79 85 57 104 -81 -110 -87 -27 127 122 -20 -123 44 -42 38 -112 127 38 -61 -20 5 -69 -73 -7 -126 -94 -64 -65 108 -8 84 -57 -128 27 -73 -97 -115 -111 -70 2 72 93 -39 -95 127 60 -25 118 -57 -21 64 -49 -127 -60 24 27 36 -79 92 -72 11 104 11 14 -62 20 -112 -111 11 -102 34 107 70 49 -32 -1 -32 -46 -44 -90 -2 -47 70 -33 56 109 33 125 28 89 -60 118 123 70 61 84 -40 107 43 -36 21 13 8 65 33 69 -58 96 -49 -38 -113 -124 29 -9 20 -83 8 -65 3 19 -128 82 4 -15 71 81 35 -66 -83 52 -54 -53 75 7 -8 0 -82 -34 -56 -19 -68 -14 -127 -53 -61 -127 -6 10 -70 -54 -33 -5 -73 58 -30 -29 -48 -128 126 33 55 -41 22 -24 8 -87 -128 127 -27 -73 37 -89 -24 -34 123 -22 23 -126 -127 25 126 1 127 126 24 28 2 -52 -39 -54 -127 62 91 -84 -30 -53 126 -127 -35 43 -57 123 -79 121 -117 24 -35 -104 -60 30 35 30 121 -118 -66 -108 32 -13 94 -117 -127 45 -53 117 2 -92 102 -28 19 -127 -54 -26 127 -127 111 33 -88 7 125 -37 -19 69 -119 -32 21 -92 17 109 -125 -110 127 93 41 6 -128 115 -66 -9 -77 -9 13 127 -90 125 127 -123 -16 114 59 -24 -127 85 102 127 47 -108 116 127 0 -19 -121 10 55 -2 -70 -52 -93 -7 127 27 10 69 37 -127 39 122 48 15 -127 81 127 -127 127 -15 125 -14 -27 5 -126 -124 -67 -7 66 -96 -108 45 62 -85 -1 -102 -128 -3 -25 -66 44 84 -101 -128 64 127 -17 -50 -110 120 95 114 -67 115 -30 112 -9 4 -86 127 -59 68 -128 -16 127 66 -112 38 -127 109 92 -9 -33 -18 34 -74 50 -24 64 34 -15 -117 -85 8 -61 -51 11 -4 -85 96 22 17 47 -124 -15 95 106 113 -45 33 80 123 12 52 -59 -14 -102 18 -127 4 -46 89 -5 0 13 -84 -119 58 -40 91 36 31 -7 33 -52 105 79 -108 124 -29 123 40 -1 -38 -25 19 72 42 -17 -20 -122 126 29 -51 -127 -74 119 -66 -57 -127 -53 -34 -8 9 36 106 -42 -122 3 -69 -127 -41 -60 -8 -89 -54 19 -6 -39 35 -116 -96 -50 -20 -62 -102 57 -73 119 -91 -128 -122 7 126 12 92 -3 124 -72 -5 -39 -77 -78 -11 -19 4 119 -15 -37 -128 96 -60 42 -125 -43 13 -34 -21 -121 66 85 -40 30 124 -18 -117 94 2 1 -25 40 115 40 127 113 7 -42 -108 25 64 68 -38 7 121 -18 10 123 45 21 7 127 -125 28 -126 -82 88 33 126 61 26 -12 -77 -21 16 127 -128 6 53 126 124 -104 117 -75 -44 -10 -24 -84 -48 -73 -15 114 117 62 113 -126 -17 -127 52 -98 -128 -56 127 72 -46 -100 -79 114 -114 -127 -18 125 -28 -127 88 68 -32 22 -113 -20 -128 -123 94 84 -60 63 94 126 -59 15 -9 115 -64 127 -126 -82 1 -92 95 -54 -43 -60 -50 31 -124 -76 71 -128 -62 -125 -92 -22 -28 126 -33 -56 -30 42 25 -93 -105 126 127 89 -128 -69 -28 -27 -94 -54 -123 -125 -43 -5 99 -90 106 78 -24 120 52 -38 -106 -126 58 -9 90 38 -2 21 -115 127 32 70 -9 74 -65 8 102 -99 -96 -31 32 -18 34 -103 51 11 6 -128 98 -70 -29 -106 4 112 11 18 -13 -123 82 5 -37 -127 -125 44 -23 35 -1 -103 81 26 -1 -60 -32 -49 72 72 21 -29 99 -61 -65 52 72 63 -126 54 61 124 -69 -24 4 -67 -126 58 -77 -55 -126 6 50 32 35 91 7 -8 -18 -25 2 127 79 30 126 -12 -10 -78 -26 -49 -36 -128 126 7 -40 40 -14 81 31 83 8 127 26 18 -124 21 6 -54 -108 37 6 -5 89 -43 113 68 -1 -123 -68 127 -93 -98 -29 124 13 -49 -126 -128 109 34 -16 72 97 80 -123 -12 -95 67 -73 -32 120 -128 54 -12 -97 -112 -72 -119 -77 -31 5 -113 -104 -76 40 25 105 -126 -80 88 98 37 104 116 -6 53 127 18 126 -114 100 12 22 103 105 106 99 -81 -55 -103 20 19 37 -94 70 12 53 121 -37 -102 -83 -63 -38 25 9 126 42 -124 -126 -7 122 -117 122 -95 121 127 4 121 68 24 127 127 88 -81 72 45 58 61 102 110 -24 -6 -77 43 -126 18 87 -127 86 -127 127 -27 -120 -54 -4 61 13 -62 -21 127 124 14 124 125 127 -31 -125 -105 0 12 -124 -34 -94 -7 80 127 -5 -6 127 26 72 11 -128 -68 85 39 -30 -3 -110 127 23 126 -45 -126 53 -29 -117 -125 -53 -127 29 48 18 22 127 -3 -103 -9 70 48 -26 96 -5 -50 -68 -9 -122 -5 96 -33 -10 26 -126 127 -50 33 94 127 68 5 125 118 48 96 29 101 61 50 33 35 -78 -31 -89 18 -83 127 -118 31 42 -24 35 -127 -44 -82 27 -2 -23 -69 -7 16 -121 1 127 9 121 -30 67 2 64 -122 -37 -88 83 9 48 -100 47 22 121 0 12 -28 -46 83 -18 80 -77 -125 127 -21 -50 -70 126 68 -65 102 -56 -8 -7 -19 -5 -25 17 -9 -5 59 -43 8 10 -24 -22 60 36 124 -59 -30 86 -6 -21 -31 30 1 36 17 28 76 -18 -12 -42 20 -41 -17 -35 32 -77 -13 -52 -5 2 -5 -15 3 -93 -6 -37 54 -41 23 -3 6 28 -33 -45 -41 -12 -7 -6 -55 2 -36 -6 -11 37 -6 -11 10 37 -84 15 -22 -94 48 0 -31 34 -67 6 -17 11 -40 46 -42 -8 -88 -3 0 36 -19 -28 8 -18 2 15 -41 14 26 26 -24 -66 -88 -11 -100 13 -32 125 1 -53 74 -63 -32 -32 2 -38 -50 14 -17 -64 52 28 -2 112 -82 -33 -25 84 -121 -125 125 -63 -15 127 -32 33 -42 66 13 -61 12 21 -38 19 52 27 124 -20 -26 -119 21 27 56 -45 124 -115 3 -46 126 -48 21 63 -105 -126 20 126 19 19 62 95 -85 63 -11 -33 127 -126 -26 -8 113 -110 -1 39 -37 -18 6 20 2 13 29 -127 36 -51 -34 34 -42 35 -32 26 0 -15 22 4 35 -115 43 -27 9 -26 -2 -22 13 45 26 46 -87 -109 26 32 -77 -26 10 -25 -14 29 38 123 -4 -17 19 -76 25 -80 -26 -5 71 -53 -9 -2 15 79 27 27 -38 -6 -48 -64 5 -58 -1 -7 77 126 -128 24 15 -39 -84 -6 -17 -16 34 -64 36 5 17 -16 2 11 2 -10 20 -128 6 -21 -58 20 55 -9 -19 -13 -17 -61 -32 33 -19 75 -15 0 68 87 -53 11 6 43 -18 -10 54 3 11 -42 33 -88 -53 82 97 20 -81 63 14 -29 -82 88 24 -22 -33 -30 116 -19 2 -46 3 -9 -28 -127 -5 -116 20 -21 91 -76 81 -65 -51 46 -93 21 -98 -4 -29 -94 -3 -52 11 38 35 -72 -14 82 -26 -28 3 -53 56 70 -52 23 -20 3 -58 -127 42 -23 -36 52 -42 7 -64 -9 -63 3 28 73 -124 -44 -92 95 -14 14 6 43 -33 10 -6 64 -23 -56 9 7 -44 -128 -100 -43 10 -1 120 87 69 -21 -93 59 58 -57 -99 -100 51 -125 127 -10 70 -36 -2 87 113 -27 -85 -22 -128 -18 24 45 80 126 -88 -21 7 -97 85 45 -60 -44 24 86 -84 -122 46 -29 -54 127 6 33 83 10 125 124 26 -6 69 -14 12 -47 -80 125 -14 113 30 -89 -120 -26 -9 18 92 -11 127 73 -44 52 -106 113 56 47 117 -54 24 -2 -28 -27 -45 -57 2 -113 -87 46 -105 69 -66 -15 16 -16 66 -17 -48 -97 -34 -29 -92 -71 79 -19 -2 27 -23 94 -122 -48 29 -84 -5 -7 -1 36 5 43 126 67 -43 9 34 -104 -22 18 -17 -86 -16 -8 49 96 -20 -10 -27 12 0 49 -39 127 10 127 -36 -14 64 -126 -86 3 -38 -77 -14 -40 -14 -22 13 50 2 37 51 82 9 -2 -26 65 48 101 57 -7 -24 -16 40 6 -50 -2 -16 -44 37 12 3 23 10 -48 -127 -17 -73 -6 -14 40 24 -27 -50 -2 -41 126 -39 -49 -91 103 4 0 -100 35 31 -87 -92 25 71 -32 4 -4 -87 27 14 15 -51 57 -23 124 40 -30 -75 -43 31 9 1 -37 70 36 25 -76 57 -30 -11 -6 56 -20 34 12 -24 -75 21 -107 26 49 42 3 5 -30 -38 57 23 21 105 125 -33 -96 34 39 12 114 -87 22 21 48 -41 -54 -28 34 -127 126 44 39 -18 15 18 30 -26 127 22 -41 65 -94 15 -127 115 -23 101 121 127 126 28 -5 -1 -64 -95 -89 -54 60 53 -9 101 -37 105 9 61 13 20 -61 -91 -127 -128 122 -127 124 -5 -125 22 11 18 43 -18 -27 39 -46 49 -36 119 -8 -17 -126 39 122 -128 -128 125 -51 126 -100 110 -122 -1 -18 39 96 59 -60 -121 -95 63 85 -19 -126 -89 -89 -39 -116 120 42 -37 -16 -124 -102 -10 6 127 -118 -2 28 -80 -58 35 127 3 -127 94 19 -124 53 -76 20 34 -17 1 16 -47 -76 99 33 -126 -19 -27 -3 -84 10 -56 124 -80 -7 7 -71 -52 -1 -46 12 -4 -25 84 -125 -103 48 70 -34 -27 -83 51 7 103 -15 59 66 39 -29 31 -12 -127 71 -5 27 -90 -91 -116 -18 -27 125 125 -25 -55 -103 -27 -28 -30 85 15 71 94 -57 1 32 -15 16 -54 -15 79 127 15 21 -1 -38 119 -53 -71 -30 9 2 -27 17 117 -12 21 -83 -30 -96 40 -79 -46 9 -27 -44 -28 5 120 55 -72 -28 115 -27 66 -13 -65 -88 -6 -23 -46 8 8 -19 -21 -40 2 104 76 33 -39 -1 42 117 1 8 16 -57 -69 12 24 -49 -25 -62 13 -87 -60 -128 18 127 -58 -87 -39 15 -32 -1 70 26 108 20 -54 -43 118 -46 -15 -81 34 24 -76 -60 -72 4 120 -107 -96 83 -17 -75 45 15 -60 -63 38 79 -126 10 -46 117 35 75 44 -29 -39 127 -10 -81 7 110 -128 -94 84 119 125 -43 -126 27 -112 6 -11 -31 -46 -80 20 -102 52 -29 -12 21 61 -24 32 -124 -32 -3 46 -44 -88 70 127 -116 -34 -68 44 -9 -27 -127 -2 -58 127 40 -97 -121 -29 96 -42 -119 127 -120 91 127 127 -65 109 47 -31 -34 51 -127 4 -30 -44 127 -128 -118 42 -127 -30 -46 -78 -2 -114 -96 72 -14 127 80 -17 -1 -112 -14 -24 44 31 87 104 -19 126 -77 -29 -47 25 8 -3 10 -13 -41 -45 19 23 -63 14 -20 63 -71 127 -110 -59 -28 -19 23 -25 52 -87 43 77 -35 -25 -16 -9 -78 -4 -3 -23 -30 40 18 -31 -69 -1 -57 -22 -46 33 -18 -1 -18 89 -62 -43 -44 0 31 -4 -126 20 125 -60 -9 14 -44 126 -57 32 101 29 -12 -10 18 -82 -115 -43 70 -59 44 -1 31 -6 14 67 -127 -73 5 -23 40 24 2 68 -49 -49 27 60 53 53 86 50 -23 127 -120 9 0 61 34 -10 -115 -50 -3 72 -16 76 118 -29 127 4 74 -59 5 31 9 44 0 8 -2 -61 97 -127 120 -122 72 95 30 121 -61 -40 -10 92 24 126 15 -96 20 -58 -35 50 32 -32 -52 -45 -1 -14 67 -93 12 39 79 20 36 109 -91 -44 -57 -3 101 10 -71 68 -29 74 97 -2 -114 100 -3 -121 -3 -127 -40 -46 47 31 6 61 111 -124 -127 126 -11 41 11 42 20 -48 30 25 -107 127 -85 -109 -92 67 -32 -44 -23 -127 -1 -68 -90 127 36 124 -73 -66 -98 27 -71 2 28 20 31 77 105 15 4 -50 37 -80 33 117 12 35 76 -91 67 26 12 -28 22 44 96 -6 61 -76 42 8 -52 -117 40 127 34 118 -25 69 -16 -103 29 51 -64 77 3 69 61 -126 -14 -111 127 2 -39 4 -127 55 -116 69 114 -127 44 45 42 -97 49 -121 97 -7 17 -127 -61 -111 -41 -60 123 -128 18 37 27 82 -10 1 0 71 93 96 -113 -17 -18 -65 40 25 -39 32 -38 -29 83 -28 -25 -37 77 -85 14 -26 -103 -7 -14 -6 38 66 1 -111 -19 -66 -16 -53 20 -66 -16 -127 -104 -1 59 -11 27 19 12 -18 103 126 -48 88 2 111 -83 9 37 -81 -19 -61 125 22 15 -39 -22 30 -103 24 63 -54 8 64 -31 102 -119 82 8 -24 6 -29 -78 109 9 -22 16 -6 55 -37 -30 12 -14 -126 -120 63 -21 127 -27 46 37 -5 -30 15 67 -24 -10 -24 -70 6 85 -49 -39 -47 39 -10 -33 63 -49 58 20 -38 43 -12 -11 127 -66 9 -76 -75 -69 -98 -128 10 -21 125 -11 88 -57 62 98 64 -74 119 -123 43 -29 126 47 -74 114 9 -127 41 -123 -98 95 -16 13 -17 4 73 22 126 -97 99 -81 52 127 126 92 67 54 41 -43 12 56 -30 122 -88 -18 -85 69 -110 119 15 -53 20 -128 -66 -7 14 127 -60 -27 17 -12 -94 21 38 -42 -15 96 -84 -58 -123 -36 -37 35 80 -23 112 -72 127 115 127 -4 -41 3 -40 -29 -28 -20 -62 -27 -61 50 75 -92 47 104 -102 5 -123 126 -107 55 127 -33 -23 126 94 -35 -128 -128 127 -50 52 -128 -17 -70 -16 -122 -108 -113 92 -112 -22 -52 59 -128 -44 -15 -56 -14 -46 -109 3 -53 -87 5 -124 -62 -24 13 -72 -30 -28 -49 126 81 -54 3 -56 126 70 -59 14 117 122 -36 32 -53 -88 -56 -13 -113 116 35 56 -117 -59 -95 55 21 -4 54 -8 -16 -33 -32 -2 22 -78 -54 13 -41 -128 80 50 -60 26 -111 38 34 68 61 96 -6 -96 -49 33 49 103 -9 23 -74 0 -4 -106 -89 -125 15 -12 126 -13 81 -68 -75 -124 81 49 -86 -22 -2 -41 104 75 64 -41 -37 -72 22 14 127 -9 36 19 -45 -21 -116 53 27 -31 -50 -37 60 -34 40 25 0 97 13 -14 27 -41 -9 1 15 76 33 23 -9 -18 -84 1 -5 -30 -12 -54 119 24 -31 -9 -22 -22 -18 18 -40 -22 -25 30 3 -17 -32 -1 -3 -11 -19 -33 -31 13 -45 52 26 2 -7 5 46 -20 -36 62 2 88 93 -32 -2 -2 -29 53 -80 -52 35 -37 39 -27 16 -30 -3 -3 2 -115 -37 -5 -122 -111 -4 -68 56 -28 -41 29 29 70 -60 -96 -7 14 -29 -36 28 -46 62 1 -31 22 -32 -29 13 25 35 -1 -4 -15 1 12 21 -43 123 45 -63 5 -107 12 4 -13 -118 4 -61 -51 -14 -53 26 65 100 -43 26 -90 39 -62 118 85 -20 -20 124 20 -50 -16 50 1 -58 7 34 -26 -39 25 -21 127 -34 5 -127 13 9 54 50 98 -51 -44 47 109 -49 76 80 -21 -70 26 52 9 1 34 57 -43 -66 -37 -11 -5 48 32 -30 82 -72 -30 -7 16 11 -81 -26 -45 21 29 -118 -6 -126 -35 3 -36 4 -16 23 -38 9 -17 52 -5 -33 45 10 20 -4 79 -13 7 32 8 62 -83 -17 34 20 -115 -17 -21 -6 -4 -3 3 90 37 -27 18 16 14 45 14 -16 94 -41 -1 4 27 51 -22 25 -83 15 8 -100 -9 -40 0 -19 30 3 18 -4 16 56 16 59 -5 -28 26 -39 -10 4 -6 -104 -33 -11 14 -20 32 -16 -8 -7 -39 -17 88 -7 -41 0 -2 -43 -3 8 -5 108 -14 -23 -49 88 -59 -9 2 -27 0 -31 -99 -24 -20 -31 -13 -57 -12 33 -87 5 -85 102 25 -54 -24 -1 104 44 -24 1 -8 -36 10 -20 0 26 25 -38 -4 5 10 -55 -50 51 123 -87 -32 35 -66 29 -62 -20 -1 -93 -34 -55 20 -46 14 -70 -65 37 11 28 40 30 -39 71 10 14 -27 15 -98 34 -5 59 -45 -56 -47 9 -121 18 -12 38 98 68 -70 5 -25 58 44 -12 113 -37 13 24 -5 22 -1 33 5 24 -2 -68 26 51 -20 5 8 27 54 -85 -14 59 25 18 6 -125 20 -12 60 14 -10 13 -45 -60 105 -21 -23 -11 -123 -21 -28 42 106 113 -15 -13 -41 -27 -1 -91 -26 117 9 125 -34 -66 9 61 -78 125 6 41 66 -26 104 89 -17 -72 -40 -18 49 49 -70 125 2 -19 -59 -18 -39 33 -9 -37 57 -17 39 -30 -87 -52 -28 127 24 37 52 2 -33 70 49 -5 38 -45 26 -100 -65 47 -88 58 -65 -32 -122 12 60 34 -17 1 -72 5 -59 -26 52 -5 -9 29 -20 66 -122 38 35 -1 -32 -3 14 33 -11 47 65 -10 39 -16 38 14 -17 -48 -65 -60 68 -16 12 3 -8 2 -13 17 113 40 -2 116 -1 119 11 -40 17 0 1 -15 -27 -56 14 -1 1 91 49 -6 -5 15 13 -14 73 -19 -8 40 39 27 34 9 -17 -4 25 34 -75 -25 -57 -28 -2 15 -5 -18 -9 -13 70 28 -62 57 -67 34 38 -29 59 -76 -61 -53 3 -18 -72 65 -89 51 -63 24 42 -33 31 22 31 -37 43 -60 39 54 97 -36 -42 -12 -22 38 -8 42 9 -18 -79 24 -19 24 78 -19 14 62 -18 -65 21 -21 111 -8 27 -23 116 -23 -37 28 33 17 17 0 116 -15 19 -14 57 -7 -3 57 20 71 -114 56 102 9 -84 -7 43 1 -30 55 -4 -50 -56 58 -3 127 -126 123 -11 0 37 124 -41 -56 64 57 -41 -112 56 -25 10 127 43 90 19 23 -31 -60 -69 -20 23 -20 -51 -82 123 -51 -33 3 82 -76 29 6 -38 -52 -65 -79 -36 115 57 -86 44 -52 5 -17 -66 -23 38 21 45 -75 48 -6 -7 -73 49 126 -125 -50 91 46 127 2 21 -125 -95 0 -19 -12 19 -23 49 -71 111 82 -122 -124 -67 19 19 -6 78 52 49 8 -14 -80 -121 7 6 -35 88 112 -82 13 -73 11 -37 27 -17 0 -72 3 7 2 87 -13 -24 15 50 -4 9 8 -127 10 1 -11 -39 6 -44 61 -87 8 39 -90 -37 5 -13 -5 -9 28 24 -44 -13 25 9 -4 5 10 18 -36 4 -4 9 11 51 -37 -40 5 -110 17 -49 77 -10 -37 -37 -32 -95 11 14 -12 -28 -83 -77 19 -5 25 13 24 91 -22 -9 107 -22 13 -15 -12 44 49 5 29 121 13 64 37 -60 -33 64 -43 -71 22 84 74 -42 -46 -53 -2 -54 23 -15 -42 101 -56 83 -43 -51 116 -94 115 127 -74 -83 -25 -18 7 -13 -36 -46 6 37 3 -80 28 111 41 29 50 29 -13 -3 19 14 -16 -37 -8 -43 84 -3 52 60 -30 56 -52 -106 -123 85 121 -114 17 -44 -32 37 -20 6 6 21 -15 25 -60 -64 9 -22 62 86 -41 -7 -44 -58 19 -12 -41 -93 21 -66 -61 58 29 -2 -59 20 -123 -71 -89 -44 -62 42 -85 29 -46 10 125 5 -46 -65 29 -51 -51 -59 61 -24 -75 -36 80 -21 -9 82 -38 -26 -26 -24 39 69 -120 -46 -1 54 41 -9 -31 -42 31 18 -45 -52 71 57 21 21 -47 28 -105 -18 -11 1 -55 48 48 -21 56 -5 -9 35 -19 21 -127 13 59 92 -3 96 33 82 33 120 -76 82 45 -5 55 6 -65 -89 -112 -33 -84 27 -33 1 -34 98 -18 110 -10 7 -95 -35 -21 -1 99 29 83 -29 28 123 -38 13 64 23 -5 -29 45 45 -34 33 9 -14 -3 65 24 17 -27 127 -49 61 -26 -31 5 -25 25 -34 63 33 15 -14 -16 16 -42 9 -22 4 -70 -84 -1 -26 -52 -5 -98 -81 -106 53 -7 -10 -70 20 64 -18 -29 18 -11 26 -127 -43 55 -3 11 -113 18 33 -82 29 85 61 -12 -3 -107 -17 -60 -65 8 -30 28 73 18 13 -24 -47 -8 -14 10 39 -41 -42 -29 17 -4 -46 63 -36 -3 49 17 -7 -35 93 -1 20 120 52 -11 -113 19 -72 -34 43 -63 -71 24 25 113 6 17 -43 2 40 -14 -38 2 38 20 23 11 -69 71 89 -34 108 6 -7 25 15 20 49 -126 -29 127 55 -59 -39 -12 -24 10 5 -51 36 -77 126 40 -72 43 -1 112 -13 81 -32 61 -25 -127 -29 46 3 45 80 62 40 1 -26 -42 69 -34 -127 -100 -46 -30 -88 20 -11 112 112 122 27 -67 -67 -24 -24 79 -37 123 58 16 -68 -67 85 -7 72 -26 -22 34 127 -18 -53 -27 63 -86 53 22 -13 -26 1 7 -36 25 74 6 -23 -1 21 73 -16 51 7 10 -34 -31 45 -25 -28 44 46 -21 -26 37 6 -52 -33 31 25 65 -57 126 -45 43 -6 76 77 37 28 -31 52 62 -95 -26 -44 -64 56 21 -54 -65 -125 21 127 127 -7 -52 -51 -62 43 -86 31 -60 -38 127 -3 86 -57 9 -111 43 68 126 -41 -49 -105 -36 12 31 -14 38 37 87 -38 -3 -3 21 63 -37 87 -55 -15 29 -7 38 -16 -9 -10 -7 -7 95 -30 -2 -33 14 -48 7 -97 -40 47 15 34 33 -37 -37 61 7 -25 -39 -3 -64 33 -4 -58 -28 -1 -56 -19 11 -120 21 -75 105 28 -78 -87 7 38 -30 -31 45 -58 -29 2 -50 5 22 15 9 74 -13 -21 16 43 5 48 80 -15 -28 45 -68 100 17 -59 -49 25 20 56 6 60 58 -43 -80 49 -1 17 -1 -43 -3 -10 17 1 78 72 27 39 127 20 22 11 -44 10 17 -7 86 70 20 -13 -10 -74 -19 -118 -67 -115 1 -51 34 48 -15 50 -80 -18 -69 -17 60 53 44 -72 65 5 -20 54 58 -5 -28 29 -46 -87 -61 -14 -77 11 75 -102 0 -5 7 -125 52 -57 4 -24 -28 -88 29 125 -34 -34 -30 -97 33 121 7 8 30 97 -7 -75 60 60 27 58 43 69 -72 -42 -18 -62 -125 18 -110 55 -36 -76 -34 -23 -17 73 -54 -78 8 44 39 35 31 -106 -40 -85 -25 -21 64 72 -11 13 15 -74 71 43 33 -7 -90 -48 57 11 -19 -53 -20 69 47 -7 -20 16 -27 21 59 15 113 18 28 45 -65 -16 43 9 -21 -45 -113 102 -1 35 -25 18 27 14 -101 -28 -20 36 29 30 21 13 -101 10 -44 39 54 26 -64 55 67 -40 -126 -34 4 45 29 -90 -29 25 37 -13 54 19 19 -38 -33 46 1 -31 14 88 7 64 30 -97 66 -45 -7 -126 -1 -54 -61 -30 -54 5 10 -14 23 -27 36 -45 -112 -16 -11 -69 -47 -36 -49 -78 18 5 -24 49 -72 3 -123 -6 0 -29 -5 -13 -28 22 68 41 -12 -31 -4 44 -41 -8 -109 -75 21 -27 54 -2 -38 -12 81 11 -75 22 38 -41 -3 -48 28 75 38 17 -34 -35 49 -25 29 -5 24 7 -1 12 0 64 1 -34 -17 -22 102 -30 51 -112 31 59 38 -59 -100 -125 -49 7 56 71 66 -72 -112 -36 44 -101 33 -84 40 10 117 52 70 29 21 16 -111 10 6 1 -97 27 -114 -5 -24 -71 -17 -89 -79 -89 -94 -30 -128 -75 -34 -37 -86 -7 -1 -39 -127 -77 -14 -77 85 62 28 0 4 -122 -23 66 79 -36 99 -40 -17 13 26 126 -60 -128 68 -128 -3 -36 122 87 -42 99 -39 -126 14 30 41 57 29 -123 -50 -60 -24 56 29 -128 6 -127 -127 -22 53 -113 0 127 -32 -39 -85 -1 -26 40 46 25 -97 -61 125 64 95 -69 127 -58 -65 -102 -22 29 31 -65 -18 -30 -117 -70 -34 61 53 -95 13 -98 -127 78 1 36 -52 -17 -15 27 -42 127 -41 0 126 17 14 52 -124 -19 107 89 127 -58 -17 -97 22 36 44 -28 53 28 -26 31 -104 81 -7 -5 5 60 -121 -81 -4 -90 55 120 81 94 -59 114 -34 -44 -13 -12 68 -6 32 -39 124 -126 52 -38 -55 85 117 93 -32 -3 53 -16 42 18 127 37 -49 -32 1 -71 -39 -40 64 14 -109 -48 -62 13 60 -31 7 -13 -43 -113 -86 40 25 59 61 11 94 -38 -4 -1 -124 24 16 -11 -64 10 -14 13 111 -120 -53 -31 52 55 -38 87 -14 -83 83 47 38 -1 76 29 2 -16 -16 19 23 -68 -32 124 6 15 -50 -16 -57 -103 -8 30 28 31 -51 -68 1 -107 -50 -50 43 57 -36 104 -40 -127 -125 3 121 -127 -61 -125 -125 62 -5 119 109 65 -79 12 91 -46 60 32 89 21 -71 -16 -36 77 -24 -62 -125 13 29 -40 -109 3 -125 70 79 -70 47 -123 -126 22 -115 -48 -124 -114 -34 7 84 -1 32 49 123 -126 78 -126 -69 -38 8 4 73 -122 -24 4 88 -71 -13 -124 22 65 65 76 44 -72 14 -3 -14 -61 36 -59 -29 119 -14 119 -25 -15 15 52 43 -124 -89 -14 -19 19 57 -43 25 -127 -100 5 -125 -49 59 -105 127 68 -79 21 -46 39 56 40 -113 -80 41 0 107 -92 127 -116 -77 -124 -26 -14 -33 -114 -24 -30 -97 -21 -96 123 -24 -41 -65 -7 -127 73 50 45 -33 -36 10 -69 38 -2 -30 -32 -37 -2 -4 83 97 -29 -68 53 93 -27 60 -31 -92 -77 127 -115 -25 6 44 30 -60 -78 4 -9 24 104 -71 -21 -29 -110 29 -47 13 15 3 122 -49 -113 -106 -10 81 -13 -29 -2 121 -126 127 123 -60 116 2 72 127 -28 22 -21 68 0 71 -37 1 33 -9 -52 -42 13 7 -26 -70 40 -22 17 93 23 -49 -59 -96 15 -29 13 -3 -13 -6 28 125 8 47 29 -124 -50 14 -38 -86 2 15 45 24 -108 -16 2 -66 -30 -18 91 25 -128 -10 78 -17 17 107 58 13 4 -29 9 -16 -33 5 -49 11 5 12 42 -8 -96 -10 9 -12 -43 65 -16 -28 -128 -32 -77 109 -112 -44 90 1 -125 -125 3 3 -127 -114 75 -127 -41 33 9 62 91 51 -113 125 39 100 127 75 0 -70 -38 -96 69 80 -33 -80 -38 -11 32 -11 78 23 -48 -12 17 66 -33 -126 65 -43 -32 29 -122 124 -52 15 -46 64 90 127 -20 124 -29 -37 -19 49 112 80 94 -8 -32 -68 -126 -76 -98 110 98 57 7 85 72 -96 127 -8 -125 -85 -124 114 110 55 90 -27 -93 22 76 -20 39 16 65 42 -9 127 127 -118 84 127 67 -95 9 -1 -127 127 73 53 -18 -27 60 -101 -32 -113 -125 -3 -37 125 -58 -125 -68 2 -128 -36 -6 -9 -27 -94 -64 -112 84 13 81 34 63 -26 125 11 11 -16 65 18 -55 -65 40 127 -128 36 -15 -124 64 -128 15 43 24 -107 58 -8 -28 46 127 -95 -81 -17 -25 7 -11 122 -125 43 -126 46 47 104 46 120 71 0 62 38 -25 -127 -78 81 127 -25 -125 -115 -59 -43 -103 -49 -21 -48 47 48 126 -6 114 -14 75 125 56 77 -51 60 -26 -84 -89 -14 76 38 -26 -31 10 -18 1 -6 102 127 -24 115 54 -42 -124 -10 79 28 -40 -52 -66 -45 48 123 36 114 26 -84 38 -16 8 4 -28 109 29 14 -45 30 121 -93 -127 -16 23 10 2 -50 -14 -128 91 -72 79 -72 -47 45 -4 1 13 16 -127 -128 -35 59 62 27 -22 8 -35 -50 -92 55 85 -127 -128 29 47 111 7 13 -128 -54 -22 73 -45 -69 38 -101 -12 -82 11 28 4 -50 -122 -37 -109 50 -75 29 -34 0 31 -3 35 -23 11 102 101 -21 -70 54 -68 19 61 126 -68 32 -51 75 14 -36 -80 -127 -44 86 48 1 -11 -127 93 12 -75 -20 68 119 -127 51 96 35 63 -14 127 42 21 92 -121 8 -27 -1 58 -92 10 -43 -126 18 -124 -112 -26 -42 62 -8 122 -41 -127 79 6 22 125 35 94 84 -114 53 58 -28 127 -122 120 126 -24 -39 -43 3 49 127 -56 114 126 -22 47 2 -8 69 112 73 -3 69 40 31 -17 -60 -123 -31 26 -28 75 -99 -39 -128 -76 74 -4 105 -112 109 -25 20 -5 66 91 15 -40 -87 89 45 126 44 37 126 13 -120 -22 -128 5 67 119 79 -19 -74 23 -118 27 -125 60 68 -26 -44 -58 -97 127 -57 53 -83 -3 -41 -119 10 20 -35 125 -35 -12 -69 77 36 48 31 61 -112 -75 -15 -126 14 14 -127 -82 28 43 64 25 18 123 22 -12 87 67 61 27 -60 -78 36 -51 -51 -68 39 12 -83 -11 84 -8 58 -97 45 50 34 60 49 41 27 -23 -55 36 35 -63 95 -26 52 -21 12 42 -17 41 41 -40 127 -77 20 47 112 127 -89 21 7 47 4 -49 -19 26 -57 121 -30 2 87 55 69 -38 8 127 64 0 -33 -44 14 -34 -17 63 -12 33 -70 125 -77 -4 -8 -119 -89 36 0 -126 -124 -7 126 -46 -2 111 123 -23 -124 7 -30 33 29 -52 -29 92 88 12 23 -118 18 -65 -33 -1 11 21 -20 28 52 -42 14 -69 27 -38 69 20 78 -107 25 -35 64 114 -66 -118 50 17 -85 117 -66 -23 25 -17 -30 105 -30 121 -71 -85 126 -74 21 119 -69 50 -55 23 -7 -66 -87 -90 11 -37 110 35 -44 -124 66 -27 23 46 67 110 82 113 109 49 9 123 41 51 1 29 -30 59 -2 -108 118 110 -55 27 -69 -91 12 -127 127 14 116 -109 50 -109 85 -55 -53 119 36 -47 -33 -23 126 7 -117 22 20 -58 -87 27 117 17 -125 -49 -27 6 51 -59 15 -4 -63 45 57 0 56 -12 -49 -43 90 127 57 -3 -11 -58 -53 -9 23 67 -31 75 -45 -56 34 55 -33 -5 -103 81 -61 -15 -51 63 -12 40 4 -124 -72 -31 82 -118 32 39 6 -127 8 39 -107 74 8 60 21 -41 -103 -23 -16 126 66 56 126 -15 13 -79 -108 -34 122 4 10 -36 8 21 19 30 35 6 -6 -63 -1 2 22 -2 -31 35 0 -47 32 63 -21 90 29 7 51 0 0 -28 -13 -121 45 66 -49 5 122 34 -8 -10 -41 32 115 23 127 -17 -30 127 -32 48 123 73 26 71 7 49 127 -15 -118 57 -55 4 -35 7 -34 -67 -18 127 6 17 -20 11 -8 -24 -38 -21 70 -109 -3 127 -35 36 -15 127 -60 -125 -84 127 36 84 -78 83 -16 -18 -126 63 22 -24 126 -56 -75 7 -6 -50 122 -35 -53 64 -36 -48 77 -22 -54 -25 -2 -3 -70 89 49 -57 45 -83 110 31 77 121 23 75 21 52 75 -37 -50 17 30 -1 -127 -27 8 -18 127 -52 59 120 17 51 -71 91 -74 118 47 60 -121 -29 -50 63 85 13 127 39 56 121 -53 127 104 -124 37 -92 127 -19 -12 -25 13 5 4 -19 -18 74 -34 -33 50 -1 36 50 94 101 26 -61 98 -111 58 -95 118 -86 -126 -47 -15 79 -8 35 -118 17 22 84 -87 -117 -51 -52 -127 -88 -1 -75 -64 6 -124 -41 -92 48 22 -4 127 -74 -6 18 32 31 78 -70 38 32 -1 -116 27 -127 20 -6 89 -8 -85 -39 -56 -40 -49 107 62 -6 -13 -41 73 54 -126 110 20 95 63 -23 23 31 -5 105 -32 -102 13 -59 -2 96 -30 92 -114 -61 -23 126 22 48 119 37 -51 -127 13 20 -77 101 116 -57 -28 -45 -5 -103 11 -75 -46 8 22 13 28 -10 -4 98 -32 -14 -18 -35 17 -5 -22 -22 54 -6 72 -18 3 33 25 -81 38 -28 49 -30 20 -127 -20 -39 -97 -80 -126 25 28 -4 46 -25 73 -59 81 5 -29 30 7 -127 -28 54 23 119 -22 -30 25 100 -93 -55 51 29 38 73 23 -14 45 -128 -50 -38 -13 17 77 2 49 -17 -56 -94 6 17 -80 -123 38 -67 -122 34 -14 33 44 101 -34 -33 -3 5 -66 21 45 13 18 -24 78 34 28 -2 -4 26 -54 35 -18 -8 75 -9 16 -12 2 20 -14 127 -53 8 1 -34 27 -16 -17 21 -23 16 21 28 32 -9 18 12 0 -10 -4 -11 -2 -17 12 15 -16 1 12 43 -5 78 21 32 9 3 25 -40 0 30 -16 -12 12 -21 14 -54 37 67 -6 12 -15 -6 -3 -4 1 -2 4 25 25 -2 123 -7 13 17 -5 8 19 1 45 -15 10 -16 85 -61 69 -40 -7 -34 40 45 -31 41 -31 -22 14 -25 -37 14 -52 -6 -27 44 -118 -20 -33 -3 34 120 6 36 -2 19 17 30 -54 3 20 77 4 -20 29 -26 -36 15 -21 10 -31 31 8 -4 -40 -6 18 20 -8 3 -14 -4 12 82 17 21 -7 -15 -85 22 -29 -7 -20 75 23 44 -12 12 6 -15 -12 11 -22 29 -11 5 14 -7 11 44 -37 1 -1 -7 40 -36 -3 -10 -5 -41 30 35 4 -13 17 5 3 8 -7 8 -45 -2 -23 -18 -3 7 -12 39 -10 4 9 4 15 -8 -21 5 31 -50 8 -8 4 15 36 -5 12 -11 10 2 -48 8 -13 -34 -46 26 -5 8 -8 -12 1 -17 -3 6 6 -57 4 -7 -1 20 16 14 18 -19 -28 3 -75 -23 13 -9 1 -5 -1 -11 -7 -72 -22 -49 -8 -19 -2 32 3 -9 -8 -21 -5 -30 14 -45 10 23 22 7 -17 -6 -64 -3 -3 -20 -1 -18 -9 36 -1 6 -2 -21 -12 26 5 -4 -82 -43 11 -5 11 10 -12 35 2 7 1 -34 34 8 35 -18 -15 -10 -50 2 1 -18 -23 16 8 -12 125 51 -35 -8 10 -17 -41 7 19 -22 5 -22 18 -6 6 -31 3 -7 3 -41 45 1 -42 -30 19 -3 30 24 -23 17 -17 33 -21 -17 73 16 -8 -91 4 1 -4 -67 -13 35 1 5 17 -8 4 35 -17 -6 17 -5 -14 8 -102 -7 -1 -32 1 -20 -22 4 5 18 -39 18 -8 -28 -2 5 -22 -101 -1 -13 -12 2 24 34 25 -32 -25 62 -22 36 18 126 -52 8 111 -41 -5 1 15 -65 -30 -18 -55 48 -43 1 -2 26 111 -2 78 32 12 18 24 15 57 -21 32 9 60 -2 -14 84 2 127 22 -18 36 -1 -17 -34 1 -4 -62 23 -44 -38 -5 4 -119 -33 -4 -10 80 -48 27 22 -10 72 109 27 2 22 -30 35 -115 24 18 -8 5 4 -6 -41 -17 9 -31 7 -17 44 -7 -15 1 -38 10 10 3 -14 8 -8 1 0 21 5 -1 -2 7 -12 -35 -11 -2 0 -13 8 -14 -17 79 81 -47 1 26 -5 1 -17 -59 -12 4 -5 10 -7 -22 -18 -22 -22 -14 17 33 1 3 -3 9 5 4 21 7 13 1 -6 -1 -6 85 -1 -2 5 24 79 -8 -5 11 82 5 -9 -35 -2 -16 -39 14 8 15 0 24 0 29 -26 87 -63 39 -93 -29 -26 49 7 -15 -24 -58 -124 70 43 92 95 89 54 -30 25 33 -125 -3 -72 -34 -117 87 -4 -32 -71 -71 -83 75 -45 -18 -65 -11 77 -32 -25 -11 -125 46 -17 77 71 8 -55 75 -40 33 40 79 -85 -102 -100 -79 -119 -39 -58 -45 -44 41 61 -121 1 -48 -44 -78 103 126 8 -18 29 -76 -2 -125 -35 7 -109 5 -4 95 50 -116 -17 58 -16 24 -89 -90 -93 -14 6 -62 -57 -65 81 39 -6 -63 -29 46 -62 33 -22 -9 -24 48 49 30 -24 61 38 -68 75 14 -33 44 47 81 9 -43 102 125 1 -2 74 58 -19 28 -27 23 85 -113 16 5 -63 46 13 86 13 34 -38 53 -66 105 32 -36 65 -4 -8 -2 -87 49 31 -16 24 36 30 34 24 -7 22 -31 -27 77 22 -22 -86 80 63 -49 13 59 48 28 -32 57 -1 -12 83 20 28 60 -27 -82 93 -10 -20 17 -68 -44 64 61 16 -18 -31 126 1 -79 44 -56 5 73 5 -11 -11 -38 -8 121 36 -12 -1 -31 -10 -48 55 -12 -33 -24 -62 -43 -68 1 -67 11 -84 -19 88 -43 -103 64 37 -54 -18 2 77 -37 43 -8 41 76 34 13 -5 -86 53 -128 -3 -26 -32 -20 46 -56 -34 70 18 -49 59 -39 -109 6 52 -55 33 36 -43 1 111 22 2 45 -10 -7 -39 -1 -28 17 -43 102 -50 -13 -64 4 68 -84 -30 -30 -63 127 -128 -74 85 -74 -63 29 -18 -14 -127 110 88 -32 -55 34 -19 -61 18 -101 -125 60 -20 -17 87 41 -7 -3 3 21 -121 -32 39 -117 4 -72 50 0 33 17 21 55 4 -9 -94 107 20 16 47 -18 49 -1 63 75 75 -13 20 25 49 -6 -37 73 4 75 -3 52 -19 3 63 0 31 -44 46 69 -39 -81 39 -45 68 67 -13 57 -18 -31 -41 47 61 78 -36 52 -49 93 82 -25 75 55 52 7 -73 53 34 -24 0 45 -20 -81 5 3 11 4 -21 90 -38 -9 -10 -20 -62 32 8 31 39 -4 9 -38 -111 34 -20 40 3 34 -47 -34 94 19 -111 -15 -32 -15 -15 60 24 25 20 30 12 -70 34 -2 -25 -59 43 127 -86 23 -35 40 24 44 86 -11 42 13 23 -59 45 28 61 3 0 61 58 -1 -41 20 -77 26 -16 61 70 -1 15 -3 55 19 -58 -65 63 1 -19 -77 92 -53 -7 0 -40 35 17 69 25 1 122 1 21 40 -39 -5 52 -23 -122 125 -21 27 -32 -75 -12 -103 -25 -125 80 -36 15 -68 -16 -59 6 -36 -8 51 -41 -21 14 36 20 -83 39 -50 16 8 62 -12 26 -65 56 -50 -72 1 -24 -58 -25 17 -34 14 -14 70 -85 -65 -49 -60 83 -73 -65 -16 16 24 30 -16 12 51 3 21 72 -47 84 -53 48 64 8 22 -14 63 -11 -25 -20 -16 31 -23 4 -84 33 -114 -81 -33 -77 91 8 -95 -23 37 -126 36 5 -75 -36 -21 19 -10 -8 -123 35 27 44 -17 74 17 14 3 34 39 9 -91 -88 -106 -69 -38 -101 -46 -23 44 -63 -14 89 -66 -73 -102 -65 -6 -104 -74 -103 -69 -81 -28 7 -26 15 2 66 -38 64 -86 14 -15 -2 -12 46 -22 -12 13 51 -93 -82 -60 -58 -4 0 32 23 -44 -38 -30 -113 -35 -16 -24 -16 -45 -37 -84 24 -61 17 49 -76 5 45 25 -70 87 -7 -18 -48 -47 12 11 39 61 -60 28 -7 16 -95 -19 -100 2 -36 68 -18 -101 0 59 -35 -75 10 58 -46 19 -12 17 -72 36 -13 -128 17 -13 62 -16 1 27 -47 15 32 -16 21 -6 -58 40 20 -23 9 38 75 -45 -9 -16 57 16 8 25 -30 -35 -42 54 9 -4 -4 59 4 82 25 35 37 69 -23 29 -10 -63 63 9 42 -42 -10 -12 19 4 -27 -84 39 -73 -18 -127 -31 127 9 38 53 19 4 -17 30 -27 -28 27 -82 -10 84 -4 -88 48 -12 -26 -40 83 51 -27 23 7 -20 -54 -54 22 70 23 -16 -6 64 27 29 -33 -23 8 61 -40 56 75 -39 79 -125 127 49 -37 -62 -8 92 75 -119 -115 -91 -74 -3 -32 88 19 64 37 13 17 38 42 11 -39 -10 -21 -65 17 -105 94 76 95 -26 -3 26 -36 -56 -92 -47 15 15 120 90 30 -38 9 -80 -104 -5 -32 20 77 -128 -123 -66 4 -127 37 -77 6 25 -104 -86 -23 -42 -33 -100 28 -46 -52 -123 85 -93 -27 -47 -57 -42 -63 46 58 -85 11 -64 -128 -12 31 17 -58 -17 -59 29 -2 7 58 -41 30 12 50 41 8 -24 -59 -118 97 9 107 71 25 18 -2 1 83 50 -6 13 -11 8 26 -56 4 14 -12 -127 77 -7 -35 110 60 59 4 3 10 -83 -49 -20 -21 23 44 -19 -34 -13 -102 -29 57 51 13 52 23 -35 13 29 25 -29 22 -46 -95 -16 -23 19 -34 -64 16 74 -36 -20 -19 100 49 -31 -15 -9 122 87 1 -22 -33 16 20 44 -67 21 -84 -12 57 -107 8 -42 -78 22 127 55 5 -10 -56 28 75 -50 19 -14 8 -73 -33 17 62 3 11 -74 45 35 -35 73 17 -52 65 -37 -20 -12 28 108 -4 112 -21 8 62 28 35 101 -88 -115 -31 -16 -55 18 -43 -26 -68 -35 -2 26 57 54 -18 22 32 104 121 -15 -32 -11 55 76 59 -26 24 -120 -60 -124 1 -79 41 -66 46 -42 73 65 97 -23 -16 -126 28 -37 -70 -11 -4 32 -27 125 32 -98 50 84 12 -16 7 -17 26 48 -39 -66 -45 -76 -15 -47 -28 -26 -9 -16 -52 -86 32 13 -73 -96 -53 -82 72 -86 -72 2 34 -65 -16 -34 17 -77 -12 52 -125 -4 7 -16 -15 -46 48 63 -78 31 -22 -36 127 67 15 -7 -65 66 -102 -39 -81 -101 53 -119 69 -26 -124 -96 -39 57 67 -7 -99 69 -19 12 -27 65 8 -77 -112 37 -72 -110 -37 40 7 -30 11 -101 -40 -20 -32 49 -17 -49 -26 19 46 -4 50 -7 -87 -99 54 -114 -42 -43 123 -54 -116 -5 -50 54 -24 29 75 -67 -119 -67 -30 50 -37 -96 -72 -85 -66 84 -70 -83 6 -63 -42 -26 11 30 -42 63 -69 -4 19 -70 5 -32 -52 -10 -31 1 -47 -100 61 -51 -70 50 -37 -81 46 10 54 -79 72 4 9 -104 -77 -24 64 22 -38 -26 -92 -53 39 -1 -24 -104 26 25 -54 -10 -91 38 67 32 -85 31 52 24 -69 -32 -105 61 0 77 40 -1 -1 -26 -37 6 88 13 60 18 -63 43 -53 -97 -105 43 90 51 -27 81 -31 -36 -65 30 -1 -38 -39 -29 -9 -23 37 -28 23 26 15 -85 12 89 -8 45 -51 8 30 -58 -34 61 -89 -26 -124 -100 -90 -52 -12 70 -3 51 -45 -32 -40 50 105 112 94 50 14 7 17 -96 -34 1 57 6 59 -36 118 -109 -28 127 -128 -99 5 -41 33 -73 47 127 115 69 28 -85 -4 40 66 84 69 22 53 32 74 28 40 30 -45 -44 30 46 89 34 -43 -101 21 68 22 127 29 -67 -43 -19 -11 99 -40 30 -38 -16 25 -56 -31 19 31 27 24 -48 25 40 18 -106 32 -22 -40 31 -28 124 -21 -42 45 122 -9 51 25 -126 -12 23 -42 39 -36 58 51 -6 72 9 -96 -78 95 -51 94 115 -45 -49 48 54 25 -54 3 6 11 13 -75 39 0 90 -4 106 10 -8 98 -45 -25 11 7 8 9 -41 20 31 -66 -2 -84 -13 34 10 127 50 5 89 -39 -68 5 50 63 90 -104 29 -7 -23 53 83 69 31 21 -36 127 -6 76 -107 -58 -42 -30 2 12 22 89 68 -70 -26 123 38 -112 -61 -55 -103 -108 70 -51 84 -26 39 48 71 -37 36 -18 -4 55 29 -53 38 87 126 18 34 -38 19 39 47 -15 -58 -37 100 16 86 -64 18 65 14 15 12 6 82 10 -39 -126 -20 -5 -29 -109 44 -65 -13 78 11 -123 -108 6 -25 -60 61 -49 -29 -97 -17 -103 -9 -54 13 -80 46 -128 81 25 -84 -11 -66 -42 -33 -11 118 21 -82 30 -14 -66 -125 -107 28 -93 -28 -36 -41 89 -56 79 -16 -87 -43 -43 -11 -21 -57 -44 -30 41 31 9 -69 1 -15 -4 57 25 50 38 -4 17 -127 -46 -33 16 2 52 24 18 23 8 26 -10 -104 -57 -14 -71 63 -43 -49 88 37 61 127 -127 -44 32 98 110 -33 59 -75 -49 6 39 -19 -9 -9 14 -71 -81 -43 -8 -115 45 56 -18 -83 24 89 -36 -100 23 66 -15 -19 -50 89 -23 -89 -19 43 -75 -48 -89 -26 22 -28 60 12 -45 -43 13 -52 17 29 30 32 70 -34 93 53 47 32 15 -58 -127 -41 -10 10 64 17 89 -128 -7 0 -33 54 55 36 -25 119 -57 -46 -16 -25 -23 -31 -117 -49 -10 -122 106 18 -68 -7 -45 64 -45 -89 -124 -25 -17 -57 -71 -62 -74 -33 -79 -83 -33 -52 -64 -36 11 -68 115 -38 -17 121 -42 -19 15 -102 103 40 69 -125 70 76 47 -67 125 14 12 -37 6 -101 15 -102 -89 30 -65 -50 46 -66 -44 1 52 -83 41 67 3 122 76 43 -22 25 50 25 95 27 -30 -11 -3 103 -48 -2 -46 -35 2 91 97 -35 30 59 -37 -33 -71 -75 -27 -30 -16 -25 12 23 27 69 7 53 8 21 105 52 -12 53 21 88 -71 26 -78 43 -33 -36 -23 51 -43 -53 80 37 36 42 13 26 -34 -123 -3 -42 -67 49 31 -54 -17 -39 51 -45 13 -100 74 -37 -12 86 14 -125 3 -15 -26 -48 -44 62 1 36 25 -100 5 26 59 -43 -9 50 -53 -29 -106 -56 43 -69 -7 126 -56 -27 -7 -9 -35 39 30 127 25 -19 -47 -21 -97 4 -3 43 -47 30 8 -107 27 -33 71 68 -87 2 65 -75 89 -109 7 59 35 127 -34 2 13 -77 125 36 112 22 -9 81 73 -86 -31 -10 -89 27 -17 -25 -6 -18 17 -6 85 107 17 82 -2 -107 -74 -11 125 -113 94 -58 40 -110 24 -59 9 20 -13 -23 22 -27 -89 -66 -11 -111 -25 12 -52 7 -20 0 29 36 5 52 95 25 -19 -61 62 -34 10 84 -1 -10 44 -91 -127 127 -3 -13 -3 -53 -54 -33 0 -47 -24 -12 -13 -34 -1 -32 -29 -35 22 5 -28 27 -10 104 -17 33 -89 -59 114 -51 66 14 -54 37 36 -80 51 77 -109 10 119 48 -42 -94 -41 -35 -53 15 62 9 -35 39 109 14 -84 95 82 83 11 -35 -21 50 -100 49 27 67 -126 -3 -31 16 -33 54 46 2 19 -100 107 74 6 61 63 41 101 124 3 -37 55 -15 -9 82 -44 24 -18 -34 -48 -55 -1 46 1 65 68 -4 2 24 -5 -35 24 -32 9 -7 3 -20 47 38 25 56 -40 105 -1 64 -60 -93 -78 27 19 11 79 10 -18 28 13 -17 87 -16 -59 -16 -17 -24 -39 17 -13 -16 12 -47 -8 -33 27 -11 108 -34 -27 -61 8 -6 38 6 28 -36 -53 4 18 -36 49 54 118 -50 -3 44 -31 -26 2 96 52 25 -28 -40 21 39 -62 26 47 49 -31 -54 9 26 10 -69 -23 -19 -31 17 -14 54 6 -50 -8 67 -41 27 67 4 -21 24 48 -50 28 16 -14 -4 21 49 74 -26 -1 48 -76 2 -18 25 -33 45 -61 -14 1 36 34 26 54 -6 5 -47 10 38 49 12 13 23 27 -12 35 -27 -37 10 -20 -5 -82 -15 4 32 -11 4 -54 15 -10 63 33 -22 20 0 6 17 -11 14 -4 30 -27 70 15 40 7 9 15 -26 -25 -35 29 28 53 -78 -46 74 -49 30 63 2 2 -27 -3 63 -40 -53 99 0 66 38 -86 32 -100 -25 -84 -100 -39 -46 14 -49 60 36 -9 30 -39 95 -7 63 -15 -45 -9 -28 53 64 4 -22 -70 -78 13 -55 0 118 -118 -75 -3 -126 45 32 -121 -7 -1 17 44 59 -95 -16 -52 -23 13 6 109 -5 94 29 91 21 65 -28 -127 -11 -26 90 18 -17 -6 -83 4 -17 58 100 -116 -68 83 -14 -123 105 -50 -34 -16 91 -7 -73 -41 125 95 81 -85 -22 16 -9 23 22 2 110 33 126 13 47 -41 -73 -24 22 -41 16 0 -44 -6 0 -19 8 126 77 -28 -38 34 -24 -16 69 -116 -17 102 35 -12 -13 -77 -11 -44 -120 42 -44 5 60 -32 57 78 -95 -74 50 5 127 45 53 66 -40 83 14 -36 30 85 23 -84 -94 119 67 -9 -123 -87 126 109 -3 9 3 27 127 127 -13 -90 25 -15 20 -13 -10 -9 84 -46 58 -30 53 21 -27 -5 -88 13 -55 -14 -12 1 68 83 53 -50 87 30 -45 -125 -80 4 -35 47 15 -25 -54 -87 -93 33 28 -125 92 -58 3 19 80 37 -31 -5 15 -1 -83 36 15 83 49 -64 -4 -1 16 10 32 -8 17 -45 22 -41 -76 89 60 -22 1 21 10 -3 -12 35 -74 -70 67 33 21 -127 -1 67 72 46 -101 59 -27 -16 45 11 -39 -11 -8 -7 39 36 2 -88 88 25 17 20 -24 88 -24 -26 -18 36 15 -7 13 33 82 63 3 22 -66 16 67 52 69 -12 -17 53 11 31 57 101 -107 67 11 -34 56 25 45 -36 25 52 -54 50 1 70 17 -71 -69 30 -2 60 -47 22 7 50 20 109 86 52 -34 -64 91 46 61 14 21 17 19 -34 110 90 -5 -70 82 82 63 30 18 73 70 32 32 96 57 -38 -10 -46 52 49 43 98 20 -2 127 6 47 28 55 42 14 11 77 -39 89 95 96 -5 16 -11 62 -40 -16 -19 -41 -50 0 31 17 34 27 -32 69 9 -24 43 86 35 45 7 -22 47 39 41 -8 -39 11 -43 -57 113 -24 32 -37 -109 91 -6 24 45 40 -101 -41 24 93 19 -9 16 18 55 42 86 17 -28 -41 35 -20 34 -31 42 1 2 -114 -48 -29 28 34 -42 -12 73 80 65 13 -17 127 34 3 24 40 8 -32 24 21 71 29 33 21 73 7 -28 -44 67 10 -1 -23 -54 45 35 -25 -57 -110 -16 18 1 -24 -16 22 70 -24 -42 41 79 -127 -13 -95 -44 -78 -4 5 72 -19 -68 38 -94 -10 -23 78 -14 -63 -86 -77 33 -23 -45 -5 65 -79 5 -42 -96 81 62 -41 -3 11 46 -2 3 -23 -125 -11 -122 58 50 -12 -63 49 70 -22 -31 50 -114 127 85 -27 5 -25 -43 7 17 59 -20 5 67 -18 -12 46 -22 -22 67 -2 -36 14 -34 17 -1 -19 54 -22 -5 127 -108 -26 13 115 53 -44 24 53 52 33 -17 -14 92 66 31 73 -77 40 91 -18 -54 24 1 -117 -28 -11 53 -47 56 20 -125 124 125 52 6 -43 -40 105 52 83 -23 -91 -12 47 -59 -18 44 -126 -19 -30 21 -47 64 -68 -112 4 12 -16 83 34 -89 -18 -61 13 -23 20 -48 39 -64 -70 -35 -14 -13 23 -75 3 -125 -9 21 -23 -118 -73 7 23 -35 46 -33 64 -35 -61 -30 -13 -66 -36 -17 -46 23 69 -2 -63 -8 15 -29 -52 -107 15 57 7 10 -64 -26 21 -110 -76 -32 -18 -17 -22 -25 2 -23 -15 28 -11 2 127 35 -127 -43 6 -33 -3 63 28 51 32 -6 -29 -118 -12 72 3 10 26 39 58 5 72 -47 45 62 -13 87 112 104 -25 49 91 27 -11 32 -58 54 -89 95 125 109 53 -2 -10 72 -85 29 82 7 33 13 -6 -39 10 96 -8 -9 23 -14 -1 32 -5 -66 91 -62 67 -36 -57 21 -37 -73 6 -59 25 -127 -1 43 -58 -39 -25 -58 -37 -9 56 -85 -104 4 21 65 -74 48 60 43 -58 2 -13 47 30 6 -84 20 -20 -4 12 37 -30 10 -3 -35 2 30 -29 -9 15 -91 -60 -35 -1 -5 20 -47 -58 114 23 26 15 29 -50 -20 1 -73 -16 -45 -25 52 88 -3 30 -32 -50 -63 -69 39 -53 10 -33 -9 -37 -49 -46 -7 38 25 -14 -33 -30 9 -69 12 -12 78 -25 10 -65 -45 -65 78 -22 123 30 9 12 -82 21 -33 -63 -112 -1 0 20 85 -91 7 37 31 16 18 35 27 -56 51 -29 1 16 -58 -39 3 -35 58 -3 -18 25 -96 89 -122 108 -2 18 -43 -47 5 65 -71 121 12 -113 81 29 -50 62 20 -48 -108 12 -35 2 20 -12 -125 -60 -127 30 10 -64 86 -9 -27 -67 -81 -8 89 -100 -101 47 35 12 -26 11 -60 126 80 -24 -54 76 75 49 67 -127 -75 -12 61 39 -4 -1 85 -89 37 -35 -87 80 59 -30 113 0 0 99 0 -6 -10 -26 124 28 -22 -7 -43 98 -33 -12 -128 116 -55 -39 107 93 -59 -77 -72 -23 12 24 -4 -42 91 -29 1 123 38 -57 -48 -76 -25 -33 26 18 -40 -9 -10 -106 14 26 -113 36 39 -46 75 97 -128 6 14 -11 -127 31 -36 13 0 -18 -42 41 50 -56 -7 -98 62 -10 32 26 19 -14 -42 -42 127 -43 16 67 -1 -56 4 -19 -75 -28 -44 -41 73 15 35 54 21 48 -14 50 22 76 3 -71 -45 65 39 26 34 -42 47 -53 73 -42 22 -43 -13 -72 27 44 50 -118 50 63 -16 -59 119 8 -12 -14 -56 -113 20 77 65 -82 -14 43 -37 7 -24 -61 116 -6 -36 58 -13 29 3 127 -32 -34 114 34 90 -15 -9 41 59 127 -26 46 68 -28 44 21 35 -19 -81 56 -32 -6 -61 -52 121 5 23 -5 6 27 69 15 87 -127 -117 -4 -8 -100 126 -2 -40 42 -7 -104 -127 -83 -85 12 -123 24 26 -36 84 67 -53 9 67 123 -86 11 -9 -24 72 -5 73 -9 10 -1 90 -98 1 -13 26 -44 69 23 83 -26 -62 115 68 38 7 -4 119 29 81 -21 -40 103 127 18 64 40 123 -8 115 58 98 -30 37 -38 -30 6 23 -79 -22 38 42 -17 122 -63 -48 45 59 22 -76 32 72 116 -3 39 76 70 -97 113 -33 11 39 -126 -11 75 -55 -30 -22 -67 -66 -6 -1 -36 -15 -79 -68 -18 -55 46 127 71 116 10 65 65 -30 23 -39 -75 -42 -6 76 -33 125 -12 46 1 -3 -126 53 22 -53 66 3 -25 0 -18 -6 -11 -17 41 119 -32 -53 -33 126 -83 -4 -3 -14 -37 21 -8 -13 24 21 70 -8 10 47 10 67 -26 -28 126 -50 -65 127 -101 91 86 -32 -26 75 22 -126 44 5 26 20 30 -26 59 -72 -43 -80 -9 126 27 -4 -3 77 -20 -77 -9 43 12 11 -37 -24 43 82 -121 39 11 -76 -34 56 7 17 -121 -116 -7 -73 -125 -92 -47 -37 -52 -127 -89 23 -41 -78 37 25 -101 51 49 -23 -3 53 -5 124 -16 -46 16 -61 -89 127 18 -91 -13 46 -19 20 74 67 -1 -42 35 21 82 23 -121 51 78 0 0 17 127 10 26 12 -12 66 18 34 -63 74 -32 -115 -70 29 -25 12 -5 64 26 -105 -15 60 -22 22 4 51 0 -20 95 -44 -4 -82 -51 11 -8 17 64 30 45 22 35 -30 57 -44 17 -28 49 -41 0 -12 -18 -6 35 -22 -11 9 -89 24 -22 15 22 -13 -28 22 21 46 15 14 58 -49 -36 10 74 -84 87 25 69 -21 -17 -27 1 -15 4 -11 125 46 -75 -64 -2 -14 -17 115 25 74 -43 -22 -12 -72 4 21 -32 22 18 -11 50 49 -66 87 -48 16 126 40 33 122 -44 16 -37 -50 -39 -29 55 79 -3 42 -11 -14 -40 93 -37 125 -16 -30 42 -14 10 44 58 -76 -62 -82 -57 42 20 9 -50 58 67 35 -30 12 -3 0 -42 32 56 -19 49 -10 31 -43 -70 63 -83 -2 -10 37 17 -13 66 92 -9 -13 -13 68 70 19 -61 65 53 0 -64 23 -15 -128 77 42 11 -21 32 -38 36 39 4 15 11 -41 50 -85 -71 40 15 44 23 -4 35 48 -17 -13 24 47 -27 -8 -126 -120 -85 49 -69 -16 3 -71 -81 -55 52 -46 -27 -54 43 13 -15 -40 13 -59 19 -34 17 38 2 -76 -14 -30 4 71 -35 15 29 38 29 18 -30 -34 -51 21 -54 -55 127 5 -1 -29 -15 33 -125 56 -6 39 4 -68 48 -46 -5 -8 64 127 6 -13 122 -22 23 -19 29 80 34 -58 0 -50 61 -49 88 -22 -88 70 -70 3 -36 -37 -16 -3 0 -84 30 21 124 -32 30 92 16 -2 -46 15 17 -47 87 -12 48 10 -123 1 35 -90 74 -32 -53 32 44 -118 28 0 58 1 -113 -18 30 -38 -32 45 -127 -40 25 -26 -101 -22 30 -99 -53 -65 -13 -19 4 -114 -8 51 3 -13 -18 -87 25 42 89 -34 25 -65 82 -126 -63 -90 -40 44 -75 -54 -40 -93 -72 -99 -47 -68 -74 -122 -15 -122 -58 50 68 62 -41 -78 -29 -36 -50 -119 16 -101 -19 29 -84 -61 -8 9 -56 -22 -78 -90 -31 7 -3 51 -6 33 -36 -36 90 44 84 -17 24 -106 -31 2 15 -13 49 23 69 60 -2 61 17 -39 -60 -82 22 55 25 -6 12 80 25 -10 -1 -95 -68 -24 111 40 -7 101 89 -51 69 3 41 -11 9 -12 -3 -89 -53 50 34 -62 13 -42 -12 -114 -15 -39 -76 -50 -39 20 -54 72 48 -16 18 -28 -17 61 -67 38 -48 -46 -122 19 -62 25 -14 -66 -104 19 -6 -39 -23 73 -26 4 -23 18 -24 -5 -1 29 5 -9 -104 -69 7 -92 52 -116 -119 -83 11 62 -2 -49 11 -41 10 -33 89 -107 -52 54 104 -128 119 -64 -30 26 -41 -54 51 97 -49 -15 57 14 -3 -128 127 30 -126 -32 35 -8 -10 77 -44 24 47 -117 -36 -33 15 39 54 -125 -24 100 -89 -124 57 74 -125 76 25 78 -84 9 -41 -45 46 -31 8 -1 22 -22 -72 -75 -32 -30 -20 -66 -42 -27 22 -125 65 28 -11 92 30 -5 -31 99 -18 15 39 -29 44 -44 98 77 -16 -78 43 20 -10 23 -12 -45 123 125 0 -47 38 56 -35 108 76 -11 -75 19 -47 -6 -30 -31 21 30 -79 3 24 104 -44 62 -60 -126 -128 44 -126 -28 90 4 51 30 81 -60 -48 -40 -5 -4 61 93 42 -6 -124 37 -25 -53 29 -35 117 -58 7 -23 -6 18 -62 44 -18 12 42 39 78 -51 -64 60 -21 58 -5 -25 20 -28 37 67 -79 -37 -75 -71 -28 4 -33 -4 56 -37 12 -67 41 17 31 71 -2 29 -4 -24 7 59 51 68 4 -13 106 63 41 -65 24 18 -21 -65 39 -84 66 108 4 40 60 28 -28 11 -48 -14 6 -44 51 -38 27 -18 -74 14 -41 -52 100 44 4 24 -5 -21 23 73 -10 26 -18 -16 53 55 43 6 -68 2 -41 71 -38 -55 28 -36 7 80 71 -43 -29 77 76 -68 -115 -13 -11 20 22 -30 -22 98 -37 46 -124 -2 4 102 -6 -41 -17 31 54 16 -43 38 -34 11 -31 5 -22 70 -44 -4 48 102 42 10 26 -1 37 -29 -33 52 -104 25 0 94 76 40 68 49 89 -56 74 43 43 14 65 -7 -80 57 104 -57 35 -45 37 72 -68 -85 29 2 34 75 90 -56 -9 45 101 1 -52 62 -40 28 9 -30 0 14 -78 53 54 35 -40 -11 -73 8 -5 40 -58 -33 2 4 -8 -79 -78 12 21 -4 124 1 0 -4 10 18 -22 -8 9 -29 1 59 -88 -103 50 79 -29 67 -35 -89 -46 73 -63 -125 -120 68 81 -43 -13 -107 -38 1 102 -53 -75 22 95 -89 -55 56 -18 127 -19 25 52 -70 3 -74 -122 88 71 -5 22 98 -42 -6 11 -30 62 8 7 -86 -50 20 8 95 -72 -125 73 46 15 20 117 11 -56 121 -13 100 45 -16 3 1 -78 95 -115 -13 56 -23 45 40 -14 -52 9 -49 66 -17 5 66 97 16 -27 -94 76 -17 -23 15 69 -3 -100 -100 125 33 -39 123 -77 -81 6 105 -52 0 -47 -3 19 -71 -38 123 -31 25 121 -7 111 73 126 83 -11 -125 53 -12 58 40 62 -20 -56 -43 -72 49 -9 -68 84 -11 126 49 57 -118 -105 14 10 98 -5 -54 35 25 -123 -6 -35 44 -5 36 117 1 66 35 -20 -32 -39 71 -19 41 23 26 -45 42 -4 28 47 57 72 -12 120 9 -56 -107 -53 -64 57 -17 -47 42 -46 -34 -31 -14 -79 -126 12 -127 17 -116 -124 41 -123 -10 -9 -58 -62 15 29 -110 127 -113 -126 127 127 -35 -36 -4 -82 -21 -128 52 56 -25 -8 -3 -67 35 -24 -15 -89 -114 -16 61 53 -1 12 107 -16 -9 42 -128 -33 -28 124 -71 -28 68 -77 126 -12 55 62 7 -127 62 -37 -25 -19 28 12 12 32 -72 12 -40 86 -85 -99 -65 -67 48 -27 -68 60 44 -31 67 108 -58 -36 49 -75 -27 -35 31 55 43 -108 -31 16 -78 121 5 36 127 0 -18 44 -16 -61 -112 -77 24 125 4 78 62 21 78 28 -67 -18 28 54 29 -72 127 91 -1 127 -83 -40 -35 14 119 -4 -56 40 38 23 -4 -16 5 123 63 31 91 -41 102 48 25 -56 124 -39 34 122 18 -4 -86 89 -8 -30 -1 -124 -8 16 -40 127 -110 22 17 -5 -9 -96 41 -116 57 44 -82 58 -12 -55 10 67 37 -104 -18 2 -21 61 -10 87 68 -44 50 13 14 58 78 22 -126 -11 -23 -66 -53 -14 -7 6 -7 -4 21 -83 -107 94 -89 -36 9 -73 -23 -33 -90 -1 66 71 83 -2 -34 -79 83 59 6 -17 1 -39 71 117 34 19 -35 -21 29 -10 63 127 -62 2 126 -11 33 -63 41 -59 -26 13 -10 1 -80 -61 -15 1 83 126 -91 39 22 12 -62 -2 -65 9 -27 -55 -45 -66 18 -118 99 -95 49 76 49 15 65 -25 -24 -44 -59 32 -15 20 17 56 -47 -128 -55 -29 36 -38 99 -7 10 -42 33 -50 -22 37 94 28 -66 4 29 78 51 19 -101 125 -59 -96 -29 -62 33 2 24 -5 -116 -71 8 19 -24 -123 -74 18 -1 -42 109 13 16 -21 -10 -52 48 5 -40 12 25 -126 -63 82 7 -60 -125 89 -127 88 89 123 -1 26 8 62 44 -20 -2 -70 88 -9 -33 122 -11 -43 55 -97 20 43 -118 15 -5 37 -57 -99 48 -9 78 -79 40 -36 -87 -31 10 -128 34 -85 -13 44 -45 -76 -2 28 -3 -19 25 -66 81 77 -14 -24 -14 -37 8 -35 -77 -34 -69 -15 51 -72 -122 -74 19 -5 5 29 -125 28 -94 -83 -78 -92 -1 15 -10 -125 44 -62 77 -12 -64 -103 -1 16 59 -18 72 -124 55 25 -23 -121 117 11 -23 -12 -6 127 21 -14 -22 -98 84 -57 30 -34 -125 6 -19 -57 28 40 50 -37 -48 75 73 57 -4 -29 99 9 -70 -5 71 -45 -34 -49 -50 38 -45 -41 37 -93 11 -25 -64 21 -30 -50 -51 17 118 -3 -70 -120 -62 -36 44 -47 -26 -19 39 -21 -126 -92 17 -127 -37 51 14 1 6 52 -18 -43 -76 39 -27 4 108 22 -42 6 94 78 -67 -53 -34 -53 -15 -13 68 -21 -17 -76 14 125 27 -73 -12 -77 -1 -118 -50 -11 -4 86 53 34 50 53 -19 46 1 -11 7 9 0 70 -83 9 -15 25 -8 -14 -28 47 33 -8 -22 1 4 -3 35 127 -5 -47 126 28 -15 99 -13 52 9 -67 -47 -57 3 -99 -46 -23 -123 -93 45 16 124 -127 -18 80 -62 24 -22 6 17 -126 -68 -126 71 -35 91 127 17 48 -21 -58 -115 57 0 44 125 36 24 -37 1 -80 -18 126 -98 -45 -1 -50 20 73 57 -108 -26 -53 44 90 -24 -124 27 100 54 -31 79 38 127 -99 -37 2 28 45 -39 52 27 -105 -52 -58 -17 -66 -41 96 -91 50 -62 44 -33 49 44 -128 -126 -9 -122 -4 -124 -14 19 -127 78 93 24 25 -11 30 -109 14 17 -122 -58 -51 -95 31 -7 -111 93 35 -98 1 -82 -60 34 23 -31 37 -74 -102 -59 -58 36 97 -46 5 -106 -127 -55 -97 -85 -73 -87 81 -43 44 -84 -105 -126 -77 1 -9 -50 -33 -32 14 -123 -8 -78 -9 111 -21 -80 -65 -20 36 -67 -1 -49 -79 -58 -1 13 -103 -2 -15 52 -18 -61 -38 -42 75 -52 -117 10 -122 65 22 -108 -41 -24 -125 -25 -39 7 9 19 -120 -14 -11 -31 -20 119 -57 91 -58 1 18 -85 -81 18 60 114 3 -36 -20 127 -107 -40 34 -21 -123 71 108 -21 -23 -56 -31 -7 -64 55 -62 -107 -22 78 40 -19 -8 -3 -75 113 -16 -31 -47 -57 -121 -106 67 -77 -100 -5 -126 -127 -115 67 56 -46 85 -39 40 -11 16 -23 -34 -94 30 12 -17 -24 22 -40 98 -12 86 -47 77 6 -26 -23 19 37 -40 -35 1 30 36 -34 50 -27 64 -55 56 -33 95 39 10 -8 -4 15 -76 49 -70 -59 -47 -2 41 35 -31 -16 -62 -9 -128 -47 15 17 23 -56 -28 -33 22 18 -33 -12 -5 -59 -13 19 68 19 -14 127 -85 -22 -126 20 -58 -59 127 -31 20 6 22 -14 127 8 -41 -9 16 -29 -26 18 -46 36 86 28 -16 51 -70 61 -39 61 92 14 -48 -18 87 7 -127 14 -5 39 123 73 91 -90 -122 -66 96 60 43 -128 119 66 1 -47 -50 16 -47 22 15 -33 14 10 -47 112 -110 20 -39 127 68 -52 83 13 -39 -51 16 -71 61 -66 -126 77 -34 -36 -9 -32 71 -44 -89 41 -95 -38 -27 -128 38 31 1 -56 -21 23 -88 -80 26 -30 -57 -22 18 -38 -34 -8 28 -26 -40 -41 15 99 -61 16 21 23 -50 -39 -55 26 107 -45 -47 -53 -24 122 -76 -41 48 -28 11 -32 112 -122 -12 -13 34 -52 -52 -91 4 6 -41 -95 26 -123 -37 -72 25 64 -1 39 15 -58 -74 -32 -39 -103 42 -29 126 -10 -20 4 -13 -2 -44 -62 -1 109 19 -124 124 -77 0 -9 -66 3 -55 17 2 15 16 -35 1 -8 -70 -26 12 -8 -25 20 5 -2 -35 -48 38 -2 22 -32 89 2 7 -4 -33 7 3 -15 58 -52 -5 -11 -17 0 24 -53 -31 0 -6 -3 -22 -33 -57 39 -82 -45 13 50 2 6 -3 -4 -1 1 -127 56 44 -21 19 -86 43 14 -50 126 0 -24 3 -51 17 15 5 -35 -43 -52 55 76 -16 10 -50 -6 -14 62 -56 -39 11 -60 6 -125 -28 -24 4 1 -36 97 -26 24 -18 -3 -102 36 9 47 89 24 11 -46 -103 8 -2 20 -75 7 64 28 -90 -14 13 -2 -32 -10 3 -53 -13 26 -7 -48 -91 18 44 23 -43 16 24 -67 -5 42 -7 64 -118 18 -26 35 -2 -19 52 8 21 -30 37 28 -5 -36 -22 89 23 -25 -18 125 38 38 58 -16 -50 -60 22 -68 47 -86 -8 5 125 -119 52 19 -54 -65 48 92 39 65 22 8 59 -4 80 -124 74 59 -21 70 14 -52 10 61 18 35 74 -71 12 -38 -26 40 -2 35 88 -9 12 41 -21 -51 34 79 -110 -50 -57 -111 117 -3 -27 -75 -22 -81 2 13 84 -12 17 -28 -63 -10 -110 -23 -16 -25 -19 -35 -35 65 -51 -55 -45 -69 -4 -58 37 113 25 0 -63 -50 27 2 12 91 11 -49 -34 30 -5 -38 -9 -62 -1 -61 -21 120 -14 78 110 -73 -43 -20 -56 -14 18 -111 -56 -32 11 31 26 -20 45 32 -13 -15 -51 -35 45 66 -11 84 -5 -83 -3 73 1 41 2 -85 22 60 14 -32 -5 43 -111 -13 127 -7 -27 -3 -33 -10 -12 -22 97 73 30 18 -116 -74 -84 62 53 -58 -127 -90 -61 -30 -61 90 6 -14 55 34 -34 -17 -36 -9 -8 -10 -20 118 42 117 -8 16 -110 45 -83 -65 57 22 21 -125 -81 -17 -4 54 3 63 -40 -9 41 8 89 1 73 -51 103 21 -88 1 -61 -44 -1 -22 65 31 -26 19 23 -21 -98 -88 42 6 27 122 -41 36 -10 99 -21 -45 -47 -11 67 1 -23 -89 61 -5 43 -7 85 7 118 -3 58 16 35 33 -6 -3 41 -15 -32 22 -27 23 118 22 16 -90 -101 -29 15 -52 -127 51 32 -52 10 71 -83 -6 15 -1 -24 30 -43 81 -69 19 -48 -41 125 -72 54 -126 -36 -11 -2 87 32 18 -12 4 -13 55 52 -88 -94 -83 -7 63 -91 -15 -67 8 84 -29 -73 126 -44 -78 35 16 -30 -128 -42 19 -55 -56 46 -69 -17 -15 -65 -7 -52 -18 127 -114 -47 -41 -38 23 5 4 88 -33 18 -128 -128 -117 -15 -127 -35 -26 -37 -17 49 -24 -11 -36 -26 91 53 -128 -121 -10 30 25 102 62 -33 5 -43 -32 -82 -100 -58 3 -110 8 17 76 -51 -30 74 -4 6 -30 -20 -93 -72 14 16 25 39 -25 -127 23 -30 -12 51 53 -99 -10 -14 -22 6 97 -36 -101 -8 4 -54 108 60 -116 26 1 -108 97 -13 -30 114 -3 60 -28 -117 43 -19 -14 16 125 58 18 -55 62 -27 59 26 -48 113 19 -33 -70 -73 100 49 -118 5 -51 27 15 50 -90 -31 15 -28 78 -1 -63 14 112 64 62 45 -46 17 69 -8 50 51 88 50 21 21 65 79 119 -33 -62 -11 -54 71 -51 -86 84 -29 -27 -88 -94 -20 107 -78 -56 -124 -18 -48 119 -9 74 7 -80 -8 -73 -128 127 92 123 -112 -128 29 -125 -46 77 30 -88 36 127 -65 -48 125 119 50 127 105 77 -50 -110 -17 7 -87 -127 51 -77 -14 49 124 -13 -120 31 127 8 123 62 74 64 56 4 -4 81 16 -12 80 14 127 19 -63 117 -51 -101 -61 -127 -98 86 89 41 127 122 -17 -57 64 10 66 22 35 -5 26 -36 4 13 16 48 -108 61 72 44 4 -2 -15 -59 26 -74 19 31 -52 39 -45 -30 27 2 -35 -47 -8 104 34 -30 4 -40 -22 11 11 -68 -23 -64 2 37 -79 7 -11 -91 -19 28 -24 -88 23 38 3 -101 23 -116 2 26 -47 -43 13 48 18 57 -33 -10 -8 38 -16 -60 -74 82 26 -9 -5 20 29 23 66 -21 42 7 -10 -20 -44 -61 2 -8 15 -29 46 30 -44 -35 65 -37 -51 -38 -18 -75 2 27 6 58 -66 -110 -28 12 -21 -79 33 -17 -77 25 34 -44 33 -43 16 93 -19 -12 28 79 -92 27 69 -9 -92 34 -10 5 -46 125 -57 -89 8 -38 58 -7 127 -38 108 42 112 26 30 -14 38 41 96 -22 8 -45 53 39 35 55 -44 -94 -56 86 14 -1 48 0 0 -56 55 -81 17 11 -57 45 122 -66 -27 26 -33 -42 37 -36 52 3 56 -50 -19 13 56 25 -44 22 44 48 47 5 -59 -2 20 -85 22 95 -29 -73 12 0 -49 78 70 -1 -41 26 12 -35 53 -87 -41 -60 -29 -20 56 13 4 10 54 -25 -83 7 4 -54 28 -4 -36 -19 46 22 53 4 -2 -15 -52 -42 8 78 27 -27 -52 91 2 -15 -26 19 -89 38 -6 77 26 -25 -57 -39 27 77 -31 59 -12 21 9 -27 29 14 -20 52 11 26 34 -49 -1 17 -6 126 -15 -22 20 -58 -26 96 93 -75 -39 -39 0 109 -94 30 -76 107 28 10 12 -123 11 112 -23 2 7 -6 -2 -29 -57 83 81 -75 -41 86 -17 56 -27 27 -74 -61 -41 -21 -51 102 88 27 81 -123 48 -58 -87 -57 93 53 60 78 113 -106 -6 46 8 25 85 -27 -16 -52 15 -70 83 8 -127 -22 77 56 102 -72 -6 42 -86 -44 -57 40 -19 52 115 -51 -25 10 -34 -57 -126 -49 125 81 -22 5 -63 0 -23 -17 35 3 14 -65 -94 -59 14 3 -126 32 96 44 93 -22 -91 -11 -44 108 22 -82 39 20 42 61 8 24 9 107 -2 -16 29 -45 6 126 28 16 31 -54 -55 -31 -34 -56 39 -41 -35 34 -66 -6 -70 -31 68 17 102 9 -25 -26 78 74 126 -15 -20 42 62 -78 121 15 -50 -23 52 -48 -55 106 -10 -57 -34 -14 92 -77 3 -19 -90 17 16 -81 -11 63 -1 -104 81 45 22 34 -39 -104 11 51 72 -32 -51 34 4 59 17 35 19 -16 52 -5 22 49 -1 -80 1 -11 -45 51 2 52 -55 14 -8 49 -66 -41 36 9 -66 -27 6 -4 -28 -69 39 54 -128 1 44 86 127 -19 -29 -67 16 -38 -19 89 29 -7 60 -51 -63 -59 40 -107 22 119 42 17 54 -71 114 -82 53 43 16 -60 3 6 -118 -21 13 114 67 114 29 32 -11 70 -86 87 6 -54 -41 -44 67 25 -30 11 -12 16 127 2 -25 25 22 -6 -100 -3 42 -91 30 126 107 37 28 -20 16 -66 126 20 31 -35 28 -5 -98 38 -14 -37 -100 -11 74 -15 -21 79 -47 23 -39 95 29 58 -36 38 -37 83 21 112 106 54 51 -23 107 -61 101 58 -36 -27 -56 -2 -58 -8 17 46 -17 65 -54 35 -13 -11 -66 7 11 53 -26 -4 46 -65 40 -89 126 73 -74 7 -27 59 -4 89 59 59 111 69 -115 48 -65 -110 -19 111 121 -32 91 73 -111 -31 -87 34 65 3 120 83 -3 -122 -67 26 8 48 35 -35 -100 49 45 94 -10 -10 26 -36 45 -98 -105 -35 -21 -106 74 31 -13 77 103 11 20 42 -42 10 32 56 -46 -11 -52 9 -16 28 -63 -9 27 -33 -22 -68 67 11 -127 114 -3 75 43 -4 42 -70 -52 -36 -58 -70 16 -18 17 19 71 -77 -45 5 -91 11 -10 12 -7 -2 -13 71 51 -119 21 -15 53 114 -119 117 97 76 53 4 -16 -6 24 -18 -17 15 -16 -76 0 49 -32 21 -55 6 -3 115 -126 24 21 -128 39 -43 65 28 63 0 -34 -52 -65 -113 -31 0 39 -48 -48 35 -3 -35 88 -92 -8 38 -25 -12 64 9 -42 24 -69 44 27 -2 -19 6 -60 -105 -70 -30 -56 2 89 124 29 12 54 -13 54 15 -117 -31 -14 98 -98 -44 -13 69 9 29 -17 26 37 -38 37 23 -54 38 11 7 41 69 45 -87 27 -85 20 1 43 64 6 -14 -113 48 46 -29 118 -23 44 -98 127 62 16 -107 67 71 -27 -30 -45 -126 -2 0 18 -40 -6 25 70 115 40 -91 -45 122 27 86 54 44 93 -27 87 -31 13 -8 70 -44 -42 45 -17 -122 52 -83 -83 -127 1 -24 35 17 31 25 -71 28 -31 -78 -44 -128 123 -124 -127 -6 29 -61 45 -37 126 103 -30 -57 21 -54 -55 54 -92 -56 -12 31 28 -38 -102 2 -88 127 43 62 -113 19 92 -35 61 -81 63 -11 -7 -66 -48 -63 -43 -6 1 7 44 -29 -68 127 76 -124 -1 119 45 -11 -16 -29 7 7 1 -119 -1 23 -74 125 36 -122 121 -49 15 15 15 75 3 116 13 7 -106 18 -5 -59 -11 -15 -102 -6 97 -46 -125 -37 -20 55 -52 -96 -121 43 -43 127 17 -126 44 -63 -22 -16 -12 -71 -69 -40 -32 48 67 48 -36 100 46 67 66 76 45 -20 28 -14 -121 117 -57 -42 41 -63 55 -83 -82 -33 -124 -22 -23 115 40 96 -127 108 27 0 -97 65 -4 -114 -125 48 -25 10 126 -6 -33 -31 -128 -44 -113 -126 -14 -4 90 -128 70 3 6 -48 46 -12 81 67 -65 25 -19 -121 -38 28 73 11 8 -77 -68 -123 48 9 31 -48 -44 -127 100 -79 124 126 127 -127 119 69 16 -32 -24 -1 -28 120 24 -81 2 16 58 125 48 -60 5 -46 -33 18 13 -108 126 49 -15 -9 38 30 126 -46 12 -15 -32 55 -118 48 -56 107 -45 56 77 -71 -14 -15 33 126 74 112 -50 23 19 -79 -1 -50 39 52 103 5 28 7 24 -76 -112 -47 -6 15 -84 84 61 16 50 1 27 18 49 10 -45 -36 87 -67 6 1 -125 -35 -18 24 49 14 -94 43 26 -52 -18 115 120 -79 44 0 -40 116 -126 12 38 -86 -14 28 -11 -24 44 33 -65 17 -43 -53 3 45 -17 32 -51 64 70 93 21 2 39 -40 -5 38 62 -46 8 -31 4 50 -46 -3 29 48 -29 30 -18 104 21 11 12 -6 -11 106 24 87 33 58 -23 -30 -66 -93 21 -16 -65 10 1 -32 -7 -21 0 30 -61 127 31 0 -7 -12 -127 32 -1 -44 -15 -55 -71 -37 40 13 4 -76 2 26 -15 -40 -82 -12 70 38 -2 -108 -50 -21 -20 19 35 64 37 -72 17 44 42 116 44 49 -13 37 9 66 26 7 20 39 -32 45 -57 -24 16 15 19 24 -11 -62 -74 -8 -81 -5 17 40 -10 1 -16 31 -37 16 -7 -59 -70 -15 -21 16 -67 -19 -31 72 6 1 -13 -95 70 24 31 9 26 20 -1 -127 39 -4 25 -10 -56 -39 13 -48 19 43 -40 19 74 67 -13 -5 3 -40 -13 0 -19 2 -9 16 86 60 63 -47 -2 45 -15 22 -4 64 -31 29 -47 61 -45 27 95 23 71 -43 -33 -19 -31 47 -123 -27 33 -34 72 -102 -40 -29 63 -97 39 9 127 52 -91 -3 22 -96 104 -25 -7 -1 51 5 90 6 8 -3 -13 -10 74 -20 36 0 62 28 -84 10 127 116 24 -106 -2 108 -22 124 -11 89 54 -61 -5 69 -105 2 -22 -45 -43 2 -20 -26 5 -35 30 -89 12 3 31 -4 -65 -33 34 -25 51 3 44 -90 -64 -74 -71 94 -59 98 21 70 25 10 44 18 -13 -123 -126 67 -122 -38 -91 -61 -27 -45 -57 -20 -50 -13 1 -108 -43 19 53 -4 82 30 46 13 33 -37 -55 41 8 -17 -7 62 -20 63 17 -57 44 -29 49 18 -23 -56 -4 -8 -57 -49 -29 -54 -104 -114 16 48 9 -22 54 -46 5 -101 9 73 113 -10 4 -24 16 -57 -84 -125 24 -45 -1 -18 19 -111 -9 33 -65 1 -45 -4 -22 10 -9 37 18 -103 28 -28 -73 -35 -5 -79 -44 23 13 25 -50 -41 4 26 121 32 51 -26 -36 -76 0 44 -34 75 -20 -26 -3 65 -31 -98 -117 -71 -97 -87 24 87 1 35 -125 -35 68 72 125 -8 -7 -26 -21 104 19 15 34 -91 91 44 -118 -37 13 63 54 18 116 4 52 -75 9 21 -113 -81 43 2 -5 39 -6 -57 11 5 54 19 -24 7 0 -22 41 -52 86 -45 -13 -44 27 -96 121 90 75 -30 -29 24 9 0 -27 24 -22 25 -15 25 79 0 23 45 -49 -59 68 -49 12 -6 21 -119 88 55 -6 89 -44 25 -55 8 21 -3 46 -1 -28 0 9 42 18 -25 -4 104 126 -25 62 25 13 43 51 71 -17 1 1 72 63 -45 -20 81 114 -5 68 39 56 125 -62 59 70 45 43 -3 10 71 56 28 16 -67 16 -56 1 31 -30 60 48 -76 -1 -10 -12 65 -37 5 14 -17 105 -35 110 22 -7 3 110 125 31 48 42 -3 83 -26 -30 27 -35 86 5 63 -9 18 -51 100 29 -10 8 1 1 77 -13 35 29 11 88 -52 14 -66 -66 -64 -12 -4 -51 -27 -4 13 -69 -55 60 -2 8 -11 -8 -8 2 26 26 58 -45 22 76 1 -33 10 -58 -15 -40 14 -11 19 23 6 45 -42 31 13 4 31 -27 83 -5 18 65 -2 49 -5 -19 22 -80 8 25 33 -67 -1 57 -19 -4 48 -46 3 -34 18 91 34 -20 -24 -11 -33 -15 -37 8 -37 -67 34 14 27 1 31 3 19 47 14 43 8 -41 -8 -10 -62 -55 20 47 -103 -29 -60 22 -40 64 66 11 77 12 58 -21 -62 -2 42 -29 -32 -92 50 16 10 41 6 38 -27 -62 -1 33 78 62 -17 -73 14 -4 76 31 -126 21 -22 46 16 -29 1 -4 -32 18 -128 76 59 45 -28 -42 3 4 78 53 8 -6 -43 -14 -13 57 16 74 25 -29 -38 -12 -6 -74 84 -5 40 49 -52 3 -12 0 67 -13 1 -5 11 114 -49 116 -113 70 29 -53 125 -9 46 5 -86 -83 -86 41 111 46 -61 127 -37 5 -4 4 -25 64 26 62 56 27 122 37 94 105 2 -19 -16 120 1 -52 35 47 -15 111 -55 17 71 -10 20 78 68 19 23 12 127 -97 -37 126 -89 -126 -19 -125 -17 -28 12 -40 3 -20 -113 121 74 -26 -127 -58 -12 37 16 22 -111 -93 -42 -10 -52 44 0 -25 -84 85 31 -68 -1 -9 -125 62 57 -36 52 18 20 2 -82 20 68 -36 -38 -32 26 -37 6 -25 24 30 34 -125 62 2 -15 -1 -17 15 54 -46 38 73 16 61 -21 83 -14 31 -89 -39 48 50 22 -76 23 120 -112 2 -69 -69 -31 -22 35 1 44 126 -64 83 61 -52 -62 -91 28 44 21 30 -29 -117 -43 23 9 -33 -127 36 -66 -22 -63 32 -92 62 -29 -87 -127 -7 112 127 9 9 -1 4 61 -92 11 10 -128 27 -104 -82 -27 -30 -54 -24 11 -51 59 43 -70 52 13 -7 123 -127 32 -6 44 -59 83 -127 -1 119 1 -80 82 -37 -59 69 35 28 -52 -39 65 117 -126 -64 79 7 -8 100 127 20 125 24 -78 46 -108 -80 124 -5 -9 117 -37 -82 0 14 1 42 -53 -67 -93 -60 44 47 -47 79 127 -25 -126 16 16 -12 -117 -57 -4 95 52 70 -45 -53 -110 -128 126 42 -58 22 -28 22 -80 37 1 -30 127 19 22 33 -126 1 11 26 126 -23 49 -87 38 16 14 -87 2 27 104 -73 -28 15 13 0 -13 -14 47 17 119 103 -116 25 24 10 -119 9 78 -1 88 -63 43 -59 4 42 -1 52 8 -22 -34 -123 -35 31 -1 -82 26 -31 97 47 19 65 53 123 -95 -40 0 89 28 44 -32 51 116 29 101 36 -25 70 100 40 -91 -24 42 36 35 -1 -43 44 -82 61 90 56 6 -72 -70 103 123 -19 -49 -98 -6 28 91 62 -40 125 -83 27 16 6 81 -16 69 59 36 64 -47 -92 41 -50 62 -14 58 -17 -49 123 -23 36 64 49 54 13 -57 56 -28 100 16 38 63 -93 42 100 -39 -74 3 38 10 56 104 9 -52 -18 -1 54 54 -32 -49 -35 -98 -112 29 -63 -26 -15 32 28 28 -18 10 66 43 -51 91 -112 40 -43 -54 59 69 -78 -1 -47 -24 30 3 -42 46 17 -67 51 55 17 -27 -28 77 64 36 5 -51 -36 51 126 123 52 94 48 -31 28 58 54 36 -27 -89 -43 100 61 44 16 80 41 20 33 63 7 62 -17 5 34 68 -121 114 71 -114 -12 4 -75 -7 -12 -44 48 -23 -56 -11 60 45 26 13 -79 116 118 62 16 14 5 20 52 -21 70 8 50 127 55 73 5 27 63 18 45 -127 -9 -85 -10 43 -44 57 -8 -55 -14 24 28 -16 -41 16 125 -16 8 22 67 12 43 14 24 -97 -50 -30 -32 -11 -108 20 -6 91 -1 -28 0 39 8 -66 22 -44 16 -42 20 29 19 38 -25 -10 -110 79 41 42 -122 -41 -39 -46 -29 -16 -50 47 0 27 37 2 44 30 33 -72 -128 -125 -16 -24 31 -125 51 -9 -54 -15 -14 78 37 12 -125 9 7 118 -64 -78 -61 7 32 -102 -98 32 91 -85 26 56 -45 12 57 6 35 40 -111 70 -64 87 -67 -121 50 56 60 52 -81 -34 -46 -26 12 5 30 -1 -22 57 -71 -118 -34 20 -41 -1 63 -53 80 -97 72 124 -14 -89 32 -84 -64 -31 1 -3 -24 84 31 9 9 52 33 -67 -89 -73 83 -69 -25 -77 15 50 9 -97 -85 -62 -52 47 -44 -11 32 57 52 104 10 9 -37 36 6 54 -30 -11 -17 -25 58 20 90 31 -16 -14 -1 6 48 67 53 12 4 -50 -6 37 11 52 -15 -23 33 127 62 0 -19 27 -71 -9 -24 -17 42 -14 4 -62 44 -22 -14 -11 29 113 60 75 -36 5 82 -6 5 -14 13 8 -20 -41 47 17 3 6 -26 96 -23 -20 -29 -26 17 24 -127 -19 56 19 7 42 -6 -3 -5 73 -42 6 0 8 -63 -106 -11 97 -30 -61 -25 -18 41 -19 24 -13 -6 -14 16 77 -52 -30 -88 -29 -89 26 -20 -16 -3 29 104 -4 34 -33 -99 -39 -12 -55 7 -72 10 54 104 0 65 7 49 86 51 -20 35 -52 -12 -9 24 -10 13 33 91 -11 44 24 -2 79 13 -31 -36 -55 -7 -52 15 -85 123 -32 14 -34 -103 -23 -45 -61 -106 2 -98 33 -20 -13 -49 25 45 13 90 42 20 -10 39 -121 22 -75 -12 17 31 41 14 -39 -26 -85 -71 54 -11 -40 -72 -20 -33 -5 -127 55 -26 92 -21 -49 11 92 -12 -52 87 -44 37 33 -31 -56 -126 63 4 27 83 20 -22 63 -22 66 113 41 -86 25 -93 -79 -20 1 -74 -17 62 37 -16 -20 -8 -46 -10 -32 -46 -45 23 -14 81 39 -15 24 -74 31 -57 34 72 -5 30 52 80 53 22 -11 -1 13 -18 -4 51 37 29 -29 12 17 4 19 41 -36 41 -44 -59 91 51 -28 -74 -100 -1 27 -41 -6 -9 58 55 -8 59 12 -32 9 -16 12 -26 41 -35 -37 45 -56 -30 -38 38 -21 -26 -15 6 -28 57 38 -31 -20 74 53 10 -27 56 -53 -9 -73 12 -112 -65 -4 -4 -65 -62 8 -54 -7 -30 -72 6 35 3 -18 47 11 -2 47 -53 9 37 -47 -17 106 50 -25 -26 78 -52 62 68 -25 -32 47 -124 -40 -60 74 40 27 -4 69 -80 -111 66 58 11 -48 55 -24 0 -123 -41 123 -24 -64 -72 4 3 -2 -8 2 -94 19 -34 -3 -38 -66 -84 115 -111 -39 -61 -37 -59 63 -23 -126 21 90 -23 -2 72 -88 9 -3 80 88 93 -128 -113 24 -8 65 -125 86 36 27 -31 -49 -22 69 6 37 66 19 -18 -107 -17 -35 -31 -69 -47 32 24 -21 -32 -55 -40 9 62 74 -101 16 19 -21 -9 72 -26 -16 62 -16 65 58 15 5 -70 14 -46 -112 15 22 8 -123 18 6 47 -60 18 -109 -39 9 44 3 14 68 62 53 1 17 78 -94 -37 -69 -84 12 -43 -47 51 -12 53 51 -22 34 53 18 -80 -30 -53 -29 -83 39 55 -17 0 -54 -45 -29 27 32 45 81 18 30 26 22 55 -105 -17 14 -32 -62 29 44 -20 -5 -78 34 41 -12 -56 -14 -74 13 -12 -11 46 36 -41 -34 -50 17 5 48 9 -22 -31 -2 21 32 51 9 -126 -18 -41 -128 23 71 20 0 25 -21 -7 102 -17 -70 3 -68 2 5 26 -34 46 28 3 -17 85 -10 -8 16 47 -54 -32 8 60 -26 -8 24 -125 -84 20 -19 -86 7 -27 -12 68 -32 -39 -46 -50 85 55 -23 23 -35 89 -30 -55 13 6 -11 -24 54 -9 7 -23 -64 -9 82 -65 -43 30 13 -44 -62 -123 -13 -49 -8 13 77 -36 27 82 -22 15 71 -14 70 -57 -44 -8 40 9 19 60 57 94 -7 45 -127 95 -53 -62 -6 -30 27 120 23 -45 -2 125 -17 122 29 39 -94 -77 30 27 -1 -35 109 30 99 -23 7 105 -8 -124 57 67 -38 43 11 -61 -25 -4 70 -100 24 -94 -75 -25 54 -121 -70 -23 17 -25 3 -121 -42 -15 26 18 51 -63 -60 41 -71 60 15 40 65 67 -127 121 7 -124 -13 -32 -20 -27 3 -65 -34 -52 -74 45 -60 7 5 50 -109 -22 0 -13 -74 -33 -40 -40 67 0 -42 -21 -44 6 -61 0 -61 38 116 -14 -68 -2 -36 72 121 38 -36 -42 91 84 -68 -53 -19 126 -46 -99 -1 13 -2 -36 67 -54 9 17 -108 -16 31 -1 27 25 -114 -42 12 -55 36 -124 -47 82 29 127 -25 -91 -60 81 -101 -90 33 20 -72 14 4 -21 -16 -41 24 4 31 33 -5 99 64 -37 -104 -108 103 4 -5 13 2 -40 34 6 -125 79 -26 50 -10 -30 -4 -88 65 -41 53 -123 -47 -127 13 -14 11 -73 11 -11 16 -56 -46 11 -25 55 44 23 -48 -13 39 -127 -37 -74 45 3 -66 -73 72 65 -19 16 -57 5 -26 -27 -10 31 28 18 74 10 47 7 -2 46 -18 17 -63 43 1 -47 19 81 83 124 58 45 46 65 -74 32 -18 20 -4 30 -82 57 31 52 71 4 -27 -49 -12 -28 -13 -60 1 6 -16 3 23 -30 -6 -40 100 -23 -22 97 79 -116 -4 4 -34 72 -23 -35 93 0 -25 -86 -3 -1 -65 22 -57 14 -128 48 39 124 46 4 -29 -117 -47 30 27 94 -8 35 -22 66 17 31 101 -63 -15 -32 39 -53 -39 68 127 57 -17 33 -5 -21 -12 -51 38 -30 48 -32 37 1 -1 -47 -10 48 -109 -31 41 -14 -18 45 7 -39 -61 4 -68 -36 14 -13 76 28 91 66 -67 14 58 34 39 -15 -74 127 78 -36 -99 -23 -4 -84 85 -100 96 86 -43 44 -76 -6 38 -22 -128 -27 -16 -127 4 117 -76 -21 -42 -28 -18 63 55 -63 21 -16 -110 32 5 -17 46 84 96 125 -90 74 44 -128 94 41 94 127 41 9 -32 21 -77 86 61 71 33 -3 -5 82 -19 29 23 -18 -33 21 61 38 59 -38 24 -23 -65 0 53 -18 31 -24 126 45 30 -49 -33 1 -39 -62 92 38 -15 79 69 107 -35 -5 -50 -7 13 -50 89 60 27 -89 23 -107 -13 53 -60 56 -45 -31 51 -18 -13 -66 4 8 58 -32 -120 17 2 66 63 -68 54 49 72 32 41 23 28 32 -2 -49 4 13 27 -72 26 -22 55 40 72 108 -70 25 -14 0 72 77 31 -23 19 -19 29 -3 -43 15 93 30 28 44 -62 -63 -32 -83 13 126 46 103 3 28 22 13 32 3 -20 -18 54 104 -31 121 24 -44 -12 15 41 -27 -27 -25 -41 -23 123 -43 -16 41 97 47 42 103 -56 44 40 28 29 11 50 -95 31 -46 -83 -47 -58 -83 77 -64 -52 50 -123 18 -27 6 1 -126 -17 44 73 77 88 59 -16 -13 -11 -28 -65 21 61 28 -40 -14 58 -40 -56 40 -39 -31 -60 -21 33 -47 -38 -8 42 -28 -69 -1 34 67 9 3 -43 -10 88 17 62 27 37 9 -64 29 -21 43 -34 60 -5 -51 -23 76 17 68 -25 51 25 -15 -29 -7 -9 50 67 -10 -15 115 -32 32 123 48 34 118 45 52 73 -5 -60 -16 -22 31 -42 42 84 98 -12 33 57 -21 72 8 13 -21 -72 -13 26 -27 77 79 58 34 35 6 61 -14 -43 -10 89 3 -25 -54 27 86 -66 72 -53 121 -31 30 -67 -5 72 -38 48 47 39 1 43 48 18 52 61 35 79 -20 52 114 37 -14 -33 16 23 72 43 43 105 6 32 -101 -12 61 13 52 36 -30 -51 -6 -7 57 -11 -33 26 -23 1 35 70 80 -30 -34 8 -8 42 -17 27 -12 10 23 26 3 -58 45 69 29 0 11 34 1 26 81 -35 -11 19 -64 26 43 2 -2 35 26 7 -42 7 -60 31 -11 19 -24 -11 60 24 -21 12 -21 30 -26 -58 -16 -12 -22 -18 -1 -4 23 -44 -16 87 29 -37 -10 42 33 63 -12 20 -25 -50 9 14 -16 -6 9 -35 -21 34 -30 -5 77 46 36 9 -9 28 -23 -92 7 6 26 4 58 31 89 66 -17 -26 -6 4 64 63 -62 -34 -20 41 88 -1 10 4 -27 91 -63 43 -19 -69 127 -27 -16 22 28 108 -33 -32 -23 -54 21 22 65 -38 71 -23 14 -13 -30 -62 99 8 64 18 -13 -50 65 66 -39 31 70 11 -29 65 -24 14 -122 0 21 -39 21 -35 -22 40 23 -39 -51 30 -78 -35 26 -51 10 4 25 24 58 27 30 75 126 -2 -16 80 29 -19 99 21 -63 -17 -123 -31 -12 -41 102 125 -3 -83 -26 13 -32 -124 16 5 -35 -11 -24 -111 -60 -20 126 -43 -112 -29 51 39 -45 0 14 -17 25 -34 27 -94 15 76 -87 31 120 60 19 -39 54 19 -54 -40 16 -9 45 -43 -100 96 -117 25 58 87 21 72 -12 -60 11 104 62 -18 12 22 28 126 -44 14 -76 -58 -116 66 -3 127 -76 -38 -67 49 1 -2 63 -3 -31 53 106 -101 44 127 -6 78 11 -126 21 27 -29 43 96 -120 -58 39 -16 -92 23 -75 -99 -28 -118 4 -36 3 -27 -30 -77 99 16 -3 67 -125 104 -21 -71 -127 34 -50 6 111 126 -81 -109 -51 -105 27 -26 7 -9 42 75 75 -58 -16 -82 -9 27 47 49 -95 -99 18 -127 -54 -16 -28 -92 -10 75 -51 47 -23 3 -49 -111 -44 -126 -28 116 -85 -23 -13 -10 -48 -28 56 -16 -16 57 13 1 -125 -38 -2 -8 -45 -95 127 -54 2 55 82 101 -33 -17 -21 -107 69 -87 13 -41 -54 63 41 22 35 -44 59 31 17 8 15 127 62 -36 -18 -23 88 -32 -11 70 -59 -110 2 48 31 87 36 -44 -91 60 1 -56 112 -28 -49 68 -54 -30 -22 46 32 63 -23 -55 -32 3 -47 -59 -29 -11 -58 91 -28 55 91 46 -45 -9 56 -83 14 37 22 79 -16 60 -13 47 -15 61 8 -50 -12 103 -80 -26 -33 24 -38 43 12 23 -45 -69 42 71 -14 31 -26 -76 24 13 -5 90 126 70 29 -5 10 38 -126 103 44 -31 18 -3 -33 -101 43 121 9 75 -58 115 76 -14 -58 -7 -1 -47 -36 -11 18 47 108 127 -16 127 -14 -78 12 -55 -7 8 22 51 69 51 -97 -105 11 -21 -65 93 -59 -10 -3 -54 -30 -2 74 0 3 -1 78 8 -8 24 17 55 -16 -109 42 19 29 71 -75 1 -22 41 60 -41 -14 22 1 39 6 55 6 40 58 -42 27 44 -83 -50 -79 -39 -5 -70 89 77 -66 75 -125 -100 -6 -69 22 24 -32 -12 80 20 53 52 32 -17 125 94 -85 -70 -90 -35 -23 43 72 43 -43 -9 -56 -10 -69 -28 26 16 11 -28 106 -26 -19 -28 -17 83 38 -42 -40 26 32 -17 8 -75 11 -11 -112 93 5 103 -35 -28 34 -91 -13 -28 -31 17 4 121 -69 -3 51 42 52 67 -29 30 34 -22 -57 45 -50 97 33 20 -11 -3 -27 -34 89 11 48 21 -58 21 -18 -20 0 0 -36 21 37 -44 -24 -75 127 -64 -8 -90 36 -72 -53 44 38 53 -29 -54 39 42 -20 -81 89 -107 19 7 67 48 18 29 -78 6 107 -52 -23 27 -56 -60 71 52 -19 -65 -37 -58 -22 -35 -60 -52 15 -6 -54 -9 -18 34 3 96 -27 -35 -41 -12 -25 21 55 30 93 22 4 32 27 13 76 -61 -24 -25 10 32 -12 41 -96 117 109 -34 55 -61 75 54 37 -22 39 -78 -69 34 17 -12 -69 76 -21 -27 48 -20 45 21 -35 -11 -17 -24 4 35 -85 65 37 31 -7 6 -34 35 -45 -26 -29 -2 -63 69 -9 69 -7 89 61 18 -84 -17 39 -26 42 -46 16 -39 -90 99 -20 -75 124 -60 -69 -6 28 1 51 65 -91 -20 -3 15 67 8 63 -65 -26 -99 44 82 8 6 -86 37 -48 86 60 110 -47 23 -34 116 -50 16 -49 -30 109 -51 -45 -55 -18 35 7 -24 37 0 109 58 45 71 -31 -45 -52 42 7 57 -94 -21 -52 93 -71 -68 11 88 -72 -14 -59 -62 32 -11 3 -20 7 57 -86 13 -99 -50 -28 52 93 111 31 33 -50 37 89 112 -61 -18 -33 -31 31 -53 -100 10 -16 -75 -16 80 -21 -38 16 -62 -32 -72 -80 55 -70 -28 -9 -2 -56 -100 -104 103 94 -52 78 -32 -74 12 61 -60 -38 -109 -102 16 116 -73 -38 -35 -98 48 14 -8 -18 9 87 127 -22 -55 -16 -54 -59 24 53 -119 3 -46 -83 15 126 31 -74 42 73 107 35 26 14 -120 -122 30 6 8 -14 126 119 -9 -66 -65 112 -84 -59 29 1 -66 74 2 -37 -8 55 -37 124 127 -67 102 -117 -16 82 59 92 93 86 123 32 -17 78 -29 -119 -8 -72 -109 26 -54 -121 111 -40 -81 -73 -12 -21 -48 33 -21 -114 -76 -80 8 -26 -32 -30 2 29 21 -124 -112 -118 20 24 -7 14 -15 56 -126 -124 115 126 116 23 -57 -32 -41 92 59 -15 8 36 36 36 -83 1 1 74 69 -18 119 93 42 -79 -2 20 115 -26 -1 7 15 127 14 112 -81 14 121 -64 -104 53 31 -128 30 97 37 52 3 -87 42 123 36 -17 -23 18 78 27 16 -18 -52 43 -32 125 -62 31 -14 -22 -116 -126 -33 -41 -127 42 -36 14 -42 -14 -60 23 55 -97 -6 43 -25 -18 71 -20 37 65 -2 39 -108 13 80 19 19 -126 25 -106 -22 -62 41 -66 32 70 -29 -53 -125 124 40 34 13 125 119 -69 -102 -21 -15 53 31 5 -101 -85 -18 -27 -73 -4 -65 -40 -54 -2 12 -20 91 -21 82 33 34 123 -16 -4 25 -9 59 -6 -116 -41 93 -38 -7 37 100 -98 111 106 34 -20 -29 -105 -16 14 -32 33 54 19 38 17 -62 7 -61 58 51 0 -109 35 -65 4 -48 -3 -15 106 -102 6 -32 -42 58 -39 40 -4 110 -44 -8 97 -49 127 -21 53 -10 -79 -19 22 58 -87 96 16 79 -36 -15 33 58 122 -89 -6 1 93 18 100 43 66 -28 116 111 3 31 104 7 2 70 -33 -62 5 127 -118 49 -33 16 -20 35 55 -67 -52 -6 67 -66 51 -21 44 14 -48 -13 53 22 -79 90 -33 -35 36 -56 -52 126 -13 17 12 -37 0 -121 127 -50 -46 -85 -12 -126 17 -18 15 -25 46 87 -53 -17 -22 90 77 0 10 54 74 -3 -12 -79 -2 -72 15 -33 108 4 -112 2 9 -28 -125 -25 -36 57 -48 -10 -31 124 -97 48 -18 -72 -31 45 29 -22 126 79 63 -5 -98 68 5 -66 13 6 27 25 65 46 -33 3 -52 61 22 82 74 36 -23 -92 -46 -34 -31 46 6 11 -43 -42 8 6 -26 50 -62 79 -127 -18 103 6 54 60 -88 -28 19 -31 30 -97 -52 -57 15 98 18 16 29 96 11 79 -18 9 21 105 25 -32 -18 1 119 -78 -15 -73 41 3 -33 64 -115 -92 18 -110 23 38 -61 -18 -3 -73 85 -2 90 69 66 -92 -30 88 -71 69 -127 -17 35 39 52 29 -104 -77 -122 -77 4 -22 1 1 -106 -25 79 69 7 -74 21 97 -12 27 -79 -93 27 -79 44 82 29 -34 31 127 -6 79 78 -3 -81 -66 62 -62 -21 -5 47 36 -43 21 11 48 -54 39 14 64 11 -41 -102 86 -10 60 127 -73 105 12 -77 -13 86 54 -77 -101 -55 -35 -33 29 8 1 11 -122 15 -79 57 -22 -32 2 -43 -11 -22 65 12 65 -53 14 83 -85 -5 11 38 -56 -34 46 15 81 -7 1 -99 40 -5 15 2 16 17 -100 11 50 -94 8 10 87 68 56 85 -77 50 -75 -57 4 -50 -96 8 27 -7 11 -32 -73 -25 -5 7 24 -7 109 27 19 64 -5 -69 -8 -49 -18 -88 -4 6 74 47 80 -45 -124 15 -66 -58 -44 40 -86 28 -38 -17 59 22 -116 -70 78 -16 70 1 4 -64 71 28 19 21 -18 16 -26 10 -40 -46 4 -16 109 19 4 14 27 -40 -43 -124 30 77 46 -26 -18 24 7 41 -26 0 -26 -99 78 -60 -71 36 -57 -119 15 60 25 29 -79 -88 61 -57 -83 -22 -48 17 33 -2 -127 -56 103 -45 -40 -42 60 60 34 2 -13 15 -24 -24 30 -25 -90 57 -127 -9 19 -80 -78 -70 -47 13 -24 -14 -49 -120 -4 75 -25 48 33 -43 58 108 2 18 54 26 -38 25 20 13 -60 6 100 96 0 5 62 -127 14 -37 54 121 -3 -3 29 18 -74 -70 52 -127 19 50 -107 -18 -31 -9 -21 48 -38 38 -28 -104 73 -27 -68 -51 -12 -35 -11 16 -11 -126 26 49 -110 8 1 -52 -28 -71 -2 -37 -28 76 78 -10 -14 126 71 4 31 73 -15 -28 -39 37 -3 -48 41 -98 22 123 -128 -54 -4 9 -33 -7 -117 64 8 44 38 -124 -84 50 60 -126 0 11 88 -23 -128 -18 73 5 19 -21 25 -70 28 31 32 13 73 -45 60 32 -58 70 61 98 13 -11 6 127 116 -118 37 7 -62 -46 127 5 79 77 -37 5 39 -56 127 -4 27 -9 16 36 76 26 97 -24 8 62 -11 -55 -5 31 -36 13 -128 -52 74 -35 -1 -23 -65 16 -17 -24 26 67 -57 -127 65 29 -38 -50 -13 92 86 -117 81 -41 -33 116 16 125 48 -70 -49 82 -26 -12 -21 -116 36 15 74 13 -39 79 87 120 -96 -37 -74 -16 -6 97 -45 -27 -4 -20 -79 -49 -45 -15 104 10 -70 -37 -52 29 -60 -53 -24 -61 -48 -4 72 -26 69 80 -51 -32 126 -10 74 54 -43 54 10 -67 -32 -3 -63 -20 18 101 53 66 -65 -78 1 -41 -2 -126 7 -100 -24 -50 -18 -93 -57 57 53 -29 -2 43 -85 -7 99 46 -2 -44 -101 -24 18 -53 -3 3 -36 -7 89 -22 -7 -83 119 -90 -74 23 19 -63 30 -65 -14 56 -21 -14 -17 -87 20 -122 10 -40 17 27 53 79 -98 -32 13 95 10 -27 15 22 10 -66 87 56 -13 34 52 -62 63 -123 -55 -37 -3 -92 26 -125 -32 66 -40 3 -23 40 -90 -98 -6 4 -51 49 -75 42 -68 18 58 -78 -113 46 -83 -9 -50 -4 107 -47 0 124 -44 -101 62 -9 3 23 -18 -11 -71 18 -83 24 8 -53 -24 15 -8 -85 61 -56 -26 57 124 23 -32 -21 -24 56 78 53 -45 -7 -8 58 23 -15 38 -16 -36 46 -1 -65 14 22 -13 12 -56 27 -19 -31 37 1 24 44 33 95 -5 -111 -15 -10 -99 33 38 -22 -14 62 -25 -4 -33 -25 32 -47 25 -50 15 15 -125 14 11 -5 1 -124 39 -21 -68 -21 -12 -4 28 -11 0 -13 98 2 -55 -103 47 25 -10 -30 -101 29 20 6 -6 26 13 -15 53 0 19 101 -39 -32 7 40 -9 29 -67 126 77 76 102 72 -1 -42 46 -24 15 47 33 -19 21 67 65 60 28 119 50 -47 -59 -35 51 20 -88 -20 104 117 24 -122 24 -50 -27 46 -23 29 42 110 28 64 126 -78 -3 69 -18 43 29 79 11 14 55 27 -43 68 25 107 36 22 53 26 -44 -42 -26 -58 92 86 31 -60 96 51 70 -123 74 91 -66 -12 -17 67 103 68 66 94 -5 92 3 -54 46 -58 35 77 -15 -100 43 33 20 50 -18 49 -75 20 0 33 0 -6 -9 16 31 41 -11 -75 -12 25 -24 18 -63 11 42 -10 -12 -2 1 -48 16 19 -28 12 34 35 0 -70 -124 81 11 -18 -12 -62 37 55 -55 67 23 5 103 64 -35 17 -126 125 -55 -42 25 7 88 -61 12 -23 -71 -14 -104 -27 -35 64 49 37 2 -40 -21 -36 -10 -7 -16 25 24 -46 10 14 121 -108 116 55 62 11 -30 -1 55 14 26 -128 73 47 80 26 71 44 -12 -69 -110 121 16 127 -43 -125 -46 16 -48 1 -46 -64 -27 94 -18 -32 28 -70 34 23 -86 -55 65 18 -28 -77 65 22 -30 -58 127 78 -57 -51 32 -88 -77 -50 -44 47 7 10 60 -13 -127 9 81 -18 -42 25 -37 -113 -128 41 23 -70 73 -24 91 46 -104 28 55 25 4 -86 60 -49 -23 -42 5 44 127 101 46 39 24 0 -47 -20 -45 15 -49 -25 9 -19 -117 14 -31 -34 71 -83 -128 -11 -29 -61 -96 -69 -93 -102 106 17 -89 -60 -13 10 -10 42 -1 -99 -124 8 -108 -2 -121 -48 126 -1 -4 -33 41 97 43 -20 -84 -40 5 9 -42 -112 120 44 -103 -112 -10 26 9 -108 -27 21 -14 -32 10 81 -42 -19 -109 88 4 -46 79 -105 37 -110 -27 -23 -40 -3 -29 -5 -21 18 2 84 0 -36 23 46 -68 27 -52 -17 49 -28 116 -6 -30 29 61 13 -41 -100 2 -4 -12 -52 24 56 67 95 66 10 25 -14 -37 0 -26 -23 -9 -51 57 33 -1 -8 71 105 11 -10 -49 -5 -14 -46 -56 -127 -22 -4 8 -55 6 -111 46 37 -12 -6 -78 49 -8 93 -26 -22 5 37 -78 -69 -118 22 -32 -65 13 -98 -37 -62 4 -16 -3 5 -57 45 -7 63 -75 -128 -51 -15 -36 -41 -9 -40 -55 63 -85 -8 -13 -20 10 21 5 -6 -55 51 -67 -54 3 10 -44 127 -7 -50 72 44 22 3 77 41 -127 -20 -31 32 -66 54 -114 -55 -28 -4 66 -11 8 -10 -29 44 37 92 -23 -45 -33 118 19 124 15 -63 50 24 115 81 41 29 -29 3 -61 1 -6 10 19 29 -3 -25 -27 -5 -23 40 -28 5 -42 -41 52 -35 42 -15 56 17 -1 -12 15 58 -53 -9 -127 74 38 -61 -47 39 -19 -8 -37 -25 -20 39 -14 -56 51 42 29 -63 9 70 39 58 71 -35 99 -21 -27 14 37 -9 -48 -61 2 -93 -8 -108 -49 -72 -1 -101 -78 33 -54 91 -19 100 -84 35 72 10 20 61 -67 -37 -61 119 -74 26 14 3 -57 50 -46 103 16 -15 74 -20 -16 -8 -64 -10 57 5 61 -51 18 -7 -42 -46 -35 -21 -60 -125 -63 28 -19 -66 36 14 36 21 -52 -41 -31 -82 14 -103 66 -70 -18 -28 -50 27 41 -32 -10 5 119 -9 -44 -57 33 -96 5 -5 -9 -20 -127 -11 60 -85 8 -47 -108 5 -56 17 12 46 -32 9 -18 -9 57 5 90 17 4 2 32 14 -38 -29 13 22 -31 -39 -37 -5 -8 28 79 52 60 -20 -42 -48 29 -102 -18 11 38 47 115 -24 -6 46 -21 0 2 -38 -85 1 16 44 -76 -3 59 109 12 -127 52 121 -92 -20 -30 53 -5 -45 63 -38 -5 73 -7 -84 -32 33 63 1 18 37 -4 64 -15 36 -18 -1 13 -86 -12 17 -94 28 -60 -33 126 -23 22 23 -43 46 47 -109 -33 110 -68 36 86 109 -73 93 -32 -127 -15 127 -89 -122 52 12 99 -60 17 67 -11 -31 -33 127 -71 121 24 -67 45 -81 71 127 -65 10 35 16 -40 14 -78 -2 36 25 -76 -43 9 -85 -61 0 -73 100 126 -36 -21 125 6 -127 72 28 -31 -27 -31 -17 -127 -52 -97 -61 98 -127 -7 127 -27 -99 -93 6 -93 26 -36 -85 -51 -85 58 -119 23 127 -13 65 -64 -126 81 94 -111 -21 10 -20 9 113 -85 -27 -23 -51 -23 3 31 22 9 -1 -77 -73 -45 -20 -64 -49 -9 -91 -67 46 -34 -32 -11 56 -80 -54 -39 -120 22 29 27 -50 54 5 -60 -90 -116 -54 -98 -40 -79 -82 -82 32 -48 9 25 -23 37 -7 -126 40 32 -53 -124 -23 -75 33 5 -16 -5 -42 -94 29 48 46 -29 -38 -79 -95 -127 -32 -83 -51 20 2 -73 -42 -14 -11 -123 -2 93 -50 28 14 -27 -63 -10 -115 -21 8 40 28 -51 -2 -61 2 27 -3 -62 -25 -24 2 11 35 66 36 -35 68 24 23 28 -43 -26 51 -96 -48 12 -18 -8 -68 -69 -70 -43 39 4 42 8 2 -4 -4 -35 29 26 -15 -28 19 47 6 7 32 20 -46 -90 57 14 4 19 -2 42 5 65 -16 12 -20 17 -57 -14 12 -8 -66 22 -35 -59 -47 14 21 -22 40 34 55 -20 -7 -29 -34 8 -27 -18 44 -9 -19 -10 7 -92 0 54 -48 -15 -40 67 31 126 111 -69 37 -87 85 -23 27 119 26 -61 7 -43 45 31 23 -48 -127 -128 59 -55 112 -84 -106 -36 58 -61 27 15 124 -25 -103 30 -25 -15 17 3 28 21 6 5 -46 -28 51 -78 56 -61 -1 -5 -115 -68 -1 21 21 -44 61 -63 -84 67 -55 127 -65 13 -12 114 57 -126 6 63 40 -120 4 32 -18 19 -67 64 77 38 92 60 -46 -29 -35 -13 108 -22 3 14 -17 -38 -126 51 22 -125 -45 59 4 -115 57 -36 -88 -55 -16 54 -13 82 91 58 12 -39 -24 -60 27 119 -27 31 -16 19 -12 -93 -72 69 -89 106 -40 -30 -30 57 -80 -54 -82 17 -7 -40 -117 -26 -85 24 -27 52 -15 127 -97 19 108 -40 93 83 -28 40 37 -3 -8 -11 127 -65 50 80 32 88 -64 -69 -123 -127 -74 124 120 10 -41 33 77 14 -99 -2 -115 -30 48 11 7 69 -101 28 125 28 -19 -92 -40 48 41 -72 -107 1 -35 -47 90 6 -3 11 6 -30 18 12 -6 15 17 123 70 54 20 44 34 -33 -102 46 55 70 98 -77 -127 37 -88 -49 -117 15 -62 -29 114 26 -36 -52 24 27 -74 36 -24 -23 -67 -60 23 -127 -73 -6 -66 -101 -125 -13 43 -21 -86 18 1 -7 -62 -58 -15 -33 -125 47 117 14 1 48 -82 -12 -32 64 -88 -39 68 -21 -13 -73 22 -26 78 47 -37 -28 -110 -94 116 -91 46 0 60 -89 -126 7 -17 -121 -58 24 110 15 124 127 -70 -53 -77 49 -96 35 36 26 41 -120 23 -96 11 -84 127 111 104 125 125 122 -30 -78 124 -68 -5 -60 -49 91 24 0 36 57 45 -125 -91 -12 -17 125 -106 -72 125 73 -127 6 127 6 -10 93 66 -90 35 -127 -85 -128 -8 -127 96 80 -33 -67 -77 -18 -59 -66 -5 -52 -107 35 -3 15 -128 -44 50 108 96 7 -88 -60 -48 -10 74 22 105 53 93 40 33 91 104 86 51 37 57 26 10 114 -26 12 103 68 -39 -19 34 37 -38 -39 48 -5 4 -11 -98 23 -25 -117 42 -73 126 32 -126 7 -42 -20 85 48 -10 103 10 -68 52 44 123 12 4 120 6 30 86 10 -60 68 23 -29 60 9 33 -62 27 -6 19 50 19 -10 61 -67 36 48 -38 42 -12 -14 45 -24 1 -28 43 53 8 127 99 6 -5 54 55 -41 -17 -5 121 -2 4 127 38 -24 13 24 -123 25 -86 59 -79 13 23 63 -21 -4 -29 6 -13 -79 -36 17 -27 -10 86 29 10 -10 -112 25 57 16 55 61 24 -96 87 44 36 -5 -39 -72 -49 7 -11 27 -53 20 68 -27 -24 46 0 11 6 5 -25 -14 118 -5 2 77 -12 -15 26 -5 23 -14 97 99 -9 -68 80 12 -56 -66 -55 -61 23 54 60 70 -23 -1 6 10 2 42 -33 72 20 -41 -28 42 28 77 -25 -26 -57 -14 53 42 22 60 126 21 -85 -9 -13 -39 70 67 -16 -67 -9 -126 84 -18 -26 -14 125 52 -90 -56 2 -17 -72 32 -56 55 70 14 -63 -97 -39 -8 3 125 35 -41 -10 -69 -15 95 59 -34 32 20 -27 53 12 -13 -29 6 -128 40 -22 -26 -13 82 82 -28 22 32 14 88 -37 -72 -16 66 11 0 -37 35 -95 39 6 -3 67 14 8 28 -16 -19 -1 48 116 -30 34 60 -38 3 -105 35 -29 30 -39 6 81 98 -41 84 -10 107 21 22 87 30 45 -33 -10 0 -7 24 38 42 127 71 -48 125 -104 -23 -120 12 -30 21 -25 73 24 22 0 97 47 -23 -117 -91 -125 -123 -8 2 -20 18 92 -124 -11 108 -1 -14 -31 71 -64 -104 47 93 -37 -14 98 5 -37 60 17 48 64 -49 58 1 -7 48 -2 -73 9 51 -9 -25 51 30 10 -31 44 -92 6 -38 -125 41 95 -37 -17 -125 -31 28 41 -51 -28 -7 -58 -55 35 27 -81 -16 43 28 -16 7 -9 -26 -126 -49 20 -1 15 -4 -103 -42 -91 1 93 107 -39 -61 81 -127 -26 64 -40 -14 126 -19 74 -23 -94 60 -41 94 14 -15 30 -23 -43 64 -27 -27 6 47 86 122 126 126 47 0 -111 74 -38 38 -23 -45 23 -117 127 42 -107 -30 -5 -96 98 7 -61 -28 80 91 96 2 -46 26 -7 -3 46 30 -37 22 9 -34 -124 -36 25 -20 14 -62 31 20 64 117 -71 83 20 12 8 35 -102 -31 -80 -5 -75 -60 27 30 -7 -112 -73 -21 26 24 -59 -13 -14 86 30 75 3 -8 -5 -17 -78 3 45 -30 52 -11 -68 30 75 -23 95 16 39 24 -61 -50 18 -14 -11 -12 78 -24 -51 70 25 -123 -36 -87 -52 -117 2 22 -79 58 -63 -3 -122 -21 -69 -64 22 -62 7 -23 -83 -105 -21 13 89 77 1 -126 55 35 -63 -113 -2 2 -62 -34 10 0 91 -35 8 1 116 102 98 75 20 -6 -10 80 123 -11 24 71 13 117 61 10 -17 -47 -47 38 1 11 -30 13 12 9 -62 52 14 61 27 84 25 -3 46 33 6 31 29 -4 -12 -108 -29 5 -51 42 86 62 23 -16 37 -62 -16 11 -5 2 48 103 -80 59 -119 -2 -72 48 5 81 -25 -15 0 126 11 -13 -18 -77 20 73 48 0 -10 34 98 -6 -52 -3 74 -99 -5 12 25 -54 -7 -28 9 9 56 19 15 56 29 -7 -9 48 -21 -15 50 63 -26 50 17 -60 7 -50 -111 48 42 -23 -56 18 19 -9 63 17 8 -14 13 19 15 37 17 41 -98 37 -16 64 35 32 -8 71 -70 -80 43 3 76 5 -28 -58 -23 3 -86 -89 25 -27 -27 -39 -60 -33 4 19 94 -8 -26 -4 27 -6 88 -29 45 -47 23 -18 0 -23 22 -28 -30 40 126 -51 -23 30 69 2 13 -52 11 -58 40 50 6 34 49 44 46 33 -16 -4 -19 -58 -2 123 110 20 -39 -82 40 68 0 -38 -24 18 3 55 102 -9 48 89 37 -27 -11 -3 4 -5 -33 125 -42 -34 49 6 -24 19 1 9 19 59 -93 56 71 41 126 38 -115 -8 -7 -13 -56 -46 0 -20 -34 -9 6 -72 -43 20 -12 36 -83 -19 93 125 -29 -71 20 15 46 6 -79 2 -63 -21 -3 59 89 96 29 57 44 -37 63 -3 -19 79 -128 56 23 -7 29 -15 6 -15 -100 -50 -108 -33 33 -11 -3 -9 47 18 16 15 -8 14 -102 -66 17 -9 9 -80 -11 -6 -95 3 -29 -28 -1 16 11 -22 0 -44 -59 -10 10 88 -3 5 -72 -95 -2 -27 -111 -44 22 19 -122 -35 -16 -51 46 -17 -127 31 -13 -25 -27 13 -124 -33 -45 -23 28 7 43 -6 -20 2 -44 -103 39 -99 -18 -55 -20 -76 -27 -8 97 28 -57 -50 -106 -19 -68 31 -12 -76 44 -32 -7 60 -73 -46 -18 3 34 38 76 -9 13 75 69 -14 20 -64 47 20 -56 -16 -34 -13 -2 13 69 48 61 80 -6 -31 40 4 -68 4 30 -73 0 47 -3 -7 8 -30 33 -25 -62 32 96 31 -34 -47 -87 23 34 98 -83 36 3 -90 9 50 -18 -31 45 17 -69 5 21 21 -22 67 4 42 -25 -5 -19 49 -65 13 -64 -25 -20 -1 -7 32 43 -23 35 -2 33 7 83 73 -29 -4 60 14 29 -49 19 -90 -79 48 54 -36 105 -38 -67 61 92 16 -13 42 -75 94 -41 -55 -102 7 13 10 127 -14 -12 96 -11 -27 -15 -7 62 -5 -26 47 -8 -128 -20 -113 -54 4 66 -86 59 41 -126 -33 108 -2 76 47 -90 10 -22 69 69 -27 -15 -36 5 36 -24 -77 24 -21 86 92 -62 -32 -29 -67 -54 -94 -38 -8 126 -54 -128 4 -124 27 -30 -31 127 -29 26 42 -7 -42 -67 -36 39 45 -51 41 27 -105 -36 -123 -111 -47 16 -3 -80 3 -22 -18 91 30 65 -17 39 123 35 39 -123 -68 -12 -11 0 -74 -47 -9 71 -44 -23 -46 97 -35 2 95 -24 46 25 14 -3 28 -50 56 10 -38 -33 -12 -75 -125 -126 -36 -127 50 -12 -48 -124 -9 -73 -30 -50 14 -69 14 -85 -70 -43 51 116 -6 23 -98 19 30 -57 0 17 59 80 -27 74 -68 -99 56 5 -126 -40 -125 -109 82 47 50 3 -20 64 27 -40 47 -63 46 99 120 -9 28 -90 -11 -103 69 -116 -19 -34 -15 -24 33 -66 116 97 -27 -95 38 2 -5 118 -31 -78 -10 -23 19 31 -2 -82 -27 -51 -112 -3 -8 125 48 104 90 -25 -127 -29 -31 -51 35 109 21 127 35 10 -67 38 -18 12 -19 36 -121 -22 63 126 -42 -46 5 -126 -40 5 -91 10 52 -8 -9 37 121 98 38 37 12 102 103 39 -86 -24 -102 5 72 42 -45 -93 21 -52 13 34 -25 -7 -55 -126 -127 -30 16 -61 -124 25 -127 -11 29 111 125 2 -112 -17 29 43 -34 -69 26 -128 71 -32 -29 -6 -125 43 83 -124 39 -59 127 -5 32 126 3 -56 -19 -112 19 12 -31 -6 -93 28 68 -128 -29 127 -25 22 86 -37 -31 35 33 71 9 96 8 -75 -2 -22 -127 99 -33 53 -5 84 19 5 45 -122 50 111 -12 127 69 -25 25 -127 -128 17 24 -128 -33 17 -56 80 -61 14 -59 103 -37 -75 32 91 -57 -126 -50 -101 -17 -21 -29 -52 -106 70 -40 62 -13 68 34 -78 43 127 -32 0 46 -57 -41 69 -74 38 -31 -74 0 28 46 -89 -13 4 -69 -75 -35 20 124 -14 -118 -16 29 99 -22 -31 110 25 -104 101 37 -25 97 106 -66 -47 5 -12 -18 108 -119 79 42 33 26 98 -26 33 44 89 -24 -57 -53 -2 4 -83 117 52 -22 -60 126 9 -39 -3 117 -18 56 -18 21 92 -68 39 2 120 5 -117 23 -45 -2 -27 24 48 -81 114 77 -51 6 -40 18 -5 -107 14 1 -34 -34 -75 -10 -16 53 127 127 86 -60 38 -35 -19 -12 70 4 30 -12 -96 2 -65 124 69 94 -78 -35 101 -49 -88 65 37 -92 23 5 121 36 -7 -128 51 -113 -60 56 43 127 -13 48 16 -9 -44 16 67 21 122 -13 75 70 -106 63 86 -28 -101 -101 124 -48 53 -6 -52 123 -120 -126 33 39 9 26 -30 -62 -127 -27 -47 -109 48 126 -78 11 -58 -47 87 1 -125 127 -126 -120 127 127 19 21 32 -108 59 -11 -43 -33 -26 23 -31 19 -68 -7 24 -35 -23 -127 54 -5 -62 14 3 -104 -78 74 -72 -22 57 -112 -48 -43 57 58 127 35 -74 -25 45 -115 -7 7 58 -90 22 -14 38 126 67 -8 -48 5 -41 -124 -9 -50 -5 -1 -30 -102 27 -127 49 113 -55 5 72 6 -32 -29 70 -49 29 -32 51 89 -40 107 115 29 52 108 -28 -7 -66 21 47 42 49 93 32 43 31 27 89 19 -53 -41 87 28 -81 9 59 94 -47 99 -35 30 124 85 -6 59 96 54 3 58 -34 -14 -35 95 -22 -29 126 -61 -110 0 55 -2 -28 19 114 58 35 8 81 75 -125 -4 -42 69 19 28 -40 37 -49 75 84 57 83 89 42 30 43 -18 -33 -16 45 -64 -56 -10 -8 1 -53 10 113 -11 -6 -34 4 -75 14 -10 -49 19 14 -5 -40 31 -7 -41 2 -22 -2 2 -67 3 -39 7 35 15 -68 20 -91 -6 -14 -6 -25 69 -8 28 -22 21 -81 -37 -49 34 12 -49 12 61 -10 42 19 -72 -30 -42 -21 -16 -22 -38 41 -69 -47 -22 47 -35 19 28 2 12 14 -45 41 -67 -14 17 4 30 68 18 -32 -15 -13 -28 -33 -66 49 7 -79 -76 32 5 -61 43 -15 -23 34 -92 -6 -21 -12 6 1 -72 21 -22 67 -69 -54 -34 -54 98 -50 99 9 125 28 48 -49 -30 -40 -65 29 26 -56 49 26 67 -106 -9 55 54 -41 -18 -57 37 17 43 -76 -22 4 39 12 86 53 26 -67 -5 2 11 75 3 77 16 55 20 -38 -112 51 36 36 61 -25 -15 -39 86 108 -23 26 -62 -9 -114 97 13 -9 44 -4 93 74 -67 45 -59 -23 -65 -22 9 -86 -27 -78 -51 49 -36 -75 0 -88 51 24 -39 10 -59 -66 -16 4 17 -10 98 45 -103 27 -16 -124 -7 -124 -115 16 13 104 -39 17 95 55 40 12 127 -41 -127 13 9 44 -103 -42 63 58 52 -51 7 73 -21 -71 25 -127 -128 -15 -93 81 19 62 60 -87 -17 -11 -21 -22 37 -14 -4 58 -5 30 -31 70 -8 -24 -20 50 2 -78 -65 -126 -32 -59 3 15 -57 67 -78 -100 81 61 -71 7 -13 45 -62 43 43 13 50 91 -37 -21 -47 -9 -97 -37 8 -13 -26 61 -54 26 -13 75 12 97 106 -47 -2 60 -111 77 40 39 3 -55 -99 -24 51 -28 87 -19 31 -57 1 -92 -114 -17 123 45 22 68 -88 -77 -17 8 -26 64 127 -11 75 5 -20 -34 60 -80 16 0 -36 45 -45 46 55 -46 31 -39 16 -87 87 -39 14 82 -26 -16 -64 -42 27 -32 99 -78 105 92 -126 30 -127 70 67 -51 0 -67 -104 46 23 9 -7 107 -67 45 -123 -31 -25 -61 -7 -84 -54 49 -118 -6 -64 -78 -122 -91 -31 -100 -11 70 -64 -65 -5 61 43 -55 81 -57 -15 0 98 58 -24 28 -77 63 30 33 -23 81 -8 -12 11 -58 2 -82 2 -52 -127 55 -7 -22 -13 81 -115 43 -6 -28 -4 -17 36 -2 42 6 -22 97 109 23 53 21 54 41 61 -26 19 4 -44 76 2 -32 -38 -69 83 3 -87 -10 -56 -1 40 30 -36 -23 -104 38 61 1 -39 -60 -49 -103 13 51 28 61 32 5 72 86 -40 -39 -31 -28 -82 118 62 72 -44 -110 -33 -94 -2 -65 -31 16 -30 67 -39 -94 -31 79 -69 -27 -4 -3 32 -87 -10 21 -14 65 10 22 -61 -4 -45 39 35 -34 51 22 -42 9 66 45 -69 45 28 91 -17 107 -37 44 -1 118 -17 -87 48 -53 -34 44 -65 -30 43 70 49 72 51 30 -69 28 -42 -101 -50 -9 -41 3 41 -1 -11 -44 -65 29 54 95 124 40 -32 -39 -14 -9 42 -65 -18 69 -109 -37 5 -64 27 29 29 76 10 73 70 127 74 -9 34 -1 -71 117 30 88 27 -114 38 -44 -101 -68 79 64 29 64 68 44 -46 41 -91 -31 -7 24 -55 -8 -91 25 -36 64 126 0 21 7 -3 -54 68 38 59 -50 32 7 17 101 -22 -25 126 96 13 -55 11 -3 -23 -5 -17 -16 -100 105 -85 -5 -38 -112 -47 -14 -13 -115 -72 -12 -46 -112 80 -3 74 80 -5 18 -19 -9 19 56 3 20 -92 52 -32 7 -21 67 -34 29 127 -46 81 84 111 -70 22 27 32 8 -76 -88 73 2 -55 61 -75 25 -11 91 -12 -54 27 2 47 -9 -27 23 39 -28 -51 39 -25 22 -7 -46 -128 -40 -5 12 5 -12 127 -55 98 47 83 127 -21 -83 -25 -64 -73 78 -41 12 -59 11 56 -63 15 -13 43 -33 3 7 14 46 -127 -91 -96 -21 12 -9 2 50 95 -15 54 50 41 8 34 30 14 66 67 -79 127 82 -83 -12 62 -57 -48 -83 -75 31 1 -84 -33 42 14 23 79 -8 36 -118 -66 -74 -14 -60 2 57 109 127 62 13 1 122 -7 49 -42 -57 -3 43 -31 -56 40 -14 -38 -90 106 7 27 -55 -29 -12 22 -47 -26 -10 65 49 -18 -23 -52 -97 -7 -71 47 -81 52 -42 -88 46 -27 32 -16 121 -54 48 4 -83 -15 -125 -109 -54 14 -70 -23 52 37 -55 23 -33 -22 79 -29 62 -25 47 -4 -109 -3 -84 90 126 76 -30 -11 75 23 45 -5 3 20 -36 70 41 -6 28 99 43 42 -17 -13 31 1 77 86 -32 90 -24 -72 -127 -48 -93 -3 35 86 -25 -72 29 -83 65 18 -4 31 -98 -113 98 -62 45 39 -58 72 -125 51 37 55 23 -121 5 -50 -7 106 101 -120 -127 9 71 -49 13 43 19 -82 26 -83 80 36 64 -5 61 -17 -32 -31 94 -106 -60 -62 -13 -24 54 -127 -18 50 -20 -60 -29 -16 -60 1 -103 23 80 11 -14 54 -9 52 -4 77 -14 64 -71 16 -26 22 -57 17 -9 -117 20 59 53 127 15 -94 -25 23 117 14 -32 71 10 -127 -8 3 -27 -11 68 -23 -4 26 -85 115 -67 -11 -41 58 8 -9 72 33 5 54 89 -60 32 93 6 -75 74 -127 -26 68 -34 -75 5 -24 26 21 -43 13 22 -12 -80 9 62 -2 -47 127 33 -10 -82 20 16 23 76 53 117 -16 1 -8 -84 42 16 -87 65 26 -92 -25 -71 -125 13 100 1 -36 2 33 42 -40 7 116 -77 0 34 -11 -18 -55 17 -4 88 -28 -16 8 71 -11 -37 1 -121 65 84 -23 -43 121 -50 -18 -124 -91 22 -70 -17 -8 -73 9 -24 -48 -18 19 -108 50 -126 50 -56 78 48 -29 -111 -12 -2 27 75 17 69 -42 -81 57 39 12 -7 127 -69 -101 21 -23 -104 -19 79 -72 -28 23 -26 35 -34 -54 -25 -83 31 64 -17 69 3 -19 65 -14 59 -52 -18 -1 -71 76 -15 -36 51 40 59 -67 18 49 -115 8 69 -42 -31 -18 -19 65 28 82 -19 -4 -96 -32 -31 40 3 88 70 0 -33 -15 14 -27 -50 1 61 -56 -39 -9 36 -102 -76 -53 -66 2 2 -38 -16 -10 -53 -47 -12 -62 45 -25 -127 28 105 84 -32 4 -49 9 -50 18 -122 21 2 -33 38 13 -28 -47 52 -39 33 46 4 -10 48 12 23 76 -9 -7 -10 -17 -70 -30 -118 -55 -4 29 49 67 9 45 -38 -2 22 72 -41 3 30 -20 -1 -75 -32 26 112 51 23 65 39 -83 36 52 42 61 -55 14 99 -17 -3 -26 33 51 -36 43 -30 11 -59 -23 -41 -70 -47 35 14 -68 64 24 -3 2 -77 40 -2 67 -50 17 9 -50 -31 35 64 -35 14 -24 -10 18 21 -21 118 -25 -8 19 35 27 -80 10 42 -11 -100 23 -29 37 -34 -73 107 -1 71 3 -19 -109 -34 14 -42 -119 -14 -4 -81 41 60 -13 -76 -16 34 -42 -126 -69 -92 -64 23 42 -79 38 52 5 -42 -68 28 -25 -38 -36 -105 31 -22 -35 -125 -110 101 12 25 5 -85 -63 67 16 -83 84 36 -57 -86 -36 31 24 -106 -9 41 -44 27 -127 75 -34 4 60 -19 -79 29 -45 29 -44 -13 -33 -113 -96 45 -24 12 -86 43 -12 7 -58 66 -86 -69 2 62 -10 -46 25 -4 -3 -36 55 -73 -1 39 -5 43 9 64 -108 -18 -83 8 -48 40 -51 5 -1 88 16 20 -7 -4 -10 66 -80 74 2 -124 -91 -43 -42 -62 -74 56 -7 85 -22 13 59 -116 -101 -16 45 50 19 5 -43 -68 -51 85 28 -47 -62 81 10 39 39 34 -41 -11 90 -18 -11 -38 7 -18 -73 -10 25 -37 -10 4 26 68 -66 23 -17 -14 9 -38 -62 -31 -79 21 58 86 40 -123 33 36 -14 -25 10 -7 14 -49 42 59 19 41 -45 82 -17 127 12 -62 -24 75 44 70 -76 53 35 104 -112 61 25 -126 -25 127 23 30 -127 -32 -79 -122 -14 -96 58 11 -15 -77 109 29 -48 -24 -32 34 70 61 -23 -26 -7 -2 -51 52 -85 1 104 -38 -40 13 -4 -92 -96 48 -70 -41 -79 20 10 51 68 7 125 19 -54 6 -39 16 -26 38 121 74 82 39 -60 21 -3 87 101 -49 -48 7 35 64 -3 48 -2 -13 7 -98 -16 -126 -60 -14 -19 81 45 16 3 -38 -119 -107 -83 38 -46 -27 -89 82 110 -22 51 -87 46 54 -38 -68 -87 33 12 29 -38 -64 125 68 54 119 70 -19 100 -46 -15 94 74 123 122 -22 4 -56 -110 1 63 7 -26 100 -106 -1 -57 41 44 -31 -7 -126 -52 49 13 13 59 -62 58 -24 126 103 25 14 -30 -17 127 -96 -127 114 -121 -127 -117 115 -96 65 57 99 -73 54 -61 19 80 -74 20 42 -32 56 36 -41 -22 4 -100 59 -42 82 80 33 40 -8 93 66 -26 -47 29 -35 82 -29 5 -104 -50 14 72 107 22 35 110 2 57 -70 -10 57 -123 28 -52 -30 126 74 25 98 -127 3 -77 -42 -26 72 63 21 -24 -14 34 34 115 -57 -79 17 -17 52 91 -81 12 71 -72 -59 -79 -19 39 -87 81 -1 -48 -56 19 -19 46 -113 -15 61 19 -19 -50 -13 13 -10 67 -10 42 27 -36 -38 32 17 58 42 -113 -127 -126 -84 -43 -123 -61 40 -125 -19 -30 -125 -126 34 47 18 127 -126 -49 -14 126 -111 -48 51 78 78 75 119 59 109 22 4 44 127 -21 82 26 -34 -70 -37 28 119 -47 4 -127 -56 53 -59 95 -123 -81 -3 127 62 -126 127 29 1 87 82 -75 -6 78 -45 -70 25 -127 4 101 -45 -112 56 29 5 -65 38 -21 -7 -17 14 50 24 -78 -18 42 -23 -25 -127 -62 -48 -8 61 16 126 6 43 40 47 16 -79 31 -39 86 96 8 13 32 -47 -75 -77 21 1 -27 -40 1 38 45 24 51 31 28 -6 7 19 107 20 -29 42 18 106 42 16 -40 102 95 46 -19 -20 -40 14 84 59 72 -11 36 59 126 29 -38 31 120 -51 65 111 -43 -2 -41 96 -14 94 -19 5 53 87 84 14 13 19 21 -51 -7 -5 -22 -10 -10 0 36 -28 33 87 -9 -26 42 -29 125 30 20 48 -95 4 109 -85 43 -28 9 80 47 1 66 3 -11 -12 7 -15 4 49 52 51 30 46 52 12 -12 107 -40 74 -79 -9 -23 34 -100 -48 -6 -3 -82 60 7 -22 11 -57 -59 28 43 -33 120 -52 79 -7 -37 -93 44 -52 56 87 6 -24 52 43 -67 9 49 26 -19 -29 26 15 40 74 78 -116 7 18 -52 -64 -86 -34 -36 45 4 30 -80 -21 -38 46 38 73 10 31 66 -9 -3 -43 -14 19 -37 11 -25 67 -15 6 47 -3 -3 70 -4 46 25 -40 33 33 -62 -26 -64 39 -61 61 -34 -9 19 -31 9 -7 -42 -88 6 -57 41 -51 26 -14 -5 -30 -6 122 -31 -18 31 32 13 -3 -27 -41 61 -35 -55 66 8 32 20 -59 -37 -19 -62 -26 -14 10 25 -50 4 -1 -44 41 48 -30 -7 -17 -93 -40 15 40 60 32 31 -34 76 8 -16 56 -35 31 64 31 -37 -60 -1 37 -58 12 -10 31 83 -14 -60 97 38 12 19 19 -2 -37 23 60 87 113 -41 -55 49 -9 15 -18 48 -31 -34 -37 -12 7 26 14 14 -68 101 -40 -23 48 -86 -50 -5 -54 69 -17 12 2 -23 -23 16 22 -8 -12 -34 66 56 50 -58 -29 -12 -107 65 23 8 41 -37 -16 -25 99 -27 53 2 27 -47 121 33 41 35 127 45 0 -36 -20 57 -51 -19 -34 -59 80 -88 -17 18 -66 30 -66 56 -19 11 -20 11 -35 -15 1 28 -35 102 -33 -68 -36 29 1 18 69 79 -1 -91 -18 14 -88 -60 11 -29 -53 -76 22 -26 -19 3 -64 0 -15 -40 29 63 -99 -35 -6 40 11 3 -6 -1 -39 -46 114 -12 -53 -6 -44 76 -18 45 -52 3 66 37 -2 -42 -64 73 91 -33 22 -16 33 15 22 79 60 55 -128 -13 125 -9 -75 -81 -70 12 -70 25 -118 -41 15 -21 -84 -31 -54 -35 -68 33 -31 42 -8 26 4 -13 2 -5 -11 -38 -29 -71 97 63 -63 -2 -1 68 -62 -10 -49 61 62 80 7 -18 73 -73 40 -36 -47 -64 -82 28 -63 -102 -117 47 5 -50 -66 -44 -30 6 -62 100 -21 -50 -40 20 -78 -33 40 -6 -58 17 58 -96 78 -64 73 4 -46 13 18 -28 -126 -15 88 84 -11 14 -57 46 124 58 110 127 5 -35 127 38 51 -16 -14 51 46 -19 -9 41 78 -25 64 -6 -26 -90 -101 -122 94 4 57 -5 -40 7 -89 -29 15 -19 61 -47 -94 71 -119 -67 127 -21 9 118 -83 -97 -117 -45 -44 -15 -34 -112 2 -53 109 74 -84 55 28 126 -72 -45 89 -32 107 -11 -125 60 68 -87 -23 -25 13 52 28 -8 60 -125 43 40 -37 124 40 24 -69 -107 28 118 9 -20 80 20 -60 61 104 31 97 -18 49 67 87 -78 -32 20 49 20 -17 -64 49 13 71 48 -9 -49 -35 80 74 -19 -75 101 98 -15 -20 8 26 86 8 127 -4 -8 40 -26 17 38 2 -4 -5 85 -52 6 123 38 -13 1 -54 -47 -8 75 58 -1 101 15 53 56 -19 -100 -16 -28 -9 -24 24 -25 59 16 34 -25 -19 20 22 -1 9 -128 -35 -35 9 26 -27 -10 7 -17 -6 72 -2 80 69 -39 70 109 16 2 47 57 25 57 11 -7 7 -24 100 -10 18 -33 99 18 -44 -26 21 -16 69 -77 -36 -10 58 -8 -61 -39 52 5 14 -29 7 50 -43 49 30 -19 18 14 23 17 -3 13 55 -35 10 -43 -40 -41 -13 -22 -43 -54 13 8 31 35 72 -43 -30 -13 2 12 26 -115 84 14 -43 -18 105 -45 -11 -6 67 39 10 -54 -58 11 55 -68 -23 82 -24 -49 -5 -27 49 55 19 -59 10 24 -10 17 11 -15 22 -56 -43 -59 50 -89 4 -5 -46 22 17 -15 -38 -22 -4 5 -75 -72 -3 0 -77 -8 57 9 36 60 -1 -48 10 2 8 47 35 -54 -27 6 -23 36 18 -127 -40 -30 50 58 -43 -43 -3 75 41 36 -34 -69 -19 -6 25 38 -39 -98 58 35 -24 -94 -32 -31 125 43 54 75 -47 18 -17 46 48 16 -48 -80 -58 -26 -40 13 31 101 27 60 -21 18 20 -71 -62 -47 -7 -23 -72 61 99 66 -34 -19 -80 -79 32 -9 -127 -52 -20 80 110 22 95 16 1 69 -83 47 -34 -109 -26 -22 -51 31 85 123 12 34 7 42 -23 13 -74 -45 -22 -53 -39 -16 -34 80 -9 53 50 60 -7 95 7 48 -13 9 -62 71 33 91 -72 56 125 -65 -33 12 33 124 -17 29 -127 -89 -16 -127 -41 43 -103 -10 21 127 -78 -40 -31 -35 5 72 47 -30 -87 -48 46 -57 -3 -72 -125 59 -101 14 83 -77 2 -54 43 -93 21 115 77 -33 -127 -50 122 -127 -16 74 46 0 -115 14 19 31 26 -21 -99 -21 -68 5 46 -90 3 -69 87 13 127 -39 8 -9 55 -26 10 0 53 -91 13 27 -32 39 104 -125 13 61 62 -5 -34 5 -17 33 27 9 23 -4 45 -18 127 53 114 116 -59 -13 -38 3 1 -1 -13 66 -20 -36 40 22 59 42 55 -33 -51 -15 -25 91 -27 -37 127 12 53 3 23 19 -70 2 -24 -85 57 -75 45 -56 -90 -8 124 65 -98 -36 -3 -60 -7 -11 10 -53 94 -29 -28 92 -127 -6 -7 32 127 96 21 69 24 59 -85 15 -33 37 59 -75 -34 -28 -50 13 18 -34 -41 47 34 11 -75 -36 -35 39 18 -26 12 14 -38 60 124 -38 14 -48 50 -9 -50 -79 19 -6 127 39 -126 49 33 -16 28 -35 -13 26 30 -82 9 -22 8 -33 27 -3 -24 16 4 13 -8 -13 -128 -66 -47 1 11 -25 36 -73 23 -72 19 -55 62 3 25 -126 8 45 -33 -8 -47 -31 -35 -89 37 -63 -49 119 -11 51 3 -16 30 -8 -33 -13 24 -44 -9 -19 15 -11 19 10 50 -61 29 -60 -17 76 -19 -22 39 14 0 -9 0 -22 -87 66 -28 -28 42 -46 -15 -14 -74 -38 14 45 46 -33 64 -17 45 -21 79 -40 -8 -75 -15 68 -7 -123 -44 -49 -12 -48 44 36 29 -96 18 24 -22 -1 81 -28 0 90 -29 -4 48 -5 62 -3 -11 -6 46 -82 16 18 -15 -8 43 1 12 0 58 15 -29 -28 2 33 -20 15 -64 43 40 -2 -66 11 -38 127 -98 15 29 -37 -22 67 30 -62 9 3 -36 -12 10 57 0 -2 -14 -33 -52 -40 24 -4 -39 -57 87 -13 17 2 -31 12 -58 -109 -81 119 8 -117 -74 21 77 20 124 81 8 -66 -2 -26 -53 -5 32 5 -16 -65 82 90 5 24 -28 27 -57 -30 64 -22 -5 -16 42 36 -26 56 -17 23 68 -40 -28 -24 1 -5 -27 -12 34 -52 -39 -48 53 82 -47 73 -5 -60 2 19 85 23 33 127 -41 33 -37 40 -34 -9 -87 104 54 15 -24 79 -59 -6 -21 8 -2 101 -60 20 -57 40 16 -99 -51 75 103 -20 44 33 67 -85 20 7 25 81 -29 -43 38 30 -13 -4 72 -30 20 -9 93 -29 -82 21 -126 3 -4 -5 -2 103 44 32 65 114 3 -8 120 -9 -127 10 -33 -21 61 -24 -15 -33 -104 -46 0 24 1 50 33 -36 -52 -20 29 68 -127 -13 127 51 113 106 42 72 -25 -87 -79 -57 -44 -79 35 61 11 -38 80 -25 30 22 -69 16 -16 2 -8 -30 119 -44 38 71 -79 -120 -68 -103 81 12 2 -15 95 20 -96 -35 -80 -16 71 46 -5 -41 -35 11 87 -13 35 26 55 52 -85 -16 -73 -84 50 121 57 9 47 -36 -31 84 45 64 62 18 25 50 -34 76 56 50 -2 -47 -59 -60 -30 123 -41 127 49 41 -25 -86 32 -9 -46 21 -83 -52 18 61 64 -38 -23 -37 59 -3 41 -70 -47 67 -57 21 -68 24 -49 35 -5 -124 23 -128 34 -91 37 -8 -38 -45 -8 -36 -46 89 -27 56 -56 72 58 44 -33 48 88 -59 80 -1 -35 -110 -62 113 103 30 -9 -92 -23 -22 66 -17 -34 16 56 -97 -121 25 9 -8 -58 -12 -52 39 2 56 125 -27 110 -2 -2 34 52 -12 30 -60 -73 -127 -4 19 26 -79 -1 11 -55 43 6 -14 69 -61 32 46 69 -4 -104 42 65 -85 -21 -88 -16 40 41 -32 68 -63 -15 37 -48 127 -25 16 -32 119 -7 72 35 -65 -70 127 104 123 37 -54 43 -12 -34 20 -90 -10 107 -10 -32 -17 8 45 53 48 -83 -113 77 76 -13 31 123 126 30 -19 -33 -45 -52 50 -99 -35 19 -64 -27 68 -19 51 -104 -97 -15 118 -22 -92 -9 -55 -122 -29 -20 -89 -122 -33 -115 -12 -45 80 -64 121 69 17 92 -24 -37 18 -118 -25 11 -43 -59 3 -28 -24 -17 9 29 41 1 -59 17 -128 121 51 -7 15 -17 -10 -57 67 0 50 77 5 -74 31 -75 33 8 -8 -62 -6 -101 7 -24 -60 3 -40 110 61 125 -12 4 -21 -60 42 -14 -42 71 36 123 -37 2 -13 40 -53 -31 -122 0 55 -29 -5 96 -13 38 -38 -38 32 1 124 53 -67 83 -6 44 5 68 31 -76 55 -12 -54 44 -124 -38 5 -10 -30 62 61 9 28 -22 38 -49 22 -63 -59 98 -75 -57 -57 55 21 -24 9 -31 45 37 12 -50 -125 5 39 -37 18 67 -26 0 -44 -8 103 61 35 -26 67 -15 11 90 -29 -41 49 -67 49 48 -80 8 82 5 43 19 8 28 -97 -66 16 -67 -86 41 10 -32 -33 93 50 27 98 -128 116 46 16 -22 87 -94 3 17 69 -14 9 -43 -17 -77 -49 11 -29 -12 -7 -49 44 0 -81 17 83 30 -71 16 20 50 -73 -34 -78 -17 -3 -29 20 -27 110 -76 6 -35 24 12 -18 10 -46 -26 -21 38 -48 -48 77 52 6 96 -52 -51 -57 -41 -15 -54 -54 -8 24 -73 74 -94 -18 10 5 -55 -36 -18 125 -35 -92 23 -15 46 -2 -78 30 60 -93 29 -70 38 -76 16 56 33 -87 19 -90 19 25 126 -62 -73 61 100 54 19 -20 -96 -6 -12 60 69 -24 62 62 71 2 41 -36 127 -46 118 -31 -31 -96 10 -3 39 -43 68 -5 -46 -9 33 8 -41 44 49 86 122 -30 -12 10 -5 -35 36 -88 50 -15 1 60 22 -79 -15 3 -39 15 -59 -37 -26 13 63 28 -86 -19 17 0 74 0 10 13 5 -30 -53 -23 -2 22 10 8 -9 -14 36 -4 15 -26 17 -2 -24 22 40 65 20 31 -9 -24 17 -45 93 -3 4 -10 75 47 9 22 56 -33 8 29 -79 -44 3 6 27 -11 127 15 -60 -83 31 66 -25 -19 69 -63 -25 -36 -41 28 57 -30 73 27 27 -18 -7 81 28 -1 -5 -69 -13 -60 92 86 -46 52 18 -128 -73 -68 -22 67 65 -2 -111 -49 41 -1 -13 -20 -20 36 -18 -86 -12 -28 -127 104 -67 -93 60 11 56 -58 -45 -18 2 -128 -5 23 22 -4 44 -1 -78 -15 32 -56 26 -3 -77 23 -127 -26 73 -31 19 -28 124 42 0 88 42 -7 -52 62 72 19 -35 1 -79 -6 -49 31 1 61 17 8 1 -97 38 1 118 -36 60 9 -128 53 13 -126 -50 -35 -4 32 16 -127 10 -21 51 -122 -83 -28 98 50 -14 -30 29 20 21 -126 -122 -88 -17 -45 -42 52 -86 -82 72 -51 -67 -18 -116 -124 0 -5 28 7 2 -107 -30 -38 -50 113 9 -92 -17 -21 1 -81 -68 -111 -38 30 -9 92 45 27 -70 -39 20 -17 -25 -100 -52 -10 10 -52 -81 108 39 -40 14 17 48 25 77 0 -17 -5 -33 -2 44 75 -22 8 9 8 -61 -64 -11 119 -46 103 123 -23 -73 -48 47 9 25 -1 4 73 42 -3 55 0 -86 -23 25 37 -26 126 -63 -71 -28 -56 -99 -34 -31 51 -49 11 23 59 -49 -20 -55 68 -9 -74 -10 -98 55 30 41 43 -111 -49 0 -28 -1 -40 -64 -29 -24 124 43 -16 -44 19 -84 89 65 53 -20 -111 40 2 -52 -27 16 -80 -50 102 90 85 -9 12 -51 20 2 -88 -59 -79 -26 -57 24 -56 55 -37 37 4 -38 -2 -22 11 -98 29 0 -92 7 -27 64 -16 15 -24 -17 4 9 12 -73 -88 -13 -85 -55 -63 23 28 25 -92 -109 -84 37 3 -61 -112 32 60 9 91 10 -48 -98 -13 22 17 -17 -45 117 79 -77 40 -77 -46 -15 -31 -26 68 43 -62 21 46 6 -27 38 -54 -15 35 -53 -107 -2 77 -94 36 42 17 -80 2 -12 56 68 70 -104 90 110 -33 90 16 -18 38 -45 -50 -39 36 -19 81 27 -56 102 31 30 25 -30 -41 14 -4 67 50 -121 34 6 58 -71 32 42 38 -30 -72 34 -69 -21 -37 91 14 -38 20 -41 -78 -26 -62 -47 -11 -75 -55 -11 -39 41 -15 -124 -81 4 -33 60 25 -16 -63 -20 -34 47 93 5 32 24 -2 38 -11 53 -108 -46 57 -99 25 100 -23 -68 -26 -119 6 19 38 -18 -76 31 27 35 29 -76 10 -48 37 63 48 96 -52 24 -26 23 -56 -14 10 -26 -13 44 -11 -13 27 -31 -31 -33 -33 -83 -64 -20 38 19 -6 10 37 -68 -18 -13 12 73 -17 -12 -123 74 18 -40 -33 104 2 9 -30 -19 10 -100 -23 52 66 124 19 -25 69 28 28 54 111 -56 -6 48 22 126 -66 -67 -47 -50 -64 104 10 -5 -46 10 123 89 -60 -30 33 -2 56 8 -2 -4 -36 59 -45 -61 25 100 -14 -20 14 15 47 53 39 -18 -89 30 32 17 -19 6 6 -14 -40 90 102 103 35 -49 -36 7 -16 -25 74 31 23 5 -18 -14 68 -74 55 43 -35 68 -3 3 -68 27 91 13 32 49 48 27 -79 -58 -17 81 -66 -20 36 -28 51 36 55 58 -79 -28 126 70 -124 -75 -30 33 15 -78 -83 -16 -5 -12 57 -33 58 3 -57 -67 39 -16 -71 51 70 -7 41 -118 -7 47 97 -49 22 81 -30 -3 5 29 -11 66 68 -52 42 15 -117 -41 -47 -3 39 17 98 127 55 -41 88 64 114 88 54 -3 -35 -82 -128 -39 35 -25 45 -126 42 -27 -25 -1 -22 -123 68 40 79 13 64 -12 25 26 35 64 -6 59 -14 123 39 28 30 33 63 31 95 -83 77 -74 12 -29 -4 11 45 -23 -10 37 52 -57 -41 23 18 -26 77 1 28 -111 -7 -59 -22 75 -51 -81 -106 -37 45 24 -31 -35 -3 -71 -64 -31 -126 -15 -12 -25 75 -22 92 13 10 7 15 -44 -19 -1 -15 -27 11 16 -19 -27 -1 17 -38 100 -93 -32 -41 -50 16 30 -62 -107 -14 5 24 -36 -18 18 79 24 -45 35 -83 51 76 -8 16 107 5 39 -21 -87 21 15 87 -68 43 -37 -31 11 -91 7 -47 55 -67 125 -45 22 38 -3 -45 -12 -16 -78 -36 35 -17 -46 35 47 -42 -5 35 -19 63 16 52 17 -28 1 -18 20 86 -62 77 -87 36 -16 -18 59 -18 -63 3 36 -2 -11 37 -50 -16 66 -19 7 18 30 29 -13 -1 2 47 9 6 67 29 39 -31 27 27 -76 -4 48 -33 -22 -68 -2 21 73 9 19 45 -8 30 -65 74 -83 13 -53 0 -126 -47 67 11 127 -128 -50 -126 -17 -103 11 62 26 12 56 83 -3 1 28 -26 -66 64 32 -82 16 -3 -66 -25 61 -29 126 48 -10 4 -20 -16 -5 31 -6 52 10 -11 55 46 31 -25 -47 -102 28 -13 29 22 -27 58 32 36 6 -81 9 -74 -44 -23 -1 25 -57 -128 -5 -15 76 59 -26 -36 -38 -42 -81 -57 45 2 -39 -12 29 77 -31 -42 -125 22 -77 -27 10 -11 6 53 87 -27 4 -73 -17 -50 -60 7 44 -95 -7 53 -95 37 61 -74 5 11 71 49 -84 -9 13 -43 -25 -63 -37 -7 23 -74 -15 -77 9 -37 0 127 -7 -17 82 -20 -47 48 -46 66 -41 45 -79 9 21 45 -1 -52 75 -47 1 -48 59 113 79 -78 -19 -1 14 -41 -15 -21 3 39 86 85 -47 -58 53 27 2 -50 -25 -62 -19 -76 -62 -6 -2 -38 49 -23 59 -45 -28 -22 -23 10 -24 26 -13 -43 7 51 -80 -49 -44 -103 41 56 74 73 35 -8 19 -61 17 -103 -39 -76 -74 -52 32 2 60 -65 -10 10 -28 16 -11 -52 3 7 -64 31 -101 -43 91 39 -89 -7 32 -43 -7 40 44 -30 -3 -33 -17 29 -6 -47 -41 59 24 52 -9 -13 3 32 76 -60 86 -18 -91 -54 103 -44 29 19 -6 37 3 70 -11 55 -14 14 62 103 92 38 -77 26 -71 19 85 61 25 -5 32 56 -119 84 -124 -1 53 -29 -53 -86 49 -93 8 -15 17 -98 -47 -61 -8 -64 -98 117 -117 -54 -61 87 -27 -98 -74 -115 124 -39 9 25 2 104 -43 -10 6 14 -2 -41 35 5 40 27 -45 -125 2 91 -109 -9 41 19 -61 97 -50 72 6 -42 13 39 -14 -91 -10 -90 -14 -118 -61 75 100 22 19 1 11 59 -28 1 45 -57 -4 -12 26 -48 -82 -12 -4 26 -59 1 31 47 127 -8 -103 9 118 -8 103 -62 -69 103 -24 -122 36 64 -45 44 -45 -24 8 8 53 43 20 -71 21 57 2 62 126 10 -9 9 127 5 58 4 -26 57 -21 86 7 24 121 -46 75 116 51 0 83 127 29 3 -81 104 63 -19 127 37 22 54 78 49 123 127 81 46 48 43 81 86 127 86 -4 127 -28 98 39 99 108 60 65 23 22 14 52 60 76 28 68 -41 -71 -29 52 79 -60 6 15 -128 82 118 36 51 3 53 -104 2 27 1 124 -50 37 71 40 -20 127 10 56 7 -73 125 50 -7 -82 -37 -126 38 -53 80 55 47 45 -27 16 -95 -82 -88 21 -94 -16 102 12 22 -109 -108 -22 105 124 97 -67 5 91 -86 73 -10 48 -81 10 124 -44 66 41 -83 -33 71 67 12 69 -44 84 24 -76 -115 47 -115 20 85 -114 -2 -73 -125 -36 -19 -33 79 87 44 93 -15 56 54 53 -19 1 -87 -77 7 -80 -20 -69 -34 20 65 -11 0 -4 24 -44 46 -28 11 0 41 -74 -106 -29 -53 -51 72 7 50 42 -23 -70 -15 43 -4 -51 -22 8 3 13 86 16 23 -107 70 44 -5 -114 61 12 13 -9 -57 -42 44 124 -1 50 -44 -42 17 20 -12 -123 -7 28 -22 -1 92 -61 -41 -88 58 -18 -4 56 -13 -59 17 -38 81 27 45 87 40 10 27 -51 -112 -75 20 -84 109 46 -124 -14 41 -64 -67 10 38 -15 13 63 -7 2 36 20 -77 6 17 15 -51 26 45 -28 45 -14 93 71 -45 -39 46 54 124 54 53 -34 -44 41 -126 45 -72 38 26 -13 -61 39 -108 -128 -12 -28 -10 -26 -88 30 -67 45 79 1 -62 19 45 108 72 39 -68 -118 64 51 -68 2 52 -60 -26 -77 -23 -18 -128 -53 -127 66 -42 23 -44 -55 -67 -49 98 62 1 21 -11 -36 -14 -73 -57 69 11 35 -55 -36 26 -127 30 -91 -125 15 110 -29 55 4 -18 -92 -123 50 38 69 -47 62 8 -65 -39 -55 -35 -13 -67 -109 69 -2 14 -65 12 71 -37 37 9 36 95 51 125 -47 119 -21 33 123 -8 54 58 -70 -68 50 -9 -35 105 -74 -53 10 94 -5 51 88 -119 -2 -15 -47 19 -50 -32 9 -29 79 -76 65 39 6 -65 63 49 -58 21 -27 -120 -40 23 2 -7 -39 -91 47 88 24 -94 -25 58 -45 16 36 -34 56 -59 -17 -41 -62 -3 -60 -56 -3 13 -126 50 110 53 -62 127 -107 -34 97 126 23 -126 -85 -8 65 32 91 110 33 49 -12 31 97 -14 30 2 -101 -96 19 81 -68 21 56 -55 8 -56 -128 18 -19 -20 67 41 -14 -59 116 -6 46 -23 20 -80 -6 83 -92 -127 -1 -45 32 71 -24 -14 3 127 -120 -127 71 -33 48 -28 -27 -121 9 -27 -3 -33 101 -82 24 -128 -44 -11 28 -5 42 -21 -17 -66 -24 -127 -121 107 -19 -51 29 -29 52 33 -13 -126 -98 -40 -31 -117 -119 29 -125 -113 96 62 -59 46 27 122 -85 -65 -10 -44 30 -29 -83 -9 -3 28 -50 -78 9 -45 110 -75 -18 -117 -8 -71 -123 -26 -5 -27 -18 70 61 48 -31 -21 73 69 -39 79 125 87 71 76 117 -57 81 11 60 15 -37 -40 10 -121 -35 39 16 12 -88 -18 41 -28 88 -5 3 97 87 55 -127 -35 -21 5 28 42 89 10 36 -12 57 19 -15 5 -34 -68 -115 81 -70 41 22 -127 33 -26 -122 -65 124 -32 -7 -58 -2 -54 -46 20 -75 -125 -83 17 11 -21 69 125 41 -44 -43 -118 45 3 -13 49 -17 102 39 -8 14 -58 -60 -3 22 -4 32 -41 68 10 66 -7 16 65 -57 108 23 -10 49 -13 -52 -18 -1 29 20 -31 -23 26 -19 23 53 65 40 -5 44 -36 31 50 -79 30 -44 -27 60 -50 -76 94 -111 3 -36 42 71 58 57 73 126 -22 -13 -65 -115 3 20 10 46 -54 29 -32 120 86 -90 -66 6 19 -68 -8 -29 -29 -89 -72 -58 -89 -50 12 -44 0 -15 -11 16 21 32 -109 -61 25 -60 57 -24 58 47 -51 -59 -16 22 -27 72 37 -115 -125 -55 -22 -37 22 -108 -21 53 -17 -12 -35 -49 -62 -7 67 -75 14 -77 94 30 19 -8 -11 77 64 11 11 80 -79 -25 16 22 -24 -13 9 23 -6 -117 -100 -36 12 71 -8 -13 4 -26 -80 -75 104 -112 -9 -8 49 -16 50 39 -75 -67 5 -16 73 -42 35 10 80 -32 87 -92 34 127 -107 -79 -7 38 13 44 1 67 67 -67 20 -75 75 16 73 -117 126 26 127 -110 -42 -61 127 -32 -110 -41 102 27 -8 18 20 49 37 -20 -79 -113 -94 -127 44 48 51 -53 21 43 53 69 14 -110 84 23 53 95 -16 84 -4 127 64 -27 -71 65 43 113 11 -25 -44 -6 -21 85 -26 5 124 -8 125 -6 59 -7 82 21 -3 -18 105 -8 -29 13 43 -18 56 33 -13 20 39 100 5 91 -10 50 11 83 -70 -80 39 -29 -16 13 70 -76 73 -10 -55 50 30 19 42 -59 -44 37 15 -23 37 -40 105 -9 77 121 44 8 8 -35 2 -17 58 63 -10 -128 -39 65 -36 3 -5 68 92 -42 -45 67 -2 -17 -66 -100 126 -40 24 76 -15 9 43 -65 -11 -10 -10 -30 56 47 36 -52 -11 3 57 1 -55 -19 -19 79 -128 -57 30 31 72 -16 -38 -19 59 -76 -19 -28 44 -55 -40 77 -32 -47 111 -29 -10 56 -42 -15 64 118 -73 -51 -35 -44 -97 38 48 26 8 70 33 -70 -34 41 -99 127 91 -9 -16 6 -84 -19 126 16 -9 13 -99 7 -23 -49 22 42 57 14 -9 -67 -29 -25 44 -120 -78 126 -25 -103 9 -127 -28 -15 -40 99 -23 60 81 17 -34 -20 -17 -19 79 18 -117 -63 56 -3 126 -27 123 90 -67 -25 -6 94 33 -51 64 -6 31 -41 10 11 -12 -21 -79 34 -72 98 -118 -21 -33 -36 96 67 46 -18 19 -53 -13 -85 -16 13 -34 45 5 63 -108 28 27 55 21 90 20 96 -86 0 -34 -70 -2 3 -90 -8 -59 -46 26 -69 82 25 67 44 -40 42 -66 -2 62 -75 -28 -52 -12 44 -30 58 -3 -7 35 -9 -54 -11 -62 -40 113 -19 -2 103 -33 -40 50 -43 47 -19 35 26 21 31 -75 -6 -33 74 -6 35 47 73 -37 7 -40 -65 49 -71 -11 126 -56 -107 19 -48 -7 -18 9 81 24 34 5 34 -33 -38 35 -54 -46 79 -10 -35 103 -37 17 43 -71 19 49 -32 10 124 2 33 -37 89 9 13 1 34 74 46 34 -18 -51 30 -9 -41 -13 71 10 -97 -9 -16 9 -51 127 -35 64 39 32 90 -5 96 28 -66 67 22 -26 -27 -34 -3 104 49 17 -94 32 107 44 -61 -22 -60 48 -93 -12 -88 -99 127 -100 -127 -15 24 -53 -26 -124 15 3 44 -128 -55 16 -128 46 -42 -100 -18 -5 30 -27 -127 8 -40 -128 -34 22 -2 -45 -103 -49 -52 -45 35 41 7 -41 -90 -6 -128 -127 126 -112 -15 40 88 35 17 81 78 -13 -90 127 -79 53 109 -94 -22 -81 -44 6 87 70 -94 22 84 -118 127 80 97 -5 73 59 -96 -23 -28 -52 -67 -79 -50 92 6 33 125 -92 12 -61 2 48 45 19 39 -6 -41 -72 36 -21 -41 59 -76 18 43 16 -23 -63 123 -62 4 -48 -19 126 -46 7 -46 -2 -22 23 87 67 -35 -93 29 -15 -2 11 21 120 -15 -29 15 8 12 42 110 31 -56 -17 108 90 -70 -6 48 48 -61 10 -42 7 -5 -18 7 21 -3 65 -32 -23 39 -3 -97 -66 -29 -5 90 113 22 53 46 84 30 44 86 12 127 12 -9 -34 -36 38 84 126 4 47 36 -27 -63 -108 18 -51 89 119 -59 -6 -6 -12 -15 29 11 -53 -44 23 65 11 -116 5 76 93 -83 -77 -39 32 110 94 38 4 -10 -3 -37 14 -80 -26 121 -33 80 6 15 47 -55 4 14 -66 83 24 121 -75 -17 -117 125 -66 -23 96 60 85 71 63 68 1 12 30 127 6 40 28 -29 -128 73 0 34 -28 2 -40 -6 4 6 -77 17 -33 -59 62 59 39 -2 46 18 75 -45 28 -17 -17 33 -7 -9 127 47 124 -47 127 -29 48 31 -24 -35 -2 29 -63 29 57 -70 4 -16 -13 24 15 -79 -27 -33 -125 116 126 0 -115 -98 77 -40 -20 -17 18 64 44 -64 126 67 -17 -29 -2 -34 22 -31 -41 -5 18 101 -46 37 34 -45 45 21 -12 68 -44 -48 -46 53 79 -121 36 25 5 70 11 -55 12 42 -25 28 8 -95 54 -16 -71 57 -36 80 -83 54 50 45 -31 108 -36 12 -37 0 70 47 -116 -25 87 38 100 82 121 -5 -45 -8 68 -33 -21 23 13 70 -37 -83 43 -5 -47 -14 -19 26 48 66 -18 66 3 27 64 93 9 -61 121 127 5 49 70 -56 -1 -25 -47 -20 -2 14 -87 -17 -15 33 -4 -15 7 8 6 -119 46 -49 73 -40 -87 -27 -15 35 -16 53 100 56 84 32 126 27 -33 -22 -41 -2 101 -58 63 27 -9 72 33 80 93 14 -79 -30 -61 30 67 47 -62 -8 65 47 -107 16 -36 -4 -65 55 52 69 -29 61 123 58 -1 -30 -126 71 -63 -9 18 -34 50 126 107 46 54 42 76 -18 -22 6 -33 61 -12 48 39 -20 -16 70 -73 49 -7 27 85 32 57 61 2 7 119 16 42 -1 90 54 9 87 -69 18 122 51 11 35 -32 -55 -61 124 26 125 34 123 61 10 -36 -77 18 -41 45 9 8 -91 102 48 49 -103 -122 40 86 37 8 -49 52 18 -27 16 35 -1 -119 44 103 -58 4 67 -40 -61 20 -52 31 -8 69 -43 126 -27 56 -40 85 -39 -45 5 48 11 54 -13 30 38 3 -25 -14 0 -8 -106 23 -12 -44 24 -36 -90 -2 -19 -66 29 112 -10 120 -90 -37 2 96 11 28 68 51 14 16 45 -11 16 -66 -128 -25 -3 -3 -66 50 -22 -73 -65 -22 -57 -11 34 -48 -17 -67 -43 66 -10 9 4 -26 62 65 6 28 -46 13 113 -4 -6 -29 -23 21 -78 -40 -20 50 4 -11 -5 1 3 -92 -102 -126 -109 -92 -27 46 21 -13 46 -47 -117 21 -17 -2 36 -106 7 9 -42 69 -19 54 10 -70 6 -44 -25 -18 68 45 -35 1 -39 -95 -79 -1 -32 -64 -88 -85 -3 29 73 -66 11 -120 59 -43 66 -60 -97 23 -20 -37 -122 29 99 -33 54 25 59 -16 4 -126 -23 9 107 13 25 -43 -128 -55 -5 6 -85 -37 -38 28 2 34 -53 -64 104 -9 -27 5 127 -54 -22 34 -87 -58 -23 -46 -79 -69 -105 19 18 -14 18 44 -25 -27 49 46 87 20 -122 19 3 -88 -8 52 -18 -9 37 54 24 48 11 -98 -28 -108 106 -68 37 77 -112 42 35 -60 -3 66 -112 90 42 29 92 68 49 9 60 72 -55 7 -16 71 55 -6 27 74 -41 -13 -20 -19 -14 -77 -38 65 -19 -23 52 -127 -59 38 18 -31 34 0 -65 11 28 28 -37 -3 -80 -10 31 38 53 34 6 -15 -18 -5 -35 28 -41 -29 -50 15 31 -60 -67 25 30 -25 -15 -7 8 -94 27 21 13 -4 -9 44 3 -12 -31 35 35 -11 -7 49 16 2 27 105 -12 -64 31 -23 -44 -63 23 -73 -14 -96 31 -7 -126 14 -39 37 7 29 111 14 -48 33 10 -34 59 57 13 15 -3 67 -27 24 -34 -50 70 84 39 63 -21 -61 -2 -67 52 -17 -63 -17 -32 -32 34 -38 -2 -26 -126 -5 -20 -14 39 -1 -31 -77 83 63 -72 -51 33 -12 123 35 -30 16 6 -62 -12 -91 -21 49 11 15 58 42 59 100 9 75 -87 -128 -62 8 89 -42 -42 -12 -109 6 -119 -6 3 -4 18 -15 115 -40 53 20 -82 -28 42 8 14 46 2 81 -4 -126 30 26 29 54 123 -7 17 -16 48 -122 17 -62 -24 -79 4 29 19 -102 6 55 48 -14 38 -76 -44 77 75 55 5 -11 18 11 -40 -58 -115 74 2 59 -48 56 94 -15 65 19 -76 14 16 33 9 -19 -27 -96 -46 -25 -12 -101 19 -49 4 -21 -43 -5 -58 2 -56 61 -127 -17 -43 9 43 4 78 25 13 -17 -62 -39 0 -10 -18 35 25 51 32 9 28 68 -4 -11 52 44 -12 77 43 17 17 0 -1 101 2 6 8 -70 -16 60 -70 22 36 -19 -5 -20 -69 10 9 -48 -47 -12 31 -98 32 3 45 76 -42 -6 109 33 -27 62 -52 14 -82 -26 -44 6 91 127 16 -47 82 29 53 98 -28 40 50 -64 5 -112 20 -54 86 32 -24 -14 3 12 68 40 -11 33 9 -45 -69 -23 -18 -40 -25 37 52 -5 6 124 -47 -105 -39 -6 -34 70 19 33 12 -82 74 -45 -36 33 51 103 -107 -65 27 -30 -23 11 -41 4 75 -31 0 53 17 -40 20 4 51 10 22 67 -36 -118 3 -13 49 104 -1 -15 61 -66 3 -2 124 13 -22 93 -15 -30 -48 -43 6 -33 21 31 57 127 26 -89 67 72 119 125 43 54 55 3 -37 30 62 31 -15 42 3 53 -73 121 -48 76 53 34 -48 36 -25 56 15 -30 -14 7 54 43 92 52 -59 98 -6 -54 73 -13 26 43 6 121 5 -113 74 125 0 15 28 4 -72 16 127 -123 127 117 66 60 125 38 88 -61 -4 13 3 6 126 3 58 66 9 35 -98 3 121 -102 -15 -101 -11 111 -1 10 37 55 35 127 15 -44 -84 39 16 -52 8 -50 -44 -61 45 -20 28 77 7 -15 -9 52 -4 30 -25 -56 -36 28 -71 -38 30 -15 -56 4 36 23 -56 5 -98 -50 -41 33 103 33 -104 -74 -2 -39 -36 -75 -42 -27 -65 47 -41 -36 -81 -34 123 7 -105 -35 -51 -101 -22 -3 -22 -22 60 73 -64 -88 89 -35 21 11 -20 47 25 21 37 48 -57 20 43 22 44 -102 -23 -44 33 69 -19 38 2 21 -47 -51 -25 43 -48 -54 -53 7 51 58 12 24 -41 50 -41 -31 -54 -30 -4 -7 -85 -36 31 49 59 -77 -47 -25 -66 11 15 43 -12 113 -20 53 -51 16 85 -22 87 111 2 19 126 18 -126 6 42 -5 14 33 -108 71 -55 23 -14 16 76 68 63 27 -47 4 -6 -62 6 106 -64 -42 15 -110 -91 21 -24 -18 15 51 53 -43 -23 3 -85 -49 5 -6 -29 51 62 22 111 -94 -62 -18 -7 -26 9 -14 39 -34 -17 83 3 6 -93 -25 -11 47 22 22 12 31 -27 -45 -1 9 9 77 -76 -14 73 75 -42 -20 -3 -24 -53 9 -38 -10 -12 38 37 21 4 -17 25 -29 -19 73 56 -34 -55 -101 81 113 86 74 40 24 82 -13 4 -15 31 -1 127 44 31 -12 44 -42 -52 -42 -16 76 26 78 -72 0 -53 36 68 62 -76 49 -30 -6 25 3 0 97 -78 86 -14 124 -77 6 -44 25 26 -8 49 -71 -35 36 -39 80 -50 23 -43 -10 -5 26 -3 -52 -61 -4 31 -29 -9 0 -4 5 -22 20 6 53 -68 22 10 -29 74 37 26 -4 -11 -13 -27 -31 55 22 5 -66 1 72 36 -27 70 33 -36 -80 -6 -15 -32 -70 -6 -43 -74 1 9 -59 -26 -6 69 -46 1 -65 18 -1 -19 47 -28 31 49 -67 49 -44 15 -12 23 20 -33 -2 -58 -61 69 24 -41 -74 -6 4 -8 -19 15 -16 12 1 10 -8 -12 2 33 -120 -33 -67 -42 -13 8 59 -29 -6 -39 14 12 25 53 8 -25 3 -39 -19 -15 3 -58 -17 -47 -9 37 -19 47 126 9 -33 -41 56 66 -18 -89 2 29 -24 73 12 34 -3 27 -65 -22 21 -18 107 16 -20 31 72 -6 -5 61 25 -3 33 33 -87 -85 -31 20 -1 -25 -37 -8 74 -22 24 -2 114 -35 -17 -51 -30 9 -6 -24 -41 2 11 48 51 -8 28 -80 -38 20 28 23 43 -14 68 -84 -119 -7 24 21 -16 -85 -123 18 -38 -10 59 -62 127 97 125 0 1 2 -63 30 91 -7 40 60 0 -52 25 -57 126 79 -100 -102 84 -11 -37 -31 9 125 122 2 108 50 57 -51 6 48 -26 -97 32 -27 78 0 32 17 41 -69 70 -60 9 -52 -6 0 -15 -29 -53 -60 -8 -116 -87 -127 38 11 58 -17 88 127 94 -65 -31 42 41 84 -16 7 -93 -125 -77 89 -78 5 94 22 22 -30 88 65 -32 -120 -28 68 16 49 79 23 12 125 -33 118 12 -8 36 104 43 -41 95 -97 -19 -57 -34 -39 -30 -7 77 12 99 1 51 43 -50 -59 35 -20 -21 -35 126 -22 -32 -4 -128 3 -52 69 -6 -59 -70 -15 -36 -101 21 2 22 -107 14 74 -78 32 17 -1 -70 -51 102 21 -126 29 -109 4 17 33 15 40 40 31 -49 -91 54 42 -28 -75 68 18 -15 -67 -128 -92 16 -75 -32 91 -33 -42 45 -12 -107 -118 -75 24 -75 32 -42 102 -83 32 -110 -16 121 80 127 -94 42 -8 33 102 87 -77 -17 -128 14 98 -84 73 97 -36 9 48 127 23 55 -44 30 -21 -96 127 95 -26 76 53 -128 -11 24 -60 59 76 9 8 -21 -117 76 34 -20 -62 15 -74 -44 5 42 -3 -31 -127 -4 106 -40 10 -108 57 58 -79 -128 39 -11 -13 76 -36 -89 -49 88 -78 10 -23 122 -15 30 -7 98 15 62 -10 116 80 77 74 -15 1 54 -84 -38 63 -24 26 89 -67 41 9 29 50 -84 -34 -49 47 -47 -47 69 56 32 -81 98 4 42 -41 23 125 63 15 26 -9 11 87 71 29 87 16 29 21 -19 89 19 8 16 -45 23 34 38 42 -44 -39 11 107 127 127 56 91 11 69 9 39 -47 -87 -100 -39 -13 -18 33 1 -10 79 10 79 -58 127 39 -75 43 124 32 -18 82 -33 25 80 81 15 -64 17 45 2 -8 -26 -18 65 4 45 10 -6 16 -6 -15 -25 -54 -49 3 -8 22 80 29 -12 -24 -66 35 -52 25 -4 63 -31 9 3 34 13 15 -37 44 72 90 -2 -12 -101 -10 -17 -4 -26 -43 17 -5 -23 -21 -12 42 15 3 64 22 36 4 3 -63 21 -37 24 36 -20 27 -13 -31 52 -16 1 -30 18 26 3 0 -84 33 42 79 29 23 -2 53 -12 -28 -9 48 39 16 -9 10 19 -42 61 5 -44 -1 -39 -5 36 76 -61 48 43 -15 -72 86 -76 49 18 -6 17 74 3 50 31 69 -35 -56 20 -34 23 -128 -1 38 90 14 -30 -51 82 -48 47 40 43 121 -18 99 -31 21 88 7 29 -29 -41 -16 0 -29 35 -10 -7 49 127 -61 0 -61 11 -54 -25 -37 -60 -106 45 -33 -40 41 -30 9 -38 66 -46 55 2 -17 20 -94 -69 63 -76 1 27 39 75 82 75 50 -15 -99 34 26 71 -14 -16 -19 -100 -112 -19 -92 7 51 25 -37 -17 -128 -13 48 -42 2 -2 38 -78 -53 97 16 -83 -78 -33 -34 10 -126 -68 -32 14 3 3 -102 25 36 -46 3 12 -67 99 -118 -53 51 67 5 -34 -17 42 -108 8 -57 -4 72 -29 1 79 -122 -66 20 -38 26 -127 51 -58 11 -49 25 -18 33 65 48 82 14 -11 9 -107 51 -31 3 6 -127 76 100 -123 88 -26 7 -27 -120 -35 -94 -37 -16 32 -116 -26 -36 -4 -31 -29 -14 -3 -96 -9 52 -3 35 15 -40 6 12 15 -80 -36 -82 4 124 15 -12 47 -1 -8 -63 3 25 -26 42 34 -57 -22 16 16 93 58 -50 102 -74 -39 -36 63 46 -10 29 -12 13 39 40 -16 -58 -42 -33 57 53 55 49 -84 103 56 -70 63 -104 -11 28 -21 -46 59 43 -1 -29 19 -2 4 -84 14 3 -88 -28 9 37 50 21 -42 9 -2 50 5 63 54 83 17 50 -46 18 90 69 -28 34 55 -103 8 -33 -38 -55 -24 -11 -10 -71 -32 -58 -4 6 -6 0 95 77 11 42 -35 -32 -10 -81 -47 -25 -12 55 -59 29 4 14 9 68 -31 -77 -5 -24 -1 42 -6 24 42 -66 22 17 -9 -49 -18 40 -39 -23 12 13 -16 -5 -47 -44 39 -14 -15 -20 36 -42 -30 28 -71 -36 -36 6 -89 -46 36 -28 10 26 12 30 -127 -94 22 -54 82 14 -51 46 -78 -68 -38 -33 14 19 -47 102 25 -17 -18 -2 -20 81 102 -114 71 68 -44 47 -39 7 4 -52 42 -13 26 54 36 -42 -63 126 18 114 8 51 -3 49 63 14 11 -84 12 -22 -56 48 -99 88 69 46 58 116 -4 -38 0 -9 -84 -14 81 -90 -48 51 -14 -30 75 -63 18 -10 118 -48 37 -11 85 31 -106 23 -18 85 3 -31 7 -41 0 70 18 61 -36 -10 36 20 16 85 -18 127 125 30 18 0 -32 50 20 16 -33 15 35 8 9 47 19 16 84 43 82 -7 54 43 13 33 8 0 -25 13 21 19 71 98 68 32 -20 -31 17 -31 -18 -30 15 -24 18 -36 51 54 -32 21 64 -63 -3 -98 20 18 30 53 -39 10 -71 -34 -61 -48 11 27 32 5 18 14 -23 -19 -27 -21 -68 -39 -38 67 36 72 -40 108 -39 13 13 42 -49 -77 115 33 -22 21 18 17 -88 -9 17 60 56 -95 1 -62 -7 90 -81 12 64 48 -5 29 -20 -12 15 -6 -12 49 58 33 -45 110 39 -2 -15 -29 9 -23 -33 46 -8 18 -51 9 -22 30 73 27 80 -23 117 98 7 -128 1 56 -14 63 24 -9 -39 -58 12 -127 -77 -20 -13 -47 -71 45 45 16 81 -30 127 21 -59 -23 -5 -19 -61 -14 77 2 8 19 83 21 31 -6 -11 25 -21 -58 26 -37 22 -69 -8 -31 -20 -5 5 9 5 -52 126 8 -8 44 -9 66 10 -3 28 -20 25 91 46 -23 54 -53 23 67 -57 -77 -122 1 -81 -1 -115 19 -61 -1 -15 43 3 -16 -43 50 22 4 -17 31 0 -37 5 15 38 -105 -22 -28 87 -32 37 42 72 -20 36 57 -1 85 49 21 -89 97 -17 104 102 78 36 5 12 63 38 74 119 3 104 -27 -39 -23 -42 46 87 29 10 3 76 9 37 -32 -34 14 6 -10 17 -12 -42 -37 84 51 -113 19 28 57 20 48 -30 -35 34 -45 -19 71 -24 19 48 5 -95 -19 5 -37 69 19 25 -61 -45 -58 30 -29 122 37 15 5 -102 -6 -15 3 -33 77 -32 -3 89 -93 -69 -58 -55 -4 -7 -12 60 32 -45 -6 -67 6 -30 -18 28 59 65 -15 -25 68 -18 -35 -25 -22 -34 -13 12 33 -70 5 -46 -25 -12 -34 -8 -88 11 -31 41 -48 -16 -45 56 45 6 17 -28 3 37 -7 -23 1 -11 -28 -2 -125 100 9 -47 9 29 33 41 3 -71 -28 24 -84 -51 -52 -28 -62 107 22 -27 44 66 32 12 -93 -39 66 -52 -38 56 50 -51 -104 12 -5 -75 -76 -70 -62 -40 33 104 -68 20 52 -23 -101 121 10 -12 48 -11 -105 32 -49 10 127 -36 -27 44 -13 -41 -84 25 0 -63 85 9 47 38 74 21 10 21 -25 34 39 9 87 54 79 43 50 54 36 100 26 60 -43 30 23 -28 59 41 -51 -39 25 14 55 -41 -8 53 -94 -50 66 82 -68 96 -38 -54 -65 3 -12 -19 -8 34 18 -25 5 15 -17 23 26 -73 3 34 61 35 -45 -16 1 -42 -10 45 -26 -102 46 -24 60 -28 -50 17 2 12 -84 41 32 -48 9 38 -45 -44 35 107 -60 -39 -57 -1 -10 -26 24 15 -60 70 -66 -60 8 -22 9 -77 -23 -115 -10 -83 11 21 18 -97 -29 9 7 -60 -26 15 -27 -36 -71 -1 95 -7 13 -50 -120 10 -3 -29 -16 -36 -34 57 41 47 29 -109 9 2 -25 44 20 56 22 -6 68 89 -22 -14 16 27 -101 84 -50 43 -23 -18 -46 -34 -21 75 -18 4 -3 -98 -19 50 6 44 38 34 18 -54 -59 19 -14 -3 14 30 12 35 -85 -86 25 47 4 42 24 31 21 18 8 49 43 -15 -24 -12 -39 24 -54 46 39 81 11 8 -64 7 -36 -82 73 -56 -28 40 -50 -88 50 -68 -8 17 -11 -24 9 -96 39 8 99 58 4 -127 -16 78 -122 14 39 19 -128 -52 -29 -43 -13 -31 -27 21 -15 33 54 11 -2 57 39 -46 65 75 -45 5 -7 48 -8 43 -63 34 -113 -51 78 -16 -9 127 32 -93 -15 49 -69 -67 3 -70 25 -21 2 39 85 -12 -26 7 41 -12 -37 10 -104 -22 -127 -1 -30 51 -13 -52 101 -19 3 -16 -18 22 -61 87 13 -31 -79 -23 -4 -91 84 34 84 52 22 24 -10 4 24 48 -31 -3 -24 31 -115 -30 124 -12 -89 12 5 -128 -7 18 -70 59 124 126 -70 -6 36 127 -21 29 77 39 -125 -50 -16 10 -123 -2 117 -44 -52 -74 3 123 44 6 31 -126 -3 -67 -5 25 36 -7 75 -117 -75 46 7 -44 -51 103 -26 -18 -125 20 18 2 -47 -29 24 -75 25 -109 115 -97 24 -80 90 -72 -31 51 23 30 61 -79 -4 -8 54 -77 76 89 -55 1 2 17 127 -22 -122 75 -47 -124 -65 -24 -42 44 -19 -40 -59 -34 -44 119 31 -127 39 -1 -74 44 -5 12 -35 -39 4 51 54 17 127 9 -12 8 16 37 30 -5 105 -10 38 3 83 -67 -127 -7 25 42 -21 -12 -43 63 30 37 -101 -125 -84 38 75 -44 -12 -33 -69 -79 104 -94 42 -54 6 20 -8 57 -84 -21 -59 71 -39 -40 42 46 113 79 -50 -20 -40 -59 -13 17 0 -15 -3 -9 2 83 -11 79 8 -45 57 43 9 12 111 27 92 -55 17 -66 4 0 -5 -37 15 124 99 45 -1 38 9 -97 57 7 -117 50 -112 3 -128 -6 -36 15 -56 -93 -50 -34 -126 25 25 1 -88 -101 -60 -24 -42 0 -7 31 10 40 -33 27 61 59 43 83 123 4 0 -107 -59 -8 -61 -55 81 25 -35 -43 44 -41 -100 16 109 -26 102 -48 -9 6 -39 45 -26 61 36 -10 16 -57 58 29 12 96 -32 19 24 -126 43 -14 36 -39 -54 8 16 -116 -20 -48 -106 103 13 -34 -51 -7 -31 31 -59 90 90 75 67 62 -11 14 -34 -71 -45 -77 -26 -62 110 71 47 -92 -103 -15 122 -17 35 37 30 127 -33 17 -55 -39 4 67 -17 -30 -24 16 11 -22 -8 -20 -24 18 29 -53 40 37 -1 -11 19 53 -14 44 23 45 14 46 15 7 72 -39 -114 -10 -52 -60 -73 67 73 -12 29 -6 72 -47 42 -44 -24 -11 -9 -67 74 -115 31 103 -38 -64 7 -95 28 -16 -29 -108 15 -21 22 66 -39 -3 -123 39 74 -32 -48 4 -59 0 66 103 -63 22 -27 16 -8 -87 59 31 21 -15 -112 -57 -25 -11 30 -68 -5 -20 -39 83 49 -79 0 -40 36 79 -98 -4 -34 -31 -36 39 3 35 21 -14 49 -85 119 25 -59 -10 -97 -29 21 19 59 -3 -128 -17 0 76 9 45 -44 120 -6 11 2 -39 16 50 21 -1 -8 -7 -66 58 -49 -25 -15 63 -67 62 11 15 1 123 -17 -13 -109 -15 -90 -80 98 -97 -14 8 69 -87 7 3 29 -40 -33 42 32 42 -5 -35 105 14 50 5 -97 32 127 70 -35 27 -55 82 11 43 -92 56 -50 9 51 27 8 -22 -21 -48 -43 -108 -28 12 -21 -46 53 -3 29 122 58 72 -62 41 -1 -11 -120 -51 -101 -32 -109 42 87 22 67 -55 -13 -85 13 81 -26 -45 23 -72 -52 45 67 18 47 30 -47 -32 60 -55 -32 -41 41 124 59 -60 29 7 127 -6 0 -95 57 -7 36 34 -42 30 22 8 93 -23 85 39 -1 46 121 -46 45 57 27 -7 17 48 19 78 0 -42 -80 75 -39 98 38 41 118 14 72 46 127 56 96 -12 6 -55 59 93 11 -81 55 38 9 -19 120 -44 -11 -69 125 -82 -21 84 40 -12 17 67 52 44 55 77 53 -72 91 127 75 -35 62 -20 -68 -9 -97 51 -35 -81 -29 -86 5 15 38 74 60 9 11 -57 110 -42 -5 54 -9 -35 1 9 7 24 -8 10 35 35 36 -43 -45 -12 -31 8 -3 2 -1 23 -86 2 -60 70 47 20 72 11 -22 3 -9 -25 -58 -42 -7 -16 7 16 -66 -36 94 74 -2 -31 -39 -40 52 93 7 9 -7 -78 -41 9 81 -57 -81 -33 64 50 47 58 51 -10 -18 -2 -30 -58 3 22 -127 47 45 -48 -88 -39 -46 7 85 40 -35 25 9 -63 6 -22 -68 41 -6 30 -24 62 28 -111 -106 25 4 -80 28 67 24 -35 -43 -44 -15 -7 96 -28 97 -105 13 88 75 9 46 -99 105 -38 -67 63 90 45 -45 18 47 81 77 -26 -12 -29 -16 51 37 7 15 53 -47 11 -4 -76 57 -31 -24 -63 5 -11 -71 40 66 5 -61 18 16 -83 46 103 55 -64 -98 -5 68 -4 -20 45 98 17 0 -87 51 -12 -17 -10 -116 48 55 -45 127 -29 -16 -113 31 -16 -85 85 -60 7 -45 -74 -67 -100 105 123 79 58 -21 -10 -103 72 -17 7 -71 29 78 -44 125 -101 -9 -2 46 -51 -105 28 52 -49 -27 22 96 5 28 15 -63 6 -52 82 7 72 43 -47 -27 75 -66 -34 -79 -91 19 35 27 127 69 -75 75 36 35 32 80 -99 -77 -48 -21 119 40 13 -59 107 -104 127 -72 -106 63 40 88 9 -8 76 -56 4 125 91 39 123 -93 -36 -7 -97 -94 -7 20 122 -42 -87 -32 26 -23 -52 -46 4 -45 110 -53 -70 -28 91 -39 57 5 -44 90 118 -33 44 112 4 -48 25 37 2 31 -34 97 -50 -94 -63 3 126 17 -49 7 33 -63 -36 -100 51 -60 95 -12 -15 123 -26 -5 93 65 34 62 -128 112 -24 127 121 127 -17 66 -31 68 -20 -58 -127 126 87 -107 -69 -58 -112 126 -70 41 32 -93 -8 -111 -79 114 -72 -119 -111 3 110 -23 86 -26 99 -11 -52 127 -92 -106 -80 22 -22 -14 -74 8 84 -54 -40 61 -90 31 -61 -127 -26 8 22 -91 -9 81 -57 112 -86 -36 76 31 53 42 55 7 -61 -11 34 -99 63 -46 -119 127 37 -22 -85 -107 55 61 -31 45 1 -109 -65 -52 -37 -52 10 -96 -31 10 -124 -45 44 26 55 -31 79 -32 -32 42 -91 34 46 123 83 -127 18 36 49 -69 11 -1 -67 99 -64 2 -45 14 18 -84 125 -101 -101 67 -126 -72 -47 54 113 -10 -56 51 127 7 84 77 1 12 35 67 -54 -6 22 52 45 34 -39 25 -34 44 -87 -53 -33 45 96 -32 99 23 29 74 -82 97 4 -35 -30 11 7 22 -69 54 20 0 36 -10 15 66 12 -97 44 75 40 37 -110 105 -1 20 -59 75 68 125 -127 37 16 44 65 -7 105 -6 26 -126 42 -51 -54 -6 21 48 0 30 10 29 21 11 -2 -40 119 48 29 63 103 -56 35 -15 30 54 55 -70 56 8 25 105 10 4 -16 -26 -1 31 59 34 25 37 -45 13 -20 -25 -7 -12 11 56 -10 46 42 -7 -62 32 -21 58 34 36 3 -9 -51 26 -26 -6 20 41 15 40 22 23 -33 -1 -20 18 -19 -29 55 28 -52 -36 -6 50 11 -14 -42 34 22 5 -5 -35 -9 -27 -4 29 -14 10 25 16 11 -62 26 -21 -26 -10 34 17 -21 -46 4 -33 41 16 -33 -25 -8 -13 -22 29 -6 15 31 19 14 -49 11 2 -45 9 -22 6 12 87 10 54 7 31 -37 17 85 -10 -16 -9 1 -13 18 30 25 2 -70 9 11 -7 36 30 4 58 -24 -6 -34 13 52 -32 22 127 -2 29 25 -14 24 68 -23 2 -1 -71 -29 27 26 43 58 -70 20 -25 78 -32 -12 23 -33 3 11 46 6 -92 23 -24 -76 -10 -40 14 7 5 47 47 -26 -1 20 -2 -4 -6 -29 -30 29 61 -27 49 -5 51 27 -115 -7 31 -14 16 96 22 1 -9 4 -9 -1 78 86 70 58 52 37 21 15 11 14 16 7 -6 -5 2 8 23 43 85 124 126 123 121 106 103 88 62 35 29 18 11 -4 -5 2 -2 -31 1 14 2 41 110 82 44 28 19 12 6 3 9 7 0 -7 -1 2 4 42 58 59 73 68 49 -25 20 48 61 56 41 40 28 16 12 8 -1 3 6 10 8 7 4 8 10 9 24 3 74 111 114 69 16 5 -19 -34 -29 -31 -25 -29 -30 -36 -36 -48 -45 -45 -40 -29 -27 12 -32 -25 -24 -50 -64 -52 -50 -67 -62 -61 -55 -47 -48 -54 -58 -77 -73 -26 -18 -42 -67 -62 12 19 36 10 -2 1 -31 -11 -6 -1 -4 -6 -15 -22 -39 -39 -37 -36 -40 -37 -28 -9 34 36 43 40 42 31 31 45 32 25 15 17 12 3 -18 -31 -33 -29 -24 -39 -45 3 46 16 27 20 11 -1 -8 -17 -30 -32 -19 -13 -10 -16 -17 -34 -39 -16 -5 -32 -122 -128 -22 -19 -9 19 52 50 21 23 14 10 3 4 6 10 10 12 22 29 8 -6 -30 -71 58 48 35 21 10 6 -1 -3 12 19 15 7 -7 4 24 11 -3 17 26 25 33 44 6 -15 -22 -12 6 11 -15 -32 -31 -31 -35 -19 -12 0 15 5 14 89 124 116 125 123 19 78 73 67 78 3 3 20 30 48 58 46 52 63 59 27 16 11 -18 -29 -30 -23 -3 -6 -12 4 10 6 4 -3 -14 -26 -40 -57 -61 -57 -52 -46 -35 -21 -4 15 53 53 10 -28 -43 -43 -15 -37 -32 -30 -16 -33 -42 -28 -26 -33 -29 -29 -33 -40 -25 -22 -35 -38 -13 -36 -22 -25 -16 -21 -10 -6 -15 -21 -23 -24 -7 -1 -13 9 28 26 -1 0 2 9 127 110 -16 1 7 40 36 44 45 40 35 27 27 33 27 35 47 31 10 10 14 1 -90 -90 -79 -63 -68 -79 -72 -83 -70 -76 -78 -76 -55 -38 -29 -10 0 -8 -2 9 13 -11 44 1 0 74 40 -5 16 -24 1 17 25 16 1 -6 -10 -1 1 -2 0 4 7 5 57 96 53 -45 -81 -11 -9 -80 -73 -76 -79 -75 -80 -88 -90 -82 -71 -64 -61 -70 -93 -84 -128 -128 -77 -21 13 37 41 20 10 14 15 19 33 38 18 7 6 -4 0 -4 -16 -39 -64 -125 -122 -79 -66 -54 -31 -21 -25 -26 -24 -18 -12 -10 -9 -5 -1 7 -1 8 21 33 34 53 57 59 67 63 56 42 39 46 47 44 50 48 28 1 6 44 28 -3 -49 -20 -5 -7 0 0 -5 -9 -15 -1 3 15 21 8 6 3 7 18 40 27 19 11 25 -3 31 -4 6 18 37 35 39 33 24 31 34 27 28 30 24 24 20 35 44 41 -15 -5 75 22 25 34 26 10 18 18 0 -1 9 -4 6 7 -8 19 37 19 -4 -12 18 -29 -27 -1 5 7 -11 15 -24 -34 -12 -7 -11 -26 -42 -38 -48 -58 -66 -72 -70 -66 -51 -27 37 3 -41 -57 -49 -47 -49 -50 -40 -32 -32 -32 -38 -54 -67 -55 -39 -66 -78 -81 -72 -67 5 11 -18 -37 -104 -123 -85 -49 -36 -18 1 9 0 -10 -24 -27 -18 -8 1 -1 10 23 -18 -64 -94 -114 -127 -120 -121 -127 -125 -111 -117 -115 -108 -90 -36 9 12 -1 6 14 26 37 -34 -52 -47 -49 -48 -57 -51 -36 -37 -37 -33 -33 -34 -36 -33 -27 -27 -38 -26 -6 2 -21 -39 -8 34 85 127 127 103 67 8 -28 -22 0 30 33 15 11 -1 -8 -2 16 24 -21 20 3 11 20 17 7 3 30 43 34 24 18 8 8 6 10 11 22 16 2 -13 2 -31 -51 -47 -49 -49 -60 -48 -38 -42 -23 -18 -31 -34 -40 -36 -23 -12 -13 -25 -12 -16 -38 -29 -38 -82 -92 -113 -125 -125 -126 -126 -127 -126 -110 -95 -75 -56 -43 -33 -1 2 -12 -20 -26 10 36 39 6 23 54 46 0 -33 -37 0 32 49 50 48 38 25 21 25 26 28 9 36 61 62 40 28 36 32 19 22 19 17 29 32 29 25 17 6 -12 -25 -19 9 9 50 40 44 33 38 21 9 1 -7 2 25 32 16 -20 -56 -98 -128 -128 -127 -127 -59 28 1 17 17 27 15 0 -2 19 21 18 17 24 34 40 47 45 25 32 65 80 113 127 78 44 40 44 29 32 37 46 64 66 54 31 41 29 10 20 36 26 13 5 32 45 -36 -14 -13 -17 -25 -21 -35 -39 -22 -11 -8 0 -1 4 7 -9 -22 -33 -36 -30 -35 -119 -103 -86 -68 -56 -43 -47 -55 -42 -22 -23 -18 -25 -13 -8 11 -9 -18 -9 -11 2 -19 -124 88 34 59 19 36 37 50 45 61 46 36 39 41 35 46 58 62 80 105 127 127 126 -25 -27 -49 -70 -66 -56 -68 -85 -94 -89 -97 -89 -85 -79 -64 -37 -26 -29 -35 -31 -32 -22 -93 -46 -8 -3 -15 -14 -17 -38 -54 -57 -48 -46 -46 -54 -71 -73 -65 -65 -74 -76 -59 43 10 23 47 63 70 62 43 65 77 58 47 57 57 45 39 31 29 35 31 30 34 17 -31 -12 -17 -26 -33 -40 -53 -77 -95 -83 -63 -50 -48 -34 -24 -29 -45 -33 -18 -10 -5 -53 -27 -25 -28 -20 -19 -15 -17 -16 -23 -28 -30 -31 -38 -37 -39 -33 -44 -70 -94 -107 -120 -49 127 127 89 22 -7 -11 -21 -13 10 60 113 119 104 107 73 62 44 51 50 39 34 11 -20 -24 -38 -47 -42 -36 -25 -14 -11 -12 -12 -17 -10 -7 -10 -9 -15 -29 -32 -40 -84 -128 -8 -12 4 16 7 29 90 82 61 55 54 51 40 31 33 31 20 15 9 19 33 32 19 18 10 11 9 4 -9 -5 3 3 -5 1 6 5 -7 -30 -41 -35 -34 -33 12 1 -8 22 16 13 -14 -30 -40 -54 -70 -69 -61 -68 -81 -103 -126 -127 -128 -127 -110 -94 -38 -6 8 -1 -22 -17 -19 -43 -40 -39 -49 -75 -104 -126 -128 -128 -70 -58 -41 21 36 17 20 72 13 15 31 27 18 7 0 -9 -15 -25 -31 -21 -9 2 16 2 -47 -128 -128 -120 -79 -36 -81 -78 -42 -7 -14 -13 -9 -13 -18 -22 -15 -10 -5 -6 -21 -37 -52 -41 -9 -21 -49 -51 -19 -121 -128 -128 -128 -122 -89 -50 -20 -13 -22 -41 -61 -61 -54 -26 -32 -42 -52 -56 -38 -33 -6 -14 -30 -38 -44 -47 -51 -47 -41 -42 -45 -52 -57 -53 -39 -39 -48 -49 -24 -9 26 12 7 10 2 9 14 13 13 11 3 8 6 3 5 17 24 49 88 127 127 127 111 70 -25 -37 -45 -62 -57 -55 -56 -47 -49 -47 -38 -28 -24 -22 -15 -11 0 2 -9 -10 -8 15 -11 -34 -35 -37 -37 -41 -35 -39 -54 -89 -104 -79 -71 -55 -15 -3 1 -43 -47 -14 -9 -4 66 54 30 17 33 26 23 50 53 39 29 25 36 44 47 46 46 52 38 24 16 11 37 15 -11 -27 -32 -24 -22 -17 -18 -11 -6 -12 -8 -12 -14 -18 -15 -51 -54 -21 11 50 58 21 11 11 5 11 7 -11 2 17 14 14 10 17 30 25 14 7 27 31 33 32 62 37 18 14 15 29 26 19 4 -17 -24 1 17 22 20 11 -28 -4 63 120 127 117 50 86 121 127 125 127 77 33 45 66 81 111 100 79 77 93 88 60 52 47 34 26 12 -7 -8 -13 -14 -5 2 10 18 1 -36 -53 -76 -73 -61 -56 -51 -35 -48 -79 -101 -19 26 12 36 57 65 92 122 127 127 90 36 28 32 30 18 7 -5 5 15 6 3 8 25 22 16 10 13 22 30 37 57 62 70 82 81 90 105 117 125 111 126 127 127 127 -5 -31 -31 -31 -28 -30 -20 -6 -13 -16 -10 -17 -29 -32 -26 -15 -20 -26 -28 -17 -20 -24 21 30 37 45 40 34 37 50 50 54 51 54 54 61 57 51 51 71 112 127 127 127 -5 47 58 40 22 10 2 2 18 35 52 62 60 51 43 32 21 25 34 43 11 -53 16 32 41 21 13 16 23 14 20 28 35 37 34 39 34 20 10 1 10 20 18 7 -38 -12 -30 -31 -12 -18 -5 2 -10 -10 -18 -1 -9 -2 4 20 13 11 9 0 5 66 20 34 70 67 9 7 46 93 90 68 44 38 19 17 19 34 35 12 -4 -3 -4 0 104 118 109 84 67 61 78 68 48 46 52 46 37 36 41 61 60 44 43 33 13 -8 28 4 -24 -29 -30 -35 -52 -48 -15 4 7 -16 -16 -10 -8 -17 -16 -1 13 -7 -25 -47 60 67 83 59 40 31 30 53 65 59 51 55 45 51 63 49 36 37 32 41 44 -1 -15 -23 -13 -12 -14 -11 -6 -8 -21 -49 -69 -71 -71 -70 -49 -26 -2 10 18 16 23 39 -12 -7 11 8 6 22 13 -2 14 35 42 40 58 82 104 123 124 107 75 66 39 79 41 41 64 103 117 127 127 117 61 28 24 35 58 74 95 104 118 110 53 27 12 -2 95 63 54 38 26 25 30 30 28 19 21 26 33 42 21 -2 -21 -12 12 19 19 -64 -15 -29 -30 -20 -36 -39 -52 -51 -30 2 33 60 85 97 107 103 103 80 68 51 26 -8 8 17 20 -3 32 50 39 37 26 14 6 2 4 8 13 24 21 10 22 26 15 2 -38 -26 -21 -32 -27 -23 -21 -33 -25 -33 -28 -24 -25 -20 -17 9 2 -60 -71 -42 -37 -26 -128 -61 -69 -77 -78 -61 -60 -58 -33 -12 8 42 16 24 44 24 3 -2 6 5 -8 -2 26 5 -25 -2 7 -43 -37 -13 -80 -104 -120 -114 -100 -93 -87 -66 -50 -44 -52 -52 -46 -30 1 15 34 23 7 4 -11 -14 -10 4 7 -18 12 5 -64 -122 -128 25 127 53 -20 27 -7 -7 -6 17 31 26 31 36 25 14 12 17 17 18 24 15 8 -1 2 14 28 56 -31 -14 -7 -7 -4 1 1 -2 7 -4 -3 -9 -11 -9 -10 21 48 94 125 76 -22 -125 13 9 4 1 7 22 9 7 12 22 20 18 10 10 6 -1 -5 34 76 58 13 -57 -41 -16 4 25 45 57 94 100 118 126 117 105 71 37 1 -10 -13 -31 -30 -14 13 36 -36 -14 -32 -38 -37 -35 -31 -40 -48 -54 -62 -53 -55 -60 -62 -47 -55 -69 -41 -25 -21 -27 -37 -50 -47 -48 -55 -59 -66 -46 -31 -31 -25 -29 -32 -37 -34 -39 -14 0 -1 12 45 127 43 13 -2 2 2 0 -22 -74 -111 -110 -72 -37 -9 7 33 34 21 15 11 8 19 31 31 4 -21 -18 -16 -13 -17 13 21 11 -3 11 27 59 76 70 76 102 51 -50 -102 -59 -30 48 50 38 8 -6 -39 -35 32 45 35 31 17 13 1 14 40 -7 -38 -9 -14 -28 24 1 1 127 -128 98 -128 127 -128 -128 127 127 83 127 46 96 127 127 -128 127 127 -128 -128 -128 127 -128 -128 76 boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/config.cpp000066400000000000000000000050331516712004000245660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureRNNoise::ConfigID = "rnnoise"; BoCA::ConfigureRNNoise::ConfigureRNNoise() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::RNNoise"); Int signalType = config->GetIntValue(ConfigID, "SignalType", 2); Int noiseType = config->GetIntValue(ConfigID, "NoiseType", 0); group_signal = new GroupBox(i18n->TranslateString("Signal/noise type"), Point(7, 11), Size(286, 68)); text_signal = new Text(i18n->AddColon(i18n->TranslateString("Signal type")), Point(10, 15)); text_noise = new Text(i18n->AddColon(i18n->TranslateString("Noise type")), Point(10, 42)); Int maxTextSize = Math::Max(text_signal->GetUnscaledTextWidth(), text_noise->GetUnscaledTextWidth()); combo_signal = new ComboBox(Point(17 + maxTextSize, 12), Size(259 - maxTextSize, 0)); combo_signal->AddEntry(i18n->TranslateString("General")); combo_signal->AddEntry(i18n->TranslateString("Voice (incl. laughter etc.)")); combo_signal->AddEntry(i18n->TranslateString("Speech")); combo_signal->SelectNthEntry(signalType); combo_noise = new ComboBox(Point(17 + maxTextSize, 39), Size(259 - maxTextSize, 0)); combo_noise->AddEntry(i18n->TranslateString("General")); combo_noise->AddEntry(i18n->TranslateString("Recording")); combo_noise->SelectNthEntry(noiseType); group_signal->Add(text_signal); group_signal->Add(combo_signal); group_signal->Add(text_noise); group_signal->Add(combo_noise); Add(group_signal); SetSize(Size(300, 86)); } BoCA::ConfigureRNNoise::~ConfigureRNNoise() { DeleteObject(group_signal); DeleteObject(text_signal); DeleteObject(combo_signal); DeleteObject(text_noise); DeleteObject(combo_noise); } Int BoCA::ConfigureRNNoise::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "SignalType", combo_signal->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "NoiseType", combo_noise->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/config.h000066400000000000000000000021071516712004000242320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_RNNOISECONFIG #define H_RNNOISECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureRNNoise : public ConfigLayer { private: GroupBox *group_signal; Text *text_signal; ComboBox *combo_signal; Text *text_noise; ComboBox *combo_noise; public: static const String ConfigID; ConfigureRNNoise(); ~ConfigureRNNoise(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/dllinterface.cpp000066400000000000000000000035161516712004000257610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" RNNOISE_CREATE ex_rnnoise_create = NIL; RNNOISE_DESTROY ex_rnnoise_destroy = NIL; RNNOISE_PROCESS_FRAME ex_rnnoise_process_frame = NIL; RNNOISE_MODEL_FROM_FILE ex_rnnoise_model_from_file = NIL; RNNOISE_MODEL_FREE ex_rnnoise_model_free = NIL; DynamicLoader *rnnoisedll = NIL; Bool LoadRNNoiseDLL() { rnnoisedll = BoCA::Utilities::LoadCodecDLL("rnnoise"); if (rnnoisedll == NIL) return False; ex_rnnoise_create = (RNNOISE_CREATE) rnnoisedll->GetFunctionAddress("rnnoise_create"); ex_rnnoise_destroy = (RNNOISE_DESTROY) rnnoisedll->GetFunctionAddress("rnnoise_destroy"); ex_rnnoise_process_frame = (RNNOISE_PROCESS_FRAME) rnnoisedll->GetFunctionAddress("rnnoise_process_frame"); ex_rnnoise_model_from_file = (RNNOISE_MODEL_FROM_FILE) rnnoisedll->GetFunctionAddress("rnnoise_model_from_file"); ex_rnnoise_model_free = (RNNOISE_MODEL_FREE) rnnoisedll->GetFunctionAddress("rnnoise_model_free"); if (ex_rnnoise_create == NIL || ex_rnnoise_destroy == NIL || ex_rnnoise_process_frame == NIL || ex_rnnoise_model_from_file == NIL || ex_rnnoise_model_free == NIL) { FreeRNNoiseDLL(); return False; } return True; } Void FreeRNNoiseDLL() { BoCA::Utilities::FreeCodecDLL(rnnoisedll); rnnoisedll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/dllinterface.h000066400000000000000000000024501516712004000254220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *rnnoisedll; Bool LoadRNNoiseDLL(); Void FreeRNNoiseDLL(); typedef DenoiseState * (*RNNOISE_CREATE) (RNNModel *); typedef void (*RNNOISE_DESTROY) (DenoiseState *); typedef float (*RNNOISE_PROCESS_FRAME) (DenoiseState *, float *, const float *); typedef RNNModel * (*RNNOISE_MODEL_FROM_FILE) (FILE *); typedef void (*RNNOISE_MODEL_FREE) (RNNModel *); extern RNNOISE_CREATE ex_rnnoise_create; extern RNNOISE_DESTROY ex_rnnoise_destroy; extern RNNOISE_PROCESS_FRAME ex_rnnoise_process_frame; extern RNNOISE_MODEL_FROM_FILE ex_rnnoise_model_from_file; extern RNNOISE_MODEL_FREE ex_rnnoise_model_free; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/rnnoise.cpp000066400000000000000000000112071516712004000247760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "rnnoise.h" #include "config.h" const String &BoCA::DSPRNNoise::GetComponentSpecs() { static String componentSpecs; if (rnnoisedll != NIL) { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("RNNoise Noise Reduction")).Append(" \ 1.0 \ rnnoise-dsp \ dsp \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadRNNoiseDLL(); } Void smooth::DetachDLL() { FreeRNNoiseDLL(); } namespace BoCA { /* Constants. */ static const Int frameSize = 480; /* Models. */ static const char *models[2][3] = { { "mp.rnnn", "lq.rnnn", NIL }, { "cb.rnnn", "bd.rnnn", "sh.rnnn" } }; }; BoCA::DSPRNNoise::DSPRNNoise() { configLayer = NIL; model = NIL; } BoCA::DSPRNNoise::~DSPRNNoise() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPRNNoise::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); Int signal = config->GetIntValue(ConfigureRNNoise::ConfigID, "SignalType", 2); Int noise = config->GetIntValue(ConfigureRNNoise::ConfigID, "NoiseType", 0); /* Create model. */ if (models[noise][signal] != NIL) { String modelFileName = Utilities::GetBoCADirectory().Append("boca.dsp.rnnoise").Append(Directory::GetDirectoryDelimiter()).Append(models[noise][signal]); #if defined __WIN32__ FILE *modelFile = _wfopen(Directory::MakeExtendedPath(File(modelFileName)), L"rbN"); #else FILE *modelFile = fopen(modelFileName.ConvertTo("UTF-8"), "rbe"); #endif if (modelFile == NIL) { errorString = "Unable to open model file."; errorState = True; return False; } model = ex_rnnoise_model_from_file(modelFile); fclose(modelFile); } /* Create RNNoise states. */ for (Int c = 0; c < format.channels; c++) states.Add(ex_rnnoise_create(model)); return True; } Bool BoCA::DSPRNNoise::Deactivate() { /* Destroy RNNoise states. */ for (Int c = 0; c < format.channels; c++) ex_rnnoise_destroy(states.GetNth(c)); states.RemoveAll(); /* Free model. */ if (model != NIL) { ex_rnnoise_model_free(model); model = NIL; } return True; } Int BoCA::DSPRNNoise::TransformData(Buffer &data) { /* Append data to samples buffer. */ samples.Resize(samples.Size() + data.Size() / 2); memcpy(samples + samples.Size() - data.Size() / 2, data, data.Size()); /* Process frames. */ for (Int i = 0; i < samples.Size() / format.channels / frameSize; i++) { for (Int c = 0; c < format.channels; c++) { float frame[frameSize]; for (Int n = 0; n < frameSize; n++) frame[n] = samples[i * frameSize * format.channels + n * format.channels + c]; ex_rnnoise_process_frame(states.GetNth(c), frame, frame); for (Int n = 0; n < frameSize; n++) samples[i * frameSize * format.channels + n * format.channels + c] = frame[n]; } } /* Copy processed frames to data buffer. */ Int samplesLeft = samples.Size() % (frameSize * format.channels); data.Resize((samples.Size() - samplesLeft) * 2); memcpy(data, samples, data.Size()); /* Keep remaining samples. */ memmove(samples, samples + samples.Size() - samplesLeft, samplesLeft * 2); samples.Resize(samplesLeft); return data.Size(); } Int BoCA::DSPRNNoise::Flush(Buffer &data) { /* Copy remaining samples to data buffer. */ Int numSamples = samples.Size(); data.Resize(frameSize * format.channels * 2); data.Zero(); memcpy(data, samples, numSamples * 2); samples.Resize(0); /* Transform samples and cut data buffer at actual end of audio. */ TransformData(data); data.Resize(numSamples * 2); return data.Size(); } ConfigLayer *BoCA::DSPRNNoise::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureRNNoise(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rnnoise/rnnoise.h000066400000000000000000000022721516712004000244450ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DSPRNNoise) namespace BoCA { class DSPRNNoise : public CS::DSPComponent { private: ConfigLayer *configLayer; RNNModel *model; Array states; Buffer samples; public: static const String &GetComponentSpecs(); DSPRNNoise(); ~DSPRNNoise(); Bool Activate(); Bool Deactivate(); Int TransformData(Buffer &); Int Flush(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPRNNoise) BoCA_END_COMPONENT(DSPRNNoise) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/000077500000000000000000000000001516712004000232455ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/Makefile000066400000000000000000000012331516712004000247040ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = rubberband TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o rubberband.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/config.cpp000066400000000000000000000336311516712004000252240ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureRubberBand::ConfigID = "RubberBand"; BoCA::ConfigureRubberBand::ConfigureRubberBand() { const Config *config = Config::Get(); tempo = Math::Round(100.0 / (config->GetIntValue(ConfigID, "Stretch", 1000) / 1000.0)); pitchOption = config->GetIntValue(ConfigID, "PitchOption", 0); pitch = Math::Round(Math::Log2(config->GetIntValue(ConfigID, "Pitch", 1000) / 1000.0) * 12.0 * 2.0); smoothing = config->GetIntValue(ConfigID, "Smoothing", False); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::RubberBand"); /* Basic options. */ group_basic = new GroupBox(i18n->TranslateString("Basic controls"), Point(7, 11), Size(400, 92)); text_tempo = new Text(i18n->AddColon(i18n->TranslateString("Tempo")), Point(10, 15)); text_pitch = new Text(i18n->AddColon(i18n->TranslateString("Pitch")), Point(10, 40)); Int maxTextSize = Math::Max(text_tempo->GetUnscaledTextWidth(), text_pitch->GetUnscaledTextWidth()); slider_tempo = new Slider(Point(maxTextSize + 16, 13), Size(150, 0), OR_HORZ, &tempo, 25, 200); slider_tempo->onValueChange.Connect(&ConfigureRubberBand::OnChangeTempo, this); text_tempo_value = new Text(i18n->TranslateString("%1%", "Technical").Replace("%1", "+100"), Point(10, 15)); text_tempo_value->SetOrientation(OR_UPPERRIGHT); option_semitones = new OptionBox(i18n->TranslateString("Semitones"), Point(maxTextSize + 16, 38), Size(100, 0), &pitchOption, 0); option_semitones->onAction.Connect(&ConfigureRubberBand::OnChangePitchOption, this); option_ratio = new OptionBox(i18n->TranslateString("Frequency ratio"), Point(maxTextSize + 16, 64), Size(100, 0), &pitchOption, 1); option_ratio->onAction.Connect(&ConfigureRubberBand::OnChangePitchOption, this); maxTextSize = Math::Max(option_semitones->GetUnscaledTextWidth(), option_ratio->GetUnscaledTextWidth()); option_semitones->SetWidth(maxTextSize + 23); option_ratio->SetWidth(maxTextSize + 23); slider_semitones = new Slider(Point(option_semitones->GetX() + option_semitones->GetWidth() + 8, 38), Size(150, 0), OR_HORZ, &pitch, -36, 36); slider_semitones->onValueChange.Connect(&ConfigureRubberBand::OnChangeSemitones, this); text_semitones_value = new Text("+24.0", Point(10, 40)); text_semitones_value->SetOrientation(OR_UPPERRIGHT); edit_ratio_num = new EditBox("000.00", Point(option_ratio->GetX() + option_ratio->GetWidth() + 8, 63), Size(50, 0), 8); edit_ratio_num->SetFlags(EDB_NUMERIC); edit_ratio_num->SetWidth(edit_ratio_num->GetUnscaledTextWidth() + 6); edit_ratio_num->SetText(String::FromFloat(config->GetIntValue(ConfigID, "RatioNum", 4320000) / 10000.0)); edit_ratio_num->onInput.Connect(&ConfigureRubberBand::OnEditRatio, this); text_ratio_num_hz = new Text(i18n->TranslateString("Hz"), Point(edit_ratio_num->GetX() + edit_ratio_num->GetWidth() + 5, 66)); text_ratio_colon = new Text(i18n->TranslateString(":"), Point(text_ratio_num_hz->GetX() + text_ratio_num_hz->GetUnscaledTextWidth() + 5, 66)); edit_ratio_den = new EditBox(String::FromFloat(config->GetIntValue(ConfigID, "RatioDen", 4400000) / 10000.0), Point(text_ratio_colon->GetX() + text_ratio_colon->GetUnscaledTextWidth() + 5, 63), Size(edit_ratio_num->GetWidth(), 0), 8); edit_ratio_den->SetFlags(EDB_NUMERIC); edit_ratio_den->onInput.Connect(&ConfigureRubberBand::OnEditRatio, this); text_ratio_den_hz = new Text(i18n->TranslateString("Hz"), Point(edit_ratio_den->GetX() + edit_ratio_den->GetWidth() + 5, 66)); text_ratio_equals = new Text(i18n->TranslateString("="), Point(text_ratio_den_hz->GetX() + text_ratio_den_hz->GetUnscaledTextWidth() + 5, 66)); text_ratio_value = new Text(NIL, Point(text_ratio_equals->GetX() + text_ratio_equals->GetUnscaledTextWidth() + 5, 66)); maxTextSize = Math::Max(text_tempo_value->GetUnscaledTextWidth(), text_semitones_value->GetUnscaledTextWidth()); text_tempo_value->SetX(maxTextSize + 10); text_semitones_value->SetX(maxTextSize + 10); slider_tempo->SetWidth(group_basic->GetWidth() - slider_tempo->GetX() - maxTextSize - 18); slider_semitones->SetWidth(group_basic->GetWidth() - slider_semitones->GetX() - maxTextSize - 18); group_basic->Add(text_tempo); group_basic->Add(slider_tempo); group_basic->Add(text_tempo_value); group_basic->Add(text_pitch); group_basic->Add(option_semitones); group_basic->Add(slider_semitones); group_basic->Add(text_semitones_value); group_basic->Add(option_ratio); group_basic->Add(edit_ratio_num); group_basic->Add(text_ratio_num_hz); group_basic->Add(text_ratio_colon); group_basic->Add(edit_ratio_den); group_basic->Add(text_ratio_den_hz); group_basic->Add(text_ratio_equals); group_basic->Add(text_ratio_value); Add(group_basic); OnChangeTempo(slider_tempo->GetValue()); OnChangePitchOption(); OnEditRatio(); OnChangeSemitones(slider_semitones->GetValue()); /* Tuning options. */ group_tuning = new GroupBox(i18n->TranslateString("Advanced options"), Point(7, 114), Size(400, 228)); text_detector = new Text(i18n->AddColon(i18n->TranslateString("Transient detection")), Point(10, 15)); combo_detector = new ComboBox(Point(10, 12), Size(300, 0)); combo_detector->AddEntry(i18n->TranslateString("Compound")); combo_detector->AddEntry(i18n->TranslateString("Percussive")); combo_detector->AddEntry(i18n->TranslateString("Soft")); combo_detector->SelectNthEntry(config->GetIntValue(ConfigID, "Detector", 0)); text_transients = new Text(i18n->AddColon(i18n->TranslateString("Transient handling")), Point(10, 42)); combo_transients = new ComboBox(Point(10, 39), Size(300, 0)); combo_transients->AddEntry(i18n->TranslateString("Crisp")); combo_transients->AddEntry(i18n->TranslateString("Mixed")); combo_transients->AddEntry(i18n->TranslateString("Smooth")); combo_transients->SelectNthEntry(config->GetIntValue(ConfigID, "Transients", 1)); text_window = new Text(i18n->AddColon(i18n->TranslateString("Transformation window")), Point(10, 69)); combo_window = new ComboBox(Point(10, 66), Size(300, 0)); combo_window->AddEntry(i18n->TranslateString("Standard")); combo_window->AddEntry(i18n->TranslateString("Short")); combo_window->AddEntry(i18n->TranslateString("Long")); combo_window->SelectNthEntry(config->GetIntValue(ConfigID, "Window", 0)); check_smoothing = new CheckBox(i18n->TranslateString("Use time-domain smoothing"), Point(10, 93), Size(200, 0), &smoothing); text_phase = new Text(i18n->AddColon(i18n->TranslateString("Phase handling")), Point(10, 121)); combo_phase = new ComboBox(Point(10, 118), Size(300, 0)); combo_phase->AddEntry(i18n->TranslateString("Laminar")); combo_phase->AddEntry(i18n->TranslateString("Independent")); combo_phase->SelectNthEntry(config->GetIntValue(ConfigID, "Phase", 0)); text_formant = new Text(i18n->AddColon(i18n->TranslateString("Formant handling")), Point(10, 148)); combo_formant = new ComboBox(Point(10, 145), Size(300, 0)); combo_formant->AddEntry(i18n->TranslateString("Shift")); combo_formant->AddEntry(i18n->TranslateString("Preserve")); combo_formant->SelectNthEntry(config->GetIntValue(ConfigID, "Formant", 1)); text_pitchmode = new Text(i18n->AddColon(i18n->TranslateString("Pitch processing")), Point(10, 175)); combo_pitchmode = new ComboBox(Point(10, 172), Size(300, 0)); combo_pitchmode->AddEntry(i18n->TranslateString("High quality")); combo_pitchmode->AddEntry(i18n->TranslateString("High speed")); combo_pitchmode->AddEntry(i18n->TranslateString("High consistency")); combo_pitchmode->SelectNthEntry(config->GetIntValue(ConfigID, "PitchMode", 0)); text_channels = new Text(i18n->AddColon(i18n->TranslateString("Stereo processing")), Point(10, 202)); combo_channels = new ComboBox(Point(10, 199), Size(300, 0)); combo_channels->AddEntry(i18n->TranslateString("Separate")); combo_channels->AddEntry(i18n->TranslateString("Combined")); combo_channels->SelectNthEntry(config->GetIntValue(ConfigID, "Channels", 1)); maxTextSize = Math::Max(Math::Max(Math::Max(text_detector->GetUnscaledTextWidth(), text_transients->GetUnscaledTextWidth()), Math::Max(text_window->GetUnscaledTextWidth(), text_phase->GetUnscaledTextWidth())), Math::Max(Math::Max(text_formant->GetUnscaledTextWidth(), text_pitchmode->GetUnscaledTextWidth()), text_channels->GetUnscaledTextWidth())); combo_detector->SetX(maxTextSize + 16); combo_transients->SetX(maxTextSize + 16); combo_window->SetX(maxTextSize + 16); combo_phase->SetX(maxTextSize + 16); combo_formant->SetX(maxTextSize + 16); combo_pitchmode->SetX(maxTextSize + 16); combo_channels->SetX(maxTextSize + 16); check_smoothing->SetX(maxTextSize + 16); combo_detector->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_transients->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_window->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_phase->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_formant->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_pitchmode->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); combo_channels->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); check_smoothing->SetWidth(group_tuning->GetWidth() - maxTextSize - 26); group_tuning->Add(text_detector); group_tuning->Add(combo_detector); group_tuning->Add(text_transients); group_tuning->Add(combo_transients); group_tuning->Add(text_window); group_tuning->Add(combo_window); group_tuning->Add(check_smoothing); group_tuning->Add(text_phase); group_tuning->Add(combo_phase); group_tuning->Add(text_formant); group_tuning->Add(combo_formant); group_tuning->Add(text_pitchmode); group_tuning->Add(combo_pitchmode); group_tuning->Add(text_channels); group_tuning->Add(combo_channels); Add(group_tuning); SetSize(Size(414, 349)); } BoCA::ConfigureRubberBand::~ConfigureRubberBand() { DeleteObject(group_basic); DeleteObject(text_tempo); DeleteObject(slider_tempo); DeleteObject(text_tempo_value); DeleteObject(text_pitch); DeleteObject(option_semitones); DeleteObject(slider_semitones); DeleteObject(text_semitones_value); DeleteObject(option_ratio); DeleteObject(edit_ratio_num); DeleteObject(text_ratio_num_hz); DeleteObject(text_ratio_colon); DeleteObject(edit_ratio_den); DeleteObject(text_ratio_den_hz); DeleteObject(text_ratio_equals); DeleteObject(text_ratio_value); DeleteObject(group_tuning); DeleteObject(text_detector); DeleteObject(combo_detector); DeleteObject(text_transients); DeleteObject(combo_transients); DeleteObject(text_window); DeleteObject(combo_window); DeleteObject(check_smoothing); DeleteObject(text_phase); DeleteObject(combo_phase); DeleteObject(text_formant); DeleteObject(combo_formant); DeleteObject(text_pitchmode); DeleteObject(combo_pitchmode); DeleteObject(text_channels); DeleteObject(combo_channels); } Int BoCA::ConfigureRubberBand::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Stretch", Math::Round(1000.0 / (tempo / 100.0))); config->SetIntValue(ConfigID, "PitchOption", pitchOption); config->SetIntValue(ConfigID, "RatioNum", Math::Round(edit_ratio_num->GetText().ToFloat() * 10000.0)); config->SetIntValue(ConfigID, "RatioDen", Math::Round(edit_ratio_den->GetText().ToFloat() * 10000.0)); config->SetIntValue(ConfigID, "Pitch", Math::Round(Math::Pow(2.0, pitch / 2.0 / 12.0) * 1000.0)); config->SetIntValue(ConfigID, "Detector", combo_detector->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Transients", combo_transients->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Window", combo_window->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Phase", combo_phase->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Formant", combo_formant->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "PitchMode", combo_pitchmode->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Channels", combo_channels->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Smoothing", smoothing); return Success(); } Void BoCA::ConfigureRubberBand::OnChangeTempo(Int tempo) { I18n *i18n = I18n::Get(); text_tempo_value->SetText(i18n->TranslateString("%1%", "Technical").Replace("%1", String(tempo >= 100 ? "+" : NIL).Append(String::FromInt(tempo - 100)))); } Void BoCA::ConfigureRubberBand::OnChangePitchOption() { if (pitchOption == 0) { edit_ratio_num->Deactivate(); text_ratio_num_hz->Deactivate(); text_ratio_colon->Deactivate(); edit_ratio_den->Deactivate(); text_ratio_den_hz->Deactivate(); text_ratio_equals->Deactivate(); text_ratio_value->Deactivate(); slider_semitones->Activate(); text_semitones_value->Activate(); } else { slider_semitones->Deactivate(); text_semitones_value->Deactivate(); edit_ratio_num->Activate(); text_ratio_num_hz->Activate(); text_ratio_colon->Activate(); edit_ratio_den->Activate(); text_ratio_den_hz->Activate(); text_ratio_equals->Activate(); text_ratio_value->Activate(); } } Void BoCA::ConfigureRubberBand::OnEditRatio() { I18n *i18n = I18n::Get(); Float ratioNum = edit_ratio_num->GetText().ToFloat(); Float ratioDen = edit_ratio_den->GetText().ToFloat(); if (ratioNum <= 0.0 || ratioDen <= 0.0) text_ratio_value->SetText(i18n->TranslateString("invalid")); else text_ratio_value->SetText(String::FromFloat(Math::Round(ratioNum / ratioDen * 10000.0) / 10000.0)); } Void BoCA::ConfigureRubberBand::OnChangeSemitones(Int pitch) { I18n *i18n = I18n::Get(); i18n->SetContext("DSP::RubberBand"); text_semitones_value->SetText(String(pitch >= 0 ? "+" : NIL).Append(String::FromFloat(pitch / 2.0)).Append(pitch % 2 == 0 ? ".0" : NIL)); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/config.h000066400000000000000000000041041516712004000246620ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_RUBBERBANDCONFIG #define H_RUBBERBANDCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureRubberBand : public ConfigLayer { private: GroupBox *group_basic; Text *text_tempo; Slider *slider_tempo; Text *text_tempo_value; Text *text_pitch; OptionBox *option_semitones; Slider *slider_semitones; Text *text_semitones_value; OptionBox *option_ratio; EditBox *edit_ratio_num; Text *text_ratio_num_hz; Text *text_ratio_colon; EditBox *edit_ratio_den; Text *text_ratio_den_hz; Text *text_ratio_equals; Text *text_ratio_value; GroupBox *group_tuning; Text *text_detector; ComboBox *combo_detector; Text *text_transients; ComboBox *combo_transients; Text *text_window; ComboBox *combo_window; CheckBox *check_smoothing; Text *text_phase; ComboBox *combo_phase; Text *text_formant; ComboBox *combo_formant; Text *text_pitchmode; ComboBox *combo_pitchmode; Text *text_channels; ComboBox *combo_channels; Int tempo; Int pitchOption; Int pitch; Bool smoothing; slots: Void OnChangeTempo(Int); Void OnChangePitchOption(); Void OnEditRatio(); Void OnChangeSemitones(Int); public: static const String ConfigID; ConfigureRubberBand(); ~ConfigureRubberBand(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/dllinterface.cpp000066400000000000000000000043771516712004000264200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" RUBBERBAND_NEW ex_rubberband_new = NIL; RUBBERBAND_DELETE ex_rubberband_delete = NIL; RUBBERBAND_GET_LATENCY ex_rubberband_get_latency = NIL; RUBBERBAND_GET_SAMPLES_REQUIRED ex_rubberband_get_samples_required = NIL; RUBBERBAND_PROCESS ex_rubberband_process = NIL; RUBBERBAND_AVAILABLE ex_rubberband_available = NIL; RUBBERBAND_RETRIEVE ex_rubberband_retrieve = NIL; DynamicLoader *rbdll = NIL; Bool LoadRubberBandDLL() { rbdll = BoCA::Utilities::LoadCodecDLL("rubberband"); if (rbdll == NIL) return False; ex_rubberband_new = (RUBBERBAND_NEW) rbdll->GetFunctionAddress("rubberband_new"); ex_rubberband_delete = (RUBBERBAND_DELETE) rbdll->GetFunctionAddress("rubberband_delete"); ex_rubberband_get_latency = (RUBBERBAND_GET_LATENCY) rbdll->GetFunctionAddress("rubberband_get_latency"); ex_rubberband_get_samples_required = (RUBBERBAND_GET_SAMPLES_REQUIRED) rbdll->GetFunctionAddress("rubberband_get_samples_required"); ex_rubberband_process = (RUBBERBAND_PROCESS) rbdll->GetFunctionAddress("rubberband_process"); ex_rubberband_available = (RUBBERBAND_AVAILABLE) rbdll->GetFunctionAddress("rubberband_available"); ex_rubberband_retrieve = (RUBBERBAND_RETRIEVE) rbdll->GetFunctionAddress("rubberband_retrieve"); if (ex_rubberband_new == NIL || ex_rubberband_delete == NIL || ex_rubberband_get_latency == NIL || ex_rubberband_get_samples_required == NIL || ex_rubberband_process == NIL || ex_rubberband_available == NIL || ex_rubberband_retrieve == NIL) { FreeRubberBandDLL(); return False; } return True; } Void FreeRubberBandDLL() { BoCA::Utilities::FreeCodecDLL(rbdll); rbdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/dllinterface.h000066400000000000000000000033341516712004000260550ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *rbdll; Bool LoadRubberBandDLL(); Void FreeRubberBandDLL(); typedef RubberBandState (*RUBBERBAND_NEW) (unsigned int, unsigned int, RubberBandOptions, double, double); typedef void (*RUBBERBAND_DELETE) (RubberBandState); typedef unsigned int (*RUBBERBAND_GET_LATENCY) (const RubberBandState); typedef unsigned int (*RUBBERBAND_GET_SAMPLES_REQUIRED) (const RubberBandState); typedef void (*RUBBERBAND_PROCESS) (RubberBandState, const float *const *, unsigned int, int); typedef int (*RUBBERBAND_AVAILABLE) (const RubberBandState); typedef unsigned int (*RUBBERBAND_RETRIEVE) (const RubberBandState, float *const *, unsigned int); extern RUBBERBAND_NEW ex_rubberband_new; extern RUBBERBAND_DELETE ex_rubberband_delete; extern RUBBERBAND_GET_LATENCY ex_rubberband_get_latency; extern RUBBERBAND_GET_SAMPLES_REQUIRED ex_rubberband_get_samples_required; extern RUBBERBAND_PROCESS ex_rubberband_process; extern RUBBERBAND_AVAILABLE ex_rubberband_available; extern RUBBERBAND_RETRIEVE ex_rubberband_retrieve; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/rubberband.cpp000066400000000000000000000173641516712004000260720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "rubberband.h" #include "config.h" const String &BoCA::DSPRubberBand::GetComponentSpecs() { static String componentSpecs; if (rbdll != NIL) { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Rubber Band Tempo/Pitch Changer")).Append(" \ 1.0 \ rubberband-dsp \ dsp \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadRubberBandDLL(); } Void smooth::DetachDLL() { FreeRubberBandDLL(); } BoCA::DSPRubberBand::DSPRubberBand() { state = NIL; configLayer = NIL; } BoCA::DSPRubberBand::~DSPRubberBand() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPRubberBand::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); Float64 timeStretch = config->GetIntValue(ConfigureRubberBand::ConfigID, "Stretch", 1000) / 1000.0; Bool pitchOption = config->GetIntValue(ConfigureRubberBand::ConfigID, "PitchOption", 0); Float ratioNum = config->GetIntValue(ConfigureRubberBand::ConfigID, "RatioNum", 4320000) / 10000.0; Float ratioDen = config->GetIntValue(ConfigureRubberBand::ConfigID, "RatioDen", 4400000) / 10000.0; Float64 pitchScale = config->GetIntValue(ConfigureRubberBand::ConfigID, "Pitch", 1000) / 1000.0; if (pitchOption == 1) { if (ratioNum <= 0.0 || ratioDen <= 0.0) pitchScale = 1.0; else pitchScale = ratioNum / ratioDen; } Int detector = config->GetIntValue(ConfigureRubberBand::ConfigID, "Detector", 0); Int transients = config->GetIntValue(ConfigureRubberBand::ConfigID, "Transients", 1); Int window = config->GetIntValue(ConfigureRubberBand::ConfigID, "Window", 0); Int phase = config->GetIntValue(ConfigureRubberBand::ConfigID, "Phase", 0); Int formant = config->GetIntValue(ConfigureRubberBand::ConfigID, "Formant", 1); Int pitchmode = config->GetIntValue(ConfigureRubberBand::ConfigID, "PitchMode", 0); Int channels = config->GetIntValue(ConfigureRubberBand::ConfigID, "Channels", 1); Bool smoothing = config->GetIntValue(ConfigureRubberBand::ConfigID, "Smoothing", False); /* Configure and init Rubber Band state. */ RubberBandOptions options = RubberBandOptionProcessRealTime; options |= (detector == 0 ? RubberBandOptionDetectorCompound : (detector == 1 ? RubberBandOptionDetectorPercussive : RubberBandOptionDetectorSoft )); options |= (transients == 0 ? RubberBandOptionTransientsCrisp : (transients == 1 ? RubberBandOptionTransientsMixed : RubberBandOptionTransientsSmooth )); options |= (window == 0 ? RubberBandOptionWindowStandard : (window == 1 ? RubberBandOptionWindowShort : RubberBandOptionWindowLong )); options |= (smoothing == 0 ? RubberBandOptionSmoothingOff : RubberBandOptionSmoothingOn ); options |= (phase == 0 ? RubberBandOptionPhaseLaminar : RubberBandOptionPhaseIndependent ); options |= (formant == 0 ? RubberBandOptionFormantShifted : RubberBandOptionFormantPreserved ); options |= (pitchmode == 0 ? RubberBandOptionPitchHighQuality : (pitchmode == 1 ? RubberBandOptionPitchHighSpeed : RubberBandOptionPitchHighConsistency)); options |= (channels == 0 ? RubberBandOptionChannelsApart : RubberBandOptionChannelsTogether ); state = ex_rubberband_new(format.rate, format.channels, options, timeStretch, pitchScale); return True; } Bool BoCA::DSPRubberBand::Deactivate() { ex_rubberband_delete(state); state = NIL; return True; } Int BoCA::DSPRubberBand::TransformData(Buffer &data) { /* Append data to samples buffer. */ samplesBuffer.Resize(samplesBuffer.Size() + data.Size() / 4); memcpy(samplesBuffer + samplesBuffer.Size() - data.Size() / 4, data, data.Size()); data.Resize(0); /* Loop as long as enough samples are available. */ UnsignedInt samplesProcessed = 0; while (samplesBuffer.Size() / format.channels - samplesProcessed >= ex_rubberband_get_samples_required(state)) { /* Process samples. */ Int samplesToProcess = ex_rubberband_get_samples_required(state); float **samples = new float * [format.channels]; for (Int i = 0; i < format.channels; i++) { samples[i] = new float [samplesToProcess]; for (Int n = 0; n < samplesToProcess; n++) samples[i][n] = samplesBuffer[samplesProcessed * format.channels + n * format.channels + i]; } ex_rubberband_process(state, samples, samplesToProcess, false); for (Int i = 0; i < format.channels; i++) delete [] samples[i]; delete [] samples; samplesProcessed += samplesToProcess; /* Retrieve available data. */ if (ex_rubberband_available(state) > 0) { Int samplesToRead = ex_rubberband_available(state); float **samples = new float * [format.channels]; for (Int i = 0; i < format.channels; i++) samples[i] = new float [samplesToRead]; ex_rubberband_retrieve(state, samples, samplesToRead); data.Resize(data.Size() + samplesToRead * format.channels * 4); for (Int i = 0; i < format.channels; i++) { for (Int n = 0; n < samplesToRead; n++) ((float *) (UnsignedByte *) (data + data.Size() - samplesToRead * format.channels * 4))[n * format.channels + i] = samples[i][n]; delete [] samples[i]; } delete [] samples; } } /* Adjust samples buffer. */ Int samplesLeft = samplesBuffer.Size() - samplesProcessed * format.channels; memmove(samplesBuffer, samplesBuffer + samplesProcessed * format.channels, samplesLeft * 4); samplesBuffer.Resize(samplesLeft); return data.Size(); } Int BoCA::DSPRubberBand::Flush(Buffer &data) { /* Process remaining samples. */ Int samplesToProcess = samplesBuffer.Size() / format.channels; float **samples = new float * [format.channels]; for (Int i = 0; i < format.channels; i++) { samples[i] = new float [samplesToProcess]; for (Int n = 0; n < samplesToProcess; n++) samples[i][n] = samplesBuffer[n * format.channels + i]; } ex_rubberband_process(state, samples, samplesToProcess, true); for (Int i = 0; i < format.channels; i++) delete [] samples[i]; delete [] samples; /* Retrieve available data. */ if (ex_rubberband_available(state) > 0) { Int samplesToRead = ex_rubberband_available(state); float **samples = new float * [format.channels]; for (Int i = 0; i < format.channels; i++) samples[i] = new float [samplesToRead]; ex_rubberband_retrieve(state, samples, samplesToRead); data.Resize(samplesToRead * format.channels * 4); for (Int i = 0; i < format.channels; i++) { for (Int n = 0; n < samplesToRead; n++) ((float *) (UnsignedByte *) data)[n * format.channels + i] = samples[i][n]; delete [] samples[i]; } delete [] samples; } samplesBuffer.Resize(0); return data.Size(); } ConfigLayer *BoCA::DSPRubberBand::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureRubberBand(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/rubberband/rubberband.h000066400000000000000000000022671516712004000255330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(DSPRubberBand) namespace BoCA { class DSPRubberBand : public CS::DSPComponent { private: ConfigLayer *configLayer; RubberBandState state; Buffer samplesBuffer; public: static const String &GetComponentSpecs(); DSPRubberBand(); ~DSPRubberBand(); Bool Activate(); Bool Deactivate(); Int TransformData(Buffer &); Int Flush(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPRubberBand) BoCA_END_COMPONENT(DSPRubberBand) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/000077500000000000000000000000001516712004000230205ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/Makefile000066400000000000000000000014531516712004000244630ustar00rootroot00000000000000########## BoCA component makefile ########## .NOTPARALLEL: # Change these variables to fit your project: TARGET = surround TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = surround.o config.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/freesurround # Enter additional library dependencies here: LIBS = freesurround/libfreesurround.a # Enter addition commands for targets all and clean here: ALLCMD1 = $(call makein,freesurround) ALLCMD2 = CLEANCMD1 = $(call cleanin,freesurround) CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/config.cpp000066400000000000000000000043761516712004000250030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureSurround::ConfigID = "Surround"; BoCA::ConfigureSurround::ConfigureSurround() { const Config *config = Config::Get(); Int channelSetup = config->GetIntValue(ConfigID, "ChannelSetup", 6); redirectBass = config->GetIntValue(ConfigID, "RedirectBass", True); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Surround"); group_output = new GroupBox(i18n->TranslateString("Output channels"), Point(7, 11), Size(250, 67)); check_lfe = new CheckBox(i18n->TranslateString("Redirect bass content to LFE channel"), Point(10, 40), Size(230, 0), &redirectBass); text_channels = new Text(i18n->AddColon(i18n->TranslateString("Channel configuration")), Point(10, 16)); combo_channels = new ComboBox(Point(17 + text_channels->GetUnscaledTextWidth(), 13), Size(223 - text_channels->GetUnscaledTextWidth(), 0)); combo_channels->AddEntry("2.1"); combo_channels->AddEntry("3.1"); combo_channels->AddEntry("4.1"); combo_channels->AddEntry("5.1"); combo_channels->AddEntry("6.1"); combo_channels->AddEntry("7.1"); combo_channels->SelectNthEntry(channelSetup - 3); group_output->Add(text_channels); group_output->Add(combo_channels); group_output->Add(check_lfe); Add(group_output); SetSize(Size(264, 85)); } BoCA::ConfigureSurround::~ConfigureSurround() { DeleteObject(group_output); DeleteObject(text_channels); DeleteObject(combo_channels); DeleteObject(check_lfe); } Int BoCA::ConfigureSurround::SaveSettings() { Config *config = Config::Get(); Int entry = combo_channels->GetSelectedEntryNumber(); config->SetIntValue(ConfigID, "ChannelSetup", entry + 3); config->SetIntValue(ConfigID, "RedirectBass", redirectBass); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/config.h000066400000000000000000000021211516712004000244320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_SURROUNDCONFIG #define H_SURROUNDCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureSurround : public ConfigLayer { private: GroupBox *group_output; Text *text_channels; ComboBox *combo_channels; CheckBox *check_lfe; Bool redirectBass; public: static const String ConfigID; ConfigureSurround(); ~ConfigureSurround(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/000077500000000000000000000000001516712004000255435ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/Makefile000066400000000000000000000010461516712004000272040ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = channelmaps.o freesurround_decoder.o kiss_fft/kiss_fft.o kiss_fft/kiss_fftr.o TARGET = libfreesurround.a CCOPTS = -I"$(SRCDIR)"/kiss_fft -Dkiss_fft_scalar=double -Wno-unused-variable AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ .cpp.o: $(CC) $(CCOPTS) $(CXXFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/channelmaps.cpp000066400000000000000000020616601516712004000305530ustar00rootroot00000000000000/* Copyright (C) 2010 Christian Kothe 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 Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "channelmaps.h" static float map_stereo_ang[] = {-27,27}; static float map_stereo_xsf[] = {-1,1}; static float map_stereo_ysf[] = {1,1}; channel_id map_stereo_id[] = {ci_front_left,ci_front_right,ci_lfe}; static float map_stereo_lf[21][21] = { {0.89443f,0.88524f,0.87458f,0.86193f,0.84742f,0.83047f,0.81079f,0.78857f,0.76362f,0.73631f,0.70763f,0.67665f,0.64566f,0.61552f,0.58534f,0.55766f,0.53151f,0.50762f,0.48547f,0.46573f,0.44721f}, {0.89755f,0.87472f,0.86612f,0.85527f,0.84283f,0.82769f,0.80772f,0.78219f,0.75429f,0.72489f,0.69458f,0.66356f,0.63344f,0.60389f,0.57501f,0.54892f,0.52695f,0.50759f,0.49065f,0.47592f,0.44112f}, {0.90095f,0.88263f,0.86463f,0.85404f,0.84112f,0.81939f,0.79647f,0.77027f,0.74204f,0.71371f,0.68556f,0.65692f,0.62867f,0.60011f,0.57242f,0.54621f,0.52095f,0.50185f,0.48478f,0.46223f,0.4341f}, {0.90493f,0.89124f,0.87451f,0.85436f,0.83602f,0.81484f,0.78982f,0.7639f,0.73649f,0.708f,0.67884f,0.64889f,0.61965f,0.5909f,0.56273f,0.53649f,0.51235f,0.49068f,0.46842f,0.44689f,0.42579f}, {0.90935f,0.89967f,0.88515f,0.86118f,0.83546f,0.81421f,0.78928f,0.76394f,0.73562f,0.70473f,0.67234f,0.63865f,0.60548f,0.57409f,0.5446f,0.51768f,0.49394f,0.47308f,0.45005f,0.43044f,0.41628f}, {0.91439f,0.90835f,0.8916f,0.87077f,0.84576f,0.81654f,0.79414f,0.76796f,0.738f,0.70338f,0.66454f,0.62424f,0.58439f,0.54783f,0.51607f,0.48945f,0.46806f,0.44967f,0.43169f,0.41295f,0.40509f}, {0.91999f,0.91639f,0.90136f,0.88119f,0.85747f,0.82956f,0.79891f,0.77322f,0.74276f,0.70354f,0.65538f,0.60316f,0.55904f,0.52739f,0.50105f,0.46894f,0.43968f,0.41993f,0.40718f,0.39424f,0.39222f}, {0.92644f,0.9241f,0.9116f,0.89398f,0.87092f,0.84203f,0.80896f,0.77654f,0.74815f,0.70562f,0.64332f,0.58646f,0.55102f,0.52708f,0.49359f,0.45559f,0.41942f,0.38954f,0.37761f,0.37267f,0.37675f}, {0.93328f,0.93254f,0.92229f,0.90504f,0.88134f,0.85208f,0.81768f,0.7839f,0.74647f,0.70855f,0.63549f,0.58487f,0.56076f,0.52616f,0.49005f,0.44864f,0.40794f,0.36999f,0.34436f,0.34665f,0.35949f}, {0.94079f,0.94125f,0.93189f,0.91311f,0.88749f,0.85631f,0.8194f,0.78057f,0.74338f,0.70163f,0.63671f,0.60162f,0.56723f,0.53186f,0.49174f,0.44781f,0.40347f,0.35901f,0.32088f,0.31729f,0.33938f}, {0.94868f,0.94932f,0.94007f,0.9189f,0.88975f,0.85124f,0.80805f,0.75887f,0.71167f,0.67363f,0.64218f,0.61199f,0.5782f,0.54f,0.49837f,0.4526f,0.40118f,0.3514f,0.3043f,0.28639f,0.31623f}, {0.95692f,0.95638f,0.94428f,0.91841f,0.8832f,0.83951f,0.7853f,0.73414f,0.69534f,0.66315f,0.63602f,0.61218f,0.58072f,0.54574f,0.50443f,0.45716f,0.40639f,0.35175f,0.29649f,0.26018f,0.29081f}, {0.96498f,0.96276f,0.94676f,0.91627f,0.8745f,0.82172f,0.76172f,0.71817f,0.68426f,0.66051f,0.62994f,0.60192f,0.58139f,0.54844f,0.5103f,0.46277f,0.40965f,0.35109f,0.28981f,0.23919f,0.26285f}, {0.97256f,0.96914f,0.94756f,0.91234f,0.86412f,0.80293f,0.74426f,0.70593f,0.68146f,0.65506f,0.62468f,0.59559f,0.57167f,0.55047f,0.51487f,0.46757f,0.41278f,0.35109f,0.2847f,0.21785f,0.23325f}, {0.97977f,0.97551f,0.94873f,0.90549f,0.85129f,0.78757f,0.73384f,0.70417f,0.67727f,0.64923f,0.62014f,0.59112f,0.56478f,0.54094f,0.51536f,0.47061f,0.4185f,0.35479f,0.27753f,0.19394f,0.20077f}, {0.9859f,0.97906f,0.94933f,0.90364f,0.84461f,0.7748f,0.73864f,0.70505f,0.6742f,0.64447f,0.61554f,0.5866f,0.55834f,0.53048f,0.50205f,0.47467f,0.41886f,0.35115f,0.27107f,0.18027f,0.16808f}, {0.99106f,0.97904f,0.95594f,0.90263f,0.84046f,0.79665f,0.74764f,0.70961f,0.67426f,0.64169f,0.61091f,0.58092f,0.55049f,0.51961f,0.4893f,0.45375f,0.41836f,0.34667f,0.24954f,0.17965f,0.13422f}, {0.99504f,0.97686f,0.94808f,0.90616f,0.87005f,0.82768f,0.77496f,0.72517f,0.68125f,0.64279f,0.60765f,0.5735f,0.53901f,0.50302f,0.46667f,0.42437f,0.38174f,0.33637f,0.26284f,0.18498f,0.10039f}, {0.99787f,0.97282f,0.93896f,0.92728f,0.91154f,0.86712f,0.82157f,0.76586f,0.70571f,0.65384f,0.60893f,0.56563f,0.52269f,0.47746f,0.42876f,0.38009f,0.31978f,0.29601f,0.27766f,0.19432f,0.066244f}, {0.99945f,0.96755f,0.9602f,0.94951f,0.93442f,0.91368f,0.87956f,0.82681f,0.76608f,0.70193f,0.63578f,0.56816f,0.50585f,0.44097f,0.37308f,0.31653f,0.27698f,0.24634f,0.22321f,0.20651f,0.033221f}, {1.000000f,0.99854f,0.99377f,0.9845f,0.96987f,0.94832f,0.91914f,0.87965f,0.83195f,0.77384f,0.70711f,0.63203f,0.55339f,0.47409f,0.39234f,0.31565f,0.24192f,0.17365f,0.10973f,0.052336f,7.8496e-017f}}; static float map_stereo_rf[21][21] = { {0.44721f,0.46513f,0.48487f,0.50702f,0.53092f,0.55707f,0.58534f,0.61495f,0.64566f,0.67665f,0.70658f,0.73631f,0.76362f,0.78812f,0.81079f,0.83007f,0.84705f,0.86158f,0.87425f,0.88493f,0.89443f}, {0.44091f,0.47587f,0.49021f,0.50752f,0.52648f,0.54843f,0.57451f,0.6034f,0.63295f,0.66338f,0.69439f,0.72464f,0.75386f,0.78179f,0.80734f,0.82734f,0.84251f,0.85523f,0.86585f,0.87468f,0.89745f}, {0.43392f,0.46211f,0.48471f,0.50144f,0.52081f,0.54578f,0.57199f,0.59968f,0.62825f,0.65666f,0.68541f,0.71353f,0.74165f,0.76989f,0.79612f,0.81907f,0.84102f,0.85378f,0.86458f,0.88258f,0.90087f}, {0.42556f,0.4465f,0.46827f,0.49061f,0.51198f,0.53606f,0.56263f,0.59061f,0.61925f,0.64863f,0.67871f,0.70782f,0.73615f,0.76373f,0.78979f,0.81451f,0.83582f,0.85431f,0.87445f,0.89102f,0.90482f}, {0.41603f,0.43027f,0.44962f,0.47284f,0.49384f,0.51738f,0.54427f,0.57368f,0.6051f,0.63829f,0.67221f,0.7044f,0.7353f,0.76362f,0.78911f,0.81401f,0.83539f,0.86106f,0.88491f,0.8996f,0.90924f}, {0.40482f,0.41257f,0.43125f,0.44919f,0.46765f,0.48935f,0.51575f,0.54739f,0.58411f,0.62399f,0.66441f,0.70314f,0.73778f,0.76766f,0.79398f,0.81646f,0.84558f,0.8705f,0.89137f,0.90817f,0.91428f}, {0.39194f,0.39388f,0.40671f,0.41966f,0.43944f,0.46877f,0.50098f,0.52725f,0.55873f,0.60277f,0.65524f,0.70322f,0.74248f,0.77305f,0.79885f,0.8294f,0.85732f,0.88113f,0.90115f,0.91624f,0.91987f}, {0.37644f,0.37227f,0.37711f,0.38933f,0.41907f,0.45539f,0.49353f,0.52703f,0.55093f,0.58615f,0.64317f,0.70533f,0.74803f,0.77648f,0.8089f,0.84182f,0.8707f,0.89389f,0.9114f,0.92394f,0.92631f}, {0.35915f,0.34622f,0.34393f,0.36975f,0.40779f,0.44861f,0.48988f,0.52622f,0.56072f,0.58475f,0.63541f,0.70834f,0.74642f,0.78388f,0.81756f,0.85205f,0.88119f,0.90487f,0.92211f,0.93239f,0.93315f}, {0.339f,0.31682f,0.32073f,0.35905f,0.40342f,0.44785f,0.4917f,0.53187f,0.56716f,0.60159f,0.63667f,0.70158f,0.7434f,0.78057f,0.81937f,0.85635f,0.88742f,0.91312f,0.93183f,0.94111f,0.94065f}, {0.31623f,0.28631f,0.30427f,0.3514f,0.40119f,0.45261f,0.49838f,0.54f,0.5782f,0.61199f,0.64217f,0.67362f,0.71167f,0.75889f,0.80807f,0.85125f,0.88977f,0.91889f,0.94006f,0.9493f,0.94868f}, {0.29034f,0.25984f,0.29645f,0.35181f,0.40636f,0.45739f,0.5045f,0.54571f,0.58075f,0.61218f,0.63603f,0.66314f,0.69534f,0.73428f,0.78552f,0.83978f,0.8833f,0.91845f,0.94425f,0.95628f,0.95678f}, {0.26232f,0.23897f,0.28988f,0.35116f,0.40968f,0.46304f,0.51041f,0.54855f,0.58139f,0.60193f,0.62996f,0.66062f,0.68426f,0.71834f,0.76187f,0.82209f,0.87469f,0.91637f,0.94679f,0.96269f,0.96484f}, {0.23266f,0.21746f,0.28484f,0.3513f,0.41299f,0.46772f,0.51511f,0.55049f,0.57186f,0.59573f,0.6247f,0.65513f,0.68168f,0.70596f,0.74457f,0.80329f,0.86436f,0.91252f,0.94764f,0.96907f,0.97242f}, {0.20011f,0.19377f,0.27774f,0.3551f,0.41877f,0.47085f,0.51539f,0.54113f,0.56487f,0.59129f,0.62017f,0.64943f,0.67749f,0.70442f,0.73389f,0.78798f,0.85164f,0.90576f,0.94884f,0.97545f,0.97964f}, {0.16735f,0.18021f,0.2713f,0.35149f,0.41919f,0.47472f,0.50234f,0.53073f,0.5586f,0.58686f,0.61556f,0.64474f,0.6745f,0.70534f,0.73902f,0.77487f,0.84502f,0.90392f,0.94947f,0.97903f,0.98577f}, {0.13341f,0.17975f,0.24983f,0.34704f,0.41842f,0.45412f,0.48964f,0.5198f,0.5508f,0.58122f,0.61094f,0.6419f,0.6745f,0.71002f,0.74813f,0.79718f,0.84054f,0.90295f,0.9561f,0.97906f,0.99095f}, {0.099504f,0.18519f,0.2632f,0.33642f,0.38219f,0.42465f,0.46712f,0.50346f,0.53941f,0.57392f,0.60769f,0.64324f,0.68168f,0.72574f,0.77558f,0.82818f,0.87048f,0.90621f,0.94829f,0.97694f,0.99495f}, {0.065281f,0.19467f,0.27771f,0.29655f,0.32038f,0.38061f,0.42917f,0.47786f,0.52322f,0.56623f,0.609f,0.6545f,0.70642f,0.76654f,0.82216f,0.8676f,0.91195f,0.92761f,0.93899f,0.97296f,0.9978f}, {0.032183f,0.20655f,0.22377f,0.24703f,0.27778f,0.31734f,0.37412f,0.44199f,0.50657f,0.5692f,0.63593f,0.70292f,0.7669f,0.82752f,0.88018f,0.91412f,0.93482f,0.94983f,0.96045f,0.96758f,0.99942f}, {7.8496e-017f,0.054079f,0.11147f,0.17537f,0.24362f,0.3173f,0.39394f,0.47562f,0.55484f,0.63338f,0.70711f,0.77494f,0.83292f,0.88048f,0.91982f,0.94888f,0.9703f,0.98481f,0.99396f,0.99863f,1.000000f}}; static float map_3stereo_ang[] = {-27,0,27}; static float map_3stereo_xsf[] = {-1,0,1}; static float map_3stereo_ysf[] = {1,1,1}; channel_id map_3stereo_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_lfe}; static float map_3stereo_lf[21][21] = { {0.89443f,0.88524f,0.87458f,0.86193f,0.84742f,0.83047f,0.81079f,0.78857f,0.76362f,0.73631f,0.70763f,0.67665f,0.64566f,0.61552f,0.58534f,0.55766f,0.53151f,0.50762f,0.48547f,0.46573f,0.44721f}, {0.89755f,0.87472f,0.86612f,0.85527f,0.84283f,0.82769f,0.80772f,0.78219f,0.75429f,0.72489f,0.69458f,0.66356f,0.63344f,0.60389f,0.57501f,0.54892f,0.52695f,0.50759f,0.49065f,0.47592f,0.44112f}, {0.90095f,0.88263f,0.86463f,0.85404f,0.84112f,0.81939f,0.79647f,0.77027f,0.74204f,0.71371f,0.68556f,0.65692f,0.62867f,0.60011f,0.57242f,0.54621f,0.52095f,0.50185f,0.48478f,0.46223f,0.4341f}, {0.90493f,0.89124f,0.87451f,0.85436f,0.83602f,0.81484f,0.78982f,0.7639f,0.73649f,0.708f,0.67884f,0.64889f,0.61965f,0.5909f,0.56273f,0.53649f,0.51235f,0.49068f,0.46842f,0.44689f,0.42579f}, {0.90935f,0.89967f,0.88515f,0.86118f,0.83546f,0.81421f,0.78928f,0.76394f,0.73562f,0.70473f,0.67234f,0.63865f,0.60548f,0.57409f,0.5446f,0.51768f,0.49394f,0.47308f,0.45005f,0.43044f,0.41628f}, {0.91439f,0.90835f,0.8916f,0.87077f,0.84576f,0.81518f,0.79369f,0.76796f,0.738f,0.70338f,0.66454f,0.62424f,0.58439f,0.54783f,0.51565f,0.4881f,0.46806f,0.44967f,0.43169f,0.41295f,0.40509f}, {0.91999f,0.91639f,0.90136f,0.88119f,0.85355f,0.8186f,0.78112f,0.76071f,0.73829f,0.70353f,0.65538f,0.60316f,0.55465f,0.51501f,0.48328f,0.45812f,0.43585f,0.41993f,0.40718f,0.39424f,0.39222f}, {0.92644f,0.9241f,0.9116f,0.89f,0.85377f,0.81069f,0.76541f,0.7303f,0.7187f,0.69523f,0.64332f,0.57619f,0.52176f,0.48087f,0.45029f,0.42447f,0.40245f,0.38564f,0.37761f,0.37267f,0.37675f}, {0.93328f,0.93254f,0.92093f,0.88634f,0.84024f,0.79035f,0.73915f,0.70069f,0.66895f,0.6652f,0.62331f,0.54173f,0.48327f,0.44319f,0.41176f,0.3872f,0.36711f,0.3515f,0.34305f,0.34665f,0.35949f}, {0.94079f,0.94125f,0.92008f,0.87107f,0.81395f,0.7575f,0.70837f,0.66767f,0.63574f,0.60719f,0.59167f,0.50719f,0.45964f,0.41911f,0.38086f,0.34928f,0.33027f,0.31726f,0.30924f,0.31729f,0.33938f}, {0.94868f,0.94932f,0.9126f,0.85036f,0.78307f,0.72405f,0.67715f,0.63551f,0.59982f,0.57195f,0.54754f,0.51032f,0.46636f,0.41664f,0.36748f,0.32545f,0.29456f,0.28293f,0.27687f,0.28639f,0.31623f}, {0.95692f,0.95187f,0.89454f,0.81737f,0.74837f,0.69462f,0.64771f,0.60983f,0.58191f,0.55959f,0.5322f,0.50861f,0.46733f,0.4214f,0.36688f,0.31239f,0.27177f,0.25115f,0.24711f,0.25581f,0.29081f}, {0.96498f,0.95059f,0.87624f,0.78828f,0.7202f,0.66666f,0.62184f,0.59103f,0.56775f,0.54605f,0.51575f,0.48743f,0.46487f,0.42131f,0.37046f,0.30776f,0.25551f,0.22343f,0.21973f,0.22723f,0.26285f}, {0.97256f,0.95078f,0.85739f,0.7628f,0.69489f,0.64157f,0.60083f,0.57487f,0.55358f,0.52906f,0.49872f,0.46963f,0.44379f,0.41939f,0.37144f,0.30618f,0.24378f,0.20193f,0.195f,0.19978f,0.23325f}, {0.97977f,0.95292f,0.84165f,0.73647f,0.66998f,0.61976f,0.58405f,0.56013f,0.5361f,0.50957f,0.48088f,0.45142f,0.42358f,0.39691f,0.36556f,0.3028f,0.23733f,0.18612f,0.17099f,0.17167f,0.20077f}, {0.9859f,0.9429f,0.82529f,0.71935f,0.65073f,0.60004f,0.57026f,0.54247f,0.51553f,0.48797f,0.45981f,0.4301f,0.39967f,0.36796f,0.33369f,0.2999f,0.22511f,0.16724f,0.14764f,0.14455f,0.16808f}, {0.99106f,0.92029f,0.82792f,0.70355f,0.63405f,0.59419f,0.55582f,0.52345f,0.4933f,0.4638f,0.43247f,0.40308f,0.36959f,0.33341f,0.29749f,0.25133f,0.21195f,0.14799f,0.12217f,0.12145f,0.13422f}, {0.99504f,0.89296f,0.7903f,0.69419f,0.64012f,0.59235f,0.54648f,0.50481f,0.46838f,0.43448f,0.39875f,0.3652f,0.32622f,0.28267f,0.23822f,0.18912f,0.15212f,0.12446f,0.10578f,0.10172f,0.10039f}, {0.99787f,0.86251f,0.75271f,0.71164f,0.66604f,0.59703f,0.5415f,0.48914f,0.43949f,0.39493f,0.34939f,0.30672f,0.25639f,0.20073f,0.14885f,0.11031f,0.074927f,0.081099f,0.091522f,0.084744f,0.066244f}, {0.99945f,0.83163f,0.7944f,0.74743f,0.68883f,0.61889f,0.53808f,0.46304f,0.39791f,0.3335f,0.26339f,0.19986f,0.13786f,0.07777f,0.032427f,0.022634f,0.032465f,0.045267f,0.058324f,0.070706f,0.033221f}, {1.000000f,0.94446f,0.8823f,0.80914f,0.72626f,0.63102f,0.52519f,0.40402f,0.27711f,0.14046f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,7.8496e-017f}}; static float map_3stereo_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.001914f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.0155f,0.025167f,0.017695f,0.0063155f,1.0116e-005f,0.000000f,0.000000f,0.0062031f,0.017508f,0.025125f,0.015305f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0056317f,0.024256f,0.044322f,0.061583f,0.065405f,0.041656f,0.014688f,0.000000f,0.014527f,0.041389f,0.065342f,0.061236f,0.044002f,0.024003f,0.005504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0019274f,0.02644f,0.05812f,0.08731f,0.11105f,0.11767f,0.10963f,0.061306f,0.017226f,0.061006f,0.10958f,0.11735f,0.11066f,0.086884f,0.057744f,0.026151f,0.0018503f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016697f,0.059451f,0.104f,0.13974f,0.15702f,0.15962f,0.15223f,0.13355f,0.063692f,0.13353f,0.15211f,0.15945f,0.15675f,0.13934f,0.10352f,0.059047f,0.016456f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.038851f,0.096919f,0.15087f,0.17987f,0.18511f,0.17445f,0.15817f,0.14379f,0.13384f,0.14378f,0.15816f,0.17444f,0.18509f,0.17981f,0.15076f,0.096821f,0.038797f,0.000000f,0.000000f}, {0.000000f,0.0063777f,0.070344f,0.14288f,0.19068f,0.2049f,0.19453f,0.1758f,0.16036f,0.14645f,0.14681f,0.14646f,0.16036f,0.1758f,0.19453f,0.20473f,0.19031f,0.14227f,0.06984f,0.0061903f,0.000000f}, {0.000000f,0.017224f,0.099719f,0.18101f,0.21822f,0.2193f,0.19777f,0.17979f,0.16475f,0.16187f,0.16149f,0.16187f,0.16477f,0.1798f,0.19777f,0.21922f,0.21792f,0.18045f,0.099116f,0.016918f,0.000000f}, {0.000000f,0.02596f,0.12753f,0.21148f,0.23925f,0.22819f,0.20284f,0.18535f,0.18085f,0.17814f,0.17812f,0.17814f,0.18084f,0.18536f,0.20284f,0.22818f,0.23901f,0.21095f,0.12685f,0.025562f,0.000000f}, {0.000000f,0.03194f,0.15144f,0.23904f,0.2564f,0.23733f,0.21182f,0.20371f,0.19964f,0.19751f,0.19694f,0.1975f,0.19963f,0.20369f,0.21184f,0.23733f,0.25621f,0.23853f,0.15068f,0.031485f,0.000000f}, {0.000000f,0.051138f,0.17541f,0.26062f,0.27419f,0.24713f,0.23812f,0.22985f,0.2244f,0.22133f,0.22022f,0.22132f,0.22439f,0.22984f,0.2381f,0.24715f,0.274f,0.26009f,0.17455f,0.050511f,0.000000f}, {0.000000f,0.08308f,0.18105f,0.28155f,0.29188f,0.28632f,0.27128f,0.26327f,0.25585f,0.25151f,0.25234f,0.2515f,0.25584f,0.26325f,0.27127f,0.28627f,0.29189f,0.28098f,0.18013f,0.082312f,0.000000f}, {0.000000f,0.11865f,0.22314f,0.29977f,0.32517f,0.33282f,0.32312f,0.31164f,0.30095f,0.2946f,0.29542f,0.29459f,0.30094f,0.31163f,0.32308f,0.33259f,0.32473f,0.29967f,0.22211f,0.11774f,0.000000f}, {0.000000f,0.15601f,0.26339f,0.30497f,0.3472f,0.38198f,0.39609f,0.39135f,0.3765f,0.36616f,0.36703f,0.36615f,0.37649f,0.39123f,0.39574f,0.3814f,0.34627f,0.30393f,0.26322f,0.15497f,0.000000f}, {0.000000f,0.19222f,0.23448f,0.28578f,0.34732f,0.4169f,0.48293f,0.51439f,0.52067f,0.52104f,0.52661f,0.52086f,0.52026f,0.51365f,0.48176f,0.41543f,0.34579f,0.28436f,0.23319f,0.19202f,0.000000f}, {0.000000f,0.076479f,0.15764f,0.24801f,0.34452f,0.44874f,0.55712f,0.67263f,0.78467f,0.89574f,1.000000f,0.89382f,0.78261f,0.67046f,0.55485f,0.4464f,0.34213f,0.24558f,0.15519f,0.074014f,0.000000f}}; static float map_3stereo_rf[21][21] = { {0.44721f,0.46513f,0.48487f,0.50702f,0.53092f,0.55707f,0.58534f,0.61495f,0.64566f,0.67665f,0.70658f,0.73631f,0.76362f,0.78812f,0.81079f,0.83007f,0.84705f,0.86158f,0.87425f,0.88493f,0.89443f}, {0.44091f,0.47587f,0.49021f,0.50752f,0.52648f,0.54843f,0.57451f,0.6034f,0.63295f,0.66338f,0.69439f,0.72464f,0.75386f,0.78179f,0.80734f,0.82734f,0.84251f,0.85523f,0.86585f,0.87468f,0.89745f}, {0.43392f,0.46211f,0.48471f,0.50144f,0.52081f,0.54578f,0.57199f,0.59968f,0.62825f,0.65666f,0.68541f,0.71353f,0.74165f,0.76989f,0.79612f,0.81907f,0.84102f,0.85378f,0.86458f,0.88258f,0.90087f}, {0.42556f,0.4465f,0.46827f,0.49061f,0.51198f,0.53606f,0.56263f,0.59061f,0.61925f,0.64863f,0.67871f,0.70782f,0.73615f,0.76373f,0.78979f,0.81451f,0.83582f,0.85431f,0.87445f,0.89102f,0.90482f}, {0.41603f,0.43027f,0.44962f,0.47284f,0.49384f,0.51738f,0.54427f,0.57368f,0.6051f,0.63829f,0.67221f,0.7044f,0.7353f,0.76362f,0.78911f,0.81401f,0.83539f,0.86106f,0.88491f,0.8996f,0.90924f}, {0.40482f,0.41257f,0.43125f,0.44919f,0.46765f,0.48799f,0.5153f,0.54739f,0.58411f,0.62399f,0.66441f,0.70314f,0.73778f,0.76766f,0.79356f,0.81511f,0.84558f,0.8705f,0.89137f,0.90817f,0.91428f}, {0.39194f,0.39388f,0.40671f,0.41966f,0.43552f,0.45781f,0.48319f,0.51474f,0.55427f,0.60276f,0.65524f,0.70322f,0.73809f,0.76067f,0.78108f,0.81857f,0.85349f,0.88113f,0.90115f,0.91624f,0.91987f}, {0.37644f,0.37227f,0.37711f,0.38534f,0.40191f,0.42405f,0.44998f,0.48078f,0.52148f,0.57577f,0.64317f,0.69506f,0.71877f,0.73028f,0.7656f,0.81071f,0.85373f,0.89f,0.9114f,0.92394f,0.92631f}, {0.35915f,0.34622f,0.34257f,0.35105f,0.36669f,0.38687f,0.41135f,0.44301f,0.4832f,0.5414f,0.62323f,0.6652f,0.66894f,0.70091f,0.73933f,0.79062f,0.84036f,0.88638f,0.9208f,0.93239f,0.93315f}, {0.339f,0.31682f,0.30893f,0.31701f,0.32988f,0.34904f,0.38067f,0.41902f,0.45952f,0.50715f,0.59164f,0.60716f,0.63586f,0.66782f,0.70855f,0.75782f,0.81423f,0.87136f,0.9202f,0.94111f,0.94065f}, {0.31623f,0.28631f,0.2768f,0.28287f,0.29451f,0.32542f,0.36748f,0.41665f,0.46636f,0.51031f,0.54754f,0.57195f,0.59984f,0.63554f,0.6772f,0.72411f,0.78316f,0.85044f,0.91263f,0.9493f,0.94868f}, {0.29034f,0.25533f,0.24671f,0.25078f,0.27153f,0.3125f,0.36697f,0.4214f,0.46737f,0.50862f,0.53222f,0.55958f,0.58195f,0.60999f,0.64797f,0.69502f,0.74875f,0.81785f,0.89487f,0.9519f,0.95678f}, {0.26232f,0.22679f,0.21937f,0.22317f,0.25538f,0.30797f,0.37058f,0.42141f,0.4649f,0.48746f,0.51577f,0.54618f,0.56776f,0.59121f,0.62202f,0.66708f,0.72062f,0.7888f,0.8767f,0.95072f,0.96484f}, {0.23266f,0.1991f,0.19467f,0.20176f,0.24384f,0.30636f,0.37168f,0.41943f,0.44398f,0.46977f,0.49875f,0.52917f,0.5538f,0.57489f,0.60114f,0.64195f,0.69535f,0.76336f,0.85794f,0.95099f,0.97242f}, {0.20011f,0.17119f,0.17065f,0.18608f,0.23747f,0.30303f,0.36561f,0.39709f,0.4237f,0.45162f,0.48091f,0.50979f,0.53634f,0.56039f,0.5841f,0.62016f,0.67047f,0.73709f,0.8423f,0.95319f,0.97964f}, {0.16735f,0.14405f,0.14727f,0.1672f,0.22531f,0.29997f,0.33396f,0.36822f,0.39992f,0.43035f,0.45985f,0.48824f,0.51583f,0.54282f,0.57066f,0.60011f,0.65128f,0.72001f,0.82604f,0.94331f,0.98577f}, {0.13341f,0.121f,0.12181f,0.14796f,0.21203f,0.25166f,0.29782f,0.33365f,0.36991f,0.4034f,0.43252f,0.46407f,0.4936f,0.52389f,0.55631f,0.59475f,0.63415f,0.70427f,0.82873f,0.92086f,0.99095f}, {0.099504f,0.1013f,0.10541f,0.12445f,0.15226f,0.18931f,0.23864f,0.2831f,0.32663f,0.36561f,0.39881f,0.43494f,0.46889f,0.50538f,0.54712f,0.59303f,0.64086f,0.69432f,0.79124f,0.89368f,0.99495f}, {0.065281f,0.084354f,0.091461f,0.080905f,0.074866f,0.11051f,0.14909f,0.20114f,0.25699f,0.30731f,0.34947f,0.39559f,0.44023f,0.48995f,0.54236f,0.59795f,0.6671f,0.7127f,0.75287f,0.86338f,0.9978f}, {0.032183f,0.070629f,0.057967f,0.044948f,0.032184f,0.022549f,0.032636f,0.078282f,0.13841f,0.20077f,0.26356f,0.33461f,0.39907f,0.46431f,0.53952f,0.62043f,0.69031f,0.74875f,0.79556f,0.83182f,0.99942f}, {7.8496e-017f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14292f,0.27953f,0.40639f,0.52748f,0.63323f,0.72837f,0.81116f,0.88423f,0.94629f,1.000000f}}; static float map_5stereo_ang[] = {-45,-22,0,22,45}; static float map_5stereo_xsf[] = {-1,-0.5,0,0.5,1}; static float map_5stereo_ysf[] = {1,1,1,1,1}; channel_id map_5stereo_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_lfe}; static float map_5stereo_lf[21][21] = { {0.89443f,0.88524f,0.87458f,0.86193f,0.84742f,0.83047f,0.81079f,0.78857f,0.76362f,0.73631f,0.70763f,0.67665f,0.64566f,0.61552f,0.58534f,0.55766f,0.53151f,0.50762f,0.48547f,0.46573f,0.44721f}, {0.89755f,0.87472f,0.86612f,0.85527f,0.84283f,0.82769f,0.80772f,0.78219f,0.75429f,0.72489f,0.69458f,0.66356f,0.63344f,0.60389f,0.57501f,0.54892f,0.52695f,0.50759f,0.49065f,0.47592f,0.44112f}, {0.90095f,0.88263f,0.86463f,0.85404f,0.84112f,0.81939f,0.79647f,0.77027f,0.74204f,0.71371f,0.68556f,0.65692f,0.62867f,0.60011f,0.57242f,0.54621f,0.52095f,0.50185f,0.48478f,0.46223f,0.4341f}, {0.90493f,0.89124f,0.87451f,0.85436f,0.83602f,0.81484f,0.78982f,0.7639f,0.73649f,0.708f,0.67884f,0.64889f,0.61965f,0.5909f,0.56273f,0.53649f,0.51235f,0.49068f,0.46842f,0.44689f,0.42579f}, {0.90935f,0.89967f,0.88515f,0.86118f,0.83546f,0.81421f,0.78928f,0.76394f,0.73562f,0.70473f,0.67234f,0.63865f,0.60548f,0.57409f,0.5446f,0.51768f,0.49394f,0.47308f,0.45005f,0.43044f,0.41628f}, {0.91439f,0.90835f,0.8916f,0.87077f,0.84576f,0.81245f,0.7928f,0.76796f,0.738f,0.70338f,0.66454f,0.62424f,0.58439f,0.54783f,0.51565f,0.4881f,0.46806f,0.44967f,0.43169f,0.41295f,0.40509f}, {0.91999f,0.91639f,0.90136f,0.88119f,0.84571f,0.79668f,0.7467f,0.73569f,0.72936f,0.70351f,0.65538f,0.60316f,0.55465f,0.51501f,0.48328f,0.45812f,0.43585f,0.41993f,0.40718f,0.39424f,0.39222f}, {0.92644f,0.9241f,0.9116f,0.88204f,0.81948f,0.75913f,0.7093f,0.67664f,0.6742f,0.67446f,0.64332f,0.57619f,0.52176f,0.48087f,0.45029f,0.42447f,0.40245f,0.38564f,0.37761f,0.37267f,0.37675f}, {0.93328f,0.93254f,0.9182f,0.84895f,0.77794f,0.72451f,0.67899f,0.646f,0.61886f,0.61788f,0.61109f,0.54173f,0.48019f,0.44035f,0.41133f,0.3872f,0.36711f,0.3515f,0.34305f,0.34665f,0.35949f}, {0.94079f,0.94125f,0.89647f,0.80366f,0.73973f,0.69128f,0.64924f,0.61419f,0.58696f,0.56267f,0.5568f,0.48093f,0.42253f,0.38874f,0.36567f,0.34643f,0.33027f,0.31726f,0.30924f,0.31729f,0.33938f}, {0.94868f,0.94932f,0.85855f,0.76783f,0.70797f,0.6585f,0.61853f,0.58249f,0.55175f,0.52825f,0.50768f,0.4666f,0.41827f,0.3636f,0.31986f,0.30433f,0.29263f,0.28293f,0.27687f,0.28639f,0.31623f}, {0.95692f,0.94285f,0.81295f,0.72936f,0.67316f,0.62838f,0.58857f,0.55635f,0.53314f,0.51506f,0.48848f,0.4641f,0.41854f,0.36792f,0.30775f,0.26456f,0.25758f,0.25115f,0.24711f,0.25581f,0.29081f}, {0.96498f,0.92623f,0.77825f,0.69811f,0.64339f,0.59922f,0.56168f,0.53635f,0.51766f,0.49513f,0.46765f,0.43865f,0.41479f,0.36661f,0.31029f,0.24396f,0.2244f,0.2212f,0.21973f,0.22723f,0.26285f}, {0.97256f,0.91407f,0.74704f,0.66907f,0.61557f,0.57221f,0.53916f,0.51851f,0.49738f,0.47393f,0.44568f,0.41615f,0.38911f,0.36305f,0.30976f,0.23681f,0.19525f,0.19457f,0.195f,0.19978f,0.23325f}, {0.97977f,0.90775f,0.72015f,0.63895f,0.58796f,0.54758f,0.51964f,0.49723f,0.47331f,0.44904f,0.42223f,0.39228f,0.36342f,0.33524f,0.30117f,0.23059f,0.17434f,0.17166f,0.17099f,0.17167f,0.20077f}, {0.9859f,0.87057f,0.69253f,0.61473f,0.5638f,0.5249f,0.49694f,0.47075f,0.44562f,0.42048f,0.39423f,0.36386f,0.33224f,0.29859f,0.26151f,0.22478f,0.15504f,0.1498f,0.14764f,0.14455f,0.16808f}, {0.99106f,0.80597f,0.67879f,0.59077f,0.54157f,0.50615f,0.47152f,0.44064f,0.41413f,0.3874f,0.35733f,0.32787f,0.29278f,0.25408f,0.21547f,0.16499f,0.13688f,0.12892f,0.12217f,0.12145f,0.13422f}, {0.99504f,0.74543f,0.63485f,0.56981f,0.52611f,0.48531f,0.44536f,0.40751f,0.37576f,0.34528f,0.31078f,0.27718f,0.23605f,0.18894f,0.14089f,0.10295f,0.10266f,0.10793f,0.10578f,0.10172f,0.10039f}, {0.99787f,0.69017f,0.59589f,0.55331f,0.50604f,0.45667f,0.40929f,0.36672f,0.3241f,0.28428f,0.24009f,0.19737f,0.14365f,0.086107f,0.056905f,0.062385f,0.065046f,0.078632f,0.091522f,0.084744f,0.066244f}, {0.99945f,0.64208f,0.58925f,0.53016f,0.46426f,0.39194f,0.32374f,0.27699f,0.23034f,0.17491f,0.10657f,0.049487f,0.013026f,0.010495f,0.013088f,0.020503f,0.032465f,0.045267f,0.058324f,0.070706f,0.033221f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,7.8496e-017f}}; static float map_5stereo_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_5stereo_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_5stereo_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_5stereo_rf[21][21] = { {0.44721f,0.46513f,0.48487f,0.50702f,0.53092f,0.55707f,0.58534f,0.61495f,0.64566f,0.67665f,0.70658f,0.73631f,0.76362f,0.78812f,0.81079f,0.83007f,0.84705f,0.86158f,0.87425f,0.88493f,0.89443f}, {0.44091f,0.47587f,0.49021f,0.50752f,0.52648f,0.54843f,0.57451f,0.6034f,0.63295f,0.66338f,0.69439f,0.72464f,0.75386f,0.78179f,0.80734f,0.82734f,0.84251f,0.85523f,0.86585f,0.87468f,0.89745f}, {0.43392f,0.46211f,0.48471f,0.50144f,0.52081f,0.54578f,0.57199f,0.59968f,0.62825f,0.65666f,0.68541f,0.71353f,0.74165f,0.76989f,0.79612f,0.81907f,0.84102f,0.85378f,0.86458f,0.88258f,0.90087f}, {0.42556f,0.4465f,0.46827f,0.49061f,0.51198f,0.53606f,0.56263f,0.59061f,0.61925f,0.64863f,0.67871f,0.70782f,0.73615f,0.76373f,0.78979f,0.81451f,0.83582f,0.85431f,0.87445f,0.89102f,0.90482f}, {0.41603f,0.43027f,0.44962f,0.47284f,0.49384f,0.51738f,0.54427f,0.57368f,0.6051f,0.63829f,0.67221f,0.7044f,0.7353f,0.76362f,0.78911f,0.81401f,0.83539f,0.86106f,0.88491f,0.8996f,0.90924f}, {0.40482f,0.41257f,0.43125f,0.44919f,0.46765f,0.48799f,0.5153f,0.54739f,0.58411f,0.62399f,0.66441f,0.70314f,0.73778f,0.76766f,0.79269f,0.81235f,0.84558f,0.8705f,0.89137f,0.90817f,0.91428f}, {0.39194f,0.39388f,0.40671f,0.41966f,0.43552f,0.45781f,0.48319f,0.51474f,0.55427f,0.60276f,0.65524f,0.70322f,0.72923f,0.73577f,0.74653f,0.79678f,0.84573f,0.88113f,0.90115f,0.91624f,0.91987f}, {0.37644f,0.37227f,0.37711f,0.38534f,0.40191f,0.42405f,0.44998f,0.48078f,0.52148f,0.57577f,0.64317f,0.67439f,0.67427f,0.67648f,0.70945f,0.75919f,0.81959f,0.88212f,0.9114f,0.92394f,0.92631f}, {0.35915f,0.34622f,0.34257f,0.35105f,0.36669f,0.38687f,0.41089f,0.4401f,0.48011f,0.5414f,0.611f,0.6178f,0.61871f,0.64608f,0.67901f,0.72469f,0.77805f,0.84918f,0.91813f,0.93239f,0.93315f}, {0.339f,0.31682f,0.30893f,0.31701f,0.32988f,0.34612f,0.36531f,0.38841f,0.42221f,0.48085f,0.55674f,0.56251f,0.58695f,0.61421f,0.64927f,0.69144f,0.73987f,0.80398f,0.89674f,0.94111f,0.94065f}, {0.31623f,0.28631f,0.2768f,0.28287f,0.29257f,0.30426f,0.31977f,0.36346f,0.41814f,0.46648f,0.50757f,0.52811f,0.55161f,0.58235f,0.61839f,0.65835f,0.70781f,0.76766f,0.85835f,0.9493f,0.94868f}, {0.29034f,0.25533f,0.24671f,0.25078f,0.25715f,0.26439f,0.30769f,0.36779f,0.41847f,0.46397f,0.48838f,0.51493f,0.53305f,0.55637f,0.5887f,0.62862f,0.67335f,0.72964f,0.81334f,0.94301f,0.95678f}, {0.26232f,0.22679f,0.21937f,0.22086f,0.22399f,0.24396f,0.31026f,0.36659f,0.41466f,0.43856f,0.46754f,0.49513f,0.51753f,0.53639f,0.56171f,0.59947f,0.64361f,0.69839f,0.7787f,0.92656f,0.96484f}, {0.23266f,0.1991f,0.19467f,0.19425f,0.19496f,0.23683f,0.30986f,0.36292f,0.38916f,0.41616f,0.44556f,0.4739f,0.49749f,0.51838f,0.53932f,0.57241f,0.61582f,0.66942f,0.74748f,0.91454f,0.97242f}, {0.20011f,0.17119f,0.17065f,0.1714f,0.17417f,0.23067f,0.30103f,0.33526f,0.36339f,0.39235f,0.4221f,0.4491f,0.47339f,0.49735f,0.51951f,0.5478f,0.58825f,0.63932f,0.72063f,0.90831f,0.97964f}, {0.16735f,0.14405f,0.14727f,0.14951f,0.15491f,0.22462f,0.2616f,0.29868f,0.33231f,0.36396f,0.39409f,0.42057f,0.44576f,0.47095f,0.49718f,0.52476f,0.56413f,0.61513f,0.6931f,0.87142f,0.98577f}, {0.13341f,0.121f,0.12181f,0.12862f,0.1368f,0.16508f,0.21559f,0.25412f,0.2929f,0.328f,0.35717f,0.38746f,0.41422f,0.44087f,0.47184f,0.50652f,0.54141f,0.59121f,0.67941f,0.80686f,0.99095f}, {0.099504f,0.1013f,0.10541f,0.10788f,0.10237f,0.10273f,0.14105f,0.18916f,0.23623f,0.2774f,0.31059f,0.34549f,0.37607f,0.40782f,0.44579f,0.48575f,0.5266f,0.5696f,0.63552f,0.74632f,0.99495f}, {0.065281f,0.084354f,0.091461f,0.078331f,0.064744f,0.062131f,0.056625f,0.086144f,0.14401f,0.19771f,0.23987f,0.28465f,0.32453f,0.36721f,0.40981f,0.45726f,0.50676f,0.55399f,0.59562f,0.69107f,0.9978f}, {0.032183f,0.070629f,0.057967f,0.044948f,0.032184f,0.020306f,0.01291f,0.010374f,0.012904f,0.049943f,0.10632f,0.1756f,0.23105f,0.27778f,0.32471f,0.39294f,0.46531f,0.5312f,0.59027f,0.64172f,0.99942f}, {7.8496e-017f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_4point1_ang[] = {-27,27,-105,105}; static float map_4point1_xsf[] = {-1,1,-1,1}; static float map_4point1_ysf[] = {1,1,-1,-1}; channel_id map_4point1_id[] = {ci_front_left,ci_front_right,ci_back_left,ci_back_right,ci_lfe}; static float map_4point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.054079f,0.13605f,0.11031f,0.083738f,0.058746f,0.03616f,0.022585f,0.018356f,0.012179f,0.0043961f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.11103f,0.16562f,0.18635f,0.15778f,0.12791f,0.12403f,0.10709f,0.090176f,0.070512f,0.049741f,0.027549f,0.011727f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17535f,0.20208f,0.21809f,0.22862f,0.21842f,0.20197f,0.18341f,0.15706f,0.13031f,0.10103f,0.068601f,0.041975f,0.018696f,0.0039144f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24362f,0.24543f,0.25563f,0.27972f,0.28786f,0.26979f,0.24789f,0.21805f,0.18569f,0.14921f,0.10871f,0.073541f,0.041097f,0.017152f,0.0038597f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3173f,0.29703f,0.31848f,0.33006f,0.33185f,0.32708f,0.30247f,0.27305f,0.23691f,0.19431f,0.14844f,0.10174f,0.061737f,0.03134f,0.011327f,0.0027159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.39394f,0.36121f,0.3753f,0.38051f,0.37698f,0.36547f,0.34958f,0.3221f,0.28469f,0.23727f,0.18262f,0.12638f,0.083376f,0.055926f,0.035607f,0.011267f,0.0038302f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.47562f,0.43164f,0.43211f,0.42875f,0.41905f,0.40425f,0.38486f,0.3601f,0.3262f,0.27779f,0.21259f,0.15374f,0.11534f,0.092532f,0.055768f,0.031114f,0.016973f,0.0038919f,0.000000f,0.000000f,0.000000f}, {0.55484f,0.49969f,0.48676f,0.47535f,0.45999f,0.4406f,0.41747f,0.39084f,0.3589f,0.31565f,0.24497f,0.18988f,0.16127f,0.11527f,0.083186f,0.061436f,0.040831f,0.018492f,0.0013084f,0.000000f,0.000000f}, {0.63203f,0.56664f,0.53922f,0.51913f,0.49762f,0.47305f,0.44521f,0.41467f,0.38246f,0.34456f,0.28169f,0.24152f,0.1898f,0.15351f,0.12607f,0.10138f,0.073199f,0.041753f,0.011636f,0.000000f,0.000000f}, {0.70711f,0.63601f,0.5915f,0.56154f,0.5324f,0.49872f,0.46317f,0.42387f,0.38431f,0.34937f,0.31849f,0.28164f,0.24488f,0.21244f,0.18245f,0.14826f,0.10854f,0.068473f,0.027433f,0.000000f,0.000000f}, {0.77384f,0.7028f,0.64182f,0.59999f,0.5611f,0.52035f,0.47318f,0.42773f,0.39037f,0.35676f,0.34937f,0.34453f,0.31539f,0.27747f,0.23686f,0.19392f,0.14881f,0.1006f,0.049384f,0.0043772f,0.000000f}, {0.83292f,0.76642f,0.69548f,0.63988f,0.59007f,0.53795f,0.48146f,0.43778f,0.40135f,0.39034f,0.38431f,0.3824f,0.35884f,0.32588f,0.28429f,0.2365f,0.18525f,0.12989f,0.070085f,0.011962f,0.000000f}, {0.88048f,0.82659f,0.75196f,0.68173f,0.61966f,0.55557f,0.49389f,0.45152f,0.43774f,0.42776f,0.42387f,0.41451f,0.39065f,0.36002f,0.32174f,0.27262f,0.21753f,0.15652f,0.089694f,0.018075f,0.000000f}, {0.91982f,0.87898f,0.80369f,0.72266f,0.64727f,0.57793f,0.51602f,0.49394f,0.48142f,0.47314f,0.46315f,0.44506f,0.41722f,0.38449f,0.34948f,0.30197f,0.24734f,0.18313f,0.10655f,0.022264f,0.000000f}, {0.94888f,0.91176f,0.84521f,0.76937f,0.68766f,0.60203f,0.57788f,0.55561f,0.53794f,0.52028f,0.49868f,0.47276f,0.44023f,0.40381f,0.36503f,0.32695f,0.26927f,0.20135f,0.12342f,0.035717f,0.000000f}, {0.9703f,0.92966f,0.89031f,0.80673f,0.72356f,0.6876f,0.64713f,0.61943f,0.5899f,0.56088f,0.53232f,0.49722f,0.45953f,0.41857f,0.37646f,0.33123f,0.28771f,0.21775f,0.12737f,0.058204f,0.000000f}, {0.98481f,0.94077f,0.8973f,0.84179f,0.80663f,0.76916f,0.72238f,0.68134f,0.63953f,0.59955f,0.56144f,0.51865f,0.47475f,0.42817f,0.38012f,0.32941f,0.27908f,0.22844f,0.15705f,0.083257f,0.000000f}, {0.99396f,0.94647f,0.89932f,0.89719f,0.89008f,0.84488f,0.80323f,0.75136f,0.69482f,0.64113f,0.59135f,0.53856f,0.48604f,0.43137f,0.37452f,0.3177f,0.25473f,0.21738f,0.18614f,0.10958f,0.000000f}, {0.99855f,0.94808f,0.94637f,0.94057f,0.92934f,0.91132f,0.87838f,0.82589f,0.76558f,0.70182f,0.63578f,0.56555f,0.49868f,0.43048f,0.35999f,0.29603f,0.24451f,0.20108f,0.16489f,0.1358f,0.000000f}, {1.000000f,0.99854f,0.99377f,0.9845f,0.96987f,0.94832f,0.91914f,0.87965f,0.83195f,0.77384f,0.70711f,0.63203f,0.55339f,0.47409f,0.39234f,0.31565f,0.24192f,0.17365f,0.10973f,0.052336f,0.000000f}}; static float map_4point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043772f,0.011962f,0.018075f,0.022264f,0.035717f,0.058204f,0.083257f,0.10958f,0.13592f,0.052336f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013084f,0.011636f,0.027472f,0.049384f,0.070085f,0.089694f,0.10655f,0.12342f,0.12737f,0.15705f,0.18623f,0.16489f,0.10973f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038919f,0.018492f,0.041753f,0.068513f,0.1006f,0.12983f,0.15652f,0.18313f,0.20135f,0.21775f,0.22851f,0.21738f,0.20108f,0.17363f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.016973f,0.040831f,0.073199f,0.10859f,0.14876f,0.1852f,0.21753f,0.24734f,0.26927f,0.28776f,0.27908f,0.25473f,0.24451f,0.24192f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.002725f,0.011267f,0.031114f,0.061436f,0.10138f,0.14831f,0.19392f,0.2365f,0.27257f,0.30197f,0.327f,0.33123f,0.32934f,0.31761f,0.29589f,0.31565f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0039191f,0.011379f,0.035584f,0.055812f,0.083146f,0.12603f,0.18248f,0.23686f,0.28429f,0.32174f,0.34952f,0.36503f,0.37646f,0.38012f,0.37444f,0.35999f,0.39234f}, {0.000000f,0.000000f,0.000000f,0.0039822f,0.017152f,0.03134f,0.055926f,0.09249f,0.11527f,0.15351f,0.21247f,0.27743f,0.32588f,0.36005f,0.38449f,0.40381f,0.41852f,0.42817f,0.43128f,0.43048f,0.47409f}, {0.000000f,0.000000f,0.0013628f,0.018696f,0.041097f,0.061737f,0.083376f,0.11538f,0.16121f,0.18976f,0.24491f,0.31539f,0.35887f,0.39065f,0.41717f,0.44023f,0.45953f,0.47475f,0.48597f,0.49857f,0.55339f}, {0.000000f,0.000000f,0.011806f,0.042039f,0.073541f,0.10174f,0.12638f,0.15373f,0.18988f,0.24145f,0.28167f,0.34454f,0.38236f,0.41451f,0.445f,0.47276f,0.49722f,0.51865f,0.53856f,0.56555f,0.63203f}, {0.000000f,8.5322e-019f,0.027472f,0.068532f,0.10862f,0.14835f,0.18253f,0.21252f,0.24491f,0.28164f,0.31849f,0.34939f,0.38433f,0.42389f,0.46318f,0.49872f,0.53237f,0.56148f,0.59141f,0.63586f,0.70711f}, {0.000000f,0.0045097f,0.049741f,0.10103f,0.14921f,0.19436f,0.23726f,0.27779f,0.31563f,0.34453f,0.34938f,0.35677f,0.39034f,0.42771f,0.47314f,0.52028f,0.56081f,0.59955f,0.64113f,0.70182f,0.77384f}, {0.000000f,0.012179f,0.070512f,0.13031f,0.18569f,0.23696f,0.28468f,0.3262f,0.35886f,0.38246f,0.38432f,0.39033f,0.40136f,0.43778f,0.48142f,0.53794f,0.58984f,0.63945f,0.69482f,0.76558f,0.83195f}, {0.000000f,0.018356f,0.090176f,0.15706f,0.21803f,0.27305f,0.32214f,0.36006f,0.39088f,0.41462f,0.42388f,0.42773f,0.43778f,0.45153f,0.49394f,0.55555f,0.61943f,0.68134f,0.75136f,0.82586f,0.87965f}, {0.000000f,0.022585f,0.10709f,0.1837f,0.24789f,0.30247f,0.34954f,0.38486f,0.41747f,0.44521f,0.46317f,0.47313f,0.48141f,0.49393f,0.51604f,0.57793f,0.64713f,0.7226f,0.80323f,0.87839f,0.91914f}, {0.000000f,0.03616f,0.12403f,0.20197f,0.26986f,0.32703f,0.36552f,0.40423f,0.4406f,0.47305f,0.49872f,0.5204f,0.538f,0.55557f,0.57793f,0.60205f,0.6876f,0.76916f,0.84488f,0.91132f,0.94832f}, {0.000000f,0.058746f,0.12802f,0.21842f,0.2878f,0.33185f,0.37704f,0.41905f,0.45997f,0.4976f,0.53237f,0.5611f,0.59007f,0.61958f,0.64727f,0.6877f,0.7236f,0.80663f,0.89008f,0.92934f,0.96987f}, {0.000000f,0.083896f,0.15778f,0.22854f,0.27982f,0.33006f,0.38081f,0.42882f,0.47533f,0.51919f,0.56149f,0.59999f,0.63988f,0.68173f,0.72294f,0.76935f,0.80673f,0.84179f,0.89719f,0.94057f,0.9845f}, {0.000000f,0.11031f,0.18625f,0.21822f,0.25563f,0.31848f,0.3753f,0.43211f,0.48676f,0.5393f,0.59144f,0.64182f,0.69546f,0.75192f,0.80366f,0.84518f,0.89031f,0.8973f,0.8993f,0.94637f,0.99377f}, {0.000000f,0.13592f,0.16581f,0.20208f,0.24559f,0.29703f,0.36121f,0.43162f,0.49969f,0.56664f,0.63593f,0.7028f,0.76638f,0.82659f,0.87898f,0.91171f,0.92966f,0.94077f,0.94647f,0.94806f,0.99846f}, {7.8496e-017f,0.054079f,0.11147f,0.17537f,0.24362f,0.3173f,0.39394f,0.47562f,0.55484f,0.63338f,0.70711f,0.77494f,0.83292f,0.88048f,0.91982f,0.94888f,0.9703f,0.98481f,0.99396f,0.99863f,1.000000f}}; static float map_4point1_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.99854f,0.94804f,0.94647f,0.94043f,0.92966f,0.91177f,0.87898f,0.82659f,0.76643f,0.70248f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.99373f,0.94619f,0.89929f,0.8973f,0.89f,0.84522f,0.80369f,0.75196f,0.69549f,0.64182f,0.59149f,0.53909f,0.48676f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.98443f,0.94057f,0.89693f,0.84178f,0.80673f,0.76938f,0.72295f,0.68173f,0.63988f,0.59999f,0.56152f,0.51902f,0.47535f,0.42864f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.96987f,0.92924f,0.89008f,0.8064f,0.72353f,0.68753f,0.64727f,0.61961f,0.59007f,0.5611f,0.53236f,0.49762f,0.45999f,0.41905f,0.37687f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.94832f,0.91132f,0.84488f,0.76916f,0.6876f,0.60199f,0.57793f,0.55557f,0.53786f,0.52026f,0.49866f,0.47305f,0.4406f,0.40425f,0.36538f,0.32707f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.91914f,0.87839f,0.80323f,0.72262f,0.64697f,0.57779f,0.51599f,0.49381f,0.48147f,0.4732f,0.46311f,0.44521f,0.41747f,0.38486f,0.34957f,0.30247f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.87965f,0.82586f,0.75136f,0.68116f,0.61943f,0.55563f,0.49394f,0.45149f,0.43778f,0.42773f,0.42381f,0.41464f,0.39077f,0.36007f,0.32202f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.83195f,0.76558f,0.69482f,0.63955f,0.58992f,0.53794f,0.48142f,0.43767f,0.40132f,0.39038f,0.38425f,0.38246f,0.35885f,0.3262f,0.2847f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.77494f,0.70182f,0.64105f,0.59937f,0.5609f,0.52028f,0.47314f,0.42777f,0.39034f,0.35673f,0.34932f,0.34449f,0.31565f,0.27779f,0.23728f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.70711f,0.63577f,0.59134f,0.56143f,0.53234f,0.49869f,0.46315f,0.42387f,0.38431f,0.34937f,0.3185f,0.28163f,0.2449f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.63338f,0.56555f,0.53856f,0.51865f,0.49722f,0.47263f,0.44507f,0.41451f,0.38241f,0.34452f,0.2816f,0.24145f,0.18988f,0.15379f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.55339f,0.49871f,0.48607f,0.47475f,0.45953f,0.44013f,0.41724f,0.39065f,0.35885f,0.31539f,0.24485f,0.1898f,0.16119f,0.11535f,0.083376f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.47409f,0.43048f,0.43138f,0.42817f,0.41859f,0.40381f,0.38442f,0.36003f,0.32583f,0.27748f,0.21245f,0.15351f,0.11527f,0.092466f,0.055926f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.39234f,0.35999f,0.37455f,0.38033f,0.37646f,0.36503f,0.34948f,0.32174f,0.28429f,0.23686f,0.18246f,0.12608f,0.083197f,0.055812f,0.03557f,0.011379f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.31565f,0.29607f,0.31773f,0.32943f,0.33124f,0.32696f,0.30198f,0.27263f,0.2365f,0.19392f,0.14828f,0.10138f,0.061436f,0.031114f,0.011267f,0.002725f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24192f,0.24451f,0.25473f,0.27908f,0.28772f,0.26927f,0.24734f,0.21753f,0.18526f,0.14882f,0.10856f,0.073199f,0.040831f,0.01704f,0.0038302f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17365f,0.20108f,0.21738f,0.22846f,0.21775f,0.20135f,0.18335f,0.15652f,0.12991f,0.1006f,0.068474f,0.041753f,0.018492f,0.0038919f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.10973f,0.16489f,0.18616f,0.15705f,0.12737f,0.12342f,0.10655f,0.089694f,0.070085f,0.049384f,0.027446f,0.011636f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.052332f,0.13583f,0.10958f,0.083257f,0.058204f,0.035717f,0.022438f,0.018227f,0.011962f,0.0043772f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_4point1_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.70182f,0.76558f,0.82586f,0.87839f,0.91132f,0.92934f,0.94057f,0.94637f,0.94804f,0.99863f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48597f,0.53856f,0.59121f,0.64167f,0.69482f,0.75136f,0.80323f,0.84488f,0.89008f,0.89725f,0.89927f,0.94647f,0.99396f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.42817f,0.47475f,0.51865f,0.56131f,0.59998f,0.63948f,0.6818f,0.72306f,0.76916f,0.80688f,0.84174f,0.8973f,0.94077f,0.98473f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.37646f,0.41852f,0.45953f,0.49722f,0.53221f,0.56083f,0.58986f,0.61943f,0.64753f,0.6876f,0.72348f,0.80673f,0.89031f,0.92966f,0.9703f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.32696f,0.36503f,0.40381f,0.44057f,0.47309f,0.49858f,0.52028f,0.53794f,0.55557f,0.57829f,0.60191f,0.688f,0.76938f,0.84522f,0.91177f,0.94888f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30233f,0.34948f,0.3848f,0.41719f,0.44502f,0.46308f,0.47314f,0.48142f,0.49394f,0.51592f,0.57793f,0.64727f,0.72306f,0.80369f,0.87898f,0.91982f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.32174f,0.36002f,0.39065f,0.41451f,0.4238f,0.42773f,0.43804f,0.45143f,0.49424f,0.55557f,0.61961f,0.68173f,0.75196f,0.82659f,0.88048f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.28429f,0.32614f,0.35884f,0.38237f,0.38425f,0.39034f,0.40127f,0.43778f,0.48142f,0.53827f,0.59007f,0.63988f,0.69549f,0.76643f,0.83292f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.27743f,0.31539f,0.34452f,0.34932f,0.35669f,0.39034f,0.42773f,0.47315f,0.52061f,0.5611f,0.59999f,0.64182f,0.7028f,0.77494f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.24485f,0.28161f,0.31849f,0.34932f,0.38425f,0.42381f,0.46314f,0.49869f,0.53239f,0.56152f,0.59147f,0.63596f,0.70711f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12603f,0.15351f,0.18976f,0.24145f,0.28164f,0.34451f,0.38246f,0.41464f,0.44521f,0.47305f,0.49762f,0.51919f,0.5393f,0.56664f,0.63338f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.083146f,0.11527f,0.16121f,0.18988f,0.2449f,0.31565f,0.35887f,0.39092f,0.41747f,0.4406f,0.45999f,0.47535f,0.48676f,0.49969f,0.55484f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.056058f,0.092505f,0.11557f,0.15374f,0.21251f,0.27779f,0.3262f,0.36008f,0.38486f,0.40425f,0.41905f,0.42882f,0.43211f,0.43164f,0.47562f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.011267f,0.0356f,0.055926f,0.083376f,0.12638f,0.18252f,0.23728f,0.2847f,0.32214f,0.34955f,0.36552f,0.37704f,0.38081f,0.3753f,0.36121f,0.39394f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027341f,0.011405f,0.03134f,0.061737f,0.10174f,0.14834f,0.19436f,0.23696f,0.27305f,0.30247f,0.32704f,0.33185f,0.33006f,0.31848f,0.29703f,0.3173f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039191f,0.017152f,0.041097f,0.073541f,0.10862f,0.14921f,0.18569f,0.21805f,0.24789f,0.26986f,0.28782f,0.27982f,0.25563f,0.24559f,0.24362f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039822f,0.018696f,0.042039f,0.068554f,0.10103f,0.13031f,0.15706f,0.1837f,0.20197f,0.21842f,0.22858f,0.21822f,0.20208f,0.17537f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013628f,0.011806f,0.027511f,0.049741f,0.070512f,0.090176f,0.10709f,0.12403f,0.12802f,0.15778f,0.1863f,0.16581f,0.11147f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-8.5322e-019f,0.0045097f,0.012179f,0.018356f,0.022585f,0.03616f,0.058746f,0.083896f,0.11031f,0.136f,0.054075f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-7.8496e-017f}}; static float map_5point1_ang[] = {-27,0,27,-105,105}; static float map_5point1_xsf[] = {-1,0,1,-1,1}; static float map_5point1_ysf[] = {1,1,1,-1,-1}; channel_id map_5point1_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_back_left,ci_back_right,ci_lfe}; static float map_5point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.054079f,0.13605f,0.11031f,0.083738f,0.058746f,0.03616f,0.022585f,0.018356f,0.012179f,0.0043961f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.11103f,0.16562f,0.18635f,0.15778f,0.12791f,0.12403f,0.10709f,0.090176f,0.070512f,0.049741f,0.027549f,0.011727f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17535f,0.20208f,0.21809f,0.22862f,0.21842f,0.20197f,0.18341f,0.15706f,0.13031f,0.10103f,0.068601f,0.041975f,0.018696f,0.0039144f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24362f,0.24543f,0.25563f,0.27972f,0.28786f,0.26979f,0.24789f,0.21805f,0.18569f,0.14921f,0.10871f,0.073541f,0.041097f,0.017152f,0.0038597f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3173f,0.29703f,0.31848f,0.33006f,0.33185f,0.32571f,0.30203f,0.27305f,0.23691f,0.19431f,0.14844f,0.10174f,0.061737f,0.03134f,0.010908f,0.0013625f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.39394f,0.36121f,0.3753f,0.38051f,0.37306f,0.35451f,0.33178f,0.30958f,0.28023f,0.23726f,0.18262f,0.12638f,0.07899f,0.043546f,0.017841f,0.00044495f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.47562f,0.43164f,0.43211f,0.42477f,0.4019f,0.37291f,0.34131f,0.31385f,0.29675f,0.2674f,0.21259f,0.14347f,0.086077f,0.046322f,0.012467f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55484f,0.49969f,0.48539f,0.45665f,0.41889f,0.37886f,0.33895f,0.30764f,0.28138f,0.2723f,0.23279f,0.14674f,0.083778f,0.032293f,0.0048976f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.63203f,0.56664f,0.52742f,0.47709f,0.42408f,0.37424f,0.33419f,0.30176f,0.27482f,0.25011f,0.23665f,0.1471f,0.082204f,0.040759f,0.015195f,0.0028496f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.70711f,0.63601f,0.56403f,0.49301f,0.42572f,0.37154f,0.33227f,0.30051f,0.27246f,0.24769f,0.22385f,0.17996f,0.13303f,0.089089f,0.051572f,0.021112f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.77384f,0.69829f,0.59208f,0.49896f,0.42627f,0.37547f,0.33559f,0.30342f,0.27695f,0.2532f,0.24555f,0.24096f,0.202f,0.15312f,0.099312f,0.049149f,0.01419f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83292f,0.75424f,0.62497f,0.51188f,0.43577f,0.38288f,0.34157f,0.31064f,0.28485f,0.27588f,0.27011f,0.26791f,0.24233f,0.19874f,0.14444f,0.081488f,0.031102f,0.0022352f,0.000000f,0.000000f,0.000000f}, {0.88048f,0.80823f,0.66178f,0.53219f,0.45043f,0.39421f,0.35046f,0.32046f,0.30985f,0.30176f,0.29791f,0.28855f,0.26277f,0.22895f,0.1783f,0.11122f,0.048526f,0.0073556f,0.000000f,0.000000f,0.000000f}, {0.91982f,0.8564f,0.6966f,0.55364f,0.46596f,0.41011f,0.36623f,0.3499f,0.34025f,0.33348f,0.32389f,0.30536f,0.27602f,0.24046f,0.19967f,0.13416f,0.066173f,0.014462f,0.000000f,0.000000f,0.000000f}, {0.94888f,0.8756f,0.72118f,0.58509f,0.49378f,0.42727f,0.40951f,0.39303f,0.37927f,0.36377f,0.34295f,0.31626f,0.28156f,0.24129f,0.19667f,0.15218f,0.075526f,0.017441f,0.000000f,0.000000f,0.000000f}, {0.9703f,0.87092f,0.76228f,0.60765f,0.51716f,0.48514f,0.45531f,0.43328f,0.40894f,0.38299f,0.35389f,0.31939f,0.27862f,0.23237f,0.18465f,0.12881f,0.081296f,0.019071f,0.000000f,0.000000f,0.000000f}, {0.98481f,0.85688f,0.73952f,0.62982f,0.5767f,0.53382f,0.4939f,0.46098f,0.42667f,0.39124f,0.35254f,0.31034f,0.26195f,0.20782f,0.15167f,0.09417f,0.04946f,0.016531f,0.000000f,0.000000f,0.000000f}, {0.99396f,0.83616f,0.71307f,0.68155f,0.64457f,0.57478f,0.52315f,0.47464f,0.42859f,0.38222f,0.33181f,0.27965f,0.21975f,0.15464f,0.094607f,0.047925f,0.0098814f,0.0024671f,0.000000f,0.000000f,0.000000f}, {0.99855f,0.81216f,0.78057f,0.73849f,0.68375f,0.61653f,0.5369f,0.46213f,0.39741f,0.33339f,0.26339f,0.19725f,0.13069f,0.067274f,0.019339f,0.0021311f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.94446f,0.8823f,0.80914f,0.72626f,0.63102f,0.52519f,0.40402f,0.27711f,0.14046f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_5point1_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.001914f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.0155f,0.025167f,0.017695f,0.0063155f,1.0116e-005f,0.000000f,0.000000f,0.0062031f,0.017508f,0.025125f,0.015305f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0056317f,0.024256f,0.044322f,0.061583f,0.065405f,0.041656f,0.014688f,4.0817e-019f,0.014527f,0.041389f,0.065342f,0.061236f,0.044002f,0.024003f,0.005504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0019274f,0.02644f,0.05812f,0.08731f,0.11105f,0.11767f,0.10963f,0.061306f,0.017226f,0.061006f,0.10958f,0.11735f,0.11066f,0.086884f,0.057744f,0.026151f,0.0018503f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016697f,0.059451f,0.104f,0.13974f,0.15702f,0.15962f,0.15223f,0.13355f,0.063692f,0.13353f,0.15211f,0.15945f,0.15675f,0.13934f,0.10352f,0.059047f,0.016456f,0.000000f,0.000000f}, {0.000000f,1.2068e-018f,0.038851f,0.096919f,0.15087f,0.17987f,0.18511f,0.17445f,0.15817f,0.14379f,0.13384f,0.14378f,0.15816f,0.17444f,0.18509f,0.17981f,0.15076f,0.096821f,0.038797f,0.000000f,0.000000f}, {0.000000f,0.0063777f,0.070344f,0.14288f,0.19068f,0.2049f,0.19453f,0.1758f,0.16036f,0.14645f,0.14681f,0.14646f,0.16036f,0.1758f,0.19453f,0.20473f,0.19031f,0.14227f,0.06984f,0.0061903f,0.000000f}, {0.000000f,0.017224f,0.099719f,0.18101f,0.21822f,0.2193f,0.19777f,0.17979f,0.16475f,0.16187f,0.16149f,0.16187f,0.16477f,0.1798f,0.19777f,0.21922f,0.21792f,0.18045f,0.099116f,0.016918f,0.000000f}, {0.000000f,0.02596f,0.12753f,0.21148f,0.23925f,0.22819f,0.20284f,0.18535f,0.18085f,0.17814f,0.17812f,0.17814f,0.18084f,0.18536f,0.20284f,0.22818f,0.23901f,0.21095f,0.12685f,0.025562f,0.000000f}, {0.000000f,0.03194f,0.15144f,0.23904f,0.2564f,0.23733f,0.21182f,0.20371f,0.19964f,0.19751f,0.19694f,0.1975f,0.19963f,0.20369f,0.21184f,0.23733f,0.25621f,0.23853f,0.15068f,0.031485f,0.000000f}, {0.000000f,0.051138f,0.17541f,0.26062f,0.27419f,0.24713f,0.23812f,0.22985f,0.2244f,0.22133f,0.22022f,0.22132f,0.22439f,0.22984f,0.2381f,0.24715f,0.274f,0.26009f,0.17455f,0.050511f,0.000000f}, {0.000000f,0.08308f,0.18105f,0.28155f,0.29188f,0.28632f,0.27128f,0.26327f,0.25585f,0.25151f,0.25234f,0.2515f,0.25584f,0.26325f,0.27127f,0.28627f,0.29189f,0.28098f,0.18013f,0.082312f,0.000000f}, {0.000000f,0.11865f,0.22314f,0.29977f,0.32517f,0.33282f,0.32312f,0.31164f,0.30095f,0.2946f,0.29542f,0.29459f,0.30094f,0.31163f,0.32308f,0.33259f,0.32473f,0.29967f,0.22211f,0.11774f,0.000000f}, {0.000000f,0.15601f,0.26339f,0.30497f,0.3472f,0.38198f,0.39609f,0.39135f,0.3765f,0.36616f,0.36703f,0.36615f,0.37649f,0.39123f,0.39574f,0.3814f,0.34627f,0.30393f,0.26322f,0.15497f,0.000000f}, {0.000000f,0.19222f,0.23448f,0.28578f,0.34732f,0.4169f,0.48293f,0.51439f,0.52067f,0.52104f,0.52661f,0.52086f,0.52026f,0.51365f,0.48176f,0.41543f,0.34579f,0.28436f,0.23319f,0.19202f,0.000000f}, {1.1102e-016f,0.076479f,0.15764f,0.24801f,0.34452f,0.44874f,0.55712f,0.67263f,0.78467f,0.89574f,1.000000f,0.89382f,0.78261f,0.67046f,0.55485f,0.4464f,0.34213f,0.24558f,0.15519f,0.074014f,0.000000f}}; static float map_5point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043772f,0.011962f,0.018075f,0.022264f,0.035717f,0.058204f,0.083257f,0.10958f,0.13592f,0.052336f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013084f,0.011636f,0.027472f,0.049384f,0.070085f,0.089694f,0.10655f,0.12342f,0.12737f,0.15705f,0.18623f,0.16489f,0.10973f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038919f,0.018492f,0.041753f,0.068513f,0.1006f,0.12983f,0.15652f,0.18313f,0.20135f,0.21775f,0.22851f,0.21738f,0.20108f,0.17363f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.016973f,0.040831f,0.073199f,0.10859f,0.14876f,0.1852f,0.21753f,0.24734f,0.26927f,0.28776f,0.27908f,0.25473f,0.24451f,0.24192f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.010822f,0.031114f,0.061436f,0.10138f,0.14831f,0.19392f,0.2365f,0.27257f,0.30156f,0.32564f,0.33123f,0.32934f,0.31761f,0.29589f,0.31565f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00041878f,0.017789f,0.0433f,0.07868f,0.12602f,0.18248f,0.23686f,0.2799f,0.30936f,0.33175f,0.35421f,0.37263f,0.38012f,0.37444f,0.35999f,0.39234f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.01238f,0.046242f,0.085813f,0.14312f,0.21247f,0.26716f,0.29661f,0.31385f,0.34119f,0.3727f,0.40155f,0.42428f,0.43128f,0.43048f,0.47409f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0048489f,0.032179f,0.083684f,0.14641f,0.23272f,0.27225f,0.28139f,0.30767f,0.33894f,0.3788f,0.4187f,0.45626f,0.48466f,0.49857f,0.55339f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029287f,0.015357f,0.040874f,0.082238f,0.14702f,0.23663f,0.25012f,0.27481f,0.30176f,0.33418f,0.37423f,0.42403f,0.4769f,0.52692f,0.56555f,0.63203f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.021156f,0.051639f,0.089163f,0.13307f,0.17997f,0.22386f,0.24772f,0.27249f,0.30054f,0.33231f,0.37158f,0.42577f,0.49302f,0.56398f,0.63586f,0.70711f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.01438f,0.049473f,0.099723f,0.15348f,0.20226f,0.24098f,0.24557f,0.25321f,0.27695f,0.30342f,0.33559f,0.37551f,0.42626f,0.49895f,0.59175f,0.69745f,0.77384f}, {0.000000f,0.000000f,0.000000f,0.0023122f,0.031384f,0.081894f,0.14485f,0.19907f,0.24237f,0.268f,0.27012f,0.27589f,0.28486f,0.31064f,0.34157f,0.38293f,0.43576f,0.51188f,0.62473f,0.75361f,0.83195f}, {0.000000f,0.000000f,0.000000f,0.0075151f,0.048878f,0.11169f,0.17871f,0.229f,0.263f,0.28867f,0.29793f,0.30177f,0.3099f,0.32047f,0.3505f,0.39422f,0.45043f,0.53218f,0.66167f,0.80779f,0.87965f}, {0.000000f,0.000000f,0.000000f,0.014677f,0.066587f,0.13466f,0.19976f,0.24081f,0.2763f,0.30555f,0.32392f,0.33349f,0.34026f,0.3499f,0.36625f,0.41012f,0.46596f,0.55393f,0.69668f,0.85613f,0.91914f}, {0.000000f,0.000000f,0.000000f,0.017689f,0.075976f,0.15229f,0.19715f,0.24172f,0.28192f,0.31654f,0.343f,0.3639f,0.37933f,0.39305f,0.40957f,0.42729f,0.49385f,0.58524f,0.72145f,0.8756f,0.94832f}, {0.000000f,0.000000f,0.000000f,0.019339f,0.081415f,0.12939f,0.18521f,0.2329f,0.27908f,0.31978f,0.35395f,0.38326f,0.40917f,0.43346f,0.45546f,0.48528f,0.5172f,0.60794f,0.76272f,0.87113f,0.96987f}, {0.000000f,0.000000f,0.000000f,0.016574f,0.049892f,0.094728f,0.15233f,0.20846f,0.26255f,0.31088f,0.35261f,0.39169f,0.42708f,0.46137f,0.49449f,0.53421f,0.57711f,0.6299f,0.74014f,0.85731f,0.9845f}, {0.000000f,0.000000f,0.000000f,0.0025743f,0.010122f,0.048381f,0.095227f,0.15539f,0.22053f,0.28038f,0.33191f,0.38291f,0.42927f,0.47532f,0.52386f,0.57553f,0.64546f,0.68239f,0.71318f,0.83679f,0.99377f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022432f,0.019725f,0.067908f,0.13152f,0.19821f,0.26356f,0.3345f,0.39855f,0.46338f,0.53833f,0.61802f,0.68515f,0.7397f,0.78158f,0.8123f,0.99846f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14292f,0.27953f,0.40639f,0.52748f,0.63323f,0.72837f,0.81116f,0.88423f,0.94629f,1.000000f}}; static float map_5point1_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.99854f,0.94804f,0.94647f,0.94043f,0.92966f,0.91177f,0.87898f,0.82659f,0.76643f,0.70248f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.99373f,0.94619f,0.89929f,0.8973f,0.89f,0.84522f,0.80369f,0.75196f,0.69549f,0.64182f,0.59149f,0.53909f,0.48676f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.98443f,0.94057f,0.89693f,0.84178f,0.80673f,0.76938f,0.72295f,0.68173f,0.63988f,0.59999f,0.56152f,0.51902f,0.47535f,0.42864f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.96987f,0.92924f,0.89008f,0.8064f,0.72353f,0.68753f,0.64727f,0.61961f,0.59007f,0.5611f,0.53236f,0.49762f,0.45999f,0.41905f,0.37687f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.94832f,0.91132f,0.84488f,0.76916f,0.6876f,0.60199f,0.57793f,0.55557f,0.53786f,0.52026f,0.49866f,0.47305f,0.4406f,0.40425f,0.36538f,0.32707f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.91914f,0.87839f,0.80323f,0.72262f,0.64697f,0.57779f,0.51599f,0.49381f,0.48147f,0.4732f,0.46311f,0.44521f,0.41747f,0.38486f,0.34957f,0.30247f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.87965f,0.82586f,0.75136f,0.68116f,0.61943f,0.55563f,0.49394f,0.45149f,0.43778f,0.42773f,0.42381f,0.41464f,0.39077f,0.36007f,0.32202f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.83195f,0.76558f,0.69482f,0.63955f,0.58992f,0.53794f,0.48142f,0.43767f,0.40132f,0.39038f,0.38425f,0.38246f,0.35885f,0.3262f,0.2847f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.77494f,0.70182f,0.64105f,0.59937f,0.5609f,0.52028f,0.47314f,0.42777f,0.39034f,0.35673f,0.34932f,0.34449f,0.31565f,0.27779f,0.23728f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.70711f,0.63577f,0.59134f,0.56143f,0.53234f,0.49869f,0.46315f,0.42387f,0.38431f,0.34937f,0.3185f,0.28163f,0.2449f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.63338f,0.56555f,0.53856f,0.51865f,0.49722f,0.47263f,0.44507f,0.41451f,0.38241f,0.34452f,0.2816f,0.24145f,0.18988f,0.15379f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.55339f,0.49871f,0.48607f,0.47475f,0.45953f,0.44013f,0.41724f,0.39065f,0.35885f,0.31539f,0.24485f,0.1898f,0.16119f,0.11535f,0.083376f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.47409f,0.43048f,0.43138f,0.42817f,0.41859f,0.40381f,0.38442f,0.36003f,0.32583f,0.27748f,0.21245f,0.15351f,0.11527f,0.092466f,0.055926f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.39234f,0.35999f,0.37455f,0.38033f,0.37646f,0.36503f,0.34948f,0.32174f,0.28429f,0.23686f,0.18246f,0.12608f,0.083197f,0.055812f,0.03557f,0.011379f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.31565f,0.29607f,0.31773f,0.32943f,0.33124f,0.32696f,0.30198f,0.27263f,0.2365f,0.19392f,0.14828f,0.10138f,0.061436f,0.031114f,0.011267f,0.002725f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24192f,0.24451f,0.25473f,0.27908f,0.28772f,0.26927f,0.24734f,0.21753f,0.18526f,0.14882f,0.10856f,0.073199f,0.040831f,0.01704f,0.0038302f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17365f,0.20108f,0.21738f,0.22846f,0.21775f,0.20135f,0.18335f,0.15652f,0.12991f,0.1006f,0.068474f,0.041753f,0.018492f,0.0038919f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.10973f,0.16489f,0.18616f,0.15705f,0.12737f,0.12342f,0.10655f,0.089694f,0.070085f,0.049384f,0.027446f,0.011636f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.052332f,0.13583f,0.10958f,0.083257f,0.058204f,0.035717f,0.022438f,0.018227f,0.011962f,0.0043772f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_5point1_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.70182f,0.76558f,0.82586f,0.87839f,0.91132f,0.92934f,0.94057f,0.94637f,0.94804f,0.99863f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48597f,0.53856f,0.59121f,0.64167f,0.69482f,0.75136f,0.80323f,0.84488f,0.89008f,0.89725f,0.89927f,0.94647f,0.99396f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.42817f,0.47475f,0.51865f,0.56131f,0.59998f,0.63948f,0.6818f,0.72306f,0.76916f,0.80688f,0.84174f,0.8973f,0.94077f,0.98473f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.37646f,0.41852f,0.45953f,0.49722f,0.53221f,0.56083f,0.58986f,0.61943f,0.64753f,0.6876f,0.72348f,0.80673f,0.89031f,0.92966f,0.9703f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.32696f,0.36503f,0.40381f,0.44057f,0.47309f,0.49858f,0.52028f,0.53794f,0.55557f,0.57829f,0.60191f,0.688f,0.76938f,0.84522f,0.91177f,0.94888f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30233f,0.34948f,0.3848f,0.41719f,0.44502f,0.46308f,0.47314f,0.48142f,0.49394f,0.51592f,0.57793f,0.64727f,0.72306f,0.80369f,0.87898f,0.91982f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.32174f,0.36002f,0.39065f,0.41451f,0.4238f,0.42773f,0.43804f,0.45143f,0.49424f,0.55557f,0.61961f,0.68173f,0.75196f,0.82659f,0.88048f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.28429f,0.32614f,0.35884f,0.38237f,0.38425f,0.39034f,0.40127f,0.43778f,0.48142f,0.53827f,0.59007f,0.63988f,0.69549f,0.76643f,0.83292f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.27743f,0.31539f,0.34452f,0.34932f,0.35669f,0.39034f,0.42773f,0.47315f,0.52061f,0.5611f,0.59999f,0.64182f,0.7028f,0.77494f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.24485f,0.28161f,0.31849f,0.34932f,0.38425f,0.42381f,0.46314f,0.49869f,0.53239f,0.56152f,0.59147f,0.63596f,0.70711f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12603f,0.15351f,0.18976f,0.24145f,0.28164f,0.34451f,0.38246f,0.41464f,0.44521f,0.47305f,0.49762f,0.51919f,0.5393f,0.56664f,0.63338f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.083146f,0.11527f,0.16121f,0.18988f,0.2449f,0.31565f,0.35887f,0.39092f,0.41747f,0.4406f,0.45999f,0.47535f,0.48676f,0.49969f,0.55484f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.056058f,0.092505f,0.11557f,0.15374f,0.21251f,0.27779f,0.3262f,0.36008f,0.38486f,0.40425f,0.41905f,0.42882f,0.43211f,0.43164f,0.47562f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.011267f,0.0356f,0.055926f,0.083376f,0.12638f,0.18252f,0.23728f,0.2847f,0.32214f,0.34955f,0.36552f,0.37704f,0.38081f,0.3753f,0.36121f,0.39394f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027341f,0.011405f,0.03134f,0.061737f,0.10174f,0.14834f,0.19436f,0.23696f,0.27305f,0.30247f,0.32704f,0.33185f,0.33006f,0.31848f,0.29703f,0.3173f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039191f,0.017152f,0.041097f,0.073541f,0.10862f,0.14921f,0.18569f,0.21805f,0.24789f,0.26986f,0.28782f,0.27982f,0.25563f,0.24559f,0.24362f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039822f,0.018696f,0.042039f,0.068554f,0.10103f,0.13031f,0.15706f,0.1837f,0.20197f,0.21842f,0.22858f,0.21822f,0.20208f,0.17537f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013628f,0.011806f,0.027511f,0.049741f,0.070512f,0.090176f,0.10709f,0.12403f,0.12802f,0.15778f,0.1863f,0.16581f,0.11147f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-8.5322e-019f,0.0045097f,0.012179f,0.018356f,0.022585f,0.03616f,0.058746f,0.083896f,0.11031f,0.136f,0.054075f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-7.8496e-017f}}; static float map_6point1_ang[] = {-27,0,27,-100,100,180}; static float map_6point1_xsf[] = {-1,0,1,-1,1,0}; static float map_6point1_ysf[] = {1,1,1,0,0,-1}; channel_id map_6point1_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_side_center_left,ci_side_center_right,ci_back_center,ci_lfe}; static float map_6point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0025743f,0.016552f,0.019339f,0.017689f,0.014677f,0.0075151f,0.0023122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.010122f,0.049892f,0.081385f,0.075976f,0.066587f,0.048878f,0.031384f,0.01438f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0022432f,0.048381f,0.094728f,0.12939f,0.15091f,0.13421f,0.11169f,0.081894f,0.049473f,0.021188f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019725f,0.095227f,0.15233f,0.18129f,0.18619f,0.18195f,0.1662f,0.14038f,0.099716f,0.051668f,0.015357f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067908f,0.15539f,0.20448f,0.21574f,0.21038f,0.19727f,0.18275f,0.16961f,0.14309f,0.089211f,0.030602f,0.0029125f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13152f,0.21916f,0.24385f,0.23799f,0.22019f,0.19777f,0.1798f,0.16484f,0.15891f,0.12092f,0.0391f,0.0061765f,0.0028379f,0.00043186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19821f,0.26858f,0.26884f,0.24624f,0.21773f,0.19453f,0.1758f,0.16036f,0.14653f,0.13495f,0.052607f,0.038854f,0.030373f,0.015188f,0.0028496f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.26351f,0.30441f,0.28405f,0.24723f,0.21577f,0.19296f,0.17452f,0.15823f,0.14384f,0.13114f,0.13492f,0.12086f,0.089089f,0.051572f,0.021112f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32999f,0.33317f,0.29065f,0.24843f,0.21902f,0.19594f,0.17746f,0.1625f,0.14962f,0.14386f,0.14651f,0.15886f,0.14285f,0.099312f,0.049149f,0.01419f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.27953f,0.38637f,0.35876f,0.29909f,0.25487f,0.22426f,0.20041f,0.18277f,0.16832f,0.16249f,0.15824f,0.16036f,0.16482f,0.16948f,0.14005f,0.081488f,0.031102f,0.0022352f,0.000000f,0.000000f,0.000000f}, {0.40639f,0.44503f,0.38515f,0.31183f,0.26428f,0.23169f,0.20647f,0.18936f,0.18276f,0.17745f,0.17453f,0.1758f,0.17979f,0.18273f,0.16592f,0.11122f,0.048526f,0.0073556f,0.000000f,0.000000f,0.000000f}, {0.52748f,0.51574f,0.41678f,0.32546f,0.27415f,0.24175f,0.21641f,0.20646f,0.2004f,0.19593f,0.19298f,0.19453f,0.19777f,0.19716f,0.18189f,0.13374f,0.066173f,0.014462f,0.000000f,0.000000f,0.000000f}, {0.63323f,0.58186f,0.4515f,0.34992f,0.2914f,0.25248f,0.24174f,0.23169f,0.22425f,0.219f,0.21579f,0.21773f,0.22013f,0.21018f,0.18585f,0.15082f,0.075526f,0.017441f,0.000000f,0.000000f,0.000000f}, {0.72837f,0.62641f,0.51744f,0.37803f,0.31074f,0.29139f,0.27414f,0.26427f,0.25485f,0.24842f,0.24726f,0.24619f,0.23779f,0.2154f,0.18082f,0.12881f,0.081296f,0.019071f,0.000000f,0.000000f,0.000000f}, {0.81116f,0.6558f,0.5246f,0.41789f,0.37802f,0.34991f,0.32545f,0.31182f,0.29908f,0.29063f,0.28406f,0.26859f,0.24346f,0.20392f,0.15167f,0.09417f,0.04946f,0.016531f,0.000000f,0.000000f,0.000000f}, {0.88423f,0.67127f,0.52691f,0.5245f,0.51721f,0.45136f,0.41661f,0.38495f,0.35851f,0.33283f,0.30436f,0.26801f,0.21844f,0.15464f,0.094607f,0.047925f,0.0098814f,0.0024671f,0.000000f,0.000000f,0.000000f}, {0.94622f,0.67633f,0.67099f,0.65523f,0.62554f,0.58081f,0.51465f,0.44406f,0.38544f,0.32902f,0.26339f,0.19725f,0.13069f,0.067274f,0.019339f,0.0021311f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.94446f,0.8823f,0.80914f,0.72626f,0.63102f,0.52519f,0.40402f,0.27711f,0.14046f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_6point1_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.001914f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.0155f,0.025167f,0.017695f,0.0063155f,1.0116e-005f,0.000000f,0.000000f,0.0062031f,0.017508f,0.025125f,0.015305f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0056317f,0.024256f,0.044322f,0.061583f,0.065405f,0.041656f,0.014688f,4.0817e-019f,0.014527f,0.041389f,0.065342f,0.061236f,0.044002f,0.024003f,0.005504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0019274f,0.02644f,0.05812f,0.08731f,0.11105f,0.11767f,0.10963f,0.061306f,0.017226f,0.061006f,0.10958f,0.11735f,0.11066f,0.086884f,0.057744f,0.026151f,0.0018503f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016697f,0.059451f,0.104f,0.13974f,0.15702f,0.15962f,0.15223f,0.13355f,0.063692f,0.13353f,0.15211f,0.15945f,0.15675f,0.13934f,0.10352f,0.059047f,0.016456f,0.000000f,0.000000f}, {0.000000f,1.2068e-018f,0.038851f,0.096919f,0.15087f,0.17987f,0.18511f,0.17445f,0.15817f,0.14379f,0.13384f,0.14378f,0.15816f,0.17444f,0.18509f,0.17981f,0.15076f,0.096821f,0.038797f,0.000000f,0.000000f}, {0.000000f,0.0063777f,0.070344f,0.14288f,0.19068f,0.2049f,0.19453f,0.1758f,0.16036f,0.14645f,0.14681f,0.14646f,0.16036f,0.1758f,0.19453f,0.20473f,0.19031f,0.14227f,0.06984f,0.0061903f,0.000000f}, {0.000000f,0.017224f,0.099719f,0.18101f,0.21822f,0.2193f,0.19777f,0.17979f,0.16475f,0.16187f,0.16149f,0.16187f,0.16477f,0.1798f,0.19777f,0.21922f,0.21792f,0.18045f,0.099116f,0.016918f,0.000000f}, {0.000000f,0.02596f,0.12753f,0.21148f,0.23925f,0.22819f,0.20284f,0.18535f,0.18085f,0.17814f,0.17812f,0.17814f,0.18084f,0.18536f,0.20284f,0.22818f,0.23901f,0.21095f,0.12685f,0.025562f,0.000000f}, {0.000000f,0.03194f,0.15144f,0.23904f,0.2564f,0.23733f,0.21182f,0.20371f,0.19964f,0.19751f,0.19694f,0.1975f,0.19963f,0.20369f,0.21184f,0.23733f,0.25621f,0.23853f,0.15068f,0.031485f,0.000000f}, {0.000000f,0.051138f,0.17541f,0.26062f,0.27419f,0.24713f,0.23812f,0.22985f,0.2244f,0.22133f,0.22022f,0.22132f,0.22439f,0.22984f,0.2381f,0.24715f,0.274f,0.26009f,0.17455f,0.050511f,0.000000f}, {0.000000f,0.08308f,0.18105f,0.28155f,0.29188f,0.28632f,0.27128f,0.26327f,0.25585f,0.25151f,0.25234f,0.2515f,0.25584f,0.26325f,0.27127f,0.28627f,0.29189f,0.28098f,0.18013f,0.082312f,0.000000f}, {0.000000f,0.11865f,0.22314f,0.29977f,0.32517f,0.33282f,0.32312f,0.31164f,0.30095f,0.2946f,0.29542f,0.29459f,0.30094f,0.31163f,0.32308f,0.33259f,0.32473f,0.29967f,0.22211f,0.11774f,0.000000f}, {0.000000f,0.15601f,0.26339f,0.30497f,0.3472f,0.38198f,0.39609f,0.39135f,0.3765f,0.36616f,0.36703f,0.36615f,0.37649f,0.39123f,0.39574f,0.3814f,0.34627f,0.30393f,0.26322f,0.15497f,0.000000f}, {0.000000f,0.19222f,0.23448f,0.28578f,0.34732f,0.4169f,0.48293f,0.51439f,0.52067f,0.52104f,0.52661f,0.52086f,0.52026f,0.51365f,0.48176f,0.41543f,0.34579f,0.28436f,0.23319f,0.19202f,0.000000f}, {1.1102e-016f,0.076479f,0.15764f,0.24801f,0.34452f,0.44874f,0.55712f,0.67263f,0.78467f,0.89574f,1.000000f,0.89382f,0.78261f,0.67046f,0.55485f,0.4464f,0.34213f,0.24558f,0.15519f,0.074014f,0.000000f}}; static float map_6point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022352f,0.0073556f,0.014462f,0.017441f,0.019071f,0.016531f,0.0024671f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01419f,0.031102f,0.048526f,0.066173f,0.075526f,0.081297f,0.04946f,0.0098814f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.021112f,0.049149f,0.081488f,0.11122f,0.13374f,0.15081f,0.12881f,0.09417f,0.047925f,0.0021311f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.015188f,0.051545f,0.099312f,0.14005f,0.16592f,0.1819f,0.18585f,0.18082f,0.15167f,0.094607f,0.019339f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028379f,0.030373f,0.089057f,0.14285f,0.16948f,0.18273f,0.19716f,0.21018f,0.2154f,0.20392f,0.15464f,0.067274f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0004627f,0.0029125f,0.0061679f,0.038854f,0.12083f,0.15886f,0.16483f,0.17979f,0.19777f,0.22013f,0.23779f,0.24346f,0.21844f,0.13069f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029287f,0.015357f,0.030602f,0.0391f,0.052555f,0.13491f,0.14652f,0.16036f,0.1758f,0.19453f,0.21773f,0.24619f,0.26859f,0.26801f,0.19725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.021156f,0.051639f,0.089163f,0.1209f,0.13493f,0.13114f,0.14385f,0.15824f,0.17453f,0.19297f,0.21578f,0.24725f,0.28402f,0.30431f,0.2633f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.01438f,0.049473f,0.099716f,0.14309f,0.15891f,0.1465f,0.14385f,0.14961f,0.16249f,0.17745f,0.19593f,0.219f,0.24842f,0.29063f,0.33283f,0.32902f,0.14046f}, {0.000000f,0.000000f,0.000000f,0.0023122f,0.031384f,0.081894f,0.14038f,0.16961f,0.16482f,0.16036f,0.15824f,0.1625f,0.16831f,0.18276f,0.2004f,0.22425f,0.25485f,0.29908f,0.35851f,0.38544f,0.27711f}, {0.000000f,0.000000f,0.000000f,0.0075151f,0.048878f,0.11169f,0.1662f,0.18272f,0.1798f,0.1758f,0.17453f,0.17746f,0.18277f,0.18935f,0.20646f,0.23169f,0.26427f,0.31182f,0.38495f,0.44406f,0.40402f}, {0.000000f,0.000000f,0.000000f,0.014677f,0.066587f,0.13421f,0.18194f,0.19727f,0.19777f,0.19453f,0.19297f,0.19594f,0.20041f,0.20647f,0.2164f,0.24174f,0.27414f,0.32545f,0.41661f,0.51465f,0.52519f}, {0.000000f,0.000000f,0.000000f,0.017689f,0.075976f,0.15092f,0.18619f,0.21038f,0.22019f,0.21773f,0.21578f,0.21902f,0.22426f,0.23169f,0.24175f,0.25247f,0.29139f,0.34991f,0.45136f,0.58081f,0.63102f}, {0.000000f,0.000000f,0.000000f,0.019339f,0.081415f,0.12939f,0.18129f,0.21574f,0.23799f,0.24624f,0.24725f,0.24843f,0.25487f,0.26428f,0.27415f,0.2914f,0.31073f,0.37802f,0.51721f,0.62554f,0.72626f}, {0.000000f,0.000000f,0.000000f,0.016574f,0.049892f,0.094728f,0.15233f,0.20448f,0.24385f,0.26884f,0.28405f,0.29065f,0.29909f,0.31183f,0.32546f,0.34992f,0.37803f,0.41787f,0.5245f,0.65523f,0.80914f}, {0.000000f,0.000000f,0.000000f,0.0025743f,0.010122f,0.048381f,0.095227f,0.15539f,0.21916f,0.26858f,0.3044f,0.33317f,0.35876f,0.38515f,0.41678f,0.4515f,0.51744f,0.5246f,0.52688f,0.67099f,0.8823f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022432f,0.019725f,0.067908f,0.13152f,0.19821f,0.26356f,0.32999f,0.38637f,0.44503f,0.51574f,0.58186f,0.62641f,0.6558f,0.67127f,0.6763f,0.94439f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14292f,0.27953f,0.40639f,0.52748f,0.63323f,0.72837f,0.81116f,0.88423f,0.94629f,1.000000f}}; static float map_6point1_lsm[21][21] = { {0.70711f,0.66913f,0.62524f,0.57358f,0.51504f,0.44776f,0.37137f,0.28736f,0.19595f,0.09932f,0.0017453f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.74431f,0.67052f,0.63067f,0.58131f,0.52602f,0.46257f,0.39662f,0.34064f,0.29043f,0.23885f,0.18653f,0.14016f,0.092998f,0.048018f,0.013948f,0.0015862f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78118f,0.70817f,0.63603f,0.59409f,0.54607f,0.49466f,0.44615f,0.39987f,0.3534f,0.30593f,0.25428f,0.20602f,0.1569f,0.10988f,0.067336f,0.03421f,0.0071573f,0.0017445f,1.8971e-005f,0.000000f,0.000000f}, {0.82009f,0.7491f,0.67504f,0.59533f,0.54885f,0.50805f,0.46863f,0.43198f,0.3925f,0.3484f,0.29792f,0.24908f,0.19887f,0.14971f,0.10724f,0.066983f,0.034974f,0.011749f,0.000000f,0.000000f,0.000000f}, {0.85806f,0.78908f,0.71292f,0.59185f,0.51167f,0.47976f,0.45026f,0.42613f,0.39843f,0.36635f,0.32582f,0.27812f,0.2264f,0.17681f,0.13329f,0.091492f,0.057623f,0.013674f,0.000000f,0.000000f,0.000000f}, {0.89493f,0.82759f,0.70113f,0.58024f,0.49236f,0.42569f,0.40827f,0.39203f,0.37751f,0.3594f,0.33252f,0.2937f,0.24301f,0.19308f,0.14677f,0.10873f,0.053405f,0.012508f,0.000000f,0.000000f,0.000000f}, {0.92849f,0.84684f,0.69067f,0.55271f,0.46468f,0.40867f,0.36488f,0.3485f,0.33949f,0.33308f,0.32163f,0.29457f,0.2509f,0.20107f,0.15394f,0.095531f,0.047084f,0.010226f,0.000000f,0.000000f,0.000000f}, {0.95832f,0.82839f,0.66354f,0.53162f,0.45013f,0.39368f,0.3497f,0.31927f,0.30903f,0.30128f,0.29789f,0.28393f,0.24451f,0.19473f,0.13488f,0.078979f,0.034562f,0.005314f,0.000000f,0.000000f,0.000000f}, {0.98061f,0.79322f,0.63001f,0.51243f,0.43605f,0.38298f,0.34135f,0.30979f,0.2838f,0.27526f,0.27009f,0.26562f,0.22628f,0.16159f,0.10558f,0.05762f,0.022192f,0.001635f,0.000000f,0.000000f,0.000000f}, {0.99506f,0.75369f,0.60114f,0.49963f,0.42717f,0.37619f,0.33605f,0.30362f,0.27677f,0.25226f,0.24553f,0.23722f,0.17367f,0.11587f,0.07052f,0.034753f,0.010168f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.71295f,0.58231f,0.49634f,0.42725f,0.37287f,0.33346f,0.30159f,0.27344f,0.24858f,0.22384f,0.15914f,0.10274f,0.063092f,0.036535f,0.01499f,0.0013716f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.66033f,0.55567f,0.48451f,0.42558f,0.37493f,0.33506f,0.30245f,0.27526f,0.25008f,0.23921f,0.17075f,0.088654f,0.036166f,0.010859f,0.0020709f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78261f,0.61267f,0.53096f,0.47309f,0.42398f,0.37972f,0.33948f,0.30798f,0.28134f,0.27269f,0.24365f,0.17958f,0.11398f,0.043395f,0.0065303f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67046f,0.56122f,0.50057f,0.45582f,0.41557f,0.37846f,0.34285f,0.31459f,0.29944f,0.27681f,0.23747f,0.18093f,0.11935f,0.065362f,0.017508f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55485f,0.49543f,0.46264f,0.43028f,0.39912f,0.36952f,0.34049f,0.32017f,0.29681f,0.26475f,0.22159f,0.16749f,0.11097f,0.061236f,0.025146f,0.00059225f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.4464f,0.41694f,0.41528f,0.39917f,0.37733f,0.35383f,0.33184f,0.30683f,0.27684f,0.23948f,0.19477f,0.14135f,0.086884f,0.044002f,0.015305f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34213f,0.34579f,0.35326f,0.3597f,0.34941f,0.3274f,0.303f,0.27332f,0.23991f,0.20034f,0.15216f,0.10352f,0.057744f,0.024003f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24558f,0.28436f,0.30568f,0.3114f,0.29446f,0.27242f,0.24876f,0.21615f,0.18203f,0.14227f,0.096837f,0.059047f,0.026151f,0.005504f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15519f,0.23319f,0.26327f,0.22211f,0.18013f,0.17455f,0.15068f,0.12685f,0.099116f,0.06984f,0.038815f,0.016456f,0.0018503f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.074009f,0.19209f,0.15497f,0.11774f,0.082312f,0.050511f,0.031485f,0.025562f,0.016918f,0.0061903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_6point1_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.09932f,0.19595f,0.28569f,0.37137f,0.4462f,0.51354f,0.57215f,0.62388f,0.66783f,0.70711f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0015069f,0.013675f,0.04757f,0.092412f,0.13947f,0.18623f,0.23884f,0.28947f,0.33956f,0.3954f,0.46121f,0.52464f,0.58106f,0.62943f,0.67037f,0.74314f}, {0.000000f,0.000000f,0.000000f,0.0017445f,0.0069872f,0.033888f,0.066897f,0.10935f,0.15631f,0.20597f,0.25403f,0.30519f,0.35262f,0.39905f,0.44526f,0.4937f,0.54585f,0.59298f,0.63586f,0.70784f,0.78043f}, {0.000000f,0.000000f,0.000000f,0.011689f,0.034974f,0.066588f,0.10724f,0.1497f,0.1983f,0.24897f,0.29771f,0.34778f,0.39193f,0.43144f,0.46866f,0.50751f,0.54828f,0.59521f,0.67489f,0.74808f,0.81909f}, {0.000000f,0.000000f,0.000000f,0.013485f,0.057506f,0.09108f,0.13328f,0.17632f,0.22589f,0.2776f,0.32564f,0.36597f,0.39813f,0.42588f,0.45006f,0.48004f,0.51166f,0.59204f,0.71215f,0.78873f,0.85717f}, {0.000000f,0.000000f,0.000000f,0.012333f,0.053405f,0.10859f,0.14672f,0.19262f,0.24254f,0.2933f,0.33243f,0.35959f,0.37779f,0.39201f,0.40827f,0.42573f,0.49232f,0.58002f,0.70065f,0.82687f,0.89415f}, {0.000000f,0.000000f,0.000000f,0.010226f,0.046792f,0.09516f,0.15378f,0.20065f,0.25051f,0.2943f,0.3216f,0.33307f,0.33948f,0.34884f,0.36492f,0.40905f,0.46512f,0.55322f,0.69045f,0.84644f,0.92784f}, {0.000000f,0.000000f,0.000000f,0.0052012f,0.034313f,0.078646f,0.13483f,0.19459f,0.24448f,0.28376f,0.29792f,0.30128f,0.30903f,0.3193f,0.34969f,0.39367f,0.45013f,0.53213f,0.66357f,0.82833f,0.95782f}, {0.000000f,0.000000f,0.000000f,0.0015805f,0.021993f,0.05762f,0.10524f,0.16123f,0.22617f,0.2655f,0.27011f,0.27526f,0.28382f,0.31008f,0.34135f,0.38297f,0.43605f,0.51242f,0.63017f,0.79346f,0.98027f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.010034f,0.034753f,0.070224f,0.11554f,0.17334f,0.23718f,0.24556f,0.25229f,0.27677f,0.30362f,0.33605f,0.37619f,0.42717f,0.50011f,0.60174f,0.7542f,0.99488f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.014928f,0.036467f,0.062995f,0.10266f,0.15909f,0.22385f,0.24859f,0.27345f,0.3016f,0.33348f,0.37289f,0.42727f,0.49639f,0.58242f,0.71313f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.002015f,0.01075f,0.036165f,0.08878f,0.17076f,0.23925f,0.2501f,0.27526f,0.30245f,0.33506f,0.37529f,0.42563f,0.4847f,0.55608f,0.6612f,0.89574f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0066209f,0.043663f,0.11403f,0.17987f,0.2437f,0.27272f,0.28136f,0.30799f,0.33949f,0.3801f,0.42413f,0.47338f,0.53148f,0.61367f,0.78467f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017695f,0.065451f,0.11973f,0.18126f,0.23753f,0.27698f,0.29973f,0.31462f,0.34319f,0.37861f,0.41582f,0.45622f,0.50122f,0.56241f,0.67263f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062925f,0.0252f,0.061583f,0.11138f,0.16787f,0.22165f,0.26504f,0.29704f,0.32036f,0.34055f,0.36977f,0.39947f,0.43083f,0.46342f,0.49688f,0.55712f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.0155f,0.044322f,0.08731f,0.14181f,0.19485f,0.23988f,0.27721f,0.30717f,0.33223f,0.35391f,0.37781f,0.3998f,0.41619f,0.41848f,0.44874f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.024256f,0.05812f,0.104f,0.15226f,0.20085f,0.24041f,0.27381f,0.30349f,0.32791f,0.34951f,0.36044f,0.35436f,0.34732f,0.34452f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0056317f,0.02644f,0.059451f,0.09695f,0.14288f,0.18265f,0.2168f,0.24942f,0.27312f,0.29522f,0.31155f,0.30679f,0.28578f,0.24801f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019274f,0.016697f,0.038906f,0.070344f,0.099719f,0.12753f,0.15144f,0.17541f,0.18105f,0.22314f,0.26347f,0.23448f,0.15764f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.2068e-018f,0.0063777f,0.017224f,0.02596f,0.03194f,0.051138f,0.08308f,0.11865f,0.15601f,0.19233f,0.076473f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f}}; static float map_6point1_cs[21][21] = { {0.70711f,0.74314f,0.78043f,0.81915f,0.85717f,0.89415f,0.92849f,0.95782f,0.98061f,0.99506f,0.999998f,0.99506f,0.98061f,0.95832f,0.92849f,0.89493f,0.85806f,0.82015f,0.78152f,0.74431f,0.70711f}, {0.66783f,0.67021f,0.70784f,0.74866f,0.78873f,0.82837f,0.86012f,0.8759f,0.88587f,0.89408f,0.89916f,0.89385f,0.88622f,0.87641f,0.86079f,0.82918f,0.78964f,0.7491f,0.70894f,0.67037f,0.66913f}, {0.62417f,0.62995f,0.63575f,0.67663f,0.71956f,0.73454f,0.75734f,0.77291f,0.78464f,0.79125f,0.79739f,0.79171f,0.78498f,0.77342f,0.75801f,0.73534f,0.72008f,0.67767f,0.63591f,0.63067f,0.62524f}, {0.5721f,0.58106f,0.5934f,0.60681f,0.62701f,0.64661f,0.66073f,0.67632f,0.68458f,0.69003f,0.69701f,0.69043f,0.68486f,0.67696f,0.66115f,0.64722f,0.6278f,0.60693f,0.59409f,0.58237f,0.57353f}, {0.51354f,0.52507f,0.54585f,0.56206f,0.56907f,0.58364f,0.59298f,0.60244f,0.6042f,0.60125f,0.60184f,0.60129f,0.60434f,0.60269f,0.59353f,0.58386f,0.56913f,0.56253f,0.54693f,0.52602f,0.51504f}, {0.4462f,0.46121f,0.4937f,0.51984f,0.53345f,0.53229f,0.54046f,0.54229f,0.5388f,0.53032f,0.52524f,0.53015f,0.53867f,0.54244f,0.54089f,0.5323f,0.53405f,0.52056f,0.49466f,0.46257f,0.44776f}, {0.37137f,0.3954f,0.44526f,0.47914f,0.49706f,0.50302f,0.49345f,0.48927f,0.4812f,0.47361f,0.46973f,0.4736f,0.4812f,0.48919f,0.49341f,0.50317f,0.49734f,0.47957f,0.44615f,0.39662f,0.37299f}, {0.28569f,0.33956f,0.39905f,0.43688f,0.46019f,0.47066f,0.46616f,0.44842f,0.43721f,0.42793f,0.42483f,0.42793f,0.43736f,0.44835f,0.46652f,0.471f,0.46069f,0.4373f,0.39987f,0.34064f,0.28736f}, {0.19595f,0.28947f,0.35262f,0.39351f,0.42012f,0.43541f,0.43852f,0.429f,0.4003f,0.39016f,0.38518f,0.39016f,0.4002f,0.42896f,0.43875f,0.43588f,0.42062f,0.39413f,0.3534f,0.29043f,0.19766f}, {0.09932f,0.23884f,0.30544f,0.34801f,0.376f,0.39434f,0.40329f,0.40229f,0.38759f,0.35582f,0.35016f,0.35573f,0.38763f,0.40246f,0.40359f,0.39481f,0.37652f,0.3484f,0.30593f,0.23972f,0.10106f}, {-6.1232e-017f,0.18616f,0.25397f,0.29765f,0.32695f,0.34731f,0.358f,0.36085f,0.35551f,0.3409f,0.3193f,0.34085f,0.35548f,0.36084f,0.35803f,0.34735f,0.32701f,0.29772f,0.25404f,0.18625f,-6.1232e-017f}, {0.000000f,0.13947f,0.20597f,0.24897f,0.2776f,0.29548f,0.30504f,0.30524f,0.29297f,0.2743f,0.25444f,0.27429f,0.29326f,0.30557f,0.30543f,0.29577f,0.27812f,0.24955f,0.20661f,0.14016f,0.000000f}, {0.000000f,0.092412f,0.15631f,0.1983f,0.22589f,0.24271f,0.25081f,0.24649f,0.2305f,0.20098f,0.18809f,0.20115f,0.23052f,0.24687f,0.25123f,0.24301f,0.2264f,0.19887f,0.1569f,0.092998f,0.000000f}, {0.000000f,0.04757f,0.10935f,0.1497f,0.17632f,0.19262f,0.2008f,0.19456f,0.16341f,0.13718f,0.12599f,0.13735f,0.1636f,0.1946f,0.20107f,0.19308f,0.17681f,0.15022f,0.10988f,0.048018f,0.000000f}, {0.000000f,0.013675f,0.066897f,0.1073f,0.13328f,0.14672f,0.15375f,0.13483f,0.10556f,0.081083f,0.072929f,0.08126f,0.10589f,0.13521f,0.15379f,0.14716f,0.13374f,0.10771f,0.067336f,0.013948f,0.000000f}, {0.000000f,0.0015069f,0.033888f,0.066588f,0.091112f,0.10856f,0.095217f,0.078646f,0.05762f,0.036824f,0.029865f,0.036998f,0.057908f,0.078979f,0.095531f,0.1086f,0.091492f,0.066983f,0.03421f,0.0015862f,0.000000f}, {0.000000f,0.000000f,0.0069872f,0.034974f,0.057485f,0.053405f,0.046792f,0.034313f,0.021993f,0.010034f,0.002725f,0.010168f,0.022192f,0.034562f,0.047084f,0.053723f,0.057517f,0.035279f,0.0071573f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0017445f,0.011689f,0.013485f,0.012333f,0.010226f,0.0052012f,0.0015805f,0.000000f,0.000000f,0.000000f,0.001635f,0.005314f,0.010378f,0.012508f,0.013674f,0.011704f,0.0018203f,0.000000f,0.000000f}, {0.000000f,0.000000f,-6.6557e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-6.6557e-019f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_ang[] = {-27,0,27,-95,95,-142,142}; static float map_7point1_xsf[] = {-1,0,1,-1,1,-1,1}; static float map_7point1_ysf[] = {1,1,1,0,0,-1,-1}; channel_id map_7point1_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_side_center_left,ci_side_center_right,ci_back_left,ci_back_right,ci_lfe}; static float map_7point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,9.4126e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0025743f,0.016552f,0.019339f,0.017689f,0.014677f,0.0075151f,0.0023122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.010122f,0.049892f,0.081385f,0.075976f,0.066587f,0.048878f,0.031384f,0.01438f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0022432f,0.048381f,0.094728f,0.12939f,0.15091f,0.13421f,0.11169f,0.081894f,0.049473f,0.021188f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019725f,0.095227f,0.15233f,0.18129f,0.18619f,0.18195f,0.1662f,0.14038f,0.099716f,0.051668f,0.015357f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067908f,0.15539f,0.20448f,0.21574f,0.21038f,0.19727f,0.18275f,0.16961f,0.14309f,0.089211f,0.030602f,0.0029125f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13152f,0.21916f,0.24385f,0.23799f,0.22019f,0.19777f,0.1798f,0.16484f,0.15891f,0.12092f,0.0391f,0.0061765f,0.0028379f,0.00043186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19821f,0.26858f,0.26884f,0.24624f,0.21773f,0.19453f,0.1758f,0.16036f,0.14653f,0.13495f,0.052607f,0.038854f,0.030373f,0.015188f,0.0028496f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {8.6596e-017f,0.26351f,0.30441f,0.28405f,0.24723f,0.21577f,0.19296f,0.17452f,0.15823f,0.14384f,0.13114f,0.13492f,0.12086f,0.089089f,0.051572f,0.021112f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32999f,0.33317f,0.29065f,0.24843f,0.21902f,0.19594f,0.17746f,0.1625f,0.14962f,0.14386f,0.14651f,0.15886f,0.14285f,0.099312f,0.049149f,0.01419f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.27953f,0.38637f,0.35876f,0.29909f,0.25487f,0.22426f,0.20041f,0.18277f,0.16832f,0.16249f,0.15824f,0.16036f,0.16482f,0.16948f,0.14005f,0.081488f,0.031102f,0.0022352f,0.000000f,0.000000f,0.000000f}, {0.40639f,0.44503f,0.38515f,0.31183f,0.26428f,0.23169f,0.20647f,0.18936f,0.18276f,0.17745f,0.17453f,0.1758f,0.17979f,0.18273f,0.16592f,0.11122f,0.048526f,0.0073556f,0.000000f,0.000000f,0.000000f}, {0.52748f,0.51574f,0.41678f,0.32546f,0.27415f,0.24175f,0.21641f,0.20646f,0.2004f,0.19593f,0.19298f,0.19453f,0.19777f,0.19716f,0.18189f,0.13374f,0.066173f,0.014462f,0.000000f,0.000000f,0.000000f}, {0.63323f,0.58186f,0.4515f,0.34992f,0.2914f,0.25248f,0.24174f,0.23169f,0.22425f,0.219f,0.21579f,0.21773f,0.22013f,0.21018f,0.18585f,0.15082f,0.075526f,0.017441f,0.000000f,0.000000f,0.000000f}, {0.72837f,0.62641f,0.51744f,0.37803f,0.31074f,0.29139f,0.27414f,0.26427f,0.25485f,0.24842f,0.24726f,0.24619f,0.23779f,0.2154f,0.18082f,0.12881f,0.081296f,0.019071f,0.000000f,0.000000f,0.000000f}, {0.81116f,0.6558f,0.5246f,0.41789f,0.37802f,0.34991f,0.32545f,0.31182f,0.29908f,0.29063f,0.28406f,0.26859f,0.24346f,0.20392f,0.15167f,0.09417f,0.04946f,0.016531f,0.000000f,0.000000f,0.000000f}, {0.88423f,0.67127f,0.52691f,0.5245f,0.51721f,0.45136f,0.41661f,0.38495f,0.35851f,0.33283f,0.30436f,0.26801f,0.21844f,0.15464f,0.094607f,0.047925f,0.0098814f,0.0024671f,0.000000f,0.000000f,0.000000f}, {0.94622f,0.67633f,0.67099f,0.65523f,0.62554f,0.58081f,0.51465f,0.44406f,0.38544f,0.32902f,0.26339f,0.19725f,0.13069f,0.067274f,0.019339f,0.0021311f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.94446f,0.8823f,0.80914f,0.72626f,0.63102f,0.52519f,0.40402f,0.27711f,0.14046f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.001914f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.0155f,0.025167f,0.017695f,0.0063155f,1.0116e-005f,0.000000f,0.000000f,0.0062031f,0.017508f,0.025125f,0.015305f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0056317f,0.024256f,0.044322f,0.061583f,0.065405f,0.041656f,0.014688f,4.0817e-019f,0.014527f,0.041389f,0.065342f,0.061236f,0.044002f,0.024003f,0.005504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0019274f,0.02644f,0.05812f,0.08731f,0.11105f,0.11767f,0.10963f,0.061306f,0.017226f,0.061006f,0.10958f,0.11735f,0.11066f,0.086884f,0.057744f,0.026151f,0.0018503f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016697f,0.059451f,0.104f,0.13974f,0.15702f,0.15962f,0.15223f,0.13355f,0.063692f,0.13353f,0.15211f,0.15945f,0.15675f,0.13934f,0.10352f,0.059047f,0.016456f,0.000000f,0.000000f}, {0.000000f,1.2068e-018f,0.038851f,0.096919f,0.15087f,0.17987f,0.18511f,0.17445f,0.15817f,0.14379f,0.13384f,0.14378f,0.15816f,0.17444f,0.18509f,0.17981f,0.15076f,0.096821f,0.038797f,0.000000f,0.000000f}, {0.000000f,0.0063777f,0.070344f,0.14288f,0.19068f,0.2049f,0.19453f,0.1758f,0.16036f,0.14645f,0.14681f,0.14646f,0.16036f,0.1758f,0.19453f,0.20473f,0.19031f,0.14227f,0.06984f,0.0061903f,0.000000f}, {0.000000f,0.017224f,0.099719f,0.18101f,0.21822f,0.2193f,0.19777f,0.17979f,0.16475f,0.16187f,0.16149f,0.16187f,0.16477f,0.1798f,0.19777f,0.21922f,0.21792f,0.18045f,0.099116f,0.016918f,0.000000f}, {0.000000f,0.02596f,0.12753f,0.21148f,0.23925f,0.22819f,0.20284f,0.18535f,0.18085f,0.17814f,0.17812f,0.17814f,0.18084f,0.18536f,0.20284f,0.22818f,0.23901f,0.21095f,0.12685f,0.025562f,0.000000f}, {0.000000f,0.03194f,0.15144f,0.23904f,0.2564f,0.23733f,0.21182f,0.20371f,0.19964f,0.19751f,0.19694f,0.1975f,0.19963f,0.20369f,0.21184f,0.23733f,0.25621f,0.23853f,0.15068f,0.031485f,0.000000f}, {0.000000f,0.051138f,0.17541f,0.26062f,0.27419f,0.24713f,0.23812f,0.22985f,0.2244f,0.22133f,0.22022f,0.22132f,0.22439f,0.22984f,0.2381f,0.24715f,0.274f,0.26009f,0.17455f,0.050511f,0.000000f}, {0.000000f,0.08308f,0.18105f,0.28155f,0.29188f,0.28632f,0.27128f,0.26327f,0.25585f,0.25151f,0.25234f,0.2515f,0.25584f,0.26325f,0.27127f,0.28627f,0.29189f,0.28098f,0.18013f,0.082312f,0.000000f}, {0.000000f,0.11865f,0.22314f,0.29977f,0.32517f,0.33282f,0.32312f,0.31164f,0.30095f,0.2946f,0.29542f,0.29459f,0.30094f,0.31163f,0.32308f,0.33259f,0.32473f,0.29967f,0.22211f,0.11774f,0.000000f}, {0.000000f,0.15601f,0.26339f,0.30497f,0.3472f,0.38198f,0.39609f,0.39135f,0.3765f,0.36616f,0.36703f,0.36615f,0.37649f,0.39123f,0.39574f,0.3814f,0.34627f,0.30393f,0.26322f,0.15497f,0.000000f}, {0.000000f,0.19222f,0.23448f,0.28578f,0.34732f,0.4169f,0.48293f,0.51439f,0.52067f,0.52104f,0.52661f,0.52086f,0.52026f,0.51365f,0.48176f,0.41543f,0.34579f,0.28436f,0.23319f,0.19202f,0.000000f}, {1.1102e-016f,0.076479f,0.15764f,0.24801f,0.34452f,0.44874f,0.55712f,0.67263f,0.78467f,0.89574f,1.000000f,0.89382f,0.78261f,0.67046f,0.55485f,0.4464f,0.34213f,0.24558f,0.15519f,0.074014f,0.000000f}}; static float map_7point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022352f,0.0073556f,0.014462f,0.017441f,0.019071f,0.016531f,0.0024671f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01419f,0.031102f,0.048526f,0.066173f,0.075526f,0.081297f,0.04946f,0.0098814f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.021112f,0.049149f,0.081488f,0.11122f,0.13374f,0.15081f,0.12881f,0.09417f,0.047925f,0.0021311f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.015188f,0.051545f,0.099312f,0.14005f,0.16592f,0.1819f,0.18585f,0.18082f,0.15167f,0.094607f,0.019339f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028379f,0.030373f,0.089057f,0.14285f,0.16948f,0.18273f,0.19716f,0.21018f,0.2154f,0.20392f,0.15464f,0.067274f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0004627f,0.0029125f,0.0061679f,0.038854f,0.12083f,0.15886f,0.16483f,0.17979f,0.19777f,0.22013f,0.23779f,0.24346f,0.21844f,0.13069f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029287f,0.015357f,0.030602f,0.0391f,0.052555f,0.13491f,0.14652f,0.16036f,0.1758f,0.19453f,0.21773f,0.24619f,0.26859f,0.26801f,0.19725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.021156f,0.051639f,0.089163f,0.1209f,0.13493f,0.13114f,0.14385f,0.15824f,0.17453f,0.19297f,0.21578f,0.24725f,0.28402f,0.30431f,0.2633f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.01438f,0.049473f,0.099716f,0.14309f,0.15891f,0.1465f,0.14385f,0.14961f,0.16249f,0.17745f,0.19593f,0.219f,0.24842f,0.29063f,0.33283f,0.32902f,0.14046f}, {0.000000f,0.000000f,0.000000f,0.0023122f,0.031384f,0.081894f,0.14038f,0.16961f,0.16482f,0.16036f,0.15824f,0.1625f,0.16831f,0.18276f,0.2004f,0.22425f,0.25485f,0.29908f,0.35851f,0.38544f,0.27711f}, {0.000000f,0.000000f,0.000000f,0.0075151f,0.048878f,0.11169f,0.1662f,0.18272f,0.1798f,0.1758f,0.17453f,0.17746f,0.18277f,0.18935f,0.20646f,0.23169f,0.26427f,0.31182f,0.38495f,0.44406f,0.40402f}, {0.000000f,0.000000f,0.000000f,0.014677f,0.066587f,0.13421f,0.18194f,0.19727f,0.19777f,0.19453f,0.19297f,0.19594f,0.20041f,0.20647f,0.2164f,0.24174f,0.27414f,0.32545f,0.41661f,0.51465f,0.52519f}, {0.000000f,0.000000f,0.000000f,0.017689f,0.075976f,0.15092f,0.18619f,0.21038f,0.22019f,0.21773f,0.21578f,0.21902f,0.22426f,0.23169f,0.24175f,0.25247f,0.29139f,0.34991f,0.45136f,0.58081f,0.63102f}, {0.000000f,0.000000f,0.000000f,0.019339f,0.081415f,0.12939f,0.18129f,0.21574f,0.23799f,0.24624f,0.24725f,0.24843f,0.25487f,0.26428f,0.27415f,0.2914f,0.31073f,0.37802f,0.51721f,0.62554f,0.72626f}, {0.000000f,0.000000f,0.000000f,0.016574f,0.049892f,0.094728f,0.15233f,0.20448f,0.24385f,0.26884f,0.28405f,0.29065f,0.29909f,0.31183f,0.32546f,0.34992f,0.37803f,0.41787f,0.5245f,0.65523f,0.80914f}, {0.000000f,0.000000f,0.000000f,0.0025743f,0.010122f,0.048381f,0.095227f,0.15539f,0.21916f,0.26858f,0.3044f,0.33317f,0.35876f,0.38515f,0.41678f,0.4515f,0.51744f,0.5246f,0.52688f,0.67099f,0.8823f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022432f,0.019725f,0.067908f,0.13152f,0.19821f,0.26356f,0.32999f,0.38637f,0.44503f,0.51574f,0.58186f,0.62641f,0.6558f,0.67127f,0.6763f,0.94439f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14292f,0.27953f,0.40639f,0.52748f,0.63323f,0.72837f,0.81116f,0.88423f,0.94629f,1.000000f}}; static float map_7point1_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.076479f,0.1924f,0.15601f,0.11842f,0.08308f,0.051138f,0.03194f,0.02596f,0.017224f,0.006217f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15701f,0.23422f,0.26354f,0.22314f,0.18089f,0.17541f,0.15144f,0.12753f,0.099719f,0.070344f,0.038959f,0.016585f,0.0019274f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24799f,0.28578f,0.30478f,0.2999f,0.28155f,0.26062f,0.23875f,0.21148f,0.18101f,0.14288f,0.097017f,0.059361f,0.02644f,0.0055357f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34452f,0.34709f,0.3472f,0.32503f,0.29199f,0.2741f,0.2564f,0.23925f,0.21822f,0.19068f,0.15101f,0.104f,0.05812f,0.024256f,0.0054585f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44874f,0.4169f,0.38198f,0.33282f,0.28632f,0.24721f,0.23733f,0.22819f,0.21923f,0.20483f,0.17996f,0.13974f,0.08731f,0.044322f,0.015426f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55712f,0.48293f,0.39609f,0.32283f,0.2712f,0.23804f,0.21189f,0.20278f,0.19777f,0.19453f,0.18519f,0.15702f,0.11105f,0.061583f,0.025231f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67263f,0.51439f,0.39135f,0.31154f,0.26327f,0.22985f,0.20371f,0.18541f,0.17979f,0.1758f,0.17449f,0.15962f,0.11761f,0.06551f,0.017632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78467f,0.52067f,0.3765f,0.30095f,0.25585f,0.2244f,0.19964f,0.1808f,0.16481f,0.16036f,0.15821f,0.15223f,0.10975f,0.041656f,0.0063155f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52104f,0.36605f,0.29451f,0.25151f,0.22133f,0.19751f,0.17814f,0.16187f,0.14649f,0.14382f,0.13363f,0.061306f,0.014688f,1.0116e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.52679f,0.36715f,0.29551f,0.25242f,0.22029f,0.19701f,0.17818f,0.16155f,0.14686f,0.1311f,0.063705f,0.017218f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52086f,0.36615f,0.29459f,0.2515f,0.22126f,0.1975f,0.17814f,0.16187f,0.14649f,0.14382f,0.13358f,0.061006f,0.014527f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78261f,0.52026f,0.37649f,0.30094f,0.25584f,0.22432f,0.19963f,0.18084f,0.1648f,0.16036f,0.1582f,0.15211f,0.10961f,0.041389f,0.0062031f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67046f,0.51365f,0.39123f,0.31163f,0.26325f,0.22984f,0.20363f,0.1854f,0.17974f,0.1758f,0.17448f,0.15945f,0.11735f,0.065362f,0.017508f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55485f,0.48176f,0.39574f,0.32282f,0.27127f,0.2381f,0.21189f,0.20284f,0.19777f,0.19453f,0.18513f,0.15675f,0.11066f,0.061236f,0.025146f,0.00059225f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.4464f,0.41543f,0.3814f,0.33259f,0.28621f,0.2472f,0.23726f,0.22818f,0.21922f,0.20473f,0.17984f,0.13934f,0.086884f,0.044002f,0.015305f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34213f,0.34579f,0.34627f,0.32473f,0.29192f,0.274f,0.25621f,0.23901f,0.21792f,0.19031f,0.1508f,0.10352f,0.057744f,0.024003f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24558f,0.28436f,0.30393f,0.29971f,0.28098f,0.26009f,0.23836f,0.21095f,0.18045f,0.14227f,0.096837f,0.059047f,0.026151f,0.005504f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15519f,0.23319f,0.26327f,0.22211f,0.18013f,0.17455f,0.15068f,0.12685f,0.099116f,0.06984f,0.038815f,0.016456f,0.0018503f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.074009f,0.19209f,0.15497f,0.11774f,0.082312f,0.050511f,0.031485f,0.025562f,0.016918f,0.0061903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0061903f,0.016918f,0.025562f,0.031485f,0.050511f,0.082312f,0.11774f,0.15497f,0.19222f,0.074014f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0018503f,0.016456f,0.038851f,0.06984f,0.099116f,0.12685f,0.15068f,0.17455f,0.18013f,0.22211f,0.26337f,0.23319f,0.15519f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.005504f,0.026151f,0.059047f,0.096892f,0.14227f,0.18045f,0.21095f,0.23853f,0.26009f,0.28098f,0.29979f,0.30393f,0.28436f,0.24556f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0054168f,0.024003f,0.057744f,0.10352f,0.15084f,0.19031f,0.21792f,0.23901f,0.25621f,0.274f,0.29198f,0.32473f,0.34627f,0.34579f,0.34213f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.015305f,0.044002f,0.086884f,0.13934f,0.17988f,0.20473f,0.21922f,0.22818f,0.23733f,0.24725f,0.28627f,0.33259f,0.3814f,0.41543f,0.4464f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.025157f,0.061236f,0.11066f,0.15675f,0.18518f,0.19453f,0.19777f,0.20284f,0.21193f,0.2381f,0.27127f,0.32308f,0.39574f,0.48176f,0.55485f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017508f,0.065396f,0.11735f,0.15945f,0.17454f,0.1758f,0.1798f,0.18544f,0.20369f,0.22984f,0.26325f,0.31163f,0.39123f,0.51365f,0.67046f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0062031f,0.041389f,0.10962f,0.15211f,0.15825f,0.16036f,0.16483f,0.18084f,0.19963f,0.22439f,0.25584f,0.30094f,0.37649f,0.52026f,0.78261f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014527f,0.061006f,0.13359f,0.14386f,0.14652f,0.16187f,0.17814f,0.1975f,0.22132f,0.2515f,0.29459f,0.36615f,0.52086f,0.89382f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-4.0817e-019f,0.017202f,0.06369f,0.13113f,0.14689f,0.16158f,0.17821f,0.19705f,0.22033f,0.25247f,0.29557f,0.36722f,0.52689f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.0116e-005f,0.014688f,0.061306f,0.13361f,0.14385f,0.14651f,0.16187f,0.17814f,0.19751f,0.22133f,0.25151f,0.2946f,0.36616f,0.52104f,0.89574f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0063155f,0.041656f,0.10967f,0.15223f,0.15823f,0.16036f,0.16482f,0.18085f,0.19964f,0.2244f,0.25585f,0.30095f,0.3765f,0.52067f,0.78467f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017695f,0.065451f,0.11767f,0.15962f,0.17452f,0.1758f,0.17979f,0.18543f,0.20371f,0.22985f,0.26327f,0.31164f,0.39135f,0.51439f,0.67263f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062925f,0.0252f,0.061583f,0.11105f,0.15702f,0.18518f,0.19453f,0.19777f,0.20284f,0.21192f,0.23812f,0.27128f,0.32312f,0.39609f,0.48293f,0.55712f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.0155f,0.044322f,0.08731f,0.13974f,0.17992f,0.2049f,0.2193f,0.22819f,0.23733f,0.24724f,0.28632f,0.33282f,0.38198f,0.4169f,0.44874f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.024256f,0.05812f,0.104f,0.15089f,0.19068f,0.21822f,0.23925f,0.2564f,0.27419f,0.292f,0.32517f,0.3472f,0.34732f,0.34452f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0056317f,0.02644f,0.059451f,0.09695f,0.14288f,0.18101f,0.21148f,0.23904f,0.26062f,0.28155f,0.29985f,0.30497f,0.28578f,0.24801f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019274f,0.016697f,0.038906f,0.070344f,0.099719f,0.12753f,0.15144f,0.17541f,0.18105f,0.22314f,0.26347f,0.23448f,0.15764f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.2068e-018f,0.0063777f,0.017224f,0.02596f,0.03194f,0.051138f,0.08308f,0.11865f,0.15601f,0.19233f,0.076473f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f}}; static float map_7point1_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.94446f,0.81199f,0.83616f,0.85669f,0.87092f,0.87561f,0.8564f,0.80823f,0.75425f,0.69808f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.88271f,0.78057f,0.71294f,0.73952f,0.76209f,0.72118f,0.69661f,0.66179f,0.62498f,0.59208f,0.56394f,0.52736f,0.48539f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.80907f,0.73849f,0.68142f,0.62971f,0.60765f,0.58509f,0.55402f,0.53219f,0.51188f,0.49896f,0.49292f,0.47704f,0.45666f,0.42472f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.72626f,0.68381f,0.64457f,0.57657f,0.51706f,0.49372f,0.46596f,0.45043f,0.43577f,0.42627f,0.42558f,0.42408f,0.4189f,0.4019f,0.37301f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.63102f,0.61653f,0.57478f,0.53382f,0.48514f,0.42718f,0.41011f,0.39421f,0.38285f,0.37543f,0.37141f,0.37424f,0.37886f,0.37291f,0.35447f,0.32571f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.52519f,0.53691f,0.52315f,0.49422f,0.4552f,0.40947f,0.36615f,0.35043f,0.34158f,0.3356f,0.33216f,0.33419f,0.33895f,0.34131f,0.33172f,0.30203f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.40402f,0.46214f,0.47464f,0.46087f,0.43328f,0.39304f,0.3499f,0.32038f,0.31064f,0.30342f,0.30041f,0.30177f,0.30761f,0.31375f,0.30955f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.27711f,0.39741f,0.42859f,0.42667f,0.40895f,0.37927f,0.34025f,0.30982f,0.28478f,0.27695f,0.27237f,0.27482f,0.28125f,0.29675f,0.28023f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.14292f,0.33339f,0.38221f,0.39113f,0.38299f,0.36377f,0.33348f,0.30176f,0.27588f,0.25314f,0.24761f,0.25f,0.2723f,0.2674f,0.23727f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.000000f,0.26327f,0.33172f,0.35247f,0.35385f,0.34292f,0.32385f,0.29788f,0.27007f,0.24552f,0.22579f,0.23659f,0.23272f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.000000f,0.19725f,0.27965f,0.31034f,0.31939f,0.31618f,0.30536f,0.28855f,0.26792f,0.24094f,0.1799f,0.14699f,0.14674f,0.14347f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.000000f,0.13069f,0.21975f,0.26195f,0.27862f,0.28151f,0.27602f,0.26277f,0.24232f,0.202f,0.13299f,0.082204f,0.083689f,0.086082f,0.07899f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.000000f,0.067274f,0.15464f,0.20782f,0.23238f,0.24129f,0.24043f,0.22893f,0.19873f,0.15312f,0.089072f,0.040759f,0.032293f,0.046248f,0.043546f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019339f,0.094607f,0.15196f,0.18465f,0.19667f,0.19966f,0.1783f,0.14444f,0.099312f,0.051555f,0.015195f,0.0048976f,0.012512f,0.017789f,0.01096f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0021311f,0.047925f,0.09417f,0.12885f,0.15216f,0.13421f,0.11122f,0.081488f,0.049149f,0.021112f,0.0028496f,0.000000f,0.000000f,0.00044495f,0.0013625f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0098814f,0.04946f,0.081296f,0.075526f,0.066173f,0.048526f,0.031102f,0.01419f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0024671f,0.016531f,0.019071f,0.017441f,0.014677f,0.0073556f,0.0022352f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.69745f,0.75361f,0.80779f,0.85613f,0.8756f,0.87113f,0.85731f,0.83679f,0.81212f,0.94629f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48466f,0.52692f,0.56374f,0.59228f,0.62473f,0.66167f,0.69668f,0.72145f,0.76272f,0.7402f,0.71303f,0.78158f,0.88423f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.42428f,0.45626f,0.4769f,0.4928f,0.49938f,0.51188f,0.53264f,0.55439f,0.58524f,0.6082f,0.62975f,0.68239f,0.7397f,0.8111f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.37263f,0.40155f,0.4187f,0.42403f,0.42555f,0.42626f,0.43576f,0.45043f,0.46637f,0.49385f,0.51702f,0.57711f,0.64546f,0.68515f,0.72837f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.3256f,0.35421f,0.3727f,0.37913f,0.37456f,0.37139f,0.37551f,0.38293f,0.39422f,0.41047f,0.42708f,0.48557f,0.53421f,0.57553f,0.61802f,0.63323f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30191f,0.3317f,0.3415f,0.33894f,0.33418f,0.33214f,0.33559f,0.34157f,0.3505f,0.36607f,0.40957f,0.45546f,0.49461f,0.52386f,0.53833f,0.52748f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.30936f,0.31378f,0.30767f,0.30176f,0.30039f,0.30342f,0.31091f,0.32031f,0.3502f,0.39305f,0.43346f,0.46137f,0.47532f,0.46338f,0.40639f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.2799f,0.29688f,0.28132f,0.27481f,0.27235f,0.27695f,0.28472f,0.3099f,0.34026f,0.3796f,0.40917f,0.42708f,0.42927f,0.39855f,0.27953f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.26716f,0.27225f,0.25006f,0.24759f,0.25308f,0.27589f,0.30177f,0.33349f,0.36411f,0.38326f,0.39169f,0.38291f,0.3345f,0.14292f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.23269f,0.23658f,0.22577f,0.24545f,0.27f,0.29779f,0.3238f,0.34289f,0.35387f,0.35252f,0.3318f,0.26339f,-8.6596e-017f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12602f,0.14312f,0.14641f,0.14698f,0.17992f,0.24091f,0.268f,0.28867f,0.30555f,0.31654f,0.31978f,0.31088f,0.28038f,0.19821f,0.000000f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.07868f,0.085813f,0.08366f,0.082238f,0.13301f,0.20226f,0.24232f,0.26304f,0.2763f,0.28192f,0.27908f,0.26255f,0.22053f,0.13152f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.043546f,0.046224f,0.032368f,0.040874f,0.089105f,0.15348f,0.19907f,0.22896f,0.24081f,0.24172f,0.2329f,0.20846f,0.15539f,0.067908f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.010822f,0.017781f,0.01238f,0.0048489f,0.015357f,0.051582f,0.099723f,0.14485f,0.17871f,0.1997f,0.19715f,0.18521f,0.15233f,0.095227f,0.019725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.00044495f,0.000000f,0.000000f,0.0029287f,0.021123f,0.049473f,0.081894f,0.11169f,0.13466f,0.15222f,0.12939f,0.094728f,0.048381f,0.0022432f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01438f,0.031384f,0.048878f,0.066587f,0.075976f,0.081342f,0.049892f,0.010122f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0023122f,0.0075151f,0.014677f,0.017689f,0.019339f,0.016553f,0.0025743f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.4126e-019f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_panorama_ang[] = {-45,-26,0,26,45,-95,95}; static float map_7point1_panorama_xsf[] = {-1,-0.5,0,0.5,1,-1,1}; static float map_7point1_panorama_ysf[] = {1,1,1,1,1,0,0}; channel_id map_7point1_panorama_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_center_left,ci_side_center_right,ci_lfe}; static float map_7point1_panorama_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0025743f,0.016552f,0.019339f,0.017689f,0.014677f,0.0075151f,0.0023122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.010122f,0.049892f,0.081385f,0.075976f,0.066587f,0.048878f,0.031384f,0.01438f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0022432f,0.048381f,0.094728f,0.12939f,0.14819f,0.13332f,0.11169f,0.081894f,0.049473f,0.021188f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019725f,0.095227f,0.15233f,0.17345f,0.16427f,0.14754f,0.14117f,0.13145f,0.099702f,0.051668f,0.015357f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067908f,0.15539f,0.19651f,0.18146f,0.15882f,0.14116f,0.1291f,0.12511f,0.12232f,0.089211f,0.030602f,0.0029125f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13152f,0.21644f,0.20646f,0.17568f,0.15435f,0.13761f,0.1251f,0.11476f,0.11158f,0.1087f,0.0391f,0.0030968f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19821f,0.24497f,0.20143f,0.17202f,0.15152f,0.1354f,0.12233f,0.11157f,0.10201f,0.10008f,0.02634f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.26351f,0.25036f,0.20151f,0.17212f,0.15022f,0.13434f,0.1215f,0.11016f,0.10014f,0.091286f,0.091196f,0.072765f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32097f,0.25158f,0.20264f,0.17322f,0.15277f,0.1368f,0.12398f,0.11372f,0.10509f,0.10014f,0.10199f,0.11007f,0.089378f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.27953f,0.36201f,0.26077f,0.20891f,0.17806f,0.15683f,0.14026f,0.12809f,0.11822f,0.11157f,0.11015f,0.11158f,0.11474f,0.11478f,0.079886f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.40639f,0.40831f,0.2748f,0.2181f,0.18495f,0.16233f,0.1448f,0.133f,0.12656f,0.12233f,0.12149f,0.12232f,0.12511f,0.12639f,0.10424f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.52748f,0.47057f,0.29527f,0.22794f,0.19213f,0.16957f,0.152f,0.14356f,0.13761f,0.1354f,0.13433f,0.13538f,0.13762f,0.13549f,0.1175f,0.061535f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.63323f,0.50954f,0.31873f,0.2453f,0.20447f,0.17733f,0.16842f,0.15997f,0.15435f,0.15152f,0.15021f,0.15149f,0.1527f,0.14081f,0.11367f,0.0757f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.72837f,0.51209f,0.3683f,0.26525f,0.21826f,0.20334f,0.18984f,0.18146f,0.17568f,0.17202f,0.17211f,0.17098f,0.16098f,0.13607f,0.098801f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.81116f,0.50827f,0.36916f,0.29352f,0.264f,0.24288f,0.22433f,0.21451f,0.20646f,0.20143f,0.19609f,0.18058f,0.15329f,0.1102f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.88423f,0.49893f,0.37009f,0.36617f,0.35721f,0.311f,0.2844f,0.26253f,0.24312f,0.22219f,0.19506f,0.15866f,0.1057f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.94622f,0.48678f,0.46584f,0.43796f,0.40098f,0.35386f,0.3003f,0.25801f,0.21787f,0.17042f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_panorama_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_panorama_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_panorama_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_7point1_panorama_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022352f,0.0073556f,0.014462f,0.017441f,0.019071f,0.016531f,0.0024671f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01419f,0.031102f,0.048526f,0.066173f,0.075526f,0.081297f,0.04946f,0.0098814f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.021112f,0.049149f,0.081488f,0.11122f,0.13287f,0.14806f,0.12881f,0.09417f,0.047925f,0.0021311f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.015188f,0.051545f,0.099312f,0.1312f,0.14102f,0.14734f,0.16405f,0.17306f,0.15167f,0.094607f,0.019339f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028379f,0.030373f,0.089057f,0.12218f,0.12498f,0.12893f,0.14102f,0.15866f,0.18126f,0.19604f,0.15464f,0.067274f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0030797f,0.038854f,0.1086f,0.11146f,0.1146f,0.12497f,0.13745f,0.1542f,0.17549f,0.20626f,0.21577f,0.13069f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.026252f,0.10001f,0.10187f,0.11145f,0.12219f,0.13525f,0.15135f,0.17183f,0.20121f,0.24456f,0.19725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.072685f,0.091096f,0.091174f,0.10001f,0.11002f,0.12134f,0.13416f,0.15002f,0.1719f,0.20125f,0.25003f,0.2633f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040435f,0.089481f,0.11f,0.10185f,0.10001f,0.10496f,0.11359f,0.12384f,0.13666f,0.15261f,0.17302f,0.20242f,0.25131f,0.32012f,0.14046f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.080064f,0.11479f,0.11458f,0.11146f,0.11002f,0.11145f,0.11808f,0.12794f,0.14009f,0.15665f,0.17785f,0.20867f,0.2605f,0.36128f,0.27711f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.10437f,0.12621f,0.12498f,0.12218f,0.12134f,0.12219f,0.12645f,0.13284f,0.14464f,0.16215f,0.18474f,0.21787f,0.27448f,0.4076f,0.40402f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.061843f,0.11735f,0.13544f,0.13747f,0.13526f,0.13417f,0.13525f,0.13745f,0.14343f,0.15182f,0.16938f,0.19191f,0.22768f,0.29494f,0.46977f,0.52519f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.075569f,0.11383f,0.14084f,0.15258f,0.15134f,0.15002f,0.15135f,0.1542f,0.15983f,0.16828f,0.17712f,0.20424f,0.24502f,0.31841f,0.50892f,0.63102f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.099066f,0.13621f,0.16098f,0.17084f,0.1719f,0.17183f,0.17549f,0.18126f,0.18968f,0.20316f,0.21799f,0.26496f,0.36789f,0.51154f,0.72626f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.11053f,0.15345f,0.18063f,0.19584f,0.20121f,0.20626f,0.21427f,0.22413f,0.24264f,0.26377f,0.29316f,0.36878f,0.50788f,0.80914f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10618f,0.15898f,0.19481f,0.22223f,0.24306f,0.26241f,0.28423f,0.31081f,0.3571f,0.36589f,0.36964f,0.49868f,0.8823f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.17097f,0.21836f,0.25849f,0.30093f,0.35437f,0.4014f,0.43825f,0.46598f,0.4862f,0.94439f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_7point1_panorama_lsm[21][21] = { {0.94868f,0.93979f,0.92892f,0.91532f,0.89884f,0.87853f,0.8537f,0.82424f,0.78969f,0.75039f,0.70789f,0.661f,0.61351f,0.56712f,0.52077f,0.47859f,0.43917f,0.40362f,0.37114f,0.3426f,0.31623f}, {0.95693f,0.9317f,0.92102f,0.90712f,0.89078f,0.87044f,0.84289f,0.80644f,0.76604f,0.7236f,0.6804f,0.6349f,0.58948f,0.54466f,0.5005f,0.45761f,0.41877f,0.38353f,0.35198f,0.32412f,0.29116f}, {0.96462f,0.94132f,0.91583f,0.90277f,0.88622f,0.85514f,0.82266f,0.78517f,0.74448f,0.70104f,0.65656f,0.61f,0.56482f,0.52016f,0.47676f,0.43469f,0.3955f,0.36119f,0.33046f,0.29747f,0.26416f}, {0.97225f,0.95137f,0.92571f,0.88489f,0.85653f,0.82795f,0.79498f,0.76363f,0.7255f,0.68186f,0.63534f,0.58672f,0.54045f,0.49615f,0.45375f,0.41386f,0.37593f,0.34027f,0.30135f,0.26734f,0.23466f}, {0.97919f,0.96065f,0.93214f,0.86186f,0.79292f,0.76789f,0.74051f,0.71861f,0.68961f,0.65516f,0.61525f,0.56724f,0.52048f,0.47677f,0.43635f,0.3979f,0.36272f,0.31873f,0.26998f,0.23483f,0.20369f}, {0.98542f,0.9679f,0.90436f,0.82956f,0.75592f,0.68671f,0.67103f,0.65339f,0.63609f,0.61413f,0.58511f,0.54827f,0.50188f,0.45794f,0.41794f,0.38255f,0.33991f,0.29475f,0.24755f,0.20075f,0.17085f}, {0.99064f,0.96121f,0.8708f,0.78204f,0.71032f,0.65588f,0.60348f,0.58332f,0.56997f,0.56033f,0.54752f,0.52193f,0.48158f,0.43707f,0.39772f,0.3559f,0.31427f,0.27011f,0.22117f,0.16891f,0.13721f}, {0.99488f,0.92575f,0.82128f,0.73741f,0.67683f,0.6254f,0.57563f,0.53395f,0.51827f,0.50648f,0.50219f,0.48925f,0.45417f,0.4102f,0.3672f,0.32497f,0.28356f,0.24085f,0.19578f,0.14463f,0.10174f}, {0.99776f,0.87364f,0.76373f,0.693f,0.64179f,0.59802f,0.55526f,0.51595f,0.47518f,0.46214f,0.45532f,0.45265f,0.41787f,0.36979f,0.32799f,0.28872f,0.25065f,0.21145f,0.16933f,0.12196f,0.067462f}, {0.99947f,0.81537f,0.71032f,0.65167f,0.60836f,0.57105f,0.53463f,0.49872f,0.46215f,0.42238f,0.41393f,0.40752f,0.35964f,0.31638f,0.28082f,0.24757f,0.21469f,0.18028f,0.14225f,0.098254f,0.033277f}, {1.000000f,0.75555f,0.6647f,0.61519f,0.57784f,0.54265f,0.51083f,0.47959f,0.44672f,0.41273f,0.37739f,0.32488f,0.28151f,0.25128f,0.22873f,0.20406f,0.1757f,0.14641f,0.11309f,0.073649f,0.000000f}, {0.89382f,0.68791f,0.61547f,0.57441f,0.54227f,0.51265f,0.48344f,0.45315f,0.42036f,0.38304f,0.34573f,0.31179f,0.24651f,0.20178f,0.17713f,0.16064f,0.14079f,0.11665f,0.088097f,0.053513f,0.000000f}, {0.78261f,0.6272f,0.56968f,0.53556f,0.50734f,0.48031f,0.4527f,0.42322f,0.38924f,0.35404f,0.31186f,0.27072f,0.23694f,0.17604f,0.13906f,0.12194f,0.10696f,0.087506f,0.063482f,0.033993f,0.000000f}, {0.67046f,0.56634f,0.52262f,0.49572f,0.47144f,0.44729f,0.42138f,0.39319f,0.35982f,0.32059f,0.2768f,0.23458f,0.19582f,0.16167f,0.11528f,0.089805f,0.077988f,0.062177f,0.042135f,0.016712f,0.000000f}, {0.55485f,0.49618f,0.47283f,0.45393f,0.43496f,0.41386f,0.3911f,0.36252f,0.32632f,0.28454f,0.24104f,0.19635f,0.15537f,0.12066f,0.094028f,0.06429f,0.055517f,0.042187f,0.024487f,0.0046307f,0.000000f}, {0.4464f,0.41696f,0.41883f,0.4103f,0.39691f,0.3813f,0.35486f,0.32441f,0.28801f,0.24544f,0.20142f,0.15414f,0.1089f,0.075057f,0.053667f,0.046121f,0.035614f,0.02474f,0.011873f,0.00051164f,0.000000f}, {0.34213f,0.34579f,0.35357f,0.36379f,0.3589f,0.33617f,0.31041f,0.27805f,0.24238f,0.20111f,0.15264f,0.10696f,0.065501f,0.036389f,0.022645f,0.019781f,0.021189f,0.012384f,0.0023573f,0.000000f,0.000000f}, {0.24558f,0.28436f,0.30572f,0.31215f,0.29544f,0.27331f,0.24946f,0.21641f,0.18207f,0.14227f,0.096837f,0.059047f,0.026683f,0.0072615f,0.0034858f,0.004216f,0.0046111f,0.0039179f,0.0005892f,0.000000f,0.000000f}, {0.15519f,0.23319f,0.26327f,0.22211f,0.18013f,0.17455f,0.15068f,0.12685f,0.099116f,0.06984f,0.038815f,0.016456f,0.0018503f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.074009f,0.19209f,0.15497f,0.11774f,0.082312f,0.050511f,0.031485f,0.025562f,0.016918f,0.0061903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_panorama_rsm[21][21] = { {0.31623f,0.34174f,0.37027f,0.40274f,0.43828f,0.47769f,0.52077f,0.56623f,0.61351f,0.661f,0.70632f,0.75039f,0.78969f,0.82364f,0.8537f,0.87804f,0.8984f,0.91493f,0.92858f,0.93948f,0.94868f}, {0.29033f,0.32401f,0.35116f,0.38332f,0.41793f,0.45677f,0.49966f,0.54385f,0.5887f,0.63465f,0.68013f,0.72323f,0.76542f,0.80587f,0.84237f,0.86998f,0.89037f,0.90708f,0.92068f,0.93165f,0.95667f}, {0.26357f,0.29714f,0.33033f,0.36043f,0.39519f,0.43391f,0.476f,0.51943f,0.56412f,0.60952f,0.65633f,0.70077f,0.74391f,0.78464f,0.82217f,0.8547f,0.8861f,0.90245f,0.91577f,0.94127f,0.96448f}, {0.23387f,0.26656f,0.30106f,0.34015f,0.37537f,0.41319f,0.45358f,0.49568f,0.53983f,0.58627f,0.63514f,0.68158f,0.72503f,0.76355f,0.79513f,0.82772f,0.85651f,0.88483f,0.92575f,0.95113f,0.97206f}, {0.20293f,0.23442f,0.26927f,0.31844f,0.36261f,0.3976f,0.43594f,0.47622f,0.51995f,0.56672f,0.61506f,0.6548f,0.68936f,0.71846f,0.74071f,0.76806f,0.79292f,0.86211f,0.93207f,0.96059f,0.97904f}, {0.17012f,0.20003f,0.24691f,0.29416f,0.33947f,0.38245f,0.41757f,0.45745f,0.50162f,0.54808f,0.58502f,0.61408f,0.63615f,0.65342f,0.67134f,0.68672f,0.75631f,0.82977f,0.9045f,0.96781f,0.9853f}, {0.13651f,0.16829f,0.22059f,0.26993f,0.31401f,0.35564f,0.39763f,0.43683f,0.48118f,0.52165f,0.54749f,0.56033f,0.56997f,0.58346f,0.60347f,0.65615f,0.71071f,0.78267f,0.87115f,0.96137f,0.99054f}, {0.10107f,0.14409f,0.19526f,0.24062f,0.28307f,0.32452f,0.36689f,0.41011f,0.45394f,0.48907f,0.50222f,0.50647f,0.51844f,0.53393f,0.57589f,0.62556f,0.67709f,0.73799f,0.82182f,0.92616f,0.99481f}, {0.066833f,0.12148f,0.16885f,0.21098f,0.2502f,0.28838f,0.32758f,0.36957f,0.41781f,0.45253f,0.45534f,0.46213f,0.47515f,0.51608f,0.55535f,0.59835f,0.64207f,0.69341f,0.76436f,0.87429f,0.99772f}, {0.032685f,0.097839f,0.14205f,0.18011f,0.21427f,0.24724f,0.28043f,0.31601f,0.3593f,0.40753f,0.41395f,0.42235f,0.46216f,0.49878f,0.53476f,0.57137f,0.60866f,0.65226f,0.71105f,0.81621f,0.99945f}, {0.000000f,0.073611f,0.11305f,0.14636f,0.17565f,0.20399f,0.22866f,0.25121f,0.28147f,0.32487f,0.37741f,0.41271f,0.44671f,0.47959f,0.51086f,0.54269f,0.57791f,0.61529f,0.66484f,0.75577f,1.000000f}, {0.000000f,0.053223f,0.087771f,0.1163f,0.14044f,0.16049f,0.1768f,0.20162f,0.2465f,0.31181f,0.34577f,0.38304f,0.42051f,0.45334f,0.48368f,0.51308f,0.54266f,0.57492f,0.61617f,0.68897f,0.89574f}, {0.000000f,0.033762f,0.063207f,0.087205f,0.10665f,0.12181f,0.13887f,0.17604f,0.23697f,0.27083f,0.3119f,0.35422f,0.38927f,0.4235f,0.45299f,0.48077f,0.50778f,0.53612f,0.57043f,0.62834f,0.78467f}, {0.000000f,0.016548f,0.04191f,0.061926f,0.077723f,0.089535f,0.11535f,0.16173f,0.1961f,0.23477f,0.27686f,0.32086f,0.36017f,0.39325f,0.42181f,0.4477f,0.47193f,0.49633f,0.52343f,0.56761f,0.67263f}, {0.000000f,0.0045383f,0.024315f,0.042013f,0.055294f,0.064099f,0.094062f,0.1208f,0.15562f,0.19662f,0.24111f,0.28489f,0.32669f,0.36289f,0.39117f,0.41432f,0.4355f,0.4546f,0.47371f,0.49764f,0.55712f}, {0.000000f,0.00048584f,0.011756f,0.024581f,0.035454f,0.046115f,0.053729f,0.075228f,0.1092f,0.15451f,0.20151f,0.24587f,0.28846f,0.32487f,0.35534f,0.38139f,0.39751f,0.41103f,0.41979f,0.41851f,0.44874f}, {0.000000f,0.000000f,0.0023004f,0.012271f,0.021176f,0.019653f,0.022655f,0.036546f,0.065804f,0.1074f,0.15274f,0.20163f,0.24291f,0.27859f,0.31096f,0.33676f,0.35902f,0.36458f,0.35468f,0.34732f,0.34452f}, {0.000000f,0.000000f,0.00056441f,0.0039128f,0.0045454f,0.0041551f,0.0034332f,0.0073512f,0.026953f,0.059451f,0.09695f,0.14288f,0.18269f,0.21706f,0.25013f,0.27403f,0.29622f,0.31231f,0.30683f,0.28578f,0.24801f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019274f,0.016697f,0.038906f,0.070344f,0.099719f,0.12753f,0.15144f,0.17541f,0.18105f,0.22314f,0.26347f,0.23448f,0.15764f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.2068e-018f,0.0063777f,0.017224f,0.02596f,0.03194f,0.051138f,0.08308f,0.11865f,0.15601f,0.19233f,0.076473f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f}}; static float map_7point1_tricenter_ang[] = {-45,-26,0,26,45,-110,110}; static float map_7point1_tricenter_xsf[] = {-1,-0.5,0,0.5,1,-1,1}; static float map_7point1_tricenter_ysf[] = {1,1,1,1,1,-1,-1}; channel_id map_7point1_tricenter_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_back_left,ci_back_right,ci_lfe}; static float map_7point1_tricenter_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.054079f,0.13605f,0.11031f,0.083738f,0.058746f,0.03616f,0.022585f,0.018356f,0.012179f,0.0043961f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.11103f,0.16562f,0.18635f,0.15778f,0.12791f,0.12403f,0.10709f,0.090176f,0.070512f,0.049741f,0.027549f,0.011727f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17535f,0.20208f,0.21809f,0.22862f,0.21842f,0.20197f,0.18341f,0.15706f,0.13031f,0.10103f,0.068601f,0.041975f,0.018696f,0.0039144f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24362f,0.24543f,0.25563f,0.27972f,0.28786f,0.26979f,0.24789f,0.21805f,0.18569f,0.14921f,0.10871f,0.073541f,0.041097f,0.017152f,0.0038597f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3173f,0.29703f,0.31848f,0.33006f,0.33185f,0.32299f,0.30114f,0.27305f,0.23691f,0.19431f,0.14844f,0.10174f,0.061737f,0.03134f,0.010908f,0.0013625f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.39394f,0.36121f,0.3753f,0.38051f,0.36522f,0.33259f,0.29737f,0.28456f,0.2713f,0.23725f,0.18262f,0.12638f,0.07899f,0.043546f,0.017841f,0.00044495f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.47562f,0.43164f,0.43211f,0.4168f,0.36762f,0.32134f,0.2852f,0.2602f,0.25225f,0.24663f,0.21259f,0.14347f,0.086077f,0.046322f,0.012467f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55484f,0.49969f,0.48267f,0.41926f,0.35659f,0.31303f,0.27878f,0.25294f,0.23129f,0.22497f,0.22057f,0.14674f,0.080699f,0.029455f,0.0044657f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.63203f,0.56664f,0.5038f,0.40968f,0.34986f,0.30802f,0.27506f,0.24829f,0.22604f,0.20559f,0.20178f,0.12083f,0.045091f,0.010386f,7.153e-006f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.70711f,0.63601f,0.50998f,0.41047f,0.35061f,0.30599f,0.27365f,0.24749f,0.22439f,0.20399f,0.18399f,0.13624f,0.08494f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.77384f,0.68927f,0.51049f,0.41094f,0.35106f,0.30923f,0.27645f,0.24994f,0.22817f,0.20867f,0.20183f,0.19645f,0.15321f,0.099648f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83292f,0.72988f,0.52698f,0.42171f,0.35896f,0.31545f,0.28142f,0.25596f,0.23475f,0.22496f,0.22202f,0.21914f,0.19225f,0.14404f,0.084273f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.88048f,0.77152f,0.55143f,0.43846f,0.3711f,0.32485f,0.28879f,0.2641f,0.25366f,0.24663f,0.24487f,0.23507f,0.20809f,0.17261f,0.11662f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.91982f,0.81123f,0.5751f,0.45612f,0.38394f,0.33794f,0.30183f,0.28699f,0.27746f,0.27295f,0.26524f,0.24622f,0.21586f,0.17879f,0.13529f,0.061954f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.94888f,0.80328f,0.58841f,0.48047f,0.40685f,0.35213f,0.33619f,0.32131f,0.30936f,0.29628f,0.27737f,0.25002f,0.21413f,0.17193f,0.12449f,0.077062f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.9703f,0.7566f,0.61315f,0.49487f,0.42468f,0.39709f,0.37101f,0.35047f,0.32977f,0.30659f,0.27874f,0.24418f,0.20181f,0.15304f,0.10263f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.98481f,0.70934f,0.58407f,0.50544f,0.46268f,0.42679f,0.39279f,0.36368f,0.33405f,0.30203f,0.26456f,0.22233f,0.17178f,0.11409f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.99396f,0.66382f,0.55625f,0.52322f,0.48458f,0.43442f,0.39095f,0.35222f,0.3132f,0.27157f,0.22251f,0.1703f,0.10701f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.99855f,0.62261f,0.57542f,0.52122f,0.45918f,0.38957f,0.32256f,0.27607f,0.22983f,0.1748f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_tricenter_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_tricenter_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_tricenter_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_7point1_tricenter_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043772f,0.011962f,0.018075f,0.022264f,0.035717f,0.058204f,0.083257f,0.10958f,0.13592f,0.052336f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013084f,0.011636f,0.027472f,0.049384f,0.070085f,0.089694f,0.10655f,0.12342f,0.12737f,0.15705f,0.18623f,0.16489f,0.10973f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038919f,0.018492f,0.041753f,0.068513f,0.1006f,0.12983f,0.15652f,0.18313f,0.20135f,0.21775f,0.22851f,0.21738f,0.20108f,0.17363f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.016973f,0.040831f,0.073199f,0.10859f,0.14876f,0.1852f,0.21753f,0.24734f,0.26927f,0.28776f,0.27908f,0.25473f,0.24451f,0.24192f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.010822f,0.031114f,0.061436f,0.10138f,0.14831f,0.19392f,0.2365f,0.27257f,0.30069f,0.32289f,0.33123f,0.32934f,0.31761f,0.29589f,0.31565f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00041878f,0.017789f,0.0433f,0.07868f,0.12602f,0.18248f,0.23686f,0.27104f,0.28445f,0.2972f,0.33242f,0.36488f,0.38012f,0.37444f,0.35999f,0.39234f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.01238f,0.046242f,0.085813f,0.14312f,0.21247f,0.24649f,0.25211f,0.26005f,0.28505f,0.32118f,0.36741f,0.4164f,0.43128f,0.43048f,0.47409f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043862f,0.029266f,0.080596f,0.14641f,0.2205f,0.22485f,0.23115f,0.25285f,0.27862f,0.31286f,0.35639f,0.41906f,0.48199f,0.49857f,0.55339f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010272f,0.044927f,0.12071f,0.20174f,0.20547f,0.22591f,0.24815f,0.2749f,0.30785f,0.34967f,0.40951f,0.50346f,0.56555f,0.63203f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.084849f,0.13613f,0.1839f,0.20388f,0.22427f,0.24735f,0.2735f,0.30582f,0.35042f,0.41025f,0.5097f,0.63586f,0.70711f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040442f,0.099867f,0.15335f,0.19633f,0.20173f,0.20856f,0.22805f,0.2498f,0.27632f,0.30912f,0.35086f,0.41073f,0.51022f,0.68855f,0.77384f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.084529f,0.14424f,0.19214f,0.2191f,0.2219f,0.22484f,0.23463f,0.25582f,0.28126f,0.31533f,0.35876f,0.42148f,0.52673f,0.72945f,0.83195f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.11688f,0.17249f,0.20818f,0.23505f,0.24475f,0.2465f,0.25358f,0.26396f,0.28868f,0.32468f,0.3709f,0.43824f,0.55121f,0.77133f,0.87965f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.062288f,0.13517f,0.17899f,0.21599f,0.24628f,0.26511f,0.2728f,0.2773f,0.28686f,0.30166f,0.33776f,0.38374f,0.45616f,0.57501f,0.81125f,0.91914f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.076941f,0.12479f,0.17218f,0.21432f,0.25015f,0.27724f,0.29623f,0.30926f,0.32119f,0.33609f,0.35194f,0.4067f,0.48036f,0.58851f,0.80371f,0.94832f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.10298f,0.15337f,0.20208f,0.24438f,0.2786f,0.30666f,0.32979f,0.35044f,0.37098f,0.39705f,0.42446f,0.49488f,0.61339f,0.75713f,0.96987f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.11452f,0.17215f,0.22266f,0.26439f,0.30224f,0.33426f,0.36381f,0.39316f,0.42692f,0.46285f,0.50519f,0.58442f,0.70995f,0.9845f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10754f,0.17079f,0.22232f,0.27197f,0.31358f,0.35258f,0.39132f,0.43484f,0.48512f,0.52368f,0.55594f,0.66449f,0.99377f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.17548f,0.23053f,0.27684f,0.32351f,0.39053f,0.46015f,0.52214f,0.5763f,0.6222f,0.99846f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_7point1_tricenter_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.99854f,0.94804f,0.94647f,0.94043f,0.92966f,0.91177f,0.87898f,0.82659f,0.76643f,0.70248f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.99373f,0.94619f,0.89929f,0.8973f,0.89f,0.84522f,0.80369f,0.75196f,0.69549f,0.64182f,0.59149f,0.53909f,0.48676f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.98443f,0.94057f,0.89693f,0.84178f,0.80673f,0.76938f,0.72295f,0.68173f,0.63988f,0.59999f,0.56152f,0.51902f,0.47535f,0.42864f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.96987f,0.92924f,0.89008f,0.8064f,0.72353f,0.68753f,0.64727f,0.61961f,0.59007f,0.5611f,0.53236f,0.49762f,0.45999f,0.41905f,0.37687f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.94832f,0.91132f,0.84488f,0.76916f,0.6876f,0.60199f,0.57793f,0.55557f,0.53786f,0.52026f,0.49866f,0.47305f,0.4406f,0.40425f,0.36538f,0.32707f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.91914f,0.87839f,0.80323f,0.72262f,0.64697f,0.57779f,0.51599f,0.49381f,0.48147f,0.4732f,0.46311f,0.44521f,0.41747f,0.38486f,0.34957f,0.30247f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.87965f,0.82586f,0.75136f,0.68116f,0.61943f,0.55563f,0.49394f,0.45149f,0.43778f,0.42773f,0.42381f,0.41464f,0.39077f,0.36007f,0.32202f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.83195f,0.76558f,0.69482f,0.63955f,0.58992f,0.53794f,0.48142f,0.43767f,0.40132f,0.39038f,0.38425f,0.38246f,0.35885f,0.3262f,0.2847f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.77494f,0.70182f,0.64105f,0.59937f,0.5609f,0.52028f,0.47314f,0.42777f,0.39034f,0.35673f,0.34932f,0.34449f,0.31565f,0.27779f,0.23728f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.70711f,0.63577f,0.59134f,0.56143f,0.53234f,0.49869f,0.46315f,0.42387f,0.38431f,0.34937f,0.3185f,0.28163f,0.2449f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.63338f,0.56555f,0.53856f,0.51865f,0.49722f,0.47263f,0.44507f,0.41451f,0.38241f,0.34452f,0.2816f,0.24145f,0.18988f,0.15379f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.55339f,0.49871f,0.48607f,0.47475f,0.45953f,0.44013f,0.41724f,0.39065f,0.35885f,0.31539f,0.24485f,0.1898f,0.16119f,0.11535f,0.083376f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.47409f,0.43048f,0.43138f,0.42817f,0.41859f,0.40381f,0.38442f,0.36003f,0.32583f,0.27748f,0.21245f,0.15351f,0.11527f,0.092466f,0.055926f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.39234f,0.35999f,0.37455f,0.38033f,0.37646f,0.36503f,0.34948f,0.32174f,0.28429f,0.23686f,0.18246f,0.12608f,0.083197f,0.055812f,0.03557f,0.011379f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.31565f,0.29607f,0.31773f,0.32943f,0.33124f,0.32696f,0.30198f,0.27263f,0.2365f,0.19392f,0.14828f,0.10138f,0.061436f,0.031114f,0.011267f,0.002725f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24192f,0.24451f,0.25473f,0.27908f,0.28772f,0.26927f,0.24734f,0.21753f,0.18526f,0.14882f,0.10856f,0.073199f,0.040831f,0.01704f,0.0038302f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17365f,0.20108f,0.21738f,0.22846f,0.21775f,0.20135f,0.18335f,0.15652f,0.12991f,0.1006f,0.068474f,0.041753f,0.018492f,0.0038919f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.10973f,0.16489f,0.18616f,0.15705f,0.12737f,0.12342f,0.10655f,0.089694f,0.070085f,0.049384f,0.027446f,0.011636f,0.0013628f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.052332f,0.13583f,0.10958f,0.083257f,0.058204f,0.035717f,0.022438f,0.018227f,0.011962f,0.0043772f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_7point1_tricenter_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.70182f,0.76558f,0.82586f,0.87839f,0.91132f,0.92934f,0.94057f,0.94637f,0.94804f,0.99863f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48597f,0.53856f,0.59121f,0.64167f,0.69482f,0.75136f,0.80323f,0.84488f,0.89008f,0.89725f,0.89927f,0.94647f,0.99396f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.42817f,0.47475f,0.51865f,0.56131f,0.59998f,0.63948f,0.6818f,0.72306f,0.76916f,0.80688f,0.84174f,0.8973f,0.94077f,0.98473f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.37646f,0.41852f,0.45953f,0.49722f,0.53221f,0.56083f,0.58986f,0.61943f,0.64753f,0.6876f,0.72348f,0.80673f,0.89031f,0.92966f,0.9703f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.32696f,0.36503f,0.40381f,0.44057f,0.47309f,0.49858f,0.52028f,0.53794f,0.55557f,0.57829f,0.60191f,0.688f,0.76938f,0.84522f,0.91177f,0.94888f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30233f,0.34948f,0.3848f,0.41719f,0.44502f,0.46308f,0.47314f,0.48142f,0.49394f,0.51592f,0.57793f,0.64727f,0.72306f,0.80369f,0.87898f,0.91982f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.32174f,0.36002f,0.39065f,0.41451f,0.4238f,0.42773f,0.43804f,0.45143f,0.49424f,0.55557f,0.61961f,0.68173f,0.75196f,0.82659f,0.88048f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.28429f,0.32614f,0.35884f,0.38237f,0.38425f,0.39034f,0.40127f,0.43778f,0.48142f,0.53827f,0.59007f,0.63988f,0.69549f,0.76643f,0.83292f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.27743f,0.31539f,0.34452f,0.34932f,0.35669f,0.39034f,0.42773f,0.47315f,0.52061f,0.5611f,0.59999f,0.64182f,0.7028f,0.77494f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.24485f,0.28161f,0.31849f,0.34932f,0.38425f,0.42381f,0.46314f,0.49869f,0.53239f,0.56152f,0.59147f,0.63596f,0.70711f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12603f,0.15351f,0.18976f,0.24145f,0.28164f,0.34451f,0.38246f,0.41464f,0.44521f,0.47305f,0.49762f,0.51919f,0.5393f,0.56664f,0.63338f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.083146f,0.11527f,0.16121f,0.18988f,0.2449f,0.31565f,0.35887f,0.39092f,0.41747f,0.4406f,0.45999f,0.47535f,0.48676f,0.49969f,0.55484f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.056058f,0.092505f,0.11557f,0.15374f,0.21251f,0.27779f,0.3262f,0.36008f,0.38486f,0.40425f,0.41905f,0.42882f,0.43211f,0.43164f,0.47562f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.011267f,0.0356f,0.055926f,0.083376f,0.12638f,0.18252f,0.23728f,0.2847f,0.32214f,0.34955f,0.36552f,0.37704f,0.38081f,0.3753f,0.36121f,0.39394f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027341f,0.011405f,0.03134f,0.061737f,0.10174f,0.14834f,0.19436f,0.23696f,0.27305f,0.30247f,0.32704f,0.33185f,0.33006f,0.31848f,0.29703f,0.3173f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039191f,0.017152f,0.041097f,0.073541f,0.10862f,0.14921f,0.18569f,0.21805f,0.24789f,0.26986f,0.28782f,0.27982f,0.25563f,0.24559f,0.24362f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039822f,0.018696f,0.042039f,0.068554f,0.10103f,0.13031f,0.15706f,0.1837f,0.20197f,0.21842f,0.22858f,0.21822f,0.20208f,0.17537f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013628f,0.011806f,0.027511f,0.049741f,0.070512f,0.090176f,0.10709f,0.12403f,0.12802f,0.15778f,0.1863f,0.16581f,0.11147f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-8.5322e-019f,0.0045097f,0.012179f,0.018356f,0.022585f,0.03616f,0.058746f,0.083896f,0.11031f,0.136f,0.054075f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-7.8496e-017f}}; static float map_8point1_ang[] = {-45,0,45,-90,90,-135,180,135}; static float map_8point1_xsf[] = {-1,0,1,-1,1,-1,0,1}; static float map_8point1_ysf[] = {1,1,1,0,0,-1,-1,-1}; channel_id map_8point1_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_side_center_left,ci_side_center_right,ci_back_left,ci_back_center,ci_back_right,ci_lfe}; static float map_8point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,9.4126e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0025743f,0.016552f,0.019339f,0.017689f,0.014677f,0.0075151f,0.0023122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.010122f,0.049892f,0.081385f,0.075976f,0.066587f,0.048878f,0.031384f,0.01438f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0022432f,0.048381f,0.094728f,0.12939f,0.15091f,0.13421f,0.11169f,0.081894f,0.049473f,0.021188f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019725f,0.095227f,0.15233f,0.18129f,0.18619f,0.18195f,0.1662f,0.14038f,0.099716f,0.051668f,0.015357f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067908f,0.15539f,0.20448f,0.21574f,0.21038f,0.19727f,0.18275f,0.16961f,0.14309f,0.089211f,0.030602f,0.0029125f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13152f,0.21916f,0.24385f,0.23799f,0.22019f,0.19777f,0.1798f,0.16484f,0.15891f,0.12092f,0.0391f,0.0061765f,0.0028379f,0.00043186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19821f,0.26858f,0.26884f,0.24624f,0.21773f,0.19453f,0.1758f,0.16036f,0.14653f,0.13495f,0.052607f,0.038854f,0.030373f,0.015188f,0.0028496f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {8.6596e-017f,0.26351f,0.30441f,0.28405f,0.24723f,0.21577f,0.19296f,0.17452f,0.15823f,0.14384f,0.13114f,0.13492f,0.12086f,0.089089f,0.051572f,0.021112f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32999f,0.33317f,0.29065f,0.24843f,0.21902f,0.19594f,0.17746f,0.1625f,0.14962f,0.14386f,0.14651f,0.15886f,0.14285f,0.099312f,0.049149f,0.01419f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.27953f,0.38637f,0.35876f,0.29909f,0.25487f,0.22426f,0.20041f,0.18277f,0.16832f,0.16249f,0.15824f,0.16036f,0.16482f,0.16948f,0.14005f,0.081488f,0.031102f,0.0022352f,0.000000f,0.000000f,0.000000f}, {0.40639f,0.44503f,0.38515f,0.31183f,0.26428f,0.23169f,0.20647f,0.18936f,0.18276f,0.17745f,0.17453f,0.1758f,0.17979f,0.18273f,0.16592f,0.11122f,0.048526f,0.0073556f,0.000000f,0.000000f,0.000000f}, {0.52748f,0.51574f,0.41678f,0.32546f,0.27415f,0.24175f,0.21641f,0.20646f,0.2004f,0.19593f,0.19298f,0.19453f,0.19777f,0.19716f,0.18189f,0.13374f,0.066173f,0.014462f,0.000000f,0.000000f,0.000000f}, {0.63323f,0.58186f,0.4515f,0.34992f,0.2914f,0.25248f,0.24174f,0.23169f,0.22425f,0.219f,0.21579f,0.21773f,0.22013f,0.21018f,0.18585f,0.15082f,0.075526f,0.017441f,0.000000f,0.000000f,0.000000f}, {0.72837f,0.62641f,0.51744f,0.37803f,0.31074f,0.29139f,0.27414f,0.26427f,0.25485f,0.24842f,0.24726f,0.24619f,0.23779f,0.2154f,0.18082f,0.12881f,0.081296f,0.019071f,0.000000f,0.000000f,0.000000f}, {0.81116f,0.6558f,0.5246f,0.41789f,0.37802f,0.34991f,0.32545f,0.31182f,0.29908f,0.29063f,0.28406f,0.26859f,0.24346f,0.20392f,0.15167f,0.09417f,0.04946f,0.016531f,0.000000f,0.000000f,0.000000f}, {0.88423f,0.67127f,0.52691f,0.5245f,0.51721f,0.45136f,0.41661f,0.38495f,0.35851f,0.33283f,0.30436f,0.26801f,0.21844f,0.15464f,0.094607f,0.047925f,0.0098814f,0.0024671f,0.000000f,0.000000f,0.000000f}, {0.94622f,0.67633f,0.67099f,0.65523f,0.62554f,0.58081f,0.51465f,0.44406f,0.38544f,0.32902f,0.26339f,0.19725f,0.13069f,0.067274f,0.019339f,0.0021311f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.94446f,0.8823f,0.80914f,0.72626f,0.63102f,0.52519f,0.40402f,0.27711f,0.14046f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_8point1_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.001914f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.0155f,0.025167f,0.017695f,0.0063155f,1.0116e-005f,0.000000f,0.000000f,0.0062031f,0.017508f,0.025125f,0.015305f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0056317f,0.024256f,0.044322f,0.061583f,0.065405f,0.041656f,0.014688f,4.0817e-019f,0.014527f,0.041389f,0.065342f,0.061236f,0.044002f,0.024003f,0.005504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0019274f,0.02644f,0.05812f,0.08731f,0.11105f,0.11767f,0.10963f,0.061306f,0.017226f,0.061006f,0.10958f,0.11735f,0.11066f,0.086884f,0.057744f,0.026151f,0.0018503f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016697f,0.059451f,0.104f,0.13974f,0.15702f,0.15962f,0.15223f,0.13355f,0.063692f,0.13353f,0.15211f,0.15945f,0.15675f,0.13934f,0.10352f,0.059047f,0.016456f,0.000000f,0.000000f}, {0.000000f,1.2068e-018f,0.038851f,0.096919f,0.15087f,0.17987f,0.18511f,0.17445f,0.15817f,0.14379f,0.13384f,0.14378f,0.15816f,0.17444f,0.18509f,0.17981f,0.15076f,0.096821f,0.038797f,0.000000f,0.000000f}, {0.000000f,0.0063777f,0.070344f,0.14288f,0.19068f,0.2049f,0.19453f,0.1758f,0.16036f,0.14645f,0.14681f,0.14646f,0.16036f,0.1758f,0.19453f,0.20473f,0.19031f,0.14227f,0.06984f,0.0061903f,0.000000f}, {0.000000f,0.017224f,0.099719f,0.18101f,0.21822f,0.2193f,0.19777f,0.17979f,0.16475f,0.16187f,0.16149f,0.16187f,0.16477f,0.1798f,0.19777f,0.21922f,0.21792f,0.18045f,0.099116f,0.016918f,0.000000f}, {0.000000f,0.02596f,0.12753f,0.21148f,0.23925f,0.22819f,0.20284f,0.18535f,0.18085f,0.17814f,0.17812f,0.17814f,0.18084f,0.18536f,0.20284f,0.22818f,0.23901f,0.21095f,0.12685f,0.025562f,0.000000f}, {0.000000f,0.03194f,0.15144f,0.23904f,0.2564f,0.23733f,0.21182f,0.20371f,0.19964f,0.19751f,0.19694f,0.1975f,0.19963f,0.20369f,0.21184f,0.23733f,0.25621f,0.23853f,0.15068f,0.031485f,0.000000f}, {0.000000f,0.051138f,0.17541f,0.26062f,0.27419f,0.24713f,0.23812f,0.22985f,0.2244f,0.22133f,0.22022f,0.22132f,0.22439f,0.22984f,0.2381f,0.24715f,0.274f,0.26009f,0.17455f,0.050511f,0.000000f}, {0.000000f,0.08308f,0.18105f,0.28155f,0.29188f,0.28632f,0.27128f,0.26327f,0.25585f,0.25151f,0.25234f,0.2515f,0.25584f,0.26325f,0.27127f,0.28627f,0.29189f,0.28098f,0.18013f,0.082312f,0.000000f}, {0.000000f,0.11865f,0.22314f,0.29977f,0.32517f,0.33282f,0.32312f,0.31164f,0.30095f,0.2946f,0.29542f,0.29459f,0.30094f,0.31163f,0.32308f,0.33259f,0.32473f,0.29967f,0.22211f,0.11774f,0.000000f}, {0.000000f,0.15601f,0.26339f,0.30497f,0.3472f,0.38198f,0.39609f,0.39135f,0.3765f,0.36616f,0.36703f,0.36615f,0.37649f,0.39123f,0.39574f,0.3814f,0.34627f,0.30393f,0.26322f,0.15497f,0.000000f}, {0.000000f,0.19222f,0.23448f,0.28578f,0.34732f,0.4169f,0.48293f,0.51439f,0.52067f,0.52104f,0.52661f,0.52086f,0.52026f,0.51365f,0.48176f,0.41543f,0.34579f,0.28436f,0.23319f,0.19202f,0.000000f}, {1.1102e-016f,0.076479f,0.15764f,0.24801f,0.34452f,0.44874f,0.55712f,0.67263f,0.78467f,0.89574f,1.000000f,0.89382f,0.78261f,0.67046f,0.55485f,0.4464f,0.34213f,0.24558f,0.15519f,0.074014f,0.000000f}}; static float map_8point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022352f,0.0073556f,0.014462f,0.017441f,0.019071f,0.016531f,0.0024671f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01419f,0.031102f,0.048526f,0.066173f,0.075526f,0.081297f,0.04946f,0.0098814f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.021112f,0.049149f,0.081488f,0.11122f,0.13374f,0.15081f,0.12881f,0.09417f,0.047925f,0.0021311f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.015188f,0.051545f,0.099312f,0.14005f,0.16592f,0.1819f,0.18585f,0.18082f,0.15167f,0.094607f,0.019339f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028379f,0.030373f,0.089057f,0.14285f,0.16948f,0.18273f,0.19716f,0.21018f,0.2154f,0.20392f,0.15464f,0.067274f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0004627f,0.0029125f,0.0061679f,0.038854f,0.12083f,0.15886f,0.16483f,0.17979f,0.19777f,0.22013f,0.23779f,0.24346f,0.21844f,0.13069f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029287f,0.015357f,0.030602f,0.0391f,0.052555f,0.13491f,0.14652f,0.16036f,0.1758f,0.19453f,0.21773f,0.24619f,0.26859f,0.26801f,0.19725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.021156f,0.051639f,0.089163f,0.1209f,0.13493f,0.13114f,0.14385f,0.15824f,0.17453f,0.19297f,0.21578f,0.24725f,0.28402f,0.30431f,0.2633f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.01438f,0.049473f,0.099716f,0.14309f,0.15891f,0.1465f,0.14385f,0.14961f,0.16249f,0.17745f,0.19593f,0.219f,0.24842f,0.29063f,0.33283f,0.32902f,0.14046f}, {0.000000f,0.000000f,0.000000f,0.0023122f,0.031384f,0.081894f,0.14038f,0.16961f,0.16482f,0.16036f,0.15824f,0.1625f,0.16831f,0.18276f,0.2004f,0.22425f,0.25485f,0.29908f,0.35851f,0.38544f,0.27711f}, {0.000000f,0.000000f,0.000000f,0.0075151f,0.048878f,0.11169f,0.1662f,0.18272f,0.1798f,0.1758f,0.17453f,0.17746f,0.18277f,0.18935f,0.20646f,0.23169f,0.26427f,0.31182f,0.38495f,0.44406f,0.40402f}, {0.000000f,0.000000f,0.000000f,0.014677f,0.066587f,0.13421f,0.18194f,0.19727f,0.19777f,0.19453f,0.19297f,0.19594f,0.20041f,0.20647f,0.2164f,0.24174f,0.27414f,0.32545f,0.41661f,0.51465f,0.52519f}, {0.000000f,0.000000f,0.000000f,0.017689f,0.075976f,0.15092f,0.18619f,0.21038f,0.22019f,0.21773f,0.21578f,0.21902f,0.22426f,0.23169f,0.24175f,0.25247f,0.29139f,0.34991f,0.45136f,0.58081f,0.63102f}, {0.000000f,0.000000f,0.000000f,0.019339f,0.081415f,0.12939f,0.18129f,0.21574f,0.23799f,0.24624f,0.24725f,0.24843f,0.25487f,0.26428f,0.27415f,0.2914f,0.31073f,0.37802f,0.51721f,0.62554f,0.72626f}, {0.000000f,0.000000f,0.000000f,0.016574f,0.049892f,0.094728f,0.15233f,0.20448f,0.24385f,0.26884f,0.28405f,0.29065f,0.29909f,0.31183f,0.32546f,0.34992f,0.37803f,0.41787f,0.5245f,0.65523f,0.80914f}, {0.000000f,0.000000f,0.000000f,0.0025743f,0.010122f,0.048381f,0.095227f,0.15539f,0.21916f,0.26858f,0.3044f,0.33317f,0.35876f,0.38515f,0.41678f,0.4515f,0.51744f,0.5246f,0.52688f,0.67099f,0.8823f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022432f,0.019725f,0.067908f,0.13152f,0.19821f,0.26356f,0.32999f,0.38637f,0.44503f,0.51574f,0.58186f,0.62641f,0.6558f,0.67127f,0.6763f,0.94439f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14292f,0.27953f,0.40639f,0.52748f,0.63323f,0.72837f,0.81116f,0.88423f,0.94629f,1.000000f}}; static float map_8point1_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.076479f,0.1924f,0.15601f,0.11842f,0.08308f,0.051138f,0.03194f,0.02596f,0.017224f,0.006217f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15701f,0.23422f,0.26354f,0.22314f,0.18089f,0.17541f,0.15144f,0.12753f,0.099719f,0.070344f,0.038959f,0.016585f,0.0019274f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24799f,0.28578f,0.30478f,0.2999f,0.28155f,0.26062f,0.23875f,0.21148f,0.18101f,0.14288f,0.097017f,0.059361f,0.02644f,0.0055357f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34452f,0.34709f,0.3472f,0.32503f,0.29199f,0.2741f,0.2564f,0.23925f,0.21822f,0.19068f,0.15101f,0.104f,0.05812f,0.024256f,0.0054585f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44874f,0.4169f,0.38198f,0.33282f,0.28632f,0.24721f,0.23733f,0.22819f,0.21923f,0.20483f,0.17996f,0.13974f,0.08731f,0.044322f,0.015426f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55712f,0.48293f,0.39609f,0.32283f,0.2712f,0.23804f,0.21189f,0.20278f,0.19777f,0.19453f,0.18519f,0.15702f,0.11105f,0.061583f,0.025231f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67263f,0.51439f,0.39135f,0.31154f,0.26327f,0.22985f,0.20371f,0.18541f,0.17979f,0.1758f,0.17449f,0.15962f,0.11761f,0.06551f,0.017632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78467f,0.52067f,0.3765f,0.30095f,0.25585f,0.2244f,0.19964f,0.1808f,0.16481f,0.16036f,0.15821f,0.15223f,0.10975f,0.041656f,0.0063155f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52104f,0.36605f,0.29451f,0.25151f,0.22133f,0.19751f,0.17814f,0.16187f,0.14649f,0.14382f,0.13363f,0.061306f,0.014688f,1.0116e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.52679f,0.36715f,0.29551f,0.25242f,0.22029f,0.19701f,0.17818f,0.16155f,0.14686f,0.1311f,0.063705f,0.017218f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52086f,0.36615f,0.29459f,0.2515f,0.22126f,0.1975f,0.17814f,0.16187f,0.14649f,0.14382f,0.13358f,0.061006f,0.014527f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78261f,0.52026f,0.37649f,0.30094f,0.25584f,0.22432f,0.19963f,0.18084f,0.1648f,0.16036f,0.1582f,0.15211f,0.10961f,0.041389f,0.0062031f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67046f,0.51365f,0.39123f,0.31163f,0.26325f,0.22984f,0.20363f,0.1854f,0.17974f,0.1758f,0.17448f,0.15945f,0.11735f,0.065362f,0.017508f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55485f,0.48176f,0.39574f,0.32282f,0.27127f,0.2381f,0.21189f,0.20284f,0.19777f,0.19453f,0.18513f,0.15675f,0.11066f,0.061236f,0.025146f,0.00059225f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.4464f,0.41543f,0.3814f,0.33259f,0.28621f,0.2472f,0.23726f,0.22818f,0.21922f,0.20473f,0.17984f,0.13934f,0.086884f,0.044002f,0.015305f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34213f,0.34579f,0.34627f,0.32473f,0.29192f,0.274f,0.25621f,0.23901f,0.21792f,0.19031f,0.1508f,0.10352f,0.057744f,0.024003f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24558f,0.28436f,0.30393f,0.29971f,0.28098f,0.26009f,0.23836f,0.21095f,0.18045f,0.14227f,0.096837f,0.059047f,0.026151f,0.005504f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15519f,0.23319f,0.26327f,0.22211f,0.18013f,0.17455f,0.15068f,0.12685f,0.099116f,0.06984f,0.038815f,0.016456f,0.0018503f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.074009f,0.19209f,0.15497f,0.11774f,0.082312f,0.050511f,0.031485f,0.025562f,0.016918f,0.0061903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_8point1_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0061903f,0.016918f,0.025562f,0.031485f,0.050511f,0.082312f,0.11774f,0.15497f,0.19222f,0.074014f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0018503f,0.016456f,0.038851f,0.06984f,0.099116f,0.12685f,0.15068f,0.17455f,0.18013f,0.22211f,0.26337f,0.23319f,0.15519f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.005504f,0.026151f,0.059047f,0.096892f,0.14227f,0.18045f,0.21095f,0.23853f,0.26009f,0.28098f,0.29979f,0.30393f,0.28436f,0.24556f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0054168f,0.024003f,0.057744f,0.10352f,0.15084f,0.19031f,0.21792f,0.23901f,0.25621f,0.274f,0.29198f,0.32473f,0.34627f,0.34579f,0.34213f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.015305f,0.044002f,0.086884f,0.13934f,0.17988f,0.20473f,0.21922f,0.22818f,0.23733f,0.24725f,0.28627f,0.33259f,0.3814f,0.41543f,0.4464f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.025157f,0.061236f,0.11066f,0.15675f,0.18518f,0.19453f,0.19777f,0.20284f,0.21193f,0.2381f,0.27127f,0.32308f,0.39574f,0.48176f,0.55485f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017508f,0.065396f,0.11735f,0.15945f,0.17454f,0.1758f,0.1798f,0.18544f,0.20369f,0.22984f,0.26325f,0.31163f,0.39123f,0.51365f,0.67046f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0062031f,0.041389f,0.10962f,0.15211f,0.15825f,0.16036f,0.16483f,0.18084f,0.19963f,0.22439f,0.25584f,0.30094f,0.37649f,0.52026f,0.78261f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014527f,0.061006f,0.13359f,0.14386f,0.14652f,0.16187f,0.17814f,0.1975f,0.22132f,0.2515f,0.29459f,0.36615f,0.52086f,0.89382f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-4.0817e-019f,0.017202f,0.06369f,0.13113f,0.14689f,0.16158f,0.17821f,0.19705f,0.22033f,0.25247f,0.29557f,0.36722f,0.52689f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.0116e-005f,0.014688f,0.061306f,0.13361f,0.14385f,0.14651f,0.16187f,0.17814f,0.19751f,0.22133f,0.25151f,0.2946f,0.36616f,0.52104f,0.89574f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0063155f,0.041656f,0.10967f,0.15223f,0.15823f,0.16036f,0.16482f,0.18085f,0.19964f,0.2244f,0.25585f,0.30095f,0.3765f,0.52067f,0.78467f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017695f,0.065451f,0.11767f,0.15962f,0.17452f,0.1758f,0.17979f,0.18543f,0.20371f,0.22985f,0.26327f,0.31164f,0.39135f,0.51439f,0.67263f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062925f,0.0252f,0.061583f,0.11105f,0.15702f,0.18518f,0.19453f,0.19777f,0.20284f,0.21192f,0.23812f,0.27128f,0.32312f,0.39609f,0.48293f,0.55712f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.0155f,0.044322f,0.08731f,0.13974f,0.17992f,0.2049f,0.2193f,0.22819f,0.23733f,0.24724f,0.28632f,0.33282f,0.38198f,0.4169f,0.44874f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.024256f,0.05812f,0.104f,0.15089f,0.19068f,0.21822f,0.23925f,0.2564f,0.27419f,0.292f,0.32517f,0.3472f,0.34732f,0.34452f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0056317f,0.02644f,0.059451f,0.09695f,0.14288f,0.18101f,0.21148f,0.23904f,0.26062f,0.28155f,0.29985f,0.30497f,0.28578f,0.24801f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019274f,0.016697f,0.038906f,0.070344f,0.099719f,0.12753f,0.15144f,0.17541f,0.18105f,0.22314f,0.26347f,0.23448f,0.15764f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.2068e-018f,0.0063777f,0.017224f,0.02596f,0.03194f,0.051138f,0.08308f,0.11865f,0.15601f,0.19233f,0.076473f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f}}; static float map_8point1_ls[21][21] = { {1.000000f,0.94629f,0.88423f,0.81116f,0.72837f,0.63323f,0.52519f,0.40639f,0.27711f,0.14046f,0.0024683f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.94446f,0.67616f,0.67127f,0.65461f,0.62641f,0.58186f,0.51574f,0.44503f,0.38637f,0.32899f,0.2638f,0.19821f,0.13152f,0.067908f,0.019725f,0.0022432f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.88271f,0.67026f,0.52679f,0.5246f,0.51645f,0.4515f,0.41678f,0.38515f,0.35876f,0.33317f,0.30452f,0.26791f,0.21916f,0.15539f,0.095227f,0.048381f,0.010122f,0.0024671f,2.6829e-005f,0.000000f,0.000000f}, {0.80907f,0.65523f,0.52363f,0.4178f,0.37803f,0.34992f,0.32507f,0.31183f,0.29909f,0.29065f,0.28411f,0.2683f,0.24385f,0.2039f,0.15167f,0.094728f,0.04946f,0.016615f,0.000000f,0.000000f,0.000000f}, {0.72626f,0.62507f,0.51721f,0.37734f,0.31067f,0.29085f,0.27415f,0.26428f,0.25487f,0.24843f,0.24722f,0.24624f,0.23799f,0.21574f,0.18079f,0.12939f,0.081491f,0.019339f,0.000000f,0.000000f,0.000000f}, {0.63102f,0.58081f,0.45136f,0.34991f,0.29139f,0.25242f,0.24175f,0.23169f,0.22384f,0.2186f,0.21576f,0.21773f,0.22019f,0.21038f,0.18574f,0.15105f,0.075526f,0.017689f,0.000000f,0.000000f,0.000000f}, {0.52519f,0.51465f,0.41661f,0.32507f,0.27363f,0.2413f,0.21636f,0.20608f,0.20041f,0.19594f,0.19295f,0.19453f,0.19777f,0.19727f,0.18201f,0.13421f,0.066587f,0.014462f,0.000000f,0.000000f,0.000000f}, {0.40402f,0.44406f,0.38495f,0.31124f,0.26427f,0.23169f,0.20646f,0.18931f,0.18277f,0.17746f,0.17451f,0.1758f,0.17946f,0.18275f,0.16582f,0.11169f,0.048878f,0.0075151f,0.000000f,0.000000f,0.000000f}, {0.27711f,0.38544f,0.35851f,0.29908f,0.25485f,0.22425f,0.2004f,0.18242f,0.16828f,0.1625f,0.15822f,0.16036f,0.16481f,0.16961f,0.14038f,0.081488f,0.031384f,0.0023122f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32902f,0.33247f,0.29009f,0.24842f,0.219f,0.19593f,0.17745f,0.16249f,0.14958f,0.14384f,0.1465f,0.15891f,0.14309f,0.099716f,0.049149f,0.01438f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.26327f,0.30428f,0.28401f,0.24725f,0.21578f,0.19298f,0.17453f,0.15824f,0.14385f,0.13114f,0.13496f,0.12094f,0.089225f,0.051669f,0.021199f,0.0019397f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19725f,0.26801f,0.26859f,0.24619f,0.21732f,0.19453f,0.1758f,0.16036f,0.1465f,0.1349f,0.052571f,0.0391f,0.030602f,0.015357f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13069f,0.21844f,0.24346f,0.23779f,0.21977f,0.19777f,0.17979f,0.16482f,0.15886f,0.12084f,0.038854f,0.0061765f,0.0028379f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067274f,0.15464f,0.20392f,0.2154f,0.21018f,0.19689f,0.1827f,0.16928f,0.14285f,0.089072f,0.030373f,0.0028379f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019339f,0.094607f,0.15196f,0.18082f,0.18585f,0.18188f,0.16592f,0.14005f,0.099312f,0.051555f,0.015188f,0.00043186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0021311f,0.047925f,0.09417f,0.12885f,0.1508f,0.13377f,0.11122f,0.081488f,0.049149f,0.021112f,0.0028496f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0098814f,0.04946f,0.081296f,0.075526f,0.066173f,0.048526f,0.031102f,0.01419f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0024671f,0.016531f,0.019071f,0.017441f,0.014677f,0.0073556f,0.0022352f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_8point1_cs[21][21] = { {-1.1102e-016f,0.074014f,0.15519f,0.24558f,0.34213f,0.4464f,0.55712f,0.67046f,0.78467f,0.89574f,0.99825f,0.89574f,0.78467f,0.67263f,0.55712f,0.44874f,0.34452f,0.24801f,0.15764f,0.076479f,-1.1102e-016f}, {0.000000f,0.19209f,0.23319f,0.28578f,0.34579f,0.41543f,0.48176f,0.51365f,0.52026f,0.52197f,0.5264f,0.52104f,0.52067f,0.51439f,0.48293f,0.4169f,0.34732f,0.28578f,0.23448f,0.19222f,0.000000f}, {0.000000f,0.15601f,0.26325f,0.30393f,0.34738f,0.3814f,0.39574f,0.39123f,0.37649f,0.36615f,0.36688f,0.36692f,0.3765f,0.39135f,0.39609f,0.38198f,0.3472f,0.30504f,0.2634f,0.15601f,0.000000f}, {0.000000f,0.11774f,0.22314f,0.2997f,0.32473f,0.33259f,0.32378f,0.31163f,0.30094f,0.29459f,0.2953f,0.29521f,0.30095f,0.31229f,0.32378f,0.33282f,0.32553f,0.29976f,0.22314f,0.11865f,0.000000f}, {0.000000f,0.08308f,0.18013f,0.28176f,0.29188f,0.28689f,0.27127f,0.26325f,0.25584f,0.2515f,0.25223f,0.25151f,0.25585f,0.26327f,0.27185f,0.28632f,0.29183f,0.28155f,0.18105f,0.08308f,0.000000f}, {0.000000f,0.050511f,0.17455f,0.26009f,0.274f,0.24714f,0.2381f,0.22984f,0.22487f,0.22179f,0.22013f,0.22133f,0.2244f,0.22985f,0.23862f,0.24701f,0.2746f,0.26062f,0.17541f,0.051138f,0.000000f}, {0.000000f,0.031485f,0.15068f,0.23921f,0.25678f,0.23783f,0.21184f,0.20413f,0.19963f,0.1975f,0.19686f,0.19751f,0.19964f,0.20371f,0.21172f,0.23733f,0.2564f,0.23921f,0.15144f,0.03194f,0.000000f}, {0.000000f,0.025562f,0.12685f,0.2116f,0.23901f,0.22818f,0.20284f,0.18536f,0.18084f,0.17814f,0.17805f,0.17814f,0.18123f,0.18526f,0.20327f,0.22819f,0.23925f,0.21148f,0.12753f,0.02596f,0.000000f}, {0.000000f,0.016918f,0.099116f,0.18045f,0.21792f,0.21922f,0.19777f,0.18017f,0.16476f,0.16187f,0.16143f,0.16187f,0.16467f,0.17979f,0.19777f,0.21969f,0.21822f,0.18101f,0.099719f,0.017224f,0.000000f}, {0.000000f,0.0061903f,0.070344f,0.14288f,0.19031f,0.20473f,0.19453f,0.1758f,0.16036f,0.14646f,0.14675f,0.14638f,0.16036f,0.1758f,0.19453f,0.20519f,0.19068f,0.14288f,0.070344f,0.0063777f,0.000000f}, {0.000000f,-1.2068e-018f,0.038815f,0.096824f,0.15076f,0.17981f,0.18508f,0.17444f,0.15816f,0.14378f,0.13385f,0.14372f,0.15809f,0.17436f,0.18506f,0.17981f,0.15084f,0.096892f,0.038851f,-1.2068e-018f,0.000000f}, {0.000000f,0.000000f,0.016456f,0.059047f,0.10352f,0.1398f,0.15675f,0.15945f,0.15211f,0.13355f,0.063641f,0.13353f,0.15223f,0.15962f,0.15702f,0.13974f,0.104f,0.059451f,0.016697f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0018503f,0.026151f,0.057744f,0.08731f,0.11066f,0.11735f,0.1096f,0.061006f,0.017178f,0.061306f,0.10962f,0.11772f,0.11105f,0.08731f,0.05812f,0.02644f,0.0019274f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.005504f,0.024003f,0.044002f,0.061583f,0.06537f,0.041656f,0.014527f,-8.1634e-019f,0.014688f,0.041656f,0.065404f,0.061583f,0.044322f,0.024256f,0.0056317f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0054168f,0.015305f,0.025146f,0.017508f,0.0062031f,-4.5501e-019f,0.000000f,1.0116e-005f,0.0063155f,0.017695f,0.025157f,0.0155f,0.0055425f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062925f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_8point1_rs[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.14046f,0.27711f,0.40402f,0.52519f,0.63102f,0.72626f,0.80914f,0.8823f,0.94446f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0021311f,0.019339f,0.067274f,0.13069f,0.19725f,0.26337f,0.32902f,0.38544f,0.44406f,0.51465f,0.58081f,0.62554f,0.65523f,0.67099f,0.6762f,0.94629f}, {0.000000f,0.000000f,0.000000f,0.0024671f,0.0098814f,0.047925f,0.094607f,0.15464f,0.21844f,0.26801f,0.30431f,0.33283f,0.35851f,0.38495f,0.41661f,0.45136f,0.51721f,0.5245f,0.52678f,0.67127f,0.88423f}, {0.000000f,0.000000f,0.000000f,0.016531f,0.04946f,0.09417f,0.15167f,0.20392f,0.24346f,0.26859f,0.28399f,0.29063f,0.29908f,0.31182f,0.32545f,0.34991f,0.37802f,0.41779f,0.5246f,0.6558f,0.8111f}, {0.000000f,0.000000f,0.000000f,0.019071f,0.081326f,0.12881f,0.18082f,0.2154f,0.23779f,0.24619f,0.2472f,0.24842f,0.25485f,0.26427f,0.27414f,0.29139f,0.31067f,0.37803f,0.51744f,0.62641f,0.72837f}, {0.000000f,0.000000f,0.000000f,0.017441f,0.075526f,0.15084f,0.18585f,0.21018f,0.22013f,0.21773f,0.21574f,0.219f,0.22425f,0.23169f,0.24174f,0.25242f,0.2914f,0.34992f,0.4515f,0.58186f,0.63323f}, {0.000000f,0.000000f,0.000000f,0.014462f,0.066173f,0.13374f,0.1819f,0.19716f,0.19777f,0.19453f,0.19293f,0.19593f,0.2004f,0.20646f,0.21636f,0.24175f,0.27415f,0.32546f,0.41678f,0.51574f,0.52748f}, {0.000000f,0.000000f,0.000000f,0.0073556f,0.048526f,0.11122f,0.16592f,0.18271f,0.17979f,0.1758f,0.17449f,0.17745f,0.18276f,0.18931f,0.20647f,0.23169f,0.26428f,0.31183f,0.38515f,0.44503f,0.40639f}, {0.000000f,0.000000f,0.000000f,0.0022352f,0.031102f,0.081488f,0.14005f,0.16948f,0.16481f,0.16036f,0.15821f,0.16249f,0.16828f,0.18277f,0.20041f,0.22426f,0.25487f,0.29909f,0.35876f,0.38637f,0.27953f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.01419f,0.049149f,0.099312f,0.14285f,0.15886f,0.1465f,0.14382f,0.14958f,0.1625f,0.17746f,0.19594f,0.21902f,0.24843f,0.29065f,0.33317f,0.32999f,0.14292f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.021112f,0.051572f,0.089089f,0.12085f,0.13491f,0.13112f,0.14383f,0.15821f,0.1745f,0.19294f,0.21575f,0.24721f,0.28401f,0.30433f,0.26339f,-8.6596e-017f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.015188f,0.030373f,0.038854f,0.05254f,0.13492f,0.14649f,0.16036f,0.1758f,0.19453f,0.21773f,0.24624f,0.26884f,0.26858f,0.19821f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.0028379f,0.0061594f,0.0391f,0.12087f,0.15891f,0.16481f,0.1798f,0.19777f,0.22019f,0.23799f,0.24385f,0.21916f,0.13152f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029125f,0.030602f,0.089105f,0.14309f,0.16961f,0.18271f,0.19727f,0.21038f,0.21574f,0.20448f,0.15539f,0.067908f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0004627f,0.015357f,0.051582f,0.099716f,0.14038f,0.1662f,0.18192f,0.18619f,0.18129f,0.15233f,0.095227f,0.019725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0029287f,0.021123f,0.049473f,0.081894f,0.11169f,0.13421f,0.15086f,0.12939f,0.094728f,0.048381f,0.0022432f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01438f,0.031384f,0.048878f,0.066587f,0.075976f,0.081342f,0.049892f,0.010122f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0023122f,0.0075151f,0.014677f,0.017689f,0.019339f,0.016553f,0.0025743f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.4126e-019f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_ang[] = {-45,-26,0,26,45,-63,63,-95,95}; static float map_9point1_densepanorama_xsf[] = {-1,-0.5,0,0.5,1,-1,1,-1,1}; static float map_9point1_densepanorama_ysf[] = {1,1,1,1,1,0.5,0.5,0,0}; channel_id map_9point1_densepanorama_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_front_left,ci_side_front_right,ci_side_center_left,ci_side_center_right,ci_lfe}; static float map_9point1_densepanorama_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.005581f,0.003291f,1.7252e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0081504f,0.042808f,0.072882f,0.060953f,0.042164f,0.017887f,0.0013668f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0027588f,0.054743f,0.091228f,0.091909f,0.082995f,0.079348f,0.071132f,0.040421f,0.0039453f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040396f,0.10257f,0.10193f,0.089276f,0.079333f,0.072621f,0.070291f,0.068709f,0.03606f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0060181f,0.10346f,0.11606f,0.098677f,0.086748f,0.077297f,0.070277f,0.064552f,0.062673f,0.06051f,0.0017892f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.047382f,0.13537f,0.11322f,0.096621f,0.085123f,0.076125f,0.068709f,0.062673f,0.057379f,0.05627f,0.000000f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10632f,0.1408f,0.11333f,0.0968f,0.08448f,0.075551f,0.068329f,0.061952f,0.05632f,0.051341f,0.056303f,0.060536f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.16195f,0.14064f,0.1132f,0.096622f,0.085107f,0.076104f,0.068709f,0.062673f,0.060449f,0.05632f,0.057346f,0.062673f,0.068709f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.194f,0.14507f,0.11609f,0.098677f,0.086764f,0.077297f,0.071771f,0.068005f,0.062673f,0.061952f,0.062673f,0.064514f,0.070277f,0.071028f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.22178f,0.15206f,0.12055f,0.10193f,0.090467f,0.081765f,0.076506f,0.071744f,0.068709f,0.068329f,0.068709f,0.070291f,0.072578f,0.079333f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25576f,0.16273f,0.12661f,0.10766f,0.096098f,0.087435f,0.081735f,0.077297f,0.076125f,0.075551f,0.076104f,0.077297f,0.079348f,0.082947f,0.06067f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {3.1398e-016f,0.28205f,0.17804f,0.13801f,0.11623f,0.10201f,0.096063f,0.090425f,0.086748f,0.085123f,0.08448f,0.085107f,0.086764f,0.089301f,0.091873f,0.072927f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24261f,0.28709f,0.20797f,0.15099f,0.12555f,0.11619f,0.10762f,0.10193f,0.098677f,0.096621f,0.0968f,0.096622f,0.098677f,0.10193f,0.091044f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.46196f,0.29071f,0.21045f,0.16884f,0.15094f,0.13799f,0.12656f,0.12057f,0.11606f,0.11322f,0.11333f,0.1132f,0.11609f,0.10231f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.66287f,0.29364f,0.21289f,0.21045f,0.20789f,0.17806f,0.16273f,0.15206f,0.14511f,0.14066f,0.1408f,0.1352f,0.10303f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.8397f,0.29675f,0.29354f,0.29061f,0.28698f,0.28196f,0.25543f,0.22155f,0.19371f,0.16153f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_9point1_densepanorama_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031891f,0.0054514f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013174f,0.017687f,0.041859f,0.06067f,0.072899f,0.042466f,0.0079947f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003925f,0.040182f,0.071028f,0.079333f,0.082923f,0.091873f,0.091044f,0.054336f,0.0026644f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.036005f,0.068709f,0.070277f,0.072557f,0.079348f,0.089301f,0.10193f,0.10231f,0.040017f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017407f,0.060499f,0.062673f,0.064496f,0.070291f,0.077297f,0.086764f,0.098677f,0.11609f,0.10303f,0.005855f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.000000f,0.056286f,0.057329f,0.062673f,0.068709f,0.076104f,0.085107f,0.096622f,0.1132f,0.1352f,0.046879f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.06051f,0.056286f,0.051311f,0.056286f,0.061915f,0.068289f,0.075506f,0.08443f,0.096742f,0.11326f,0.14072f,0.10645f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040421f,0.068709f,0.062673f,0.057312f,0.056287f,0.060432f,0.062673f,0.068709f,0.076125f,0.085123f,0.096621f,0.11322f,0.14066f,0.16153f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.071132f,0.070291f,0.064476f,0.062673f,0.061916f,0.062673f,0.067986f,0.071744f,0.077297f,0.086748f,0.098677f,0.11606f,0.14511f,0.19371f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.079348f,0.072536f,0.070277f,0.068709f,0.068289f,0.068709f,0.071771f,0.076484f,0.081735f,0.090425f,0.10193f,0.12057f,0.15206f,0.22155f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.060953f,0.082898f,0.079333f,0.077297f,0.076125f,0.075507f,0.076104f,0.077297f,0.081765f,0.087411f,0.096063f,0.10762f,0.12656f,0.16273f,0.25543f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.072826f,0.091909f,0.089276f,0.086748f,0.085123f,0.08443f,0.085107f,0.086764f,0.090467f,0.096098f,0.10198f,0.11619f,0.13799f,0.17806f,0.28196f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.091228f,0.10193f,0.098677f,0.096621f,0.096743f,0.096622f,0.098677f,0.10193f,0.10766f,0.11623f,0.12551f,0.15094f,0.20789f,0.28698f,0.23903f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.10257f,0.11606f,0.11322f,0.11326f,0.1132f,0.11609f,0.12055f,0.12661f,0.13801f,0.15099f,0.16879f,0.21045f,0.29061f,0.4584f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10346f,0.13537f,0.14072f,0.14064f,0.14507f,0.15206f,0.16273f,0.17804f,0.20797f,0.21045f,0.21283f,0.29354f,0.65936f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.16195f,0.194f,0.22178f,0.25576f,0.28205f,0.28709f,0.29071f,0.29364f,0.29667f,0.83624f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_9point1_densepanorama_lsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040704f,0.026172f,0.030577f,0.027969f,0.023206f,0.011882f,0.003656f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016004f,0.078886f,0.11885f,0.11126f,0.10005f,0.077277f,0.049623f,0.022737f,0.0030466f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0035468f,0.076496f,0.13684f,0.13679f,0.11897f,0.11432f,0.10984f,0.10114f,0.076046f,0.033501f,0.0046306f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.031188f,0.14617f,0.15418f,0.1299f,0.11431f,0.10197f,0.097664f,0.095287f,0.093649f,0.075427f,0.024282f,0.00073159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10737f,0.1817f,0.1484f,0.12564f,0.10986f,0.097669f,0.089224f,0.086605f,0.08469f,0.083965f,0.048387f,0.004605f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19838f,0.17849f,0.14282f,0.12164f,0.1068f,0.095276f,0.0866f,0.07931f,0.077259f,0.076129f,0.058978f,0.0048965f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23832f,0.17313f,0.13935f,0.11911f,0.10488f,0.093632f,0.084699f,0.077251f,0.070498f,0.069208f,0.041647f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.24833f,0.17308f,0.13931f,0.11899f,0.10385f,0.092873f,0.083996f,0.076156f,0.069233f,0.063102f,0.05511f,0.019286f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22597f,0.25121f,0.17526f,0.1413f,0.12102f,0.1069f,0.095882f,0.087318f,0.080638f,0.070515f,0.069221f,0.070532f,0.07488f,0.032609f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44198f,0.26542f,0.18277f,0.14664f,0.1254f,0.11069f,0.099453f,0.088959f,0.07933f,0.077251f,0.076144f,0.077259f,0.079348f,0.070283f,0.013958f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64256f,0.2947f,0.1939f,0.15413f,0.13115f,0.11353f,0.099577f,0.089246f,0.0866f,0.084699f,0.083982f,0.08469f,0.086605f,0.085004f,0.039295f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83403f,0.33937f,0.20938f,0.16007f,0.13344f,0.11606f,0.102f,0.097669f,0.095276f,0.093632f,0.092858f,0.093649f,0.095287f,0.088683f,0.054552f,0.0013532f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35937f,0.22225f,0.16947f,0.13938f,0.11899f,0.11431f,0.10986f,0.1068f,0.10488f,0.10383f,0.10487f,0.10415f,0.081353f,0.034375f,0.0043588f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.7669f,0.35542f,0.25327f,0.18049f,0.14646f,0.13768f,0.1299f,0.12564f,0.12164f,0.11911f,0.11897f,0.11747f,0.098408f,0.05387f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55102f,0.34365f,0.25072f,0.19696f,0.17861f,0.1657f,0.15445f,0.1484f,0.14282f,0.13935f,0.13074f,0.10642f,0.058689f,0.012407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34893f,0.32425f,0.24834f,0.24599f,0.23588f,0.21001f,0.1922f,0.1745f,0.1548f,0.12874f,0.085642f,0.036985f,0.0041976f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.16741f,0.30017f,0.27214f,0.23269f,0.17995f,0.11341f,0.070758f,0.057469f,0.038068f,0.013988f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_rsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0036134f,0.011794f,0.023088f,0.027832f,0.030429f,0.026399f,0.0040112f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031126f,0.022632f,0.049467f,0.077089f,0.099949f,0.11118f,0.11911f,0.078648f,0.015871f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045869f,0.033596f,0.075931f,0.10117f,0.10998f,0.11448f,0.11916f,0.13692f,0.13673f,0.076245f,0.0034849f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00071455f,0.024189f,0.075553f,0.093753f,0.095409f,0.097805f,0.10214f,0.11445f,0.13006f,0.15434f,0.14595f,0.030939f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045638f,0.04826f,0.084116f,0.084794f,0.086729f,0.089374f,0.097788f,0.10998f,0.12579f,0.14861f,0.18178f,0.10702f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0049397f,0.058905f,0.076265f,0.077358f,0.079443f,0.086706f,0.095393f,0.10693f,0.1218f,0.14297f,0.17876f,0.19813f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041705f,0.069332f,0.070616f,0.077346f,0.084808f,0.093775f,0.10503f,0.11926f,0.13955f,0.17338f,0.23845f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.128e-019f,0.019251f,0.055118f,0.063203f,0.069332f,0.076265f,0.084116f,0.093006f,0.104f,0.11916f,0.13951f,0.17333f,0.24869f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,2.262e-005f,0.032844f,0.075002f,0.070621f,0.069332f,0.070599f,0.080737f,0.087417f,0.095981f,0.10702f,0.12116f,0.14146f,0.17546f,0.2515f,0.22461f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014122f,0.070466f,0.079449f,0.077358f,0.076265f,0.077346f,0.079424f,0.089097f,0.099575f,0.11084f,0.12555f,0.14685f,0.18296f,0.26573f,0.44064f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039567f,0.085048f,0.086729f,0.084794f,0.084116f,0.084808f,0.086706f,0.089352f,0.099732f,0.11371f,0.13131f,0.1543f,0.19413f,0.29503f,0.64125f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0014071f,0.054512f,0.088881f,0.095409f,0.093753f,0.093007f,0.093775f,0.095393f,0.097788f,0.10212f,0.11625f,0.13365f,0.16031f,0.20963f,0.33985f,0.83276f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043373f,0.034659f,0.08163f,0.10433f,0.105f,0.104f,0.10503f,0.10693f,0.10998f,0.11445f,0.11914f,0.1396f,0.16971f,0.22252f,0.35981f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.054219f,0.098665f,0.11764f,0.11916f,0.11926f,0.1218f,0.12579f,0.13006f,0.13785f,0.14663f,0.18077f,0.25367f,0.35599f,0.77038f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012593f,0.059121f,0.10673f,0.13084f,0.13955f,0.14297f,0.14861f,0.15464f,0.1659f,0.17883f,0.19719f,0.25106f,0.3443f,0.55456f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043097f,0.037335f,0.085557f,0.12916f,0.1552f,0.17483f,0.19253f,0.21041f,0.2363f,0.24639f,0.24863f,0.32498f,0.3525f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.6987e-018f,0.014261f,0.038514f,0.058048f,0.071419f,0.11435f,0.18086f,0.23352f,0.27289f,0.30018f,0.171f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.4828e-016f}}; static float map_9point1_densepanorama_lsm[21][21] = { {0.94868f,0.93979f,0.92892f,0.91532f,0.89884f,0.87853f,0.8537f,0.82424f,0.78969f,0.75039f,0.70789f,0.661f,0.61351f,0.56712f,0.52077f,0.47859f,0.43917f,0.40362f,0.37114f,0.3426f,0.31623f}, {0.95693f,0.9317f,0.92102f,0.90712f,0.89078f,0.87044f,0.84289f,0.80644f,0.76604f,0.7236f,0.6804f,0.6349f,0.58948f,0.54466f,0.5005f,0.45761f,0.41877f,0.38353f,0.35198f,0.32412f,0.29116f}, {0.96462f,0.94132f,0.91583f,0.90277f,0.88622f,0.85514f,0.82266f,0.78517f,0.74448f,0.70104f,0.65656f,0.61f,0.56482f,0.52016f,0.47676f,0.43469f,0.3955f,0.36119f,0.33046f,0.29747f,0.26416f}, {0.97225f,0.95137f,0.92389f,0.87318f,0.84285f,0.81544f,0.78461f,0.75832f,0.72386f,0.68186f,0.63534f,0.58672f,0.54045f,0.49615f,0.45375f,0.41386f,0.37593f,0.34027f,0.30135f,0.26734f,0.23466f}, {0.97919f,0.96065f,0.92499f,0.82658f,0.7398f,0.71817f,0.6958f,0.68405f,0.66742f,0.64499f,0.61389f,0.56724f,0.52048f,0.47677f,0.43635f,0.3979f,0.36272f,0.31873f,0.26998f,0.23483f,0.20369f}, {0.98542f,0.96631f,0.87015f,0.7684f,0.69483f,0.63359f,0.61998f,0.60434f,0.59091f,0.58013f,0.57013f,0.5462f,0.50188f,0.45794f,0.41794f,0.38255f,0.33991f,0.29475f,0.24755f,0.20075f,0.17085f}, {0.99064f,0.94726f,0.80545f,0.71318f,0.65231f,0.60483f,0.55794f,0.53972f,0.52742f,0.51851f,0.51381f,0.51107f,0.48125f,0.43707f,0.39772f,0.3559f,0.31427f,0.27011f,0.22117f,0.16891f,0.13721f}, {0.99488f,0.87774f,0.74012f,0.67115f,0.62073f,0.57635f,0.53201f,0.49411f,0.4796f,0.46866f,0.4647f,0.46761f,0.45211f,0.4102f,0.3672f,0.32497f,0.28356f,0.24085f,0.19578f,0.14463f,0.10174f}, {0.99776f,0.78496f,0.68403f,0.62923f,0.58748f,0.55033f,0.51271f,0.47728f,0.43977f,0.42764f,0.42133f,0.42629f,0.41568f,0.36979f,0.32799f,0.28872f,0.25065f,0.21145f,0.16933f,0.12196f,0.067462f}, {0.99947f,0.7089f,0.63301f,0.58945f,0.55517f,0.52422f,0.49282f,0.4609f,0.42766f,0.3909f,0.38302f,0.38889f,0.35964f,0.31638f,0.28082f,0.24757f,0.21469f,0.18028f,0.14225f,0.098254f,0.033277f}, {1.000000f,0.64466f,0.58741f,0.55298f,0.52471f,0.49628f,0.46936f,0.44208f,0.41272f,0.38181f,0.34922f,0.30028f,0.27293f,0.25128f,0.22873f,0.20406f,0.1757f,0.14641f,0.11309f,0.073649f,0.000000f}, {0.79277f,0.57573f,0.53721f,0.51131f,0.48822f,0.46492f,0.44062f,0.41416f,0.38435f,0.35155f,0.31482f,0.28029f,0.21307f,0.18725f,0.17713f,0.16064f,0.14079f,0.11665f,0.088097f,0.053513f,0.000000f}, {0.58496f,0.50869f,0.48806f,0.47008f,0.45133f,0.43088f,0.40829f,0.3835f,0.35382f,0.31954f,0.27786f,0.23622f,0.2015f,0.14466f,0.13286f,0.12194f,0.10696f,0.087506f,0.063482f,0.033993f,0.000000f}, {0.3831f,0.43474f,0.43604f,0.42689f,0.41288f,0.39659f,0.37692f,0.35334f,0.32115f,0.28278f,0.2393f,0.19676f,0.15715f,0.12371f,0.097767f,0.089805f,0.077988f,0.062177f,0.042135f,0.016712f,0.000000f}, {0.18186f,0.34462f,0.37934f,0.38246f,0.37538f,0.36204f,0.34555f,0.3189f,0.28377f,0.24273f,0.19958f,0.15453f,0.11283f,0.081069f,0.0697f,0.063697f,0.055517f,0.042187f,0.024487f,0.0046307f,0.000000f}, {0.000000f,0.25649f,0.31959f,0.33464f,0.33468f,0.32816f,0.30382f,0.27536f,0.24032f,0.19861f,0.15506f,0.10731f,0.062396f,0.038748f,0.038363f,0.044194f,0.035614f,0.02474f,0.011873f,0.00051164f,0.000000f}, {0.000000f,0.1871f,0.24049f,0.2832f,0.2935f,0.27469f,0.2524f,0.22195f,0.18807f,0.14793f,0.099514f,0.054506f,0.021573f,0.012386f,0.017228f,0.019781f,0.021189f,0.012384f,0.0023573f,0.000000f,0.000000f}, {0.000000f,0.13094f,0.19377f,0.2242f,0.21568f,0.19932f,0.18049f,0.15015f,0.1183f,0.08005f,0.038463f,0.011549f,0.00053156f,0.0017575f,0.0034858f,0.004216f,0.0046111f,0.0039179f,0.0005892f,0.000000f,0.000000f}, {0.000000f,0.088435f,0.15238f,0.11227f,0.074803f,0.080771f,0.064857f,0.048933f,0.030007f,0.012387f,0.00062972f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.05808f,0.033499f,0.013912f,0.0020664f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_densepanorama_rsm[21][21] = { {0.31623f,0.34174f,0.37027f,0.40274f,0.43828f,0.47769f,0.52077f,0.56623f,0.61351f,0.661f,0.70632f,0.75039f,0.78969f,0.82364f,0.8537f,0.87804f,0.8984f,0.91493f,0.92858f,0.93948f,0.94868f}, {0.29033f,0.32401f,0.35116f,0.38332f,0.41793f,0.45677f,0.49966f,0.54385f,0.5887f,0.63465f,0.68013f,0.72323f,0.76542f,0.80587f,0.84237f,0.86998f,0.89037f,0.90708f,0.92068f,0.93165f,0.95667f}, {0.26357f,0.29714f,0.33033f,0.36043f,0.39519f,0.43391f,0.476f,0.51943f,0.56412f,0.60952f,0.65633f,0.70077f,0.74391f,0.78464f,0.82217f,0.8547f,0.8861f,0.90245f,0.91577f,0.94127f,0.96448f}, {0.23387f,0.26656f,0.30106f,0.34015f,0.37537f,0.41319f,0.45358f,0.49568f,0.53983f,0.58627f,0.63514f,0.68158f,0.72338f,0.7582f,0.7847f,0.81515f,0.84276f,0.8729f,0.92391f,0.95113f,0.97206f}, {0.20293f,0.23442f,0.26927f,0.31844f,0.36261f,0.3976f,0.43594f,0.47622f,0.51995f,0.56672f,0.61364f,0.64458f,0.66708f,0.68378f,0.69581f,0.71813f,0.73942f,0.8267f,0.92485f,0.96059f,0.97904f}, {0.17012f,0.20003f,0.24691f,0.29416f,0.33947f,0.38245f,0.41757f,0.45745f,0.50162f,0.54599f,0.56988f,0.57995f,0.59073f,0.60407f,0.61997f,0.63325f,0.69486f,0.76836f,0.87016f,0.9662f,0.9853f}, {0.13651f,0.16829f,0.22059f,0.26993f,0.31401f,0.35564f,0.39763f,0.43683f,0.48085f,0.51074f,0.51356f,0.51825f,0.52715f,0.53957f,0.55763f,0.60478f,0.65234f,0.7134f,0.80555f,0.94735f,0.99054f}, {0.10107f,0.14409f,0.19526f,0.24062f,0.28307f,0.32452f,0.36689f,0.41011f,0.45187f,0.46736f,0.46447f,0.46842f,0.47952f,0.49382f,0.532f,0.5762f,0.62064f,0.6713f,0.74022f,0.87796f,0.99481f}, {0.066833f,0.12148f,0.16885f,0.21098f,0.2502f,0.28838f,0.32758f,0.36957f,0.41557f,0.42607f,0.42112f,0.42741f,0.4395f,0.47717f,0.51254f,0.55036f,0.58741f,0.62925f,0.68414f,0.78527f,0.99772f}, {0.032685f,0.097839f,0.14205f,0.18011f,0.21427f,0.24724f,0.28043f,0.31601f,0.3593f,0.38877f,0.38284f,0.39066f,0.42745f,0.46072f,0.49267f,0.52424f,0.55513f,0.58963f,0.63325f,0.70919f,0.99945f}, {0.000000f,0.073611f,0.11305f,0.14636f,0.17565f,0.20399f,0.22866f,0.25121f,0.27286f,0.30017f,0.34904f,0.3816f,0.41249f,0.44184f,0.46912f,0.49602f,0.52444f,0.55269f,0.58706f,0.64416f,1.000000f}, {0.000000f,0.053223f,0.087771f,0.1163f,0.14044f,0.16049f,0.17679f,0.18693f,0.21286f,0.28012f,0.31466f,0.35136f,0.38428f,0.4141f,0.4406f,0.46504f,0.48828f,0.51142f,0.53741f,0.57609f,0.79404f}, {0.000000f,0.033762f,0.063207f,0.087205f,0.10665f,0.12181f,0.13255f,0.14446f,0.20132f,0.23611f,0.27768f,0.31951f,0.35363f,0.38352f,0.4083f,0.43103f,0.45143f,0.47022f,0.48832f,0.50907f,0.58627f}, {0.000000f,0.016548f,0.04191f,0.061926f,0.077723f,0.089535f,0.097654f,0.12359f,0.15718f,0.19671f,0.23911f,0.2828f,0.32125f,0.35315f,0.37705f,0.39668f,0.413f,0.42708f,0.4363f,0.43519f,0.38445f}, {0.000000f,0.0045383f,0.024315f,0.042013f,0.055294f,0.063469f,0.069663f,0.080957f,0.1128f,0.15455f,0.19937f,0.24281f,0.28387f,0.319f,0.34535f,0.36215f,0.37553f,0.38267f,0.37962f,0.34513f,0.18322f}, {0.000000f,0.00048584f,0.011756f,0.024581f,0.035454f,0.044176f,0.038229f,0.038658f,0.062405f,0.10738f,0.15484f,0.19874f,0.24047f,0.27551f,0.30398f,0.32792f,0.33487f,0.33487f,0.31994f,0.25706f,-2.2204e-016f}, {0.000000f,0.000000f,0.0023004f,0.012271f,0.021176f,0.019653f,0.017112f,0.01229f,0.021586f,0.054618f,0.099262f,0.14811f,0.18825f,0.22214f,0.25259f,0.27489f,0.29322f,0.28346f,0.24086f,0.1876f,0.000000f}, {0.000000f,0.000000f,0.00056441f,0.0039128f,0.0045454f,0.0041551f,0.0034332f,0.0017195f,0.00051362f,0.011632f,0.038283f,0.080258f,0.11853f,0.15037f,0.18073f,0.19958f,0.21596f,0.22382f,0.19415f,0.13136f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062082f,0.01248f,0.030154f,0.049131f,0.065091f,0.081035f,0.075079f,0.1126f,0.15189f,0.088781f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0021284f,0.014056f,0.033725f,0.05778f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_ang[] = {-45,-26,0,26,45,-95,95,-142,142}; static float map_9point1_wrap_xsf[] = {-1,-0.5,0,0.5,1,-1,1,-1,1}; static float map_9point1_wrap_ysf[] = {1,1,1,1,1,0,0,-1,-1}; channel_id map_9point1_wrap_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_center_left,ci_side_center_right,ci_back_left,ci_back_right,ci_lfe}; static float map_9point1_wrap_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,9.4126e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0025743f,0.016552f,0.019339f,0.017689f,0.014677f,0.0075151f,0.0023122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.010122f,0.049892f,0.081385f,0.075976f,0.066587f,0.048878f,0.031384f,0.01438f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0022432f,0.048381f,0.094728f,0.12939f,0.14819f,0.13332f,0.11169f,0.081894f,0.049473f,0.021188f,0.0029287f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019725f,0.095227f,0.15233f,0.17345f,0.16427f,0.14754f,0.14117f,0.13145f,0.099702f,0.051668f,0.015357f,0.0004627f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.067908f,0.15539f,0.19651f,0.18146f,0.15882f,0.14116f,0.1291f,0.12511f,0.12232f,0.089211f,0.030602f,0.0029125f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13152f,0.21644f,0.20646f,0.17568f,0.15435f,0.13761f,0.1251f,0.11476f,0.11158f,0.1087f,0.0391f,0.0030968f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19821f,0.24497f,0.20143f,0.17202f,0.15152f,0.1354f,0.12233f,0.11157f,0.10201f,0.10008f,0.02634f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {8.6596e-017f,0.26351f,0.25036f,0.20151f,0.17212f,0.15022f,0.13434f,0.1215f,0.11016f,0.10014f,0.091286f,0.091196f,0.072765f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.14292f,0.32097f,0.25158f,0.20264f,0.17322f,0.15277f,0.1368f,0.12398f,0.11372f,0.10509f,0.10014f,0.10199f,0.11007f,0.089378f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.27953f,0.36201f,0.26077f,0.20891f,0.17806f,0.15683f,0.14026f,0.12809f,0.11822f,0.11157f,0.11015f,0.11158f,0.11474f,0.11478f,0.079886f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.40639f,0.40831f,0.2748f,0.2181f,0.18495f,0.16233f,0.1448f,0.133f,0.12656f,0.12233f,0.12149f,0.12232f,0.12511f,0.12639f,0.10424f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.52748f,0.47057f,0.29527f,0.22794f,0.19213f,0.16957f,0.152f,0.14356f,0.13761f,0.1354f,0.13433f,0.13538f,0.13762f,0.13549f,0.1175f,0.061535f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.63323f,0.50954f,0.31873f,0.2453f,0.20447f,0.17733f,0.16842f,0.15997f,0.15435f,0.15152f,0.15021f,0.15149f,0.1527f,0.14081f,0.11367f,0.0757f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.72837f,0.51209f,0.3683f,0.26525f,0.21826f,0.20334f,0.18984f,0.18146f,0.17568f,0.17202f,0.17211f,0.17098f,0.16098f,0.13607f,0.098801f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.81116f,0.50827f,0.36916f,0.29352f,0.264f,0.24288f,0.22433f,0.21451f,0.20646f,0.20143f,0.19609f,0.18058f,0.15329f,0.1102f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.88423f,0.49893f,0.37009f,0.36617f,0.35721f,0.311f,0.2844f,0.26253f,0.24312f,0.22219f,0.19506f,0.15866f,0.1057f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.94622f,0.48678f,0.46584f,0.43796f,0.40098f,0.35386f,0.3003f,0.25801f,0.21787f,0.17042f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_9point1_wrap_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0022352f,0.0073556f,0.014462f,0.017441f,0.019071f,0.016531f,0.0024671f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01419f,0.031102f,0.048526f,0.066173f,0.075526f,0.081297f,0.04946f,0.0098814f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028496f,0.021112f,0.049149f,0.081488f,0.11122f,0.13287f,0.14806f,0.12881f,0.09417f,0.047925f,0.0021311f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00043186f,0.015188f,0.051545f,0.099312f,0.1312f,0.14102f,0.14734f,0.16405f,0.17306f,0.15167f,0.094607f,0.019339f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0028379f,0.030373f,0.089057f,0.12218f,0.12498f,0.12893f,0.14102f,0.15866f,0.18126f,0.19604f,0.15464f,0.067274f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0030797f,0.038854f,0.1086f,0.11146f,0.1146f,0.12497f,0.13745f,0.1542f,0.17549f,0.20626f,0.21577f,0.13069f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.026252f,0.10001f,0.10187f,0.11145f,0.12219f,0.13525f,0.15135f,0.17183f,0.20121f,0.24456f,0.19725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.072685f,0.091096f,0.091174f,0.10001f,0.11002f,0.12134f,0.13416f,0.15002f,0.1719f,0.20125f,0.25003f,0.2633f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040435f,0.089481f,0.11f,0.10185f,0.10001f,0.10496f,0.11359f,0.12384f,0.13666f,0.15261f,0.17302f,0.20242f,0.25131f,0.32012f,0.14046f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.080064f,0.11479f,0.11458f,0.11146f,0.11002f,0.11145f,0.11808f,0.12794f,0.14009f,0.15665f,0.17785f,0.20867f,0.2605f,0.36128f,0.27711f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.10437f,0.12621f,0.12498f,0.12218f,0.12134f,0.12219f,0.12645f,0.13284f,0.14464f,0.16215f,0.18474f,0.21787f,0.27448f,0.4076f,0.40402f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.061843f,0.11735f,0.13544f,0.13747f,0.13526f,0.13417f,0.13525f,0.13745f,0.14343f,0.15182f,0.16938f,0.19191f,0.22768f,0.29494f,0.46977f,0.52519f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.075569f,0.11383f,0.14084f,0.15258f,0.15134f,0.15002f,0.15135f,0.1542f,0.15983f,0.16828f,0.17712f,0.20424f,0.24502f,0.31841f,0.50892f,0.63102f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.099066f,0.13621f,0.16098f,0.17084f,0.1719f,0.17183f,0.17549f,0.18126f,0.18968f,0.20316f,0.21799f,0.26496f,0.36789f,0.51154f,0.72626f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.11053f,0.15345f,0.18063f,0.19584f,0.20121f,0.20626f,0.21427f,0.22413f,0.24264f,0.26377f,0.29316f,0.36878f,0.50788f,0.80914f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10618f,0.15898f,0.19481f,0.22223f,0.24306f,0.26241f,0.28423f,0.31081f,0.3571f,0.36589f,0.36964f,0.49868f,0.8823f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.17097f,0.21836f,0.25849f,0.30093f,0.35437f,0.4014f,0.43825f,0.46598f,0.4862f,0.94439f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_9point1_wrap_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.076479f,0.1924f,0.15601f,0.11842f,0.08308f,0.051138f,0.03194f,0.02596f,0.017224f,0.006217f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15701f,0.23422f,0.26354f,0.22314f,0.18089f,0.17541f,0.15144f,0.12753f,0.099719f,0.070344f,0.038959f,0.016585f,0.0019274f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24799f,0.28578f,0.30478f,0.2999f,0.28155f,0.26062f,0.23875f,0.21148f,0.18101f,0.14288f,0.097017f,0.059361f,0.02644f,0.0055357f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34452f,0.34709f,0.3472f,0.32503f,0.29199f,0.2741f,0.2564f,0.23925f,0.21822f,0.19068f,0.15101f,0.104f,0.05812f,0.024256f,0.0054585f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44874f,0.4169f,0.38198f,0.33282f,0.28632f,0.24721f,0.23733f,0.22819f,0.21923f,0.20483f,0.17996f,0.13974f,0.08731f,0.044322f,0.015426f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55712f,0.48293f,0.39609f,0.32283f,0.2712f,0.23804f,0.21189f,0.20278f,0.19777f,0.19453f,0.18519f,0.15702f,0.11105f,0.061583f,0.025231f,0.00062925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67263f,0.51439f,0.39135f,0.31154f,0.26327f,0.22985f,0.20371f,0.18541f,0.17979f,0.1758f,0.17449f,0.15962f,0.11761f,0.06551f,0.017632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78467f,0.52067f,0.3765f,0.30095f,0.25585f,0.2244f,0.19964f,0.1808f,0.16481f,0.16036f,0.15821f,0.15223f,0.10975f,0.041656f,0.0063155f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52104f,0.36605f,0.29451f,0.25151f,0.22133f,0.19751f,0.17814f,0.16187f,0.14649f,0.14382f,0.13363f,0.061306f,0.014688f,1.0116e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.52679f,0.36715f,0.29551f,0.25242f,0.22029f,0.19701f,0.17818f,0.16155f,0.14686f,0.1311f,0.063705f,0.017218f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.89382f,0.52086f,0.36615f,0.29459f,0.2515f,0.22126f,0.1975f,0.17814f,0.16187f,0.14649f,0.14382f,0.13358f,0.061006f,0.014527f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.78261f,0.52026f,0.37649f,0.30094f,0.25584f,0.22432f,0.19963f,0.18084f,0.1648f,0.16036f,0.1582f,0.15211f,0.10961f,0.041389f,0.0062031f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.67046f,0.51365f,0.39123f,0.31163f,0.26325f,0.22984f,0.20363f,0.1854f,0.17974f,0.1758f,0.17448f,0.15945f,0.11735f,0.065362f,0.017508f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55485f,0.48176f,0.39574f,0.32282f,0.27127f,0.2381f,0.21189f,0.20284f,0.19777f,0.19453f,0.18513f,0.15675f,0.11066f,0.061236f,0.025146f,0.00059225f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.4464f,0.41543f,0.3814f,0.33259f,0.28621f,0.2472f,0.23726f,0.22818f,0.21922f,0.20473f,0.17984f,0.13934f,0.086884f,0.044002f,0.015305f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34213f,0.34579f,0.34627f,0.32473f,0.29192f,0.274f,0.25621f,0.23901f,0.21792f,0.19031f,0.1508f,0.10352f,0.057744f,0.024003f,0.0054168f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24558f,0.28436f,0.30393f,0.29971f,0.28098f,0.26009f,0.23836f,0.21095f,0.18045f,0.14227f,0.096837f,0.059047f,0.026151f,0.005504f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.15519f,0.23319f,0.26327f,0.22211f,0.18013f,0.17455f,0.15068f,0.12685f,0.099116f,0.06984f,0.038815f,0.016456f,0.0018503f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.074009f,0.19209f,0.15497f,0.11774f,0.082312f,0.050511f,0.031485f,0.025562f,0.016918f,0.0061903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0061903f,0.016918f,0.025562f,0.031485f,0.050511f,0.082312f,0.11774f,0.15497f,0.19222f,0.074014f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0018503f,0.016456f,0.038851f,0.06984f,0.099116f,0.12685f,0.15068f,0.17455f,0.18013f,0.22211f,0.26337f,0.23319f,0.15519f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.005504f,0.026151f,0.059047f,0.096892f,0.14227f,0.18045f,0.21095f,0.23853f,0.26009f,0.28098f,0.29979f,0.30393f,0.28436f,0.24556f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0054168f,0.024003f,0.057744f,0.10352f,0.15084f,0.19031f,0.21792f,0.23901f,0.25621f,0.274f,0.29198f,0.32473f,0.34627f,0.34579f,0.34213f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.015305f,0.044002f,0.086884f,0.13934f,0.17988f,0.20473f,0.21922f,0.22818f,0.23733f,0.24725f,0.28627f,0.33259f,0.3814f,0.41543f,0.4464f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00059225f,0.025157f,0.061236f,0.11066f,0.15675f,0.18518f,0.19453f,0.19777f,0.20284f,0.21193f,0.2381f,0.27127f,0.32308f,0.39574f,0.48176f,0.55485f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017508f,0.065396f,0.11735f,0.15945f,0.17454f,0.1758f,0.1798f,0.18544f,0.20369f,0.22984f,0.26325f,0.31163f,0.39123f,0.51365f,0.67046f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0062031f,0.041389f,0.10962f,0.15211f,0.15825f,0.16036f,0.16483f,0.18084f,0.19963f,0.22439f,0.25584f,0.30094f,0.37649f,0.52026f,0.78261f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014527f,0.061006f,0.13359f,0.14386f,0.14652f,0.16187f,0.17814f,0.1975f,0.22132f,0.2515f,0.29459f,0.36615f,0.52086f,0.89382f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-4.0817e-019f,0.017202f,0.06369f,0.13113f,0.14689f,0.16158f,0.17821f,0.19705f,0.22033f,0.25247f,0.29557f,0.36722f,0.52689f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.0116e-005f,0.014688f,0.061306f,0.13361f,0.14385f,0.14651f,0.16187f,0.17814f,0.19751f,0.22133f,0.25151f,0.2946f,0.36616f,0.52104f,0.89574f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0063155f,0.041656f,0.10967f,0.15223f,0.15823f,0.16036f,0.16482f,0.18085f,0.19964f,0.2244f,0.25585f,0.30095f,0.3765f,0.52067f,0.78467f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017695f,0.065451f,0.11767f,0.15962f,0.17452f,0.1758f,0.17979f,0.18543f,0.20371f,0.22985f,0.26327f,0.31164f,0.39135f,0.51439f,0.67263f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062925f,0.0252f,0.061583f,0.11105f,0.15702f,0.18518f,0.19453f,0.19777f,0.20284f,0.21192f,0.23812f,0.27128f,0.32312f,0.39609f,0.48293f,0.55712f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019397f,0.0155f,0.044322f,0.08731f,0.13974f,0.17992f,0.2049f,0.2193f,0.22819f,0.23733f,0.24724f,0.28632f,0.33282f,0.38198f,0.4169f,0.44874f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0055425f,0.024256f,0.05812f,0.104f,0.15089f,0.19068f,0.21822f,0.23925f,0.2564f,0.27419f,0.292f,0.32517f,0.3472f,0.34732f,0.34452f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0056317f,0.02644f,0.059451f,0.09695f,0.14288f,0.18101f,0.21148f,0.23904f,0.26062f,0.28155f,0.29985f,0.30497f,0.28578f,0.24801f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019274f,0.016697f,0.038906f,0.070344f,0.099719f,0.12753f,0.15144f,0.17541f,0.18105f,0.22314f,0.26347f,0.23448f,0.15764f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.2068e-018f,0.0063777f,0.017224f,0.02596f,0.03194f,0.051138f,0.08308f,0.11865f,0.15601f,0.19233f,0.076473f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f}}; static float map_9point1_wrap_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.94446f,0.81199f,0.83616f,0.85669f,0.87092f,0.87561f,0.8564f,0.80823f,0.75425f,0.69808f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.88271f,0.78057f,0.71294f,0.73952f,0.76209f,0.72118f,0.69661f,0.66179f,0.62498f,0.59208f,0.56394f,0.52736f,0.48539f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.80907f,0.73849f,0.68142f,0.62971f,0.60765f,0.58509f,0.55402f,0.53219f,0.51188f,0.49896f,0.49292f,0.47704f,0.45666f,0.42472f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.72626f,0.68381f,0.64457f,0.57657f,0.51706f,0.49372f,0.46596f,0.45043f,0.43577f,0.42627f,0.42558f,0.42408f,0.4189f,0.4019f,0.37301f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.63102f,0.61653f,0.57478f,0.53382f,0.48514f,0.42718f,0.41011f,0.39421f,0.38285f,0.37543f,0.37141f,0.37424f,0.37886f,0.37291f,0.35447f,0.32571f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.52519f,0.53691f,0.52315f,0.49422f,0.4552f,0.40947f,0.36615f,0.35043f,0.34158f,0.3356f,0.33216f,0.33419f,0.33895f,0.34131f,0.33172f,0.30203f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.40402f,0.46214f,0.47464f,0.46087f,0.43328f,0.39304f,0.3499f,0.32038f,0.31064f,0.30342f,0.30041f,0.30177f,0.30761f,0.31375f,0.30955f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.27711f,0.39741f,0.42859f,0.42667f,0.40895f,0.37927f,0.34025f,0.30982f,0.28478f,0.27695f,0.27237f,0.27482f,0.28125f,0.29675f,0.28023f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.14292f,0.33339f,0.38221f,0.39113f,0.38299f,0.36377f,0.33348f,0.30176f,0.27588f,0.25314f,0.24761f,0.25f,0.2723f,0.2674f,0.23727f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.000000f,0.26327f,0.33172f,0.35247f,0.35385f,0.34292f,0.32385f,0.29788f,0.27007f,0.24552f,0.22579f,0.23659f,0.23272f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.000000f,0.19725f,0.27965f,0.31034f,0.31939f,0.31618f,0.30536f,0.28855f,0.26792f,0.24094f,0.1799f,0.14699f,0.14674f,0.14347f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.000000f,0.13069f,0.21975f,0.26195f,0.27862f,0.28151f,0.27602f,0.26277f,0.24232f,0.202f,0.13299f,0.082204f,0.083689f,0.086082f,0.07899f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.000000f,0.067274f,0.15464f,0.20782f,0.23238f,0.24129f,0.24043f,0.22893f,0.19873f,0.15312f,0.089072f,0.040759f,0.032293f,0.046248f,0.043546f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.019339f,0.094607f,0.15196f,0.18465f,0.19667f,0.19966f,0.1783f,0.14444f,0.099312f,0.051555f,0.015195f,0.0048976f,0.012512f,0.017789f,0.01096f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0021311f,0.047925f,0.09417f,0.12885f,0.15216f,0.13421f,0.11122f,0.081488f,0.049149f,0.021112f,0.0028496f,0.000000f,0.000000f,0.00044495f,0.0013625f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0098814f,0.04946f,0.081296f,0.075526f,0.066173f,0.048526f,0.031102f,0.01419f,0.0019269f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0024671f,0.016531f,0.019071f,0.017441f,0.014677f,0.0073556f,0.0022352f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_9point1_wrap_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.69745f,0.75361f,0.80779f,0.85613f,0.8756f,0.87113f,0.85731f,0.83679f,0.81212f,0.94629f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48466f,0.52692f,0.56374f,0.59228f,0.62473f,0.66167f,0.69668f,0.72145f,0.76272f,0.7402f,0.71303f,0.78158f,0.88423f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.42428f,0.45626f,0.4769f,0.4928f,0.49938f,0.51188f,0.53264f,0.55439f,0.58524f,0.6082f,0.62975f,0.68239f,0.7397f,0.8111f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.37263f,0.40155f,0.4187f,0.42403f,0.42555f,0.42626f,0.43576f,0.45043f,0.46637f,0.49385f,0.51702f,0.57711f,0.64546f,0.68515f,0.72837f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.3256f,0.35421f,0.3727f,0.37913f,0.37456f,0.37139f,0.37551f,0.38293f,0.39422f,0.41047f,0.42708f,0.48557f,0.53421f,0.57553f,0.61802f,0.63323f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30191f,0.3317f,0.3415f,0.33894f,0.33418f,0.33214f,0.33559f,0.34157f,0.3505f,0.36607f,0.40957f,0.45546f,0.49461f,0.52386f,0.53833f,0.52748f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.30936f,0.31378f,0.30767f,0.30176f,0.30039f,0.30342f,0.31091f,0.32031f,0.3502f,0.39305f,0.43346f,0.46137f,0.47532f,0.46338f,0.40639f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.2799f,0.29688f,0.28132f,0.27481f,0.27235f,0.27695f,0.28472f,0.3099f,0.34026f,0.3796f,0.40917f,0.42708f,0.42927f,0.39855f,0.27953f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.26716f,0.27225f,0.25006f,0.24759f,0.25308f,0.27589f,0.30177f,0.33349f,0.36411f,0.38326f,0.39169f,0.38291f,0.3345f,0.14292f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.23269f,0.23658f,0.22577f,0.24545f,0.27f,0.29779f,0.3238f,0.34289f,0.35387f,0.35252f,0.3318f,0.26339f,-8.6596e-017f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12602f,0.14312f,0.14641f,0.14698f,0.17992f,0.24091f,0.268f,0.28867f,0.30555f,0.31654f,0.31978f,0.31088f,0.28038f,0.19821f,0.000000f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.07868f,0.085813f,0.08366f,0.082238f,0.13301f,0.20226f,0.24232f,0.26304f,0.2763f,0.28192f,0.27908f,0.26255f,0.22053f,0.13152f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.043546f,0.046224f,0.032368f,0.040874f,0.089105f,0.15348f,0.19907f,0.22896f,0.24081f,0.24172f,0.2329f,0.20846f,0.15539f,0.067908f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.010822f,0.017781f,0.01238f,0.0048489f,0.015357f,0.051582f,0.099723f,0.14485f,0.17871f,0.1997f,0.19715f,0.18521f,0.15233f,0.095227f,0.019725f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.00044495f,0.000000f,0.000000f,0.0029287f,0.021123f,0.049473f,0.081894f,0.11169f,0.13466f,0.15222f,0.12939f,0.094728f,0.048381f,0.0022432f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0019269f,0.01438f,0.031384f,0.048878f,0.066587f,0.075976f,0.081342f,0.049892f,0.010122f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0023122f,0.0075151f,0.014677f,0.017689f,0.019339f,0.016553f,0.0025743f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.4126e-019f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_ang[] = {-45,-26,0,26,45,-63,63,-90,90,-116,116}; static float map_11point1_densewrap_xsf[] = {-1,-0.5,0,0.5,1,-1,1,-1,1,-1,1}; static float map_11point1_densewrap_ysf[] = {1,1,1,1,1,0.5,0.5,0,0,-0.5,-0.5}; channel_id map_11point1_densewrap_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_front_left,ci_side_front_right,ci_side_center_left,ci_side_center_right,ci_side_back_left,ci_side_back_right,ci_lfe}; static float map_11point1_densewrap_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.005581f,0.003291f,1.7252e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0081504f,0.042808f,0.072882f,0.060953f,0.042164f,0.017887f,0.0013668f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0027588f,0.054743f,0.091228f,0.091909f,0.082995f,0.079348f,0.071132f,0.040421f,0.0039453f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040396f,0.10257f,0.10193f,0.089276f,0.079333f,0.072621f,0.070291f,0.068709f,0.03606f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0060181f,0.10346f,0.11606f,0.098677f,0.086748f,0.077297f,0.070277f,0.064552f,0.062673f,0.06051f,0.0017892f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.047382f,0.13537f,0.11322f,0.096621f,0.085123f,0.076125f,0.068709f,0.062673f,0.057379f,0.05627f,0.000000f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10632f,0.1408f,0.11333f,0.0968f,0.08448f,0.075551f,0.068329f,0.061952f,0.05632f,0.051341f,0.056303f,0.060536f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.16195f,0.14064f,0.1132f,0.096622f,0.085107f,0.076104f,0.068709f,0.062673f,0.060449f,0.05632f,0.057346f,0.062673f,0.068709f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.194f,0.14507f,0.11609f,0.098677f,0.086764f,0.077297f,0.071771f,0.068005f,0.062673f,0.061952f,0.062673f,0.064514f,0.070277f,0.071028f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.22178f,0.15206f,0.12055f,0.10193f,0.090467f,0.081765f,0.076506f,0.071744f,0.068709f,0.068329f,0.068709f,0.070291f,0.072578f,0.079333f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25576f,0.16273f,0.12661f,0.10766f,0.096098f,0.087435f,0.081735f,0.077297f,0.076125f,0.075551f,0.076104f,0.077297f,0.079348f,0.082947f,0.06067f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {3.1398e-016f,0.28205f,0.17804f,0.13801f,0.11623f,0.10201f,0.096063f,0.090425f,0.086748f,0.085123f,0.08448f,0.085107f,0.086764f,0.089301f,0.091873f,0.072927f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24261f,0.28709f,0.20797f,0.15099f,0.12555f,0.11619f,0.10762f,0.10193f,0.098677f,0.096621f,0.0968f,0.096622f,0.098677f,0.10193f,0.091044f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.46196f,0.29071f,0.21045f,0.16884f,0.15094f,0.13799f,0.12656f,0.12057f,0.11606f,0.11322f,0.11333f,0.1132f,0.11609f,0.10231f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.66287f,0.29364f,0.21289f,0.21045f,0.20789f,0.17806f,0.16273f,0.15206f,0.14511f,0.14066f,0.1408f,0.1352f,0.10303f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.8397f,0.29675f,0.29354f,0.29061f,0.28698f,0.28196f,0.25543f,0.22155f,0.19371f,0.16153f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_11point1_densewrap_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031891f,0.0054514f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013174f,0.017687f,0.041859f,0.06067f,0.072899f,0.042466f,0.0079947f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003925f,0.040182f,0.071028f,0.079333f,0.082923f,0.091873f,0.091044f,0.054336f,0.0026644f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.036005f,0.068709f,0.070277f,0.072557f,0.079348f,0.089301f,0.10193f,0.10231f,0.040017f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017407f,0.060499f,0.062673f,0.064496f,0.070291f,0.077297f,0.086764f,0.098677f,0.11609f,0.10303f,0.005855f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.000000f,0.056286f,0.057329f,0.062673f,0.068709f,0.076104f,0.085107f,0.096622f,0.1132f,0.1352f,0.046879f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.06051f,0.056286f,0.051311f,0.056286f,0.061915f,0.068289f,0.075506f,0.08443f,0.096742f,0.11326f,0.14072f,0.10645f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040421f,0.068709f,0.062673f,0.057312f,0.056287f,0.060432f,0.062673f,0.068709f,0.076125f,0.085123f,0.096621f,0.11322f,0.14066f,0.16153f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.071132f,0.070291f,0.064476f,0.062673f,0.061916f,0.062673f,0.067986f,0.071744f,0.077297f,0.086748f,0.098677f,0.11606f,0.14511f,0.19371f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.079348f,0.072536f,0.070277f,0.068709f,0.068289f,0.068709f,0.071771f,0.076484f,0.081735f,0.090425f,0.10193f,0.12057f,0.15206f,0.22155f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.060953f,0.082898f,0.079333f,0.077297f,0.076125f,0.075507f,0.076104f,0.077297f,0.081765f,0.087411f,0.096063f,0.10762f,0.12656f,0.16273f,0.25543f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.072826f,0.091909f,0.089276f,0.086748f,0.085123f,0.08443f,0.085107f,0.086764f,0.090467f,0.096098f,0.10198f,0.11619f,0.13799f,0.17806f,0.28196f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.091228f,0.10193f,0.098677f,0.096621f,0.096743f,0.096622f,0.098677f,0.10193f,0.10766f,0.11623f,0.12551f,0.15094f,0.20789f,0.28698f,0.23903f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.10257f,0.11606f,0.11322f,0.11326f,0.1132f,0.11609f,0.12055f,0.12661f,0.13801f,0.15099f,0.16879f,0.21045f,0.29061f,0.4584f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10346f,0.13537f,0.14072f,0.14064f,0.14507f,0.15206f,0.16273f,0.17804f,0.20797f,0.21045f,0.21283f,0.29354f,0.65936f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.16195f,0.194f,0.22178f,0.25576f,0.28205f,0.28709f,0.29071f,0.29364f,0.29667f,0.83624f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_11point1_densewrap_lsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,1.4883e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040704f,0.026172f,0.030577f,0.027969f,0.023206f,0.011882f,0.003656f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016004f,0.078886f,0.11885f,0.11126f,0.10005f,0.077277f,0.049623f,0.022737f,0.0030466f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0035468f,0.076496f,0.13684f,0.13679f,0.11897f,0.11432f,0.10984f,0.10114f,0.076046f,0.033501f,0.0046306f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.031188f,0.14617f,0.15418f,0.1299f,0.11431f,0.10197f,0.097664f,0.095287f,0.093649f,0.075427f,0.024282f,0.00073159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10737f,0.1817f,0.1484f,0.12564f,0.10986f,0.097669f,0.089224f,0.086605f,0.08469f,0.083965f,0.048387f,0.004605f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19838f,0.17849f,0.14282f,0.12164f,0.1068f,0.095276f,0.0866f,0.07931f,0.077259f,0.076129f,0.058978f,0.0048965f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23832f,0.17313f,0.13935f,0.11911f,0.10488f,0.093632f,0.084699f,0.077251f,0.070498f,0.069208f,0.041647f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.3692e-016f,0.24833f,0.17308f,0.13931f,0.11899f,0.10385f,0.092873f,0.083996f,0.076156f,0.069233f,0.063102f,0.05511f,0.019286f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22597f,0.25121f,0.17526f,0.1413f,0.12102f,0.1069f,0.095882f,0.087318f,0.080638f,0.070515f,0.069221f,0.070532f,0.07488f,0.032609f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44198f,0.26542f,0.18277f,0.14664f,0.1254f,0.11069f,0.099453f,0.088959f,0.07933f,0.077251f,0.076144f,0.077259f,0.079348f,0.070283f,0.013958f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64256f,0.2947f,0.1939f,0.15413f,0.13115f,0.11353f,0.099577f,0.089246f,0.0866f,0.084699f,0.083982f,0.08469f,0.086605f,0.085004f,0.039295f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83403f,0.33937f,0.20938f,0.16007f,0.13344f,0.11606f,0.102f,0.097669f,0.095276f,0.093632f,0.092858f,0.093649f,0.095287f,0.088683f,0.054552f,0.0013532f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35937f,0.22225f,0.16947f,0.13938f,0.11899f,0.11431f,0.10986f,0.1068f,0.10488f,0.10383f,0.10487f,0.10415f,0.081353f,0.034375f,0.0043588f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.7669f,0.35542f,0.25327f,0.18049f,0.14646f,0.13768f,0.1299f,0.12564f,0.12164f,0.11911f,0.11897f,0.11747f,0.098408f,0.05387f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55102f,0.34365f,0.25072f,0.19696f,0.17861f,0.1657f,0.15445f,0.1484f,0.14282f,0.13935f,0.13074f,0.10642f,0.058689f,0.012407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34893f,0.32425f,0.24834f,0.24599f,0.23588f,0.21001f,0.1922f,0.1745f,0.1548f,0.12874f,0.085642f,0.036985f,0.0041976f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.16741f,0.30017f,0.27214f,0.23269f,0.17995f,0.11341f,0.070758f,0.057469f,0.038068f,0.013988f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_rsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0036134f,0.011794f,0.023088f,0.027832f,0.030429f,0.026399f,0.0040112f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031126f,0.022632f,0.049467f,0.077089f,0.099949f,0.11118f,0.11911f,0.078648f,0.015871f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045869f,0.033596f,0.075931f,0.10117f,0.10998f,0.11448f,0.11916f,0.13692f,0.13673f,0.076245f,0.0034849f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00071455f,0.024189f,0.075553f,0.093753f,0.095409f,0.097805f,0.10214f,0.11445f,0.13006f,0.15434f,0.14595f,0.030939f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045638f,0.04826f,0.084116f,0.084794f,0.086729f,0.089374f,0.097788f,0.10998f,0.12579f,0.14861f,0.18178f,0.10702f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0049397f,0.058905f,0.076265f,0.077358f,0.079443f,0.086706f,0.095393f,0.10693f,0.1218f,0.14297f,0.17876f,0.19813f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041705f,0.069332f,0.070616f,0.077346f,0.084808f,0.093775f,0.10503f,0.11926f,0.13955f,0.17338f,0.23845f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.128e-019f,0.019251f,0.055118f,0.063203f,0.069332f,0.076265f,0.084116f,0.093006f,0.104f,0.11916f,0.13951f,0.17333f,0.24869f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,2.262e-005f,0.032844f,0.075002f,0.070621f,0.069332f,0.070599f,0.080737f,0.087417f,0.095981f,0.10702f,0.12116f,0.14146f,0.17546f,0.2515f,0.22461f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014122f,0.070466f,0.079449f,0.077358f,0.076265f,0.077346f,0.079424f,0.089097f,0.099575f,0.11084f,0.12555f,0.14685f,0.18296f,0.26573f,0.44064f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039567f,0.085048f,0.086729f,0.084794f,0.084116f,0.084808f,0.086706f,0.089352f,0.099732f,0.11371f,0.13131f,0.1543f,0.19413f,0.29503f,0.64125f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0014071f,0.054512f,0.088881f,0.095409f,0.093753f,0.093007f,0.093775f,0.095393f,0.097788f,0.10212f,0.11625f,0.13365f,0.16031f,0.20963f,0.33985f,0.83276f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043373f,0.034659f,0.08163f,0.10433f,0.105f,0.104f,0.10503f,0.10693f,0.10998f,0.11445f,0.11914f,0.1396f,0.16971f,0.22252f,0.35981f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.054219f,0.098665f,0.11764f,0.11916f,0.11926f,0.1218f,0.12579f,0.13006f,0.13785f,0.14663f,0.18077f,0.25367f,0.35599f,0.77038f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012593f,0.059121f,0.10673f,0.13084f,0.13955f,0.14297f,0.14861f,0.15464f,0.1659f,0.17883f,0.19719f,0.25106f,0.3443f,0.55456f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043097f,0.037335f,0.085557f,0.12916f,0.1552f,0.17483f,0.19253f,0.21041f,0.2363f,0.24639f,0.24863f,0.32498f,0.3525f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.6987e-018f,0.014261f,0.038514f,0.058048f,0.071419f,0.11435f,0.18086f,0.23352f,0.27289f,0.30018f,0.171f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.4828e-016f}}; static float map_11point1_densewrap_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.057837f,0.033725f,0.014056f,0.0021284f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088781f,0.15197f,0.1126f,0.075079f,0.081035f,0.065091f,0.049131f,0.030154f,0.01248f,0.00065038f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13136f,0.19047f,0.19972f,0.18761f,0.17365f,0.15926f,0.13948f,0.11522f,0.080258f,0.038352f,0.011632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1876f,0.22622f,0.20877f,0.17308f,0.16259f,0.15331f,0.14824f,0.14136f,0.12698f,0.096228f,0.051224f,0.013903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25386f,0.24792f,0.19549f,0.16259f,0.14063f,0.13492f,0.12979f,0.12612f,0.12377f,0.11836f,0.09054f,0.040513f,0.0077516f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18322f,0.31647f,0.23665f,0.18234f,0.15331f,0.13491f,0.12054f,0.11534f,0.11241f,0.11063f,0.10978f,0.10408f,0.067907f,0.021737f,0.00081869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.38445f,0.33396f,0.22305f,0.17613f,0.14823f,0.12977f,0.11534f,0.10547f,0.10221f,0.099919f,0.099291f,0.099924f,0.076689f,0.027385f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58627f,0.31272f,0.21469f,0.17128f,0.14518f,0.12698f,0.11241f,0.1022f,0.093751f,0.091147f,0.090023f,0.091143f,0.07194f,0.010076f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79404f,0.30169f,0.2101f,0.16888f,0.14394f,0.12647f,0.11263f,0.10109f,0.091143f,0.083334f,0.081839f,0.083344f,0.027665f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.30431f,0.2121f,0.17071f,0.14582f,0.12726f,0.11381f,0.10293f,0.093322f,0.084838f,0.074566f,0.014386f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79277f,0.30166f,0.21008f,0.16887f,0.14393f,0.12645f,0.11261f,0.10108f,0.091147f,0.083312f,0.081796f,0.083334f,0.02757f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58496f,0.31272f,0.21465f,0.17129f,0.14517f,0.12697f,0.11241f,0.10221f,0.093725f,0.091143f,0.089976f,0.091147f,0.071938f,0.010015f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3831f,0.33384f,0.22305f,0.17611f,0.14824f,0.12979f,0.11534f,0.10544f,0.1022f,0.099924f,0.099238f,0.099919f,0.076598f,0.027407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18186f,0.31619f,0.23666f,0.18235f,0.15331f,0.13492f,0.1205f,0.11534f,0.11241f,0.11064f,0.10973f,0.10402f,0.06778f,0.021645f,0.00081784f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25335f,0.24781f,0.1955f,0.16259f,0.14059f,0.13491f,0.12977f,0.12612f,0.12378f,0.11834f,0.090417f,0.040382f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1871f,0.22597f,0.20873f,0.17303f,0.16259f,0.15331f,0.14823f,0.14133f,0.12691f,0.096247f,0.051065f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13094f,0.19014f,0.19982f,0.18747f,0.17352f,0.15913f,0.13934f,0.11502f,0.08005f,0.038463f,0.011549f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088435f,0.15238f,0.11227f,0.074803f,0.080771f,0.064857f,0.048933f,0.030007f,0.012387f,0.00062972f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.05808f,0.033499f,0.013912f,0.0020664f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0020664f,0.013912f,0.033499f,0.058195f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062972f,0.012387f,0.030007f,0.048933f,0.064857f,0.080771f,0.074803f,0.11227f,0.15246f,0.088435f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011549f,0.038509f,0.08005f,0.11502f,0.13934f,0.15913f,0.17352f,0.18747f,0.19989f,0.19014f,0.13094f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013816f,0.051065f,0.096286f,0.12691f,0.14133f,0.14823f,0.15331f,0.16259f,0.17308f,0.20873f,0.22597f,0.1871f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0076928f,0.040382f,0.090417f,0.11837f,0.12378f,0.12612f,0.12977f,0.13491f,0.14063f,0.16259f,0.1955f,0.24781f,0.25335f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00081784f,0.021645f,0.06778f,0.10402f,0.10977f,0.11064f,0.11241f,0.11534f,0.12054f,0.13492f,0.15331f,0.18235f,0.23666f,0.31619f,0.18186f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027451f,0.076598f,0.099919f,0.099281f,0.099924f,0.1022f,0.10547f,0.11534f,0.12979f,0.14824f,0.17611f,0.22305f,0.33384f,0.3831f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010015f,0.071952f,0.091147f,0.090014f,0.091143f,0.093752f,0.10221f,0.11241f,0.12697f,0.14517f,0.17129f,0.21465f,0.31272f,0.58496f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.02757f,0.083335f,0.081831f,0.083335f,0.091147f,0.10108f,0.11261f,0.12645f,0.14393f,0.16887f,0.21008f,0.30166f,0.79277f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014385f,0.074587f,0.084862f,0.093348f,0.10296f,0.11384f,0.12729f,0.14586f,0.17076f,0.21215f,0.30439f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027665f,0.083335f,0.08182f,0.083335f,0.091143f,0.10109f,0.11263f,0.12647f,0.14394f,0.16888f,0.2101f,0.30169f,0.79404f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010076f,0.071837f,0.091143f,0.090002f,0.091147f,0.093752f,0.1022f,0.11241f,0.12698f,0.14518f,0.17128f,0.21469f,0.31272f,0.58627f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027311f,0.076689f,0.099924f,0.099267f,0.099919f,0.10221f,0.10547f,0.11534f,0.12977f,0.14823f,0.17613f,0.22305f,0.33396f,0.38445f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080127f,0.021737f,0.067907f,0.10408f,0.10976f,0.11063f,0.11241f,0.11534f,0.12054f,0.13491f,0.15331f,0.18234f,0.23665f,0.31647f,0.18322f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0077516f,0.040513f,0.09054f,0.11831f,0.12377f,0.12612f,0.12979f,0.13492f,0.14063f,0.16259f,0.19549f,0.24792f,0.25386f,-2.2204e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.22e-018f,0.013903f,0.051224f,0.096055f,0.12698f,0.14136f,0.14824f,0.15331f,0.16259f,0.17308f,0.20877f,0.22622f,0.1876f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011632f,0.038283f,0.080258f,0.11522f,0.13948f,0.15926f,0.17365f,0.18761f,0.19965f,0.19047f,0.13136f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062082f,0.01248f,0.030154f,0.049131f,0.065091f,0.081035f,0.075079f,0.1126f,0.15189f,0.088781f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0021284f,0.014056f,0.033725f,0.05778f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_lsb[21][21] = { {1.1859f,1.2049f,1.2221f,1.2365f,1.2463f,1.25f,1.2457f,1.2315f,1.2059f,1.168f,1.119f,1.0566f,0.98636f,0.91121f,0.82991f,0.75053f,0.67162f,0.59645f,0.52432f,0.45813f,0.39456f}, {1.1627f,1.0921f,1.1253f,1.1542f,1.1748f,1.184f,1.1757f,1.143f,1.101f,1.0549f,1.0052f,0.94385f,0.88061f,0.81643f,0.74864f,0.66953f,0.59013f,0.5199f,0.45894f,0.40675f,0.33195f}, {1.1345f,1.0508f,0.98171f,1.025f,1.0641f,1.0338f,1.0225f,0.99916f,0.97056f,0.93339f,0.89139f,0.83635f,0.78469f,0.73009f,0.67212f,0.61005f,0.54532f,0.48947f,0.44032f,0.35834f,0.26202f}, {1.0991f,0.99539f,0.93363f,0.88673f,0.87596f,0.86582f,0.84603f,0.83303f,0.80854f,0.78862f,0.77938f,0.75481f,0.72284f,0.68f,0.63167f,0.5811f,0.52714f,0.47047f,0.39384f,0.30564f,0.18259f}, {1.055f,0.92369f,0.87871f,0.81546f,0.76376f,0.75115f,0.72949f,0.71102f,0.68821f,0.67365f,0.67301f,0.67115f,0.66327f,0.63663f,0.59709f,0.55413f,0.50889f,0.44178f,0.34334f,0.25134f,0.095899f}, {1.000000f,0.83591f,0.78647f,0.75537f,0.71687f,0.66409f,0.6465f,0.62204f,0.60461f,0.59334f,0.58736f,0.59237f,0.60009f,0.59098f,0.56249f,0.52623f,0.47673f,0.40808f,0.31875f,0.19708f,0.000000f}, {0.83276f,0.73136f,0.71535f,0.69879f,0.67128f,0.6337f,0.57729f,0.55287f,0.53919f,0.53022f,0.52528f,0.52905f,0.53707f,0.54111f,0.52612f,0.49125f,0.44046f,0.37302f,0.28147f,0.15452f,0.000000f}, {0.64125f,0.62972f,0.64726f,0.6474f,0.63283f,0.60244f,0.55242f,0.50512f,0.49012f,0.4792f,0.47507f,0.47793f,0.48774f,0.49764f,0.49034f,0.45063f,0.39696f,0.32989f,0.24613f,0.13109f,0.000000f}, {0.44064f,0.54301f,0.58208f,0.59439f,0.58983f,0.57111f,0.53563f,0.4895f,0.449f,0.43718f,0.43073f,0.43546f,0.44615f,0.46976f,0.44537f,0.40308f,0.35042f,0.28649f,0.20741f,0.10548f,0.000000f}, {0.22461f,0.46059f,0.5171f,0.53939f,0.54356f,0.53498f,0.51318f,0.47728f,0.4363f,0.39911f,0.39157f,0.39658f,0.43062f,0.42265f,0.3891f,0.3474f,0.29803f,0.23913f,0.16635f,0.07466f,0.000000f}, {0.000000f,0.37491f,0.44793f,0.48022f,0.49255f,0.49144f,0.47954f,0.45833f,0.42655f,0.38828f,0.35707f,0.37405f,0.36841f,0.34862f,0.3211f,0.28535f,0.23875f,0.1856f,0.12032f,0.041971f,0.000000f}, {0.000000f,0.29404f,0.37997f,0.41974f,0.43776f,0.44156f,0.4356f,0.42009f,0.39508f,0.3512f,0.28456f,0.26238f,0.26053f,0.26295f,0.24712f,0.21941f,0.18369f,0.13776f,0.081442f,0.018729f,0.000000f}, {0.000000f,0.20513f,0.30628f,0.35399f,0.37726f,0.38516f,0.38253f,0.3674f,0.33923f,0.2768f,0.21042f,0.17293f,0.17637f,0.18429f,0.17894f,0.15782f,0.12851f,0.090137f,0.044099f,0.0023788f,0.000000f}, {0.000000f,0.10702f,0.22934f,0.28548f,0.31406f,0.32616f,0.32695f,0.31229f,0.26914f,0.20707f,0.14104f,0.10001f,0.09644f,0.12292f,0.1223f,0.10514f,0.080892f,0.049952f,0.015968f,0.000000f,0.000000f}, {0.000000f,0.030939f,0.14915f,0.21889f,0.25331f,0.26639f,0.26955f,0.24102f,0.19708f,0.1414f,0.081769f,0.04018f,0.039392f,0.060989f,0.074445f,0.06227f,0.04532f,0.021639f,0.0010905f,0.000000f,0.000000f}, {0.000000f,0.0034849f,0.076245f,0.14627f,0.18729f,0.21103f,0.18815f,0.15968f,0.12215f,0.077493f,0.033596f,0.0051272f,0.0070705f,0.016667f,0.025139f,0.031985f,0.016921f,0.0032217f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.015871f,0.078648f,0.12649f,0.11765f,0.10373f,0.077089f,0.049467f,0.022632f,0.0031126f,0.000000f,0.000000f,0.000000f,0.0013009f,0.0022061f,0.0024313f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040112f,0.026399f,0.030429f,0.027832f,0.023088f,0.011794f,0.0036134f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_11point1_densewrap_rsb[21][21] = { {0.39528f,0.45681f,0.52303f,0.5952f,0.67043f,0.74939f,0.83048f,0.91024f,0.98682f,1.057f,1.1171f,1.1683f,1.2061f,1.2313f,1.2457f,1.25f,1.2464f,1.2367f,1.2224f,1.2053f,1.1856f}, {0.33058f,0.40718f,0.45818f,0.52008f,0.58928f,0.66875f,0.74761f,0.81551f,0.87989f,0.94409f,1.0051f,1.0545f,1.1006f,1.1428f,1.1756f,1.1839f,1.1749f,1.1545f,1.1257f,1.0916f,1.1633f}, {0.26115f,0.35842f,0.44063f,0.48883f,0.54542f,0.60952f,0.67161f,0.72963f,0.7843f,0.83594f,0.89143f,0.93364f,0.97024f,0.99897f,1.0225f,1.0338f,1.0643f,1.0254f,0.98114f,1.0512f,1.135f}, {0.18334f,0.30498f,0.39398f,0.47073f,0.52673f,0.58068f,0.63196f,0.67962f,0.72234f,0.75459f,0.77925f,0.78892f,0.80854f,0.83344f,0.84641f,0.86582f,0.87633f,0.88628f,0.9341f,0.99597f,1.0988f}, {0.096659f,0.25132f,0.34275f,0.44182f,0.50908f,0.55418f,0.59678f,0.6364f,0.66294f,0.6709f,0.67291f,0.67361f,0.68817f,0.7108f,0.72984f,0.75115f,0.76343f,0.81572f,0.87916f,0.92428f,1.0546f}, {0.000000f,0.19635f,0.31808f,0.4075f,0.47641f,0.52638f,0.56225f,0.59065f,0.60029f,0.59259f,0.58727f,0.59329f,0.60455f,0.62204f,0.64676f,0.66381f,0.71718f,0.75559f,0.78694f,0.83674f,1.000000f}, {0.000000f,0.15428f,0.28088f,0.37331f,0.44047f,0.49127f,0.52623f,0.54126f,0.53704f,0.52904f,0.5252f,0.53004f,0.53902f,0.55281f,0.57709f,0.63371f,0.67137f,0.69903f,0.71575f,0.7319f,0.83403f}, {0.000000f,0.13086f,0.24559f,0.32994f,0.39652f,0.45039f,0.49013f,0.49768f,0.4877f,0.47777f,0.475f,0.47917f,0.4903f,0.50496f,0.55263f,0.60235f,0.63292f,0.64765f,0.64765f,0.63022f,0.64256f}, {0.000000f,0.10504f,0.20691f,0.28618f,0.35012f,0.40283f,0.44506f,0.46986f,0.44618f,0.43543f,0.43067f,0.43704f,0.44885f,0.48946f,0.53558f,0.57138f,0.5899f,0.59455f,0.58249f,0.54359f,0.44198f}, {0.000000f,0.074469f,0.16639f,0.23921f,0.29774f,0.34717f,0.38878f,0.4225f,0.43045f,0.39661f,0.39151f,0.39898f,0.43628f,0.47713f,0.51317f,0.53523f,0.54366f,0.53967f,0.51742f,0.46108f,0.22597f}, {0.000000f,0.042125f,0.1205f,0.18577f,0.2389f,0.28548f,0.32122f,0.34872f,0.36849f,0.37407f,0.35697f,0.38813f,0.42638f,0.45809f,0.4793f,0.49116f,0.49224f,0.47985f,0.44747f,0.37426f,-1.3692e-016f}, {0.000000f,0.01853f,0.081227f,0.13749f,0.18332f,0.21944f,0.2469f,0.26266f,0.26034f,0.26234f,0.28446f,0.35101f,0.39508f,0.42016f,0.43565f,0.44175f,0.43799f,0.42001f,0.38031f,0.29451f,0.000000f}, {0.000000f,0.0024135f,0.044054f,0.089831f,0.12819f,0.15787f,0.17874f,0.18409f,0.17643f,0.17282f,0.21028f,0.27697f,0.33901f,0.36755f,0.38265f,0.38536f,0.37752f,0.35433f,0.30655f,0.20552f,0.000000f}, {0.000000f,0.000000f,0.016013f,0.049808f,0.080755f,0.10486f,0.12234f,0.12304f,0.0965f,0.10005f,0.14085f,0.20722f,0.2693f,0.31205f,0.32713f,0.32642f,0.31428f,0.28576f,0.2296f,0.10737f,0.000000f}, {0.000000f,0.000000f,0.0011106f,0.021725f,0.045206f,0.062127f,0.074563f,0.060842f,0.039245f,0.040165f,0.081549f,0.14161f,0.19728f,0.24121f,0.26928f,0.26662f,0.25356f,0.21909f,0.14945f,0.031188f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0032548f,0.016837f,0.032077f,0.02508f,0.016671f,0.0069915f,0.0051514f,0.033399f,0.077667f,0.12235f,0.15984f,0.18836f,0.21072f,0.18755f,0.1465f,0.076496f,0.0035468f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0024605f,0.0021549f,0.0012606f,0.000000f,0.000000f,0.000000f,0.0030466f,0.022737f,0.049623f,0.077277f,0.10395f,0.11788f,0.12614f,0.078886f,0.016004f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003656f,0.011882f,0.023206f,0.027969f,0.030577f,0.026172f,0.0040704f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.4883e-018f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_ang[] = {-45,-26,0,26,45,-63,63,-90,90,-116,116,-135,135}; static float map_13point1_totalwrap_xsf[] = {-1,-0.5,0,0.5,1,-1,1,-1,1,-1,1,-1,1}; static float map_13point1_totalwrap_ysf[] = {1,1,1,1,1,0.5,0.5,0,0,-0.5,-0.5,-1,-1}; channel_id map_13point1_totalwrap_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_front_left,ci_side_front_right,ci_side_center_left,ci_side_center_right,ci_side_back_left,ci_side_back_right,ci_back_left,ci_back_right,ci_lfe}; static float map_13point1_totalwrap_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.005581f,0.003291f,1.7252e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0081504f,0.042808f,0.072882f,0.060953f,0.042164f,0.017887f,0.0013668f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0027588f,0.054743f,0.091228f,0.091909f,0.082995f,0.079348f,0.071132f,0.040421f,0.0039453f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040396f,0.10257f,0.10193f,0.089276f,0.079333f,0.072621f,0.070291f,0.068709f,0.03606f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0060181f,0.10346f,0.11606f,0.098677f,0.086748f,0.077297f,0.070277f,0.064552f,0.062673f,0.06051f,0.0017892f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.047382f,0.13537f,0.11322f,0.096621f,0.085123f,0.076125f,0.068709f,0.062673f,0.057379f,0.05627f,0.000000f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10632f,0.1408f,0.11333f,0.0968f,0.08448f,0.075551f,0.068329f,0.061952f,0.05632f,0.051341f,0.056303f,0.060536f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.16195f,0.14064f,0.1132f,0.096622f,0.085107f,0.076104f,0.068709f,0.062673f,0.060449f,0.05632f,0.057346f,0.062673f,0.068709f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.194f,0.14507f,0.11609f,0.098677f,0.086764f,0.077297f,0.071771f,0.068005f,0.062673f,0.061952f,0.062673f,0.064514f,0.070277f,0.071028f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.22178f,0.15206f,0.12055f,0.10193f,0.090467f,0.081765f,0.076506f,0.071744f,0.068709f,0.068329f,0.068709f,0.070291f,0.072578f,0.079333f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25576f,0.16273f,0.12661f,0.10766f,0.096098f,0.087435f,0.081735f,0.077297f,0.076125f,0.075551f,0.076104f,0.077297f,0.079348f,0.082947f,0.06067f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {3.1398e-016f,0.28205f,0.17804f,0.13801f,0.11623f,0.10201f,0.096063f,0.090425f,0.086748f,0.085123f,0.08448f,0.085107f,0.086764f,0.089301f,0.091873f,0.072927f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24261f,0.28709f,0.20797f,0.15099f,0.12555f,0.11619f,0.10762f,0.10193f,0.098677f,0.096621f,0.0968f,0.096622f,0.098677f,0.10193f,0.091044f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.46196f,0.29071f,0.21045f,0.16884f,0.15094f,0.13799f,0.12656f,0.12057f,0.11606f,0.11322f,0.11333f,0.1132f,0.11609f,0.10231f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.66287f,0.29364f,0.21289f,0.21045f,0.20789f,0.17806f,0.16273f,0.15206f,0.14511f,0.14066f,0.1408f,0.1352f,0.10303f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.8397f,0.29675f,0.29354f,0.29061f,0.28698f,0.28196f,0.25543f,0.22155f,0.19371f,0.16153f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_13point1_totalwrap_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031891f,0.0054514f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013174f,0.017687f,0.041859f,0.06067f,0.072899f,0.042466f,0.0079947f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003925f,0.040182f,0.071028f,0.079333f,0.082923f,0.091873f,0.091044f,0.054336f,0.0026644f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.036005f,0.068709f,0.070277f,0.072557f,0.079348f,0.089301f,0.10193f,0.10231f,0.040017f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017407f,0.060499f,0.062673f,0.064496f,0.070291f,0.077297f,0.086764f,0.098677f,0.11609f,0.10303f,0.005855f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.000000f,0.056286f,0.057329f,0.062673f,0.068709f,0.076104f,0.085107f,0.096622f,0.1132f,0.1352f,0.046879f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.06051f,0.056286f,0.051311f,0.056286f,0.061915f,0.068289f,0.075506f,0.08443f,0.096742f,0.11326f,0.14072f,0.10645f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040421f,0.068709f,0.062673f,0.057312f,0.056287f,0.060432f,0.062673f,0.068709f,0.076125f,0.085123f,0.096621f,0.11322f,0.14066f,0.16153f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.071132f,0.070291f,0.064476f,0.062673f,0.061916f,0.062673f,0.067986f,0.071744f,0.077297f,0.086748f,0.098677f,0.11606f,0.14511f,0.19371f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.079348f,0.072536f,0.070277f,0.068709f,0.068289f,0.068709f,0.071771f,0.076484f,0.081735f,0.090425f,0.10193f,0.12057f,0.15206f,0.22155f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.060953f,0.082898f,0.079333f,0.077297f,0.076125f,0.075507f,0.076104f,0.077297f,0.081765f,0.087411f,0.096063f,0.10762f,0.12656f,0.16273f,0.25543f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.072826f,0.091909f,0.089276f,0.086748f,0.085123f,0.08443f,0.085107f,0.086764f,0.090467f,0.096098f,0.10198f,0.11619f,0.13799f,0.17806f,0.28196f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.091228f,0.10193f,0.098677f,0.096621f,0.096743f,0.096622f,0.098677f,0.10193f,0.10766f,0.11623f,0.12551f,0.15094f,0.20789f,0.28698f,0.23903f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.10257f,0.11606f,0.11322f,0.11326f,0.1132f,0.11609f,0.12055f,0.12661f,0.13801f,0.15099f,0.16879f,0.21045f,0.29061f,0.4584f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10346f,0.13537f,0.14072f,0.14064f,0.14507f,0.15206f,0.16273f,0.17804f,0.20797f,0.21045f,0.21283f,0.29354f,0.65936f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.16195f,0.194f,0.22178f,0.25576f,0.28205f,0.28709f,0.29071f,0.29364f,0.29667f,0.83624f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_13point1_totalwrap_lsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,1.4883e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040704f,0.026172f,0.030577f,0.027969f,0.023206f,0.011882f,0.003656f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016004f,0.078886f,0.11885f,0.11126f,0.10005f,0.077277f,0.049623f,0.022737f,0.0030466f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0035468f,0.076496f,0.13684f,0.13679f,0.11897f,0.11432f,0.10984f,0.10114f,0.076046f,0.033501f,0.0046306f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.031188f,0.14617f,0.15418f,0.1299f,0.11431f,0.10197f,0.097664f,0.095287f,0.093649f,0.075427f,0.024282f,0.00073159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10737f,0.1817f,0.1484f,0.12564f,0.10986f,0.097669f,0.089224f,0.086605f,0.08469f,0.083965f,0.048387f,0.004605f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19838f,0.17849f,0.14282f,0.12164f,0.1068f,0.095276f,0.0866f,0.07931f,0.077259f,0.076129f,0.058978f,0.0048965f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23832f,0.17313f,0.13935f,0.11911f,0.10488f,0.093632f,0.084699f,0.077251f,0.070498f,0.069208f,0.041647f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.3692e-016f,0.24833f,0.17308f,0.13931f,0.11899f,0.10385f,0.092873f,0.083996f,0.076156f,0.069233f,0.063102f,0.05511f,0.019286f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22597f,0.25121f,0.17526f,0.1413f,0.12102f,0.1069f,0.095882f,0.087318f,0.080638f,0.070515f,0.069221f,0.070532f,0.07488f,0.032609f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44198f,0.26542f,0.18277f,0.14664f,0.1254f,0.11069f,0.099453f,0.088959f,0.07933f,0.077251f,0.076144f,0.077259f,0.079348f,0.070283f,0.013958f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64256f,0.2947f,0.1939f,0.15413f,0.13115f,0.11353f,0.099577f,0.089246f,0.0866f,0.084699f,0.083982f,0.08469f,0.086605f,0.085004f,0.039295f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83403f,0.33937f,0.20938f,0.16007f,0.13344f,0.11606f,0.102f,0.097669f,0.095276f,0.093632f,0.092858f,0.093649f,0.095287f,0.088683f,0.054552f,0.0013532f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35937f,0.22225f,0.16947f,0.13938f,0.11899f,0.11431f,0.10986f,0.1068f,0.10488f,0.10383f,0.10487f,0.10415f,0.081353f,0.034375f,0.0043588f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.7669f,0.35542f,0.25327f,0.18049f,0.14646f,0.13768f,0.1299f,0.12564f,0.12164f,0.11911f,0.11897f,0.11747f,0.098408f,0.05387f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55102f,0.34365f,0.25072f,0.19696f,0.17861f,0.1657f,0.15445f,0.1484f,0.14282f,0.13935f,0.13074f,0.10642f,0.058689f,0.012407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34893f,0.32425f,0.24834f,0.24599f,0.23588f,0.21001f,0.1922f,0.1745f,0.1548f,0.12874f,0.085642f,0.036985f,0.0041976f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.16741f,0.30017f,0.27214f,0.23269f,0.17995f,0.11341f,0.070758f,0.057469f,0.038068f,0.013988f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_rsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0036134f,0.011794f,0.023088f,0.027832f,0.030429f,0.026399f,0.0040112f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031126f,0.022632f,0.049467f,0.077089f,0.099949f,0.11118f,0.11911f,0.078648f,0.015871f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045869f,0.033596f,0.075931f,0.10117f,0.10998f,0.11448f,0.11916f,0.13692f,0.13673f,0.076245f,0.0034849f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00071455f,0.024189f,0.075553f,0.093753f,0.095409f,0.097805f,0.10214f,0.11445f,0.13006f,0.15434f,0.14595f,0.030939f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045638f,0.04826f,0.084116f,0.084794f,0.086729f,0.089374f,0.097788f,0.10998f,0.12579f,0.14861f,0.18178f,0.10702f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0049397f,0.058905f,0.076265f,0.077358f,0.079443f,0.086706f,0.095393f,0.10693f,0.1218f,0.14297f,0.17876f,0.19813f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041705f,0.069332f,0.070616f,0.077346f,0.084808f,0.093775f,0.10503f,0.11926f,0.13955f,0.17338f,0.23845f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.128e-019f,0.019251f,0.055118f,0.063203f,0.069332f,0.076265f,0.084116f,0.093006f,0.104f,0.11916f,0.13951f,0.17333f,0.24869f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,2.262e-005f,0.032844f,0.075002f,0.070621f,0.069332f,0.070599f,0.080737f,0.087417f,0.095981f,0.10702f,0.12116f,0.14146f,0.17546f,0.2515f,0.22461f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014122f,0.070466f,0.079449f,0.077358f,0.076265f,0.077346f,0.079424f,0.089097f,0.099575f,0.11084f,0.12555f,0.14685f,0.18296f,0.26573f,0.44064f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039567f,0.085048f,0.086729f,0.084794f,0.084116f,0.084808f,0.086706f,0.089352f,0.099732f,0.11371f,0.13131f,0.1543f,0.19413f,0.29503f,0.64125f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0014071f,0.054512f,0.088881f,0.095409f,0.093753f,0.093007f,0.093775f,0.095393f,0.097788f,0.10212f,0.11625f,0.13365f,0.16031f,0.20963f,0.33985f,0.83276f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043373f,0.034659f,0.08163f,0.10433f,0.105f,0.104f,0.10503f,0.10693f,0.10998f,0.11445f,0.11914f,0.1396f,0.16971f,0.22252f,0.35981f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.054219f,0.098665f,0.11764f,0.11916f,0.11926f,0.1218f,0.12579f,0.13006f,0.13785f,0.14663f,0.18077f,0.25367f,0.35599f,0.77038f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012593f,0.059121f,0.10673f,0.13084f,0.13955f,0.14297f,0.14861f,0.15464f,0.1659f,0.17883f,0.19719f,0.25106f,0.3443f,0.55456f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043097f,0.037335f,0.085557f,0.12916f,0.1552f,0.17483f,0.19253f,0.21041f,0.2363f,0.24639f,0.24863f,0.32498f,0.3525f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.6987e-018f,0.014261f,0.038514f,0.058048f,0.071419f,0.11435f,0.18086f,0.23352f,0.27289f,0.30018f,0.171f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.4828e-016f}}; static float map_13point1_totalwrap_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.057837f,0.033725f,0.014056f,0.0021284f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088781f,0.15197f,0.1126f,0.075079f,0.081035f,0.065091f,0.049131f,0.030154f,0.01248f,0.00065038f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13136f,0.19047f,0.19972f,0.18761f,0.17365f,0.15926f,0.13948f,0.11522f,0.080258f,0.038352f,0.011632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1876f,0.22622f,0.20877f,0.17308f,0.16259f,0.15331f,0.14824f,0.14136f,0.12698f,0.096228f,0.051224f,0.013903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25386f,0.24792f,0.19549f,0.16259f,0.14063f,0.13492f,0.12979f,0.12612f,0.12377f,0.11836f,0.09054f,0.040513f,0.0077516f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18322f,0.31647f,0.23665f,0.18234f,0.15331f,0.13491f,0.12054f,0.11534f,0.11241f,0.11063f,0.10978f,0.10408f,0.067907f,0.021737f,0.00081869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.38445f,0.33396f,0.22305f,0.17613f,0.14823f,0.12977f,0.11534f,0.10547f,0.10221f,0.099919f,0.099291f,0.099924f,0.076689f,0.027385f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58627f,0.31272f,0.21469f,0.17128f,0.14518f,0.12698f,0.11241f,0.1022f,0.093751f,0.091147f,0.090023f,0.091143f,0.07194f,0.010076f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79404f,0.30169f,0.2101f,0.16888f,0.14394f,0.12647f,0.11263f,0.10109f,0.091143f,0.083334f,0.081839f,0.083344f,0.027665f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.30431f,0.2121f,0.17071f,0.14582f,0.12726f,0.11381f,0.10293f,0.093322f,0.084838f,0.074566f,0.014386f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79277f,0.30166f,0.21008f,0.16887f,0.14393f,0.12645f,0.11261f,0.10108f,0.091147f,0.083312f,0.081796f,0.083334f,0.02757f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58496f,0.31272f,0.21465f,0.17129f,0.14517f,0.12697f,0.11241f,0.10221f,0.093725f,0.091143f,0.089976f,0.091147f,0.071938f,0.010015f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3831f,0.33384f,0.22305f,0.17611f,0.14824f,0.12979f,0.11534f,0.10544f,0.1022f,0.099924f,0.099238f,0.099919f,0.076598f,0.027407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18186f,0.31619f,0.23666f,0.18235f,0.15331f,0.13492f,0.1205f,0.11534f,0.11241f,0.11064f,0.10973f,0.10402f,0.06778f,0.021645f,0.00081784f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25335f,0.24781f,0.1955f,0.16259f,0.14059f,0.13491f,0.12977f,0.12612f,0.12378f,0.11834f,0.090417f,0.040382f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1871f,0.22597f,0.20873f,0.17303f,0.16259f,0.15331f,0.14823f,0.14133f,0.12691f,0.096247f,0.051065f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13094f,0.19014f,0.19982f,0.18747f,0.17352f,0.15913f,0.13934f,0.11502f,0.08005f,0.038463f,0.011549f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088435f,0.15238f,0.11227f,0.074803f,0.080771f,0.064857f,0.048933f,0.030007f,0.012387f,0.00062972f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.05808f,0.033499f,0.013912f,0.0020664f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0020664f,0.013912f,0.033499f,0.058195f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062972f,0.012387f,0.030007f,0.048933f,0.064857f,0.080771f,0.074803f,0.11227f,0.15246f,0.088435f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011549f,0.038509f,0.08005f,0.11502f,0.13934f,0.15913f,0.17352f,0.18747f,0.19989f,0.19014f,0.13094f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013816f,0.051065f,0.096286f,0.12691f,0.14133f,0.14823f,0.15331f,0.16259f,0.17308f,0.20873f,0.22597f,0.1871f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0076928f,0.040382f,0.090417f,0.11837f,0.12378f,0.12612f,0.12977f,0.13491f,0.14063f,0.16259f,0.1955f,0.24781f,0.25335f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00081784f,0.021645f,0.06778f,0.10402f,0.10977f,0.11064f,0.11241f,0.11534f,0.12054f,0.13492f,0.15331f,0.18235f,0.23666f,0.31619f,0.18186f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027451f,0.076598f,0.099919f,0.099281f,0.099924f,0.1022f,0.10547f,0.11534f,0.12979f,0.14824f,0.17611f,0.22305f,0.33384f,0.3831f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010015f,0.071952f,0.091147f,0.090014f,0.091143f,0.093752f,0.10221f,0.11241f,0.12697f,0.14517f,0.17129f,0.21465f,0.31272f,0.58496f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.02757f,0.083335f,0.081831f,0.083335f,0.091147f,0.10108f,0.11261f,0.12645f,0.14393f,0.16887f,0.21008f,0.30166f,0.79277f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014385f,0.074587f,0.084862f,0.093348f,0.10296f,0.11384f,0.12729f,0.14586f,0.17076f,0.21215f,0.30439f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027665f,0.083335f,0.08182f,0.083335f,0.091143f,0.10109f,0.11263f,0.12647f,0.14394f,0.16888f,0.2101f,0.30169f,0.79404f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010076f,0.071837f,0.091143f,0.090002f,0.091147f,0.093752f,0.1022f,0.11241f,0.12698f,0.14518f,0.17128f,0.21469f,0.31272f,0.58627f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027311f,0.076689f,0.099924f,0.099267f,0.099919f,0.10221f,0.10547f,0.11534f,0.12977f,0.14823f,0.17613f,0.22305f,0.33396f,0.38445f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080127f,0.021737f,0.067907f,0.10408f,0.10976f,0.11063f,0.11241f,0.11534f,0.12054f,0.13491f,0.15331f,0.18234f,0.23665f,0.31647f,0.18322f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0077516f,0.040513f,0.09054f,0.11831f,0.12377f,0.12612f,0.12979f,0.13492f,0.14063f,0.16259f,0.19549f,0.24792f,0.25386f,-2.2204e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.22e-018f,0.013903f,0.051224f,0.096055f,0.12698f,0.14136f,0.14824f,0.15331f,0.16259f,0.17308f,0.20877f,0.22622f,0.1876f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011632f,0.038283f,0.080258f,0.11522f,0.13948f,0.15926f,0.17365f,0.18761f,0.19965f,0.19047f,0.13136f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062082f,0.01248f,0.030154f,0.049131f,0.065091f,0.081035f,0.075079f,0.1126f,0.15189f,0.088781f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0021284f,0.014056f,0.033725f,0.05778f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_lsb[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17101f,0.3002f,0.27289f,0.23302f,0.18086f,0.11435f,0.071419f,0.058048f,0.038514f,0.013902f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3511f,0.3244f,0.24861f,0.24639f,0.23594f,0.21041f,0.19253f,0.17483f,0.1552f,0.12916f,0.08561f,0.037085f,0.0043097f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55452f,0.3443f,0.25064f,0.19717f,0.17883f,0.1659f,0.15438f,0.14861f,0.14297f,0.13955f,0.13083f,0.10653f,0.059121f,0.012378f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.77038f,0.35549f,0.25367f,0.18047f,0.14661f,0.13765f,0.13006f,0.12579f,0.1218f,0.11926f,0.11904f,0.11764f,0.098665f,0.054219f,0.012206f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35981f,0.22252f,0.16971f,0.1396f,0.11912f,0.11445f,0.10998f,0.10677f,0.10488f,0.10389f,0.105f,0.10433f,0.08163f,0.034493f,0.0043086f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83276f,0.33985f,0.20963f,0.16005f,0.13346f,0.11608f,0.10211f,0.097647f,0.095393f,0.093775f,0.092909f,0.093753f,0.095409f,0.088881f,0.054543f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64125f,0.29503f,0.19413f,0.15408f,0.13131f,0.11371f,0.099732f,0.089343f,0.086706f,0.084808f,0.084028f,0.084794f,0.086604f,0.085015f,0.039425f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44064f,0.26573f,0.18296f,0.14685f,0.12555f,0.11084f,0.099575f,0.088972f,0.079416f,0.077346f,0.076185f,0.077358f,0.079366f,0.070466f,0.014122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22461f,0.2515f,0.17521f,0.14126f,0.12116f,0.10702f,0.095981f,0.087417f,0.080737f,0.070592f,0.06926f,0.070547f,0.075002f,0.032844f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.24865f,0.1733f,0.13949f,0.11914f,0.10398f,0.09299f,0.084101f,0.076252f,0.06932f,0.063198f,0.055167f,0.019305f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23845f,0.17338f,0.13955f,0.11926f,0.10488f,0.093775f,0.084808f,0.077346f,0.070615f,0.069326f,0.041681f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19813f,0.17876f,0.14297f,0.1218f,0.10677f,0.095393f,0.086706f,0.079442f,0.077358f,0.076259f,0.058905f,0.0049261f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10702f,0.18178f,0.14861f,0.12579f,0.10998f,0.097647f,0.089373f,0.086604f,0.084794f,0.084109f,0.04826f,0.0045638f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.030939f,0.14595f,0.15412f,0.13006f,0.11445f,0.10214f,0.097805f,0.095409f,0.093753f,0.075568f,0.024189f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0034849f,0.076245f,0.13673f,0.13678f,0.11916f,0.11432f,0.10998f,0.10117f,0.075931f,0.033596f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.015871f,0.078648f,0.11911f,0.11118f,0.099949f,0.077089f,0.049467f,0.022632f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040112f,0.026399f,0.030429f,0.027832f,0.023088f,0.011794f,0.0036134f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_rsb[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013988f,0.038068f,0.057469f,0.070758f,0.11341f,0.17995f,0.23269f,0.27214f,0.30022f,0.16743f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0041976f,0.036985f,0.085724f,0.12874f,0.1548f,0.1745f,0.1922f,0.21001f,0.23588f,0.24599f,0.24837f,0.32425f,0.34893f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012407f,0.058689f,0.10642f,0.13076f,0.13935f,0.14282f,0.1484f,0.15445f,0.1657f,0.17861f,0.19698f,0.25072f,0.34365f,0.55098f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012211f,0.05387f,0.098408f,0.11747f,0.11899f,0.11911f,0.12164f,0.12564f,0.1299f,0.13768f,0.14648f,0.18049f,0.25327f,0.35542f,0.7669f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043588f,0.034375f,0.081353f,0.10415f,0.10487f,0.10385f,0.10488f,0.1068f,0.10986f,0.11431f,0.11901f,0.13938f,0.16947f,0.22225f,0.35937f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.054576f,0.088683f,0.095287f,0.093649f,0.092871f,0.093632f,0.095276f,0.097669f,0.10201f,0.11606f,0.13344f,0.16007f,0.20938f,0.33937f,0.83403f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039295f,0.084981f,0.086605f,0.08469f,0.083994f,0.084699f,0.0866f,0.089259f,0.099577f,0.11353f,0.13115f,0.15413f,0.1939f,0.2947f,0.64256f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.070283f,0.079341f,0.077259f,0.076154f,0.077251f,0.079341f,0.088959f,0.099453f,0.11069f,0.1254f,0.14664f,0.18277f,0.26542f,0.44198f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.07488f,0.070525f,0.069231f,0.070525f,0.080638f,0.087318f,0.095882f,0.1069f,0.12102f,0.1413f,0.17526f,0.25121f,0.22597f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.019304f,0.055126f,0.063107f,0.069231f,0.076154f,0.083994f,0.092871f,0.10385f,0.11899f,0.13931f,0.17308f,0.24833f,-1.3692e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041554f,0.069226f,0.070525f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.17313f,0.23832f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0048829f,0.058978f,0.076149f,0.077259f,0.079341f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.17849f,0.19838f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.004605f,0.048387f,0.083988f,0.08469f,0.086605f,0.089259f,0.097669f,0.10986f,0.12564f,0.1484f,0.1817f,0.10737f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.024282f,0.075363f,0.093649f,0.095287f,0.097664f,0.10201f,0.11431f,0.1299f,0.15418f,0.14617f,0.031188f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.033399f,0.076046f,0.10114f,0.10984f,0.11432f,0.11901f,0.13679f,0.13684f,0.076496f,0.0035468f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0030466f,0.022737f,0.049623f,0.077277f,0.10005f,0.11126f,0.11884f,0.078886f,0.016004f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003656f,0.011882f,0.023206f,0.027969f,0.030577f,0.026172f,0.0040704f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.4883e-018f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_ls[21][21] = { {1.000000f,0.99863f,0.99396f,0.98481f,0.9703f,0.94888f,0.91914f,0.88048f,0.83195f,0.77384f,0.70834f,0.63338f,0.55484f,0.47562f,0.39394f,0.3173f,0.24362f,0.17537f,0.11147f,0.054079f,-7.8496e-017f}, {0.8363f,0.62244f,0.66382f,0.70947f,0.7566f,0.80329f,0.81123f,0.77152f,0.72989f,0.68929f,0.63602f,0.56664f,0.49969f,0.43164f,0.36121f,0.29703f,0.24559f,0.20208f,0.16581f,0.13592f,0.000000f}, {0.66065f,0.57579f,0.55614f,0.58407f,0.61318f,0.58842f,0.57511f,0.55144f,0.52699f,0.51049f,0.50982f,0.50391f,0.48267f,0.43211f,0.3753f,0.31848f,0.25563f,0.21817f,0.18628f,0.11031f,0.000000f}, {0.45837f,0.52122f,0.52335f,0.50536f,0.49487f,0.48047f,0.45645f,0.43846f,0.42171f,0.41094f,0.41034f,0.40976f,0.41927f,0.41689f,0.38061f,0.33006f,0.27965f,0.22857f,0.15778f,0.083896f,0.000000f}, {0.23903f,0.45956f,0.48458f,0.46274f,0.42459f,0.40691f,0.38394f,0.3711f,0.35896f,0.35106f,0.3505f,0.34986f,0.35659f,0.36762f,0.36529f,0.33185f,0.28785f,0.21842f,0.12802f,0.058746f,0.000000f}, {0.000000f,0.38957f,0.43442f,0.42679f,0.39709f,0.35204f,0.33794f,0.32485f,0.31551f,0.30928f,0.30589f,0.30802f,0.31303f,0.32135f,0.33266f,0.32299f,0.2697f,0.20197f,0.12403f,0.03616f,0.000000f}, {0.000000f,0.32257f,0.39095f,0.39305f,0.37103f,0.33625f,0.30175f,0.28885f,0.28142f,0.27645f,0.27356f,0.27506f,0.27878f,0.2852f,0.29725f,0.30114f,0.24789f,0.18361f,0.10709f,0.022585f,0.000000f}, {0.000000f,0.27608f,0.35222f,0.3637f,0.35047f,0.32132f,0.28699f,0.26403f,0.25596f,0.24994f,0.24741f,0.24829f,0.25299f,0.26009f,0.28462f,0.27305f,0.21805f,0.15706f,0.090176f,0.018356f,0.000000f}, {0.000000f,0.22983f,0.3132f,0.33406f,0.32977f,0.30936f,0.27746f,0.25371f,0.2347f,0.22818f,0.22432f,0.22604f,0.23119f,0.25225f,0.2713f,0.23683f,0.18569f,0.13031f,0.070512f,0.012179f,0.000000f}, {0.000000f,0.1748f,0.27173f,0.30205f,0.30659f,0.29628f,0.27295f,0.24664f,0.22496f,0.20862f,0.20393f,0.2055f,0.22497f,0.24663f,0.23725f,0.19424f,0.14921f,0.10103f,0.049741f,0.0045097f,0.000000f}, {0.000000f,0.10645f,0.22243f,0.2645f,0.27871f,0.27734f,0.2652f,0.24483f,0.22198f,0.2018f,0.18593f,0.20175f,0.22052f,0.21252f,0.18253f,0.14834f,0.1086f,0.068513f,0.027472f,-8.5322e-019f,0.000000f}, {0.000000f,0.046879f,0.1703f,0.22233f,0.24418f,0.25003f,0.24622f,0.23507f,0.21914f,0.1964f,0.13618f,0.12075f,0.14674f,0.14347f,0.12638f,0.10174f,0.073541f,0.042039f,0.011806f,0.000000f,0.000000f}, {0.000000f,0.005855f,0.10701f,0.17178f,0.20181f,0.21417f,0.21587f,0.20809f,0.19221f,0.15321f,0.084892f,0.045091f,0.080618f,0.086082f,0.07899f,0.061737f,0.041097f,0.018696f,0.0013628f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040017f,0.11409f,0.15305f,0.17193f,0.17885f,0.17256f,0.14411f,0.09965f,0.036025f,0.010386f,0.029455f,0.046248f,0.043546f,0.03134f,0.017152f,0.0039822f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0026644f,0.054553f,0.10263f,0.12449f,0.13524f,0.11662f,0.084273f,0.040182f,0.003925f,7.153e-006f,0.0044657f,0.012512f,0.017789f,0.01096f,0.0039191f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0079947f,0.042595f,0.077006f,0.062112f,0.041859f,0.017687f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.00044495f,0.0013625f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0062247f,0.0054514f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_13point1_totalwrap_rs[21][21] = { {-7.8496e-017f,0.052336f,0.10973f,0.17365f,0.24192f,0.31565f,0.39394f,0.47409f,0.55484f,0.63338f,0.70587f,0.77384f,0.83195f,0.87965f,0.91914f,0.94832f,0.96987f,0.9845f,0.99377f,0.99854f,1.000000f}, {0.000000f,0.13583f,0.16489f,0.20208f,0.24451f,0.29589f,0.35999f,0.43048f,0.49857f,0.56633f,0.63558f,0.68855f,0.72945f,0.77133f,0.81125f,0.80371f,0.75713f,0.70995f,0.66449f,0.62205f,0.83976f}, {0.000000f,0.11031f,0.18615f,0.21738f,0.25552f,0.31761f,0.37444f,0.43128f,0.48199f,0.50346f,0.50942f,0.51076f,0.52673f,0.55121f,0.57501f,0.58851f,0.61339f,0.58448f,0.55581f,0.5763f,0.66287f}, {0.000000f,0.083257f,0.15778f,0.22845f,0.27908f,0.32934f,0.38061f,0.4164f,0.41906f,0.40951f,0.41002f,0.41117f,0.42148f,0.4387f,0.45663f,0.48036f,0.49514f,0.50506f,0.52368f,0.52214f,0.46192f}, {0.000000f,0.058746f,0.12737f,0.2183f,0.28772f,0.33167f,0.36488f,0.36741f,0.35639f,0.34967f,0.35023f,0.35086f,0.35876f,0.3709f,0.38414f,0.4067f,0.4243f,0.46285f,0.48512f,0.46015f,0.24261f}, {0.000000f,0.035717f,0.12342f,0.20135f,0.26927f,0.32283f,0.33242f,0.32118f,0.3132f,0.30818f,0.30565f,0.30912f,0.31533f,0.32468f,0.33811f,0.35174f,0.39734f,0.42692f,0.43484f,0.39053f,0.000000f}, {0.000000f,0.022264f,0.10655f,0.18361f,0.24774f,0.30104f,0.29712f,0.28536f,0.27862f,0.2749f,0.27335f,0.27632f,0.28126f,0.28868f,0.3015f,0.33609f,0.37098f,0.39328f,0.39132f,0.32351f,0.000000f}, {0.000000f,0.018075f,0.089694f,0.15698f,0.21753f,0.27257f,0.28445f,0.25998f,0.25285f,0.24815f,0.24722f,0.2498f,0.25609f,0.26381f,0.28717f,0.32119f,0.35044f,0.36381f,0.35258f,0.27684f,0.000000f}, {0.000000f,0.011962f,0.070085f,0.12983f,0.1852f,0.2365f,0.27104f,0.25238f,0.2311f,0.22591f,0.22415f,0.22805f,0.2345f,0.25358f,0.2773f,0.30954f,0.32979f,0.33426f,0.31358f,0.23053f,0.000000f}, {0.000000f,0.0043772f,0.049741f,0.10103f,0.14876f,0.19392f,0.23686f,0.24649f,0.22485f,0.20542f,0.20377f,0.20844f,0.22484f,0.2465f,0.2728f,0.29644f,0.30666f,0.30224f,0.27197f,0.17548f,0.000000f}, {0.000000f,-8.5322e-019f,0.027447f,0.068465f,0.10853f,0.14825f,0.18244f,0.21244f,0.22045f,0.20168f,0.18582f,0.20163f,0.22179f,0.24462f,0.26501f,0.27715f,0.27854f,0.26434f,0.22224f,0.1062f,0.000000f}, {0.000000f,0.000000f,0.011636f,0.041753f,0.073199f,0.1017f,0.12602f,0.14312f,0.14641f,0.1207f,0.1361f,0.19627f,0.2191f,0.23505f,0.24628f,0.25015f,0.24438f,0.22266f,0.17079f,0.047382f,0.000000f}, {0.000000f,0.000000f,0.0013084f,0.018492f,0.040831f,0.061737f,0.07868f,0.085813f,0.080572f,0.044927f,0.084809f,0.15335f,0.1921f,0.20822f,0.21599f,0.21432f,0.20208f,0.17215f,0.10754f,0.0060181f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0038919f,0.016973f,0.031114f,0.043546f,0.046224f,0.029455f,0.010272f,0.03594f,0.099867f,0.14424f,0.17246f,0.17899f,0.17218f,0.15337f,0.11452f,0.040396f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0038302f,0.010822f,0.017781f,0.01238f,0.0043862f,-3.2171e-019f,0.0039004f,0.040442f,0.084529f,0.11688f,0.13513f,0.12479f,0.10298f,0.054743f,0.0027588f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013625f,0.00044495f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.017887f,0.042164f,0.062288f,0.076885f,0.042808f,0.0081504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.005581f,0.0061507f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_ang[] = {-45,-26,0,26,45,-63,63,-90,90,-116,116,-135,-153,180,153,135}; static float map_16point1_xsf[] = {-1,-0.5,0,0.5,1,-1,1,-1,1,-1,1,-1,-0.5,0,0.5,1}; static float map_16point1_ysf[] = {1,1,1,1,1,0.5,0.5,0,0,-0.5,-0.5,-1,-1,-1,-1,-1}; channel_id map_16point1_id[] = {ci_front_left,ci_front_center_left,ci_front_center,ci_front_center_right,ci_front_right,ci_side_front_left,ci_side_front_right,ci_side_center_left,ci_side_center_right,ci_side_back_left,ci_side_back_right,ci_back_left,ci_back_center_left,ci_back_center,ci_back_center_right,ci_back_right,ci_lfe}; static float map_16point1_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.005581f,0.003291f,1.7252e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0081504f,0.042808f,0.072882f,0.060953f,0.042164f,0.017887f,0.0013668f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0027588f,0.054743f,0.091228f,0.091909f,0.082995f,0.079348f,0.071132f,0.040421f,0.0039453f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040396f,0.10257f,0.10193f,0.089276f,0.079333f,0.072621f,0.070291f,0.068709f,0.03606f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0060181f,0.10346f,0.11606f,0.098677f,0.086748f,0.077297f,0.070277f,0.064552f,0.062673f,0.06051f,0.0017892f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.047382f,0.13537f,0.11322f,0.096621f,0.085123f,0.076125f,0.068709f,0.062673f,0.057379f,0.05627f,0.000000f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10632f,0.1408f,0.11333f,0.0968f,0.08448f,0.075551f,0.068329f,0.061952f,0.05632f,0.051341f,0.056303f,0.060536f,0.036045f,0.0039474f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.16195f,0.14064f,0.1132f,0.096622f,0.085107f,0.076104f,0.068709f,0.062673f,0.060449f,0.05632f,0.057346f,0.062673f,0.068709f,0.040182f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.194f,0.14507f,0.11609f,0.098677f,0.086764f,0.077297f,0.071771f,0.068005f,0.062673f,0.061952f,0.062673f,0.064514f,0.070277f,0.071028f,0.017687f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.22178f,0.15206f,0.12055f,0.10193f,0.090467f,0.081765f,0.076506f,0.071744f,0.068709f,0.068329f,0.068709f,0.070291f,0.072578f,0.079333f,0.041859f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25576f,0.16273f,0.12661f,0.10766f,0.096098f,0.087435f,0.081735f,0.077297f,0.076125f,0.075551f,0.076104f,0.077297f,0.079348f,0.082947f,0.06067f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f}, {3.1398e-016f,0.28205f,0.17804f,0.13801f,0.11623f,0.10201f,0.096063f,0.090425f,0.086748f,0.085123f,0.08448f,0.085107f,0.086764f,0.089301f,0.091873f,0.072927f,0.0054514f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24261f,0.28709f,0.20797f,0.15099f,0.12555f,0.11619f,0.10762f,0.10193f,0.098677f,0.096621f,0.0968f,0.096622f,0.098677f,0.10193f,0.091044f,0.042466f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.46196f,0.29071f,0.21045f,0.16884f,0.15094f,0.13799f,0.12656f,0.12057f,0.11606f,0.11322f,0.11333f,0.1132f,0.11609f,0.10231f,0.054336f,0.0079947f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.66287f,0.29364f,0.21289f,0.21045f,0.20789f,0.17806f,0.16273f,0.15206f,0.14511f,0.14066f,0.1408f,0.1352f,0.10303f,0.040017f,0.0026644f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.8397f,0.29675f,0.29354f,0.29061f,0.28698f,0.28196f,0.25543f,0.22155f,0.19371f,0.16153f,0.10657f,0.046879f,0.005855f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.8363f,0.65936f,0.4584f,0.23903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_lcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043086f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.034659f,0.054439f,0.039567f,0.014122f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012593f,0.054219f,0.08163f,0.088881f,0.085013f,0.070466f,0.032844f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0043097f,0.059121f,0.098665f,0.10433f,0.095409f,0.086729f,0.079418f,0.075002f,0.019323f,0.000000f,0.0049397f,0.0045638f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.037335f,0.10673f,0.11764f,0.105f,0.093753f,0.084794f,0.077358f,0.070593f,0.05521f,0.041727f,0.058905f,0.04826f,0.024189f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,2.6987e-018f,0.0855f,0.13077f,0.11909f,0.10393f,0.092946f,0.084061f,0.076215f,0.069287f,0.063193f,0.069321f,0.076253f,0.084102f,0.07556f,0.033596f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.014261f,0.12916f,0.13955f,0.11926f,0.10503f,0.093775f,0.084808f,0.077346f,0.070604f,0.069321f,0.070582f,0.077358f,0.084794f,0.093753f,0.075931f,0.022632f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038514f,0.1552f,0.14297f,0.1218f,0.10693f,0.095393f,0.086706f,0.07943f,0.080737f,0.076253f,0.077346f,0.079405f,0.086729f,0.095409f,0.10117f,0.049467f,0.0036134f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.058048f,0.17483f,0.14861f,0.12579f,0.10998f,0.097788f,0.089359f,0.089097f,0.087417f,0.084102f,0.084808f,0.086706f,0.08933f,0.097805f,0.10998f,0.077089f,0.011794f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.071419f,0.19253f,0.15464f,0.13006f,0.11445f,0.10212f,0.099732f,0.099575f,0.095981f,0.092991f,0.093775f,0.095393f,0.097788f,0.10209f,0.11448f,0.099949f,0.023088f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11435f,0.21041f,0.1659f,0.13785f,0.11915f,0.11625f,0.11371f,0.11084f,0.10702f,0.10398f,0.10503f,0.10693f,0.10998f,0.11445f,0.11911f,0.11118f,0.027832f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.18086f,0.2363f,0.17883f,0.14664f,0.1396f,0.13365f,0.13131f,0.12555f,0.12116f,0.11915f,0.11926f,0.1218f,0.12579f,0.13006f,0.13692f,0.11911f,0.030429f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23352f,0.24639f,0.19721f,0.18077f,0.16971f,0.16031f,0.1543f,0.14685f,0.14146f,0.13949f,0.13955f,0.14297f,0.14861f,0.15434f,0.13673f,0.078648f,0.026399f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27289f,0.24865f,0.25106f,0.25367f,0.22252f,0.20963f,0.19413f,0.18296f,0.17546f,0.1733f,0.17338f,0.17876f,0.18178f,0.14595f,0.076245f,0.015871f,0.0040112f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.30021f,0.32498f,0.3443f,0.35599f,0.35981f,0.33985f,0.29503f,0.26573f,0.2515f,0.24865f,0.23845f,0.19813f,0.10702f,0.030939f,0.0034849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {2.4828e-016f,0.17101f,0.3525f,0.55456f,0.77038f,1.000000f,0.83276f,0.64125f,0.44064f,0.22461f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,-6.1001e-019f,0.0077516f,0.021737f,0.027281f,0.010076f,0.000000f,0.000000f,0.000000f,0.010015f,0.027391f,0.021645f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013903f,0.040513f,0.067907f,0.076689f,0.07181f,0.027665f,0.000000f,0.02757f,0.071899f,0.076598f,0.06778f,0.040382f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011632f,0.051224f,0.09054f,0.10408f,0.099924f,0.091143f,0.083276f,0.01435f,0.083264f,0.091147f,0.099919f,0.10402f,0.090417f,0.051065f,0.011549f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00059126f,0.038282f,0.096055f,0.11827f,0.1097f,0.09921f,0.089951f,0.081773f,0.077286f,0.08175f,0.089925f,0.099183f,0.10967f,0.11828f,0.096188f,0.038438f,0.00060016f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.01248f,0.080258f,0.12698f,0.12377f,0.11063f,0.099919f,0.091147f,0.083264f,0.08478f,0.083287f,0.091143f,0.099924f,0.11064f,0.12378f,0.12691f,0.08005f,0.012387f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030154f,0.11522f,0.14136f,0.12612f,0.11241f,0.10221f,0.093672f,0.091143f,0.093258f,0.091147f,0.093698f,0.1022f,0.11241f,0.12612f,0.14133f,0.11502f,0.030007f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.049131f,0.13948f,0.14824f,0.12979f,0.11534f,0.10538f,0.1022f,0.10109f,0.10286f,0.10108f,0.10221f,0.10541f,0.11534f,0.12977f,0.14823f,0.13934f,0.048933f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.065091f,0.15926f,0.15331f,0.13492f,0.12044f,0.11534f,0.11241f,0.11263f,0.11373f,0.11261f,0.11241f,0.11534f,0.12047f,0.13491f,0.15331f,0.15913f,0.064857f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.081035f,0.17365f,0.16259f,0.14051f,0.13491f,0.12977f,0.12698f,0.12647f,0.12717f,0.12645f,0.12697f,0.12979f,0.13492f,0.14055f,0.16259f,0.17352f,0.080771f,0.000000f,0.000000f}, {0.000000f,0.0021284f,0.075079f,0.18761f,0.17293f,0.16259f,0.15331f,0.14823f,0.14518f,0.14394f,0.14572f,0.14393f,0.14517f,0.14824f,0.15331f,0.16259f,0.17298f,0.18747f,0.074803f,0.0020664f,0.000000f}, {0.000000f,0.014056f,0.1126f,0.19956f,0.20877f,0.19549f,0.18234f,0.17613f,0.17128f,0.16888f,0.17059f,0.16887f,0.17129f,0.17611f,0.18235f,0.1955f,0.20873f,0.19976f,0.11227f,0.013912f,0.000000f}, {0.000000f,0.033725f,0.15181f,0.19047f,0.22622f,0.24792f,0.23665f,0.22305f,0.21469f,0.2101f,0.21195f,0.21008f,0.21465f,0.22305f,0.23666f,0.24781f,0.22597f,0.19014f,0.15229f,0.033499f,0.000000f}, {0.000000f,0.057662f,0.088781f,0.13136f,0.1876f,0.25386f,0.31647f,0.33396f,0.31272f,0.30169f,0.3041f,0.30166f,0.31272f,0.33384f,0.31619f,0.25335f,0.1871f,0.13094f,0.088435f,0.057961f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.1102e-016f,0.18322f,0.38445f,0.58627f,0.79404f,1.000000f,0.79277f,0.58496f,0.3831f,0.18186f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rcf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.0043301f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.039295f,0.054543f,0.034375f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.070283f,0.084996f,0.088683f,0.081353f,0.05387f,0.012407f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.004605f,0.0048829f,0.000000f,0.019285f,0.07488f,0.079354f,0.086605f,0.095287f,0.10415f,0.098408f,0.058689f,0.0041976f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.024282f,0.048387f,0.058978f,0.041588f,0.055116f,0.070537f,0.077259f,0.08469f,0.093649f,0.10487f,0.11747f,0.10642f,0.036985f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0030669f,0.03345f,0.075417f,0.084016f,0.076175f,0.06925f,0.063133f,0.069255f,0.07618f,0.084023f,0.092903f,0.10388f,0.11903f,0.13076f,0.085668f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022737f,0.076046f,0.093649f,0.08469f,0.077259f,0.070537f,0.069255f,0.070537f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.12874f,0.013988f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.003656f,0.049623f,0.10114f,0.095287f,0.086605f,0.079355f,0.077251f,0.07618f,0.080638f,0.079354f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.1548f,0.038068f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011882f,0.077277f,0.10984f,0.097664f,0.089274f,0.0866f,0.084699f,0.084022f,0.087318f,0.088959f,0.089273f,0.097669f,0.10986f,0.12564f,0.1484f,0.1745f,0.057469f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023206f,0.10005f,0.11432f,0.10203f,0.097669f,0.095276f,0.093632f,0.092902f,0.095882f,0.099453f,0.099577f,0.10203f,0.11431f,0.1299f,0.15445f,0.1922f,0.070758f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027969f,0.11126f,0.11903f,0.11431f,0.10986f,0.1068f,0.10488f,0.10388f,0.1069f,0.11069f,0.11353f,0.11606f,0.11903f,0.13768f,0.1657f,0.21001f,0.11341f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030577f,0.1189f,0.13679f,0.1299f,0.12564f,0.12164f,0.11911f,0.11903f,0.12102f,0.1254f,0.13115f,0.13344f,0.13938f,0.1465f,0.17861f,0.23588f,0.17995f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026205f,0.078886f,0.13684f,0.15418f,0.1484f,0.14282f,0.13935f,0.13935f,0.1413f,0.14664f,0.15413f,0.16007f,0.16947f,0.18049f,0.19702f,0.24599f,0.23269f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040704f,0.016004f,0.076496f,0.14617f,0.1817f,0.17849f,0.17313f,0.17314f,0.17526f,0.18277f,0.1939f,0.20938f,0.22225f,0.25327f,0.25072f,0.24841f,0.27214f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0035468f,0.031188f,0.10737f,0.19838f,0.23832f,0.24841f,0.25121f,0.26542f,0.2947f,0.33937f,0.35937f,0.35542f,0.34365f,0.32425f,0.30027f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22597f,0.44198f,0.64256f,0.83403f,1.000000f,0.7669f,0.55102f,0.34893f,0.16743f,0.000000f}}; static float map_16point1_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031891f,0.0054514f,0.0062247f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013174f,0.017687f,0.041859f,0.06067f,0.072899f,0.042466f,0.0079947f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003925f,0.040182f,0.071028f,0.079333f,0.082923f,0.091873f,0.091044f,0.054336f,0.0026644f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.036005f,0.068709f,0.070277f,0.072557f,0.079348f,0.089301f,0.10193f,0.10231f,0.040017f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017407f,0.060499f,0.062673f,0.064496f,0.070291f,0.077297f,0.086764f,0.098677f,0.11609f,0.10303f,0.005855f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.000000f,0.056286f,0.057329f,0.062673f,0.068709f,0.076104f,0.085107f,0.096622f,0.1132f,0.1352f,0.046879f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039229f,0.03598f,0.06051f,0.056286f,0.051311f,0.056286f,0.061915f,0.068289f,0.075506f,0.08443f,0.096742f,0.11326f,0.14072f,0.10645f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.040421f,0.068709f,0.062673f,0.057312f,0.056287f,0.060432f,0.062673f,0.068709f,0.076125f,0.085123f,0.096621f,0.11322f,0.14066f,0.16153f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017887f,0.071132f,0.070291f,0.064476f,0.062673f,0.061916f,0.062673f,0.067986f,0.071744f,0.077297f,0.086748f,0.098677f,0.11606f,0.14511f,0.19371f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,8.626e-019f,0.042164f,0.079348f,0.072536f,0.070277f,0.068709f,0.068289f,0.068709f,0.071771f,0.076484f,0.081735f,0.090425f,0.10193f,0.12057f,0.15206f,0.22155f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.060953f,0.082898f,0.079333f,0.077297f,0.076125f,0.075507f,0.076104f,0.077297f,0.081765f,0.087411f,0.096063f,0.10762f,0.12656f,0.16273f,0.25543f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.005581f,0.072826f,0.091909f,0.089276f,0.086748f,0.085123f,0.08443f,0.085107f,0.086764f,0.090467f,0.096098f,0.10198f,0.11619f,0.13799f,0.17806f,0.28196f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.006186f,0.042808f,0.091228f,0.10193f,0.098677f,0.096621f,0.096743f,0.096622f,0.098677f,0.10193f,0.10766f,0.11623f,0.12551f,0.15094f,0.20789f,0.28698f,0.23903f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0081504f,0.054743f,0.10257f,0.11606f,0.11322f,0.11326f,0.1132f,0.11609f,0.12055f,0.12661f,0.13801f,0.15099f,0.16879f,0.21045f,0.29061f,0.4584f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0027588f,0.040396f,0.10346f,0.13537f,0.14072f,0.14064f,0.14507f,0.15206f,0.16273f,0.17804f,0.20797f,0.21045f,0.21283f,0.29354f,0.65936f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0060181f,0.047382f,0.10632f,0.16195f,0.194f,0.22178f,0.25576f,0.28205f,0.28709f,0.29071f,0.29364f,0.29667f,0.83624f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.5699e-016f,0.24261f,0.46196f,0.66287f,0.83976f,1.000000f}}; static float map_16point1_lsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,1.4883e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040704f,0.026172f,0.030577f,0.027969f,0.023206f,0.011882f,0.003656f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.016004f,0.078886f,0.11885f,0.11126f,0.10005f,0.077277f,0.049623f,0.022737f,0.0030466f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0035468f,0.076496f,0.13684f,0.13679f,0.11897f,0.11432f,0.10984f,0.10114f,0.076046f,0.033501f,0.0046306f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.031188f,0.14617f,0.15418f,0.1299f,0.11431f,0.10197f,0.097664f,0.095287f,0.093649f,0.075427f,0.024282f,0.00073159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10737f,0.1817f,0.1484f,0.12564f,0.10986f,0.097669f,0.089224f,0.086605f,0.08469f,0.083965f,0.048387f,0.004605f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19838f,0.17849f,0.14282f,0.12164f,0.1068f,0.095276f,0.0866f,0.07931f,0.077259f,0.076129f,0.058978f,0.0048965f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23832f,0.17313f,0.13935f,0.11911f,0.10488f,0.093632f,0.084699f,0.077251f,0.070498f,0.069208f,0.041647f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.3692e-016f,0.24833f,0.17308f,0.13931f,0.11899f,0.10385f,0.092873f,0.083996f,0.076156f,0.069233f,0.063102f,0.05511f,0.019286f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22597f,0.25121f,0.17526f,0.1413f,0.12102f,0.1069f,0.095882f,0.087318f,0.080638f,0.070515f,0.069221f,0.070532f,0.07488f,0.032609f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44198f,0.26542f,0.18277f,0.14664f,0.1254f,0.11069f,0.099453f,0.088959f,0.07933f,0.077251f,0.076144f,0.077259f,0.079348f,0.070283f,0.013958f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64256f,0.2947f,0.1939f,0.15413f,0.13115f,0.11353f,0.099577f,0.089246f,0.0866f,0.084699f,0.083982f,0.08469f,0.086605f,0.085004f,0.039295f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83403f,0.33937f,0.20938f,0.16007f,0.13344f,0.11606f,0.102f,0.097669f,0.095276f,0.093632f,0.092858f,0.093649f,0.095287f,0.088683f,0.054552f,0.0013532f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35937f,0.22225f,0.16947f,0.13938f,0.11899f,0.11431f,0.10986f,0.1068f,0.10488f,0.10383f,0.10487f,0.10415f,0.081353f,0.034375f,0.0043588f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.7669f,0.35542f,0.25327f,0.18049f,0.14646f,0.13768f,0.1299f,0.12564f,0.12164f,0.11911f,0.11897f,0.11747f,0.098408f,0.05387f,0.012211f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55102f,0.34365f,0.25072f,0.19696f,0.17861f,0.1657f,0.15445f,0.1484f,0.14282f,0.13935f,0.13074f,0.10642f,0.058689f,0.012407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.34893f,0.32425f,0.24834f,0.24599f,0.23588f,0.21001f,0.1922f,0.1745f,0.1548f,0.12874f,0.085642f,0.036985f,0.0041976f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.16741f,0.30017f,0.27214f,0.23269f,0.17995f,0.11341f,0.070758f,0.057469f,0.038068f,0.013988f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rsf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0036134f,0.011794f,0.023088f,0.027832f,0.030429f,0.026399f,0.0040112f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0031126f,0.022632f,0.049467f,0.077089f,0.099949f,0.11118f,0.11911f,0.078648f,0.015871f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045869f,0.033596f,0.075931f,0.10117f,0.10998f,0.11448f,0.11916f,0.13692f,0.13673f,0.076245f,0.0034849f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00071455f,0.024189f,0.075553f,0.093753f,0.095409f,0.097805f,0.10214f,0.11445f,0.13006f,0.15434f,0.14595f,0.030939f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045638f,0.04826f,0.084116f,0.084794f,0.086729f,0.089374f,0.097788f,0.10998f,0.12579f,0.14861f,0.18178f,0.10702f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0049397f,0.058905f,0.076265f,0.077358f,0.079443f,0.086706f,0.095393f,0.10693f,0.1218f,0.14297f,0.17876f,0.19813f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041705f,0.069332f,0.070616f,0.077346f,0.084808f,0.093775f,0.10503f,0.11926f,0.13955f,0.17338f,0.23845f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.128e-019f,0.019251f,0.055118f,0.063203f,0.069332f,0.076265f,0.084116f,0.093006f,0.104f,0.11916f,0.13951f,0.17333f,0.24869f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,2.262e-005f,0.032844f,0.075002f,0.070621f,0.069332f,0.070599f,0.080737f,0.087417f,0.095981f,0.10702f,0.12116f,0.14146f,0.17546f,0.2515f,0.22461f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014122f,0.070466f,0.079449f,0.077358f,0.076265f,0.077346f,0.079424f,0.089097f,0.099575f,0.11084f,0.12555f,0.14685f,0.18296f,0.26573f,0.44064f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039567f,0.085048f,0.086729f,0.084794f,0.084116f,0.084808f,0.086706f,0.089352f,0.099732f,0.11371f,0.13131f,0.1543f,0.19413f,0.29503f,0.64125f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0014071f,0.054512f,0.088881f,0.095409f,0.093753f,0.093007f,0.093775f,0.095393f,0.097788f,0.10212f,0.11625f,0.13365f,0.16031f,0.20963f,0.33985f,0.83276f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043373f,0.034659f,0.08163f,0.10433f,0.105f,0.104f,0.10503f,0.10693f,0.10998f,0.11445f,0.11914f,0.1396f,0.16971f,0.22252f,0.35981f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012393f,0.054219f,0.098665f,0.11764f,0.11916f,0.11926f,0.1218f,0.12579f,0.13006f,0.13785f,0.14663f,0.18077f,0.25367f,0.35599f,0.77038f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012593f,0.059121f,0.10673f,0.13084f,0.13955f,0.14297f,0.14861f,0.15464f,0.1659f,0.17883f,0.19719f,0.25106f,0.3443f,0.55456f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043097f,0.037335f,0.085557f,0.12916f,0.1552f,0.17483f,0.19253f,0.21041f,0.2363f,0.24639f,0.24863f,0.32498f,0.3525f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.6987e-018f,0.014261f,0.038514f,0.058048f,0.071419f,0.11435f,0.18086f,0.23352f,0.27289f,0.30018f,0.171f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-2.4828e-016f}}; static float map_16point1_lsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.057837f,0.033725f,0.014056f,0.0021284f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088781f,0.15197f,0.1126f,0.075079f,0.081035f,0.065091f,0.049131f,0.030154f,0.01248f,0.00065038f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13136f,0.19047f,0.19972f,0.18761f,0.17365f,0.15926f,0.13948f,0.11522f,0.080258f,0.038352f,0.011632f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1876f,0.22622f,0.20877f,0.17308f,0.16259f,0.15331f,0.14824f,0.14136f,0.12698f,0.096228f,0.051224f,0.013903f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25386f,0.24792f,0.19549f,0.16259f,0.14063f,0.13492f,0.12979f,0.12612f,0.12377f,0.11836f,0.09054f,0.040513f,0.0077516f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18322f,0.31647f,0.23665f,0.18234f,0.15331f,0.13491f,0.12054f,0.11534f,0.11241f,0.11063f,0.10978f,0.10408f,0.067907f,0.021737f,0.00081869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.38445f,0.33396f,0.22305f,0.17613f,0.14823f,0.12977f,0.11534f,0.10547f,0.10221f,0.099919f,0.099291f,0.099924f,0.076689f,0.027385f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58627f,0.31272f,0.21469f,0.17128f,0.14518f,0.12698f,0.11241f,0.1022f,0.093751f,0.091147f,0.090023f,0.091143f,0.07194f,0.010076f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79404f,0.30169f,0.2101f,0.16888f,0.14394f,0.12647f,0.11263f,0.10109f,0.091143f,0.083334f,0.081839f,0.083344f,0.027665f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.30431f,0.2121f,0.17071f,0.14582f,0.12726f,0.11381f,0.10293f,0.093322f,0.084838f,0.074566f,0.014386f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.79277f,0.30166f,0.21008f,0.16887f,0.14393f,0.12645f,0.11261f,0.10108f,0.091147f,0.083312f,0.081796f,0.083334f,0.02757f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.58496f,0.31272f,0.21465f,0.17129f,0.14517f,0.12697f,0.11241f,0.10221f,0.093725f,0.091143f,0.089976f,0.091147f,0.071938f,0.010015f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3831f,0.33384f,0.22305f,0.17611f,0.14824f,0.12979f,0.11534f,0.10544f,0.1022f,0.099924f,0.099238f,0.099919f,0.076598f,0.027407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.18186f,0.31619f,0.23666f,0.18235f,0.15331f,0.13492f,0.1205f,0.11534f,0.11241f,0.11064f,0.10973f,0.10402f,0.06778f,0.021645f,0.00081784f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25335f,0.24781f,0.1955f,0.16259f,0.14059f,0.13491f,0.12977f,0.12612f,0.12378f,0.11834f,0.090417f,0.040382f,0.0076928f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.1871f,0.22597f,0.20873f,0.17303f,0.16259f,0.15331f,0.14823f,0.14133f,0.12691f,0.096247f,0.051065f,0.013816f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.13094f,0.19014f,0.19982f,0.18747f,0.17352f,0.15913f,0.13934f,0.11502f,0.08005f,0.038463f,0.011549f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.088435f,0.15238f,0.11227f,0.074803f,0.080771f,0.064857f,0.048933f,0.030007f,0.012387f,0.00062972f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.05808f,0.033499f,0.013912f,0.0020664f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rsm[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0020664f,0.013912f,0.033499f,0.058195f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062972f,0.012387f,0.030007f,0.048933f,0.064857f,0.080771f,0.074803f,0.11227f,0.15246f,0.088435f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011549f,0.038509f,0.08005f,0.11502f,0.13934f,0.15913f,0.17352f,0.18747f,0.19989f,0.19014f,0.13094f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013816f,0.051065f,0.096286f,0.12691f,0.14133f,0.14823f,0.15331f,0.16259f,0.17308f,0.20873f,0.22597f,0.1871f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0076928f,0.040382f,0.090417f,0.11837f,0.12378f,0.12612f,0.12977f,0.13491f,0.14063f,0.16259f,0.1955f,0.24781f,0.25335f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00081784f,0.021645f,0.06778f,0.10402f,0.10977f,0.11064f,0.11241f,0.11534f,0.12054f,0.13492f,0.15331f,0.18235f,0.23666f,0.31619f,0.18186f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027451f,0.076598f,0.099919f,0.099281f,0.099924f,0.1022f,0.10547f,0.11534f,0.12979f,0.14824f,0.17611f,0.22305f,0.33384f,0.3831f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010015f,0.071952f,0.091147f,0.090014f,0.091143f,0.093752f,0.10221f,0.11241f,0.12697f,0.14517f,0.17129f,0.21465f,0.31272f,0.58496f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.02757f,0.083335f,0.081831f,0.083335f,0.091147f,0.10108f,0.11261f,0.12645f,0.14393f,0.16887f,0.21008f,0.30166f,0.79277f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.014385f,0.074587f,0.084862f,0.093348f,0.10296f,0.11384f,0.12729f,0.14586f,0.17076f,0.21215f,0.30439f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027665f,0.083335f,0.08182f,0.083335f,0.091143f,0.10109f,0.11263f,0.12647f,0.14394f,0.16888f,0.2101f,0.30169f,0.79404f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.010076f,0.071837f,0.091143f,0.090002f,0.091147f,0.093752f,0.1022f,0.11241f,0.12698f,0.14518f,0.17128f,0.21469f,0.31272f,0.58627f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.027311f,0.076689f,0.099924f,0.099267f,0.099919f,0.10221f,0.10547f,0.11534f,0.12977f,0.14823f,0.17613f,0.22305f,0.33396f,0.38445f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080127f,0.021737f,0.067907f,0.10408f,0.10976f,0.11063f,0.11241f,0.11534f,0.12054f,0.13491f,0.15331f,0.18234f,0.23665f,0.31647f,0.18322f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0077516f,0.040513f,0.09054f,0.11831f,0.12377f,0.12612f,0.12979f,0.13492f,0.14063f,0.16259f,0.19549f,0.24792f,0.25386f,-2.2204e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.22e-018f,0.013903f,0.051224f,0.096055f,0.12698f,0.14136f,0.14824f,0.15331f,0.16259f,0.17308f,0.20877f,0.22622f,0.1876f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.011632f,0.038283f,0.080258f,0.11522f,0.13948f,0.15926f,0.17365f,0.18761f,0.19965f,0.19047f,0.13136f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00062082f,0.01248f,0.030154f,0.049131f,0.065091f,0.081035f,0.075079f,0.1126f,0.15189f,0.088781f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0021284f,0.014056f,0.033725f,0.05778f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_lsb[21][21] = { {2.4828e-016f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17101f,0.3002f,0.27289f,0.23302f,0.18086f,0.11435f,0.071419f,0.058048f,0.038514f,0.013902f,2.6987e-018f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.3511f,0.3244f,0.24861f,0.24639f,0.23594f,0.21041f,0.19253f,0.17483f,0.1552f,0.12916f,0.08561f,0.037085f,0.0043097f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.55452f,0.3443f,0.25064f,0.19717f,0.17883f,0.1659f,0.15438f,0.14861f,0.14297f,0.13955f,0.13083f,0.10653f,0.059121f,0.012378f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.77038f,0.35549f,0.25367f,0.18047f,0.14661f,0.13765f,0.13006f,0.12579f,0.1218f,0.11926f,0.11904f,0.11764f,0.098665f,0.054219f,0.012206f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.35981f,0.22252f,0.16971f,0.1396f,0.11912f,0.11445f,0.10998f,0.10677f,0.10488f,0.10389f,0.105f,0.10433f,0.08163f,0.034493f,0.0043086f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83276f,0.33985f,0.20963f,0.16005f,0.13346f,0.11608f,0.10211f,0.097647f,0.095393f,0.093775f,0.092909f,0.093753f,0.095409f,0.088881f,0.054543f,0.0014071f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.64125f,0.29503f,0.19413f,0.15408f,0.13131f,0.11371f,0.099732f,0.089343f,0.086706f,0.084808f,0.084028f,0.084794f,0.086604f,0.085015f,0.039425f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.44064f,0.26573f,0.18296f,0.14685f,0.12555f,0.11084f,0.099575f,0.088972f,0.079416f,0.077346f,0.076185f,0.077358f,0.079366f,0.070466f,0.014122f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.22461f,0.2515f,0.17521f,0.14126f,0.12116f,0.10702f,0.095981f,0.087417f,0.080737f,0.070592f,0.06926f,0.070547f,0.075002f,0.032844f,2.262e-005f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.24865f,0.1733f,0.13949f,0.11914f,0.10398f,0.09299f,0.084101f,0.076252f,0.06932f,0.063198f,0.055167f,0.019305f,9.128e-019f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.23845f,0.17338f,0.13955f,0.11926f,0.10488f,0.093775f,0.084808f,0.077346f,0.070615f,0.069326f,0.041681f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19813f,0.17876f,0.14297f,0.1218f,0.10677f,0.095393f,0.086706f,0.079442f,0.077358f,0.076259f,0.058905f,0.0049261f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10702f,0.18178f,0.14861f,0.12579f,0.10998f,0.097647f,0.089373f,0.086604f,0.084794f,0.084109f,0.04826f,0.0045638f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.030939f,0.14595f,0.15412f,0.13006f,0.11445f,0.10214f,0.097805f,0.095409f,0.093753f,0.075568f,0.024189f,0.00071455f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0034849f,0.076245f,0.13673f,0.13678f,0.11916f,0.11432f,0.10998f,0.10117f,0.075931f,0.033596f,0.0045869f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.015871f,0.078648f,0.11911f,0.11118f,0.099949f,0.077089f,0.049467f,0.022632f,0.0031126f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0040112f,0.026399f,0.030429f,0.027832f,0.023088f,0.011794f,0.0036134f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rsb[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013988f,0.038068f,0.057469f,0.070758f,0.11341f,0.17995f,0.23269f,0.27214f,0.30022f,0.16743f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0041976f,0.036985f,0.085724f,0.12874f,0.1548f,0.1745f,0.1922f,0.21001f,0.23588f,0.24599f,0.24837f,0.32425f,0.34893f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012407f,0.058689f,0.10642f,0.13076f,0.13935f,0.14282f,0.1484f,0.15445f,0.1657f,0.17861f,0.19698f,0.25072f,0.34365f,0.55098f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.012211f,0.05387f,0.098408f,0.11747f,0.11899f,0.11911f,0.12164f,0.12564f,0.1299f,0.13768f,0.14648f,0.18049f,0.25327f,0.35542f,0.7669f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043588f,0.034375f,0.081353f,0.10415f,0.10487f,0.10385f,0.10488f,0.1068f,0.10986f,0.11431f,0.11901f,0.13938f,0.16947f,0.22225f,0.35937f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013532f,0.054576f,0.088683f,0.095287f,0.093649f,0.092871f,0.093632f,0.095276f,0.097669f,0.10201f,0.11606f,0.13344f,0.16007f,0.20938f,0.33937f,0.83403f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.039295f,0.084981f,0.086605f,0.08469f,0.083994f,0.084699f,0.0866f,0.089259f,0.099577f,0.11353f,0.13115f,0.15413f,0.1939f,0.2947f,0.64256f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.013958f,0.070283f,0.079341f,0.077259f,0.076154f,0.077251f,0.079341f,0.088959f,0.099453f,0.11069f,0.1254f,0.14664f,0.18277f,0.26542f,0.44198f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.032609f,0.07488f,0.070525f,0.069231f,0.070525f,0.080638f,0.087318f,0.095882f,0.1069f,0.12102f,0.1413f,0.17526f,0.25121f,0.22597f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.019304f,0.055126f,0.063107f,0.069231f,0.076154f,0.083994f,0.092871f,0.10385f,0.11899f,0.13931f,0.17308f,0.24833f,-1.3692e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041554f,0.069226f,0.070525f,0.077251f,0.084699f,0.093632f,0.10488f,0.11911f,0.13935f,0.17313f,0.23832f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0048829f,0.058978f,0.076149f,0.077259f,0.079341f,0.0866f,0.095276f,0.1068f,0.12164f,0.14282f,0.17849f,0.19838f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.004605f,0.048387f,0.083988f,0.08469f,0.086605f,0.089259f,0.097669f,0.10986f,0.12564f,0.1484f,0.1817f,0.10737f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00073159f,0.024282f,0.075363f,0.093649f,0.095287f,0.097664f,0.10201f,0.11431f,0.1299f,0.15418f,0.14617f,0.031188f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0046306f,0.033399f,0.076046f,0.10114f,0.10984f,0.11432f,0.11901f,0.13679f,0.13684f,0.076496f,0.0035468f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0030466f,0.022737f,0.049623f,0.077277f,0.10005f,0.11126f,0.11884f,0.078886f,0.016004f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003656f,0.011882f,0.023206f,0.027969f,0.030577f,0.026172f,0.0040704f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.4883e-018f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_ls[21][21] = { {1.000000f,0.83976f,0.66287f,0.46196f,0.24261f,-7.8496e-016f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.8363f,0.2965f,0.29364f,0.2912f,0.28709f,0.28205f,0.25576f,0.22178f,0.194f,0.1623f,0.10667f,0.047382f,0.0060181f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.66065f,0.2941f,0.21271f,0.21045f,0.20831f,0.17804f,0.16273f,0.15206f,0.14507f,0.14064f,0.14088f,0.13561f,0.10346f,0.040396f,0.0027588f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.45837f,0.29061f,0.21085f,0.1687f,0.15099f,0.13801f,0.12686f,0.12055f,0.11609f,0.1132f,0.11339f,0.11341f,0.11606f,0.10278f,0.054743f,0.0081504f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.23903f,0.28746f,0.20789f,0.15123f,0.12544f,0.11643f,0.10766f,0.10193f,0.098677f,0.096622f,0.096854f,0.096621f,0.098677f,0.10193f,0.091409f,0.042808f,0.0062213f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.28196f,0.17806f,0.13799f,0.11619f,0.10192f,0.096098f,0.090467f,0.086913f,0.085253f,0.084527f,0.085123f,0.086748f,0.089276f,0.092069f,0.073051f,0.005581f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.25543f,0.16273f,0.12682f,0.1078f,0.096222f,0.087361f,0.081901f,0.077297f,0.076104f,0.075593f,0.076125f,0.077297f,0.079333f,0.083018f,0.060953f,0.003291f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.22155f,0.15206f,0.12078f,0.10193f,0.090425f,0.081735f,0.076441f,0.071771f,0.068709f,0.068368f,0.068709f,0.070398f,0.07264f,0.079485f,0.042164f,-4.313e-018f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.19371f,0.14511f,0.11606f,0.098677f,0.086748f,0.077297f,0.071865f,0.067948f,0.062673f,0.061987f,0.062673f,0.064569f,0.070291f,0.071132f,0.017887f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.16153f,0.1409f,0.11341f,0.096621f,0.085123f,0.076125f,0.068709f,0.062673f,0.060398f,0.056351f,0.057395f,0.062673f,0.068709f,0.040421f,0.0013668f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.10645f,0.14068f,0.11323f,0.096714f,0.084405f,0.075484f,0.068269f,0.061897f,0.05627f,0.05131f,0.056318f,0.060545f,0.036079f,0.0039229f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.046879f,0.1352f,0.1132f,0.096622f,0.085253f,0.076104f,0.068709f,0.062673f,0.057295f,0.056286f,0.000000f,0.0017892f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.005855f,0.10303f,0.11609f,0.098677f,0.086913f,0.077297f,0.070291f,0.064457f,0.062673f,0.060517f,0.0017407f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.040017f,0.10231f,0.10193f,0.089301f,0.079485f,0.072514f,0.070398f,0.068709f,0.036025f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0026644f,0.054553f,0.091044f,0.091873f,0.082874f,0.079333f,0.071028f,0.040182f,0.003925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0079947f,0.042595f,0.07287f,0.060829f,0.041859f,0.017687f,0.0013174f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0062247f,0.0054514f,0.0031891f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_lcs[21][21] = { {0.000000f,0.16743f,0.34893f,0.55102f,0.7669f,1.000000f,0.8304f,0.64256f,0.43815f,0.22209f,0.0039027f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.3003f,0.32425f,0.34246f,0.35542f,0.35937f,0.33937f,0.2947f,0.26542f,0.25007f,0.24823f,0.23832f,0.19838f,0.10737f,0.031188f,0.0035468f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.27153f,0.24847f,0.25072f,0.25221f,0.22225f,0.20938f,0.1939f,0.18277f,0.17526f,0.17301f,0.17239f,0.17849f,0.1817f,0.14617f,0.076496f,0.016004f,0.0039009f,4.242e-005f,0.000000f,0.000000f}, {0.000000f,0.23269f,0.24505f,0.19707f,0.18049f,0.16947f,0.1594f,0.15413f,0.14664f,0.1413f,0.13925f,0.13875f,0.14282f,0.14776f,0.15349f,0.13684f,0.078203f,0.026271f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.17979f,0.23588f,0.17782f,0.14654f,0.13879f,0.13344f,0.13115f,0.1254f,0.12102f,0.11894f,0.11911f,0.12164f,0.12564f,0.12932f,0.13679f,0.11897f,0.030577f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.11341f,0.21001f,0.1657f,0.13768f,0.11906f,0.11606f,0.11353f,0.11021f,0.10642f,0.1038f,0.10488f,0.1068f,0.10986f,0.1138f,0.11891f,0.11067f,0.027969f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.070758f,0.1922f,0.15376f,0.12932f,0.1138f,0.10205f,0.099158f,0.099453f,0.095882f,0.092833f,0.093632f,0.095276f,0.097669f,0.10193f,0.11432f,0.10005f,0.022867f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.057469f,0.1745f,0.14776f,0.12564f,0.10986f,0.097669f,0.089296f,0.088959f,0.087318f,0.083959f,0.084699f,0.086215f,0.089185f,0.097246f,0.10984f,0.077277f,0.011882f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.038068f,0.1548f,0.14282f,0.12164f,0.1068f,0.095276f,0.086215f,0.079374f,0.080638f,0.076123f,0.077251f,0.079276f,0.086605f,0.095287f,0.10068f,0.049623f,0.003656f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.013988f,0.1285f,0.13875f,0.11911f,0.10488f,0.093632f,0.084699f,0.077251f,0.070555f,0.069203f,0.070467f,0.077259f,0.08469f,0.093649f,0.075581f,0.022737f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.08571f,0.13081f,0.1191f,0.10394f,0.092957f,0.084072f,0.076225f,0.069295f,0.063149f,0.069202f,0.076123f,0.083959f,0.075464f,0.033519f,0.003067f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.036985f,0.10642f,0.11747f,0.10441f,0.093649f,0.08469f,0.077259f,0.070572f,0.055109f,0.041636f,0.058978f,0.048387f,0.024282f,0.0046306f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.0041976f,0.058689f,0.098408f,0.10378f,0.095287f,0.086605f,0.079393f,0.07488f,0.019285f,0.000000f,0.00491f,0.0044871f,0.00073159f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.012407f,0.05387f,0.081353f,0.08843f,0.085024f,0.070118f,0.032609f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.012211f,0.034375f,0.054592f,0.039295f,0.013958f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0043588f,0.0013532f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_cs[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.18575f,0.3831f,0.58872f,0.79642f,0.99651f,0.79404f,0.58627f,0.38445f,0.18322f,5.5511e-016f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.05802f,0.088435f,0.13215f,0.1871f,0.25335f,0.31619f,0.33384f,0.31272f,0.30281f,0.30399f,0.30169f,0.31272f,0.33396f,0.31647f,0.25386f,0.1876f,0.13136f,0.088781f,0.057662f,0.000000f}, {0.000000f,0.034146f,0.1523f,0.19014f,0.22703f,0.24781f,0.23666f,0.22305f,0.21465f,0.21008f,0.21187f,0.21084f,0.21469f,0.22305f,0.23665f,0.24792f,0.22622f,0.19063f,0.15181f,0.033725f,0.000000f}, {0.000000f,0.013912f,0.11322f,0.19976f,0.20873f,0.1955f,0.18301f,0.17611f,0.17129f,0.16887f,0.17053f,0.16948f,0.17128f,0.17676f,0.18302f,0.19549f,0.20944f,0.19952f,0.1126f,0.014056f,0.000000f}, {0.000000f,0.0022437f,0.074803f,0.18827f,0.17294f,0.16318f,0.15331f,0.14824f,0.14517f,0.14393f,0.14566f,0.14394f,0.14518f,0.14823f,0.15388f,0.16259f,0.17286f,0.18761f,0.075079f,0.0021284f,0.000000f}, {0.000000f,0.000000f,0.080771f,0.17352f,0.16259f,0.14051f,0.13492f,0.12979f,0.12745f,0.12694f,0.12712f,0.12647f,0.12698f,0.12977f,0.13542f,0.14045f,0.16318f,0.17365f,0.081035f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.064857f,0.15982f,0.15388f,0.13542f,0.12044f,0.11576f,0.11241f,0.11261f,0.11369f,0.11263f,0.11241f,0.11534f,0.12039f,0.13492f,0.15331f,0.15958f,0.065091f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.048933f,0.13997f,0.14823f,0.12977f,0.11534f,0.10538f,0.10221f,0.10108f,0.10282f,0.10109f,0.10259f,0.10534f,0.11576f,0.12979f,0.14824f,0.13948f,0.049131f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.030007f,0.11502f,0.14133f,0.12612f,0.11241f,0.10259f,0.093673f,0.091147f,0.093222f,0.091143f,0.093633f,0.10221f,0.11241f,0.12658f,0.14136f,0.11522f,0.030154f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.012652f,0.080647f,0.12691f,0.12378f,0.11064f,0.099924f,0.091143f,0.083265f,0.084748f,0.08323f,0.091147f,0.099919f,0.11063f,0.12424f,0.12698f,0.080258f,0.01248f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.00060016f,0.038416f,0.096151f,0.11825f,0.10964f,0.099156f,0.089902f,0.081729f,0.077299f,0.081705f,0.089875f,0.099127f,0.1096f,0.11815f,0.095997f,0.038235f,0.00059126f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011549f,0.051065f,0.090883f,0.10402f,0.099919f,0.091147f,0.083276f,0.01435f,0.08323f,0.091143f,0.099924f,0.10408f,0.09054f,0.051224f,0.011632f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.013816f,0.040757f,0.06778f,0.076598f,0.071913f,0.02757f,0.000000f,0.027665f,0.071785f,0.076798f,0.067907f,0.040513f,0.013903f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0076928f,0.021908f,0.027406f,0.010191f,0.000000f,0.000000f,0.000000f,0.010076f,0.027281f,0.021737f,0.0077516f,3.0501e-018f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00080041f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00078385f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rcs[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.22461f,0.44064f,0.64125f,0.83276f,1.000000f,0.77038f,0.55456f,0.3525f,0.17101f,-2.4828e-016f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0034849f,0.030939f,0.10702f,0.19813f,0.23845f,0.24861f,0.2515f,0.26573f,0.29503f,0.33985f,0.35981f,0.35599f,0.3443f,0.32498f,0.30021f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0040112f,0.015871f,0.076245f,0.14595f,0.18178f,0.17876f,0.17338f,0.17327f,0.17546f,0.18296f,0.19413f,0.20963f,0.22252f,0.25367f,0.25106f,0.24861f,0.27289f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.026399f,0.078648f,0.13673f,0.15434f,0.14861f,0.14297f,0.13955f,0.13946f,0.14146f,0.14685f,0.1543f,0.16031f,0.16971f,0.18077f,0.19717f,0.24639f,0.23352f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.030429f,0.11915f,0.13692f,0.13006f,0.12579f,0.1218f,0.11926f,0.11913f,0.12116f,0.12555f,0.13131f,0.13365f,0.1396f,0.14662f,0.17883f,0.2363f,0.18086f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.027832f,0.11118f,0.11915f,0.11445f,0.10998f,0.10693f,0.10503f,0.10396f,0.10702f,0.11084f,0.11371f,0.11625f,0.11913f,0.13785f,0.1659f,0.21041f,0.11435f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.023088f,0.099949f,0.11448f,0.10212f,0.097788f,0.095393f,0.093775f,0.092976f,0.095981f,0.099575f,0.099732f,0.10211f,0.11445f,0.13006f,0.15464f,0.19253f,0.071419f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.011794f,0.077089f,0.10998f,0.097805f,0.089359f,0.086706f,0.084808f,0.084088f,0.087417f,0.089097f,0.089344f,0.097788f,0.10998f,0.12579f,0.14861f,0.17483f,0.058048f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.0036134f,0.049467f,0.10117f,0.095409f,0.086729f,0.07943f,0.077346f,0.07624f,0.080737f,0.079417f,0.086706f,0.095393f,0.10693f,0.1218f,0.14297f,0.1552f,0.038514f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.022632f,0.075931f,0.093753f,0.084794f,0.077358f,0.070604f,0.069309f,0.070593f,0.077346f,0.084808f,0.093775f,0.10503f,0.11926f,0.13955f,0.12916f,0.014261f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0031126f,0.033596f,0.07556f,0.084102f,0.076253f,0.069321f,0.063182f,0.069321f,0.076253f,0.084102f,0.092991f,0.10398f,0.11915f,0.13081f,0.0855f,-2.6987e-018f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0045869f,0.024189f,0.04826f,0.058905f,0.041715f,0.055102f,0.070593f,0.077358f,0.084794f,0.093753f,0.105f,0.11764f,0.10673f,0.037335f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.00071455f,0.0045638f,0.0049261f,0.000000f,0.019214f,0.075002f,0.079417f,0.086729f,0.095409f,0.10433f,0.098665f,0.059121f,0.0043097f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-9.128e-019f,0.032844f,0.070466f,0.085012f,0.088881f,0.08163f,0.054219f,0.012593f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,2.262e-005f,0.014122f,0.039567f,0.054455f,0.034659f,0.012393f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0014071f,0.0043086f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_16point1_rs[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.23903f,0.4584f,0.65936f,0.8363f,1.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.005855f,0.046879f,0.10657f,0.16153f,0.19371f,0.22155f,0.25543f,0.28196f,0.28698f,0.29061f,0.29354f,0.29658f,0.83976f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0026644f,0.040017f,0.10303f,0.1352f,0.14072f,0.14066f,0.14511f,0.15206f,0.16273f,0.17806f,0.20789f,0.21045f,0.21277f,0.29364f,0.66287f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0079947f,0.054336f,0.10231f,0.11609f,0.1132f,0.11326f,0.11322f,0.11606f,0.12057f,0.12656f,0.13799f,0.15094f,0.16875f,0.21045f,0.29071f,0.46192f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0062247f,0.042466f,0.091044f,0.10193f,0.098677f,0.096622f,0.096743f,0.096621f,0.098677f,0.10193f,0.10762f,0.11619f,0.12548f,0.15099f,0.20797f,0.28709f,0.24261f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0054514f,0.072927f,0.091873f,0.089301f,0.086764f,0.085107f,0.08443f,0.085123f,0.086748f,0.090425f,0.096063f,0.10195f,0.11623f,0.13801f,0.17804f,0.28205f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.0031891f,0.06067f,0.082922f,0.079348f,0.077297f,0.076104f,0.075506f,0.076125f,0.077297f,0.081735f,0.087387f,0.096098f,0.10766f,0.12661f,0.16273f,0.25576f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.041859f,0.079333f,0.072557f,0.070291f,0.068709f,0.068289f,0.068709f,0.071744f,0.076463f,0.081765f,0.090467f,0.10193f,0.12055f,0.15206f,0.22178f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.017687f,0.071028f,0.070277f,0.064495f,0.062673f,0.061915f,0.062673f,0.067967f,0.071771f,0.077297f,0.086764f,0.098677f,0.11609f,0.14507f,0.194f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013174f,0.040182f,0.068709f,0.062673f,0.057329f,0.056287f,0.060415f,0.062673f,0.068709f,0.076104f,0.085107f,0.096622f,0.1132f,0.14064f,0.16195f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039474f,0.036045f,0.060518f,0.056287f,0.051326f,0.056287f,0.061915f,0.068289f,0.075506f,0.08443f,0.096743f,0.11326f,0.14072f,0.1062f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017407f,0.000000f,0.056303f,0.057329f,0.062673f,0.068709f,0.076125f,0.085123f,0.096621f,0.11322f,0.13537f,0.047382f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0017892f,0.06051f,0.062673f,0.064495f,0.070277f,0.077297f,0.086748f,0.098677f,0.11606f,0.10346f,0.0060181f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.03594f,0.068709f,0.070291f,0.072557f,0.079333f,0.089276f,0.10193f,0.10257f,0.040396f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0039004f,0.040421f,0.071132f,0.079348f,0.082922f,0.091909f,0.091228f,0.054743f,0.0027588f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0013668f,0.017887f,0.042164f,0.060953f,0.072797f,0.042808f,0.0081504f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.003291f,0.005581f,0.0061507f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_legacy_ang[] = {-27,0,27,-105,105}; static float map_legacy_xsf[] = {-1,0,1,-1,1}; static float map_legacy_ysf[] = {1,1,1,-1,-1}; channel_id map_legacy_id[] = {ci_front_left,ci_front_center,ci_front_right,ci_back_left,ci_back_right,ci_lfe}; static float map_legacy_lf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.052559f,0.04973f,0.046444f,0.042638f,0.038255f,0.03325f,0.027609f,0.021357f,0.014571f,0.0073897f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.11043f,0.10453f,0.097663f,0.089681f,0.080466f,0.069928f,0.058038f,0.044859f,0.030571f,0.015481f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.17379f,0.16464f,0.15393f,0.14141f,0.1269f,0.11024f,0.091419f,0.070553f,0.047977f,0.024228f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.24254f,0.23009f,0.21535f,0.19799f,0.1777f,0.1543f,0.12778f,0.098374f,0.066667f,0.03352f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.31623f,0.30059f,0.28179f,0.25935f,0.23285f,0.20203f,0.16696f,0.1281f,0.086387f,0.043173f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.39392f,0.37542f,0.35271f,0.3251f,0.292f,0.25309f,0.20858f,0.15929f,0.10674f,0.05293f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.4741f,0.45334f,0.42712f,0.39444f,0.35446f,0.30682f,0.25196f,0.19128f,0.12717f,0.062479f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.5547f,0.53253f,0.50345f,0.46602f,0.41906f,0.36214f,0.29609f,0.22322f,0.14704f,0.071497f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.63324f,0.61069f,0.57963f,0.538f,0.48415f,0.41759f,0.33971f,0.25408f,0.1657f,0.079698f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.70711f,0.68525f,0.6532f,0.60812f,0.54772f,0.4714f,0.38139f,0.28284f,0.18257f,0.086874f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.77396f,0.75372f,0.72165f,0.67398f,0.60758f,0.52174f,0.41971f,0.30863f,0.19725f,0.092925f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.83205f,0.81408f,0.78279f,0.73335f,0.66169f,0.56695f,0.45356f,0.33085f,0.20953f,0.097849f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.88047f,0.86507f,0.83508f,0.78458f,0.70851f,0.6058f,0.48218f,0.34921f,0.21943f,0.10172f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.91915f,0.90626f,0.87779f,0.82678f,0.74715f,0.63768f,0.50535f,0.36378f,0.22711f,0.10467f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.94868f,0.93803f,0.91103f,0.85983f,0.77748f,0.66259f,0.52322f,0.37484f,0.23285f,0.10684f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.97014f,0.96128f,0.93553f,0.88433f,0.8f,0.68101f,0.53632f,0.38284f,0.23694f,0.10837f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.98478f,0.97723f,0.95242f,0.9013f,0.81561f,0.69373f,0.54531f,0.38828f,0.2397f,0.10939f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.99388f,0.98718f,0.963f,0.91194f,0.82541f,0.70171f,0.55092f,0.39165f,0.2414f,0.11001f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.99862f,0.99237f,0.96853f,0.91751f,0.83055f,0.70589f,0.55385f,0.39341f,0.24228f,0.11034f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {1.000000f,0.99388f,0.97014f,0.91915f,0.83205f,0.70711f,0.5547f,0.39392f,0.24254f,0.11043f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_legacy_cf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.0055256f,0.011611f,0.018273f,0.025503f,0.03325f,0.041414f,0.049832f,0.058284f,0.066507f,0.074227f,0.066507f,0.058284f,0.049832f,0.041414f,0.03325f,0.025503f,0.018273f,0.011611f,0.0055256f,0.000000f}, {0.000000f,0.011615f,0.024416f,0.038435f,0.053644f,0.069928f,0.087057f,0.10467f,0.12228f,0.13933f,0.15523f,0.13933f,0.12228f,0.10467f,0.087057f,0.069928f,0.053644f,0.038435f,0.024416f,0.011615f,0.000000f}, {0.000000f,0.018294f,0.038482f,0.060606f,0.084599f,0.11024f,0.13713f,0.16462f,0.19191f,0.21805f,0.24214f,0.21805f,0.19191f,0.16462f,0.13713f,0.11024f,0.084599f,0.060606f,0.038482f,0.018294f,0.000000f}, {0.000000f,0.025565f,0.053838f,0.084853f,0.11847f,0.1543f,0.19166f,0.22954f,0.26667f,0.30168f,0.33333f,0.30168f,0.26667f,0.22954f,0.19166f,0.1543f,0.11847f,0.084853f,0.053838f,0.025565f,0.000000f}, {0.000000f,0.033398f,0.070447f,0.11115f,0.15523f,0.20203f,0.25044f,0.29889f,0.34555f,0.38856f,0.4264f,0.38856f,0.34555f,0.29889f,0.25044f,0.20203f,0.15523f,0.11115f,0.070447f,0.033398f,0.000000f}, {0.000000f,0.041713f,0.088178f,0.13933f,0.19467f,0.25309f,0.31287f,0.37167f,0.42694f,0.47637f,0.51832f,0.47637f,0.42694f,0.37167f,0.31287f,0.25309f,0.19467f,0.13933f,0.088178f,0.041713f,0.000000f}, {0.000000f,0.050371f,0.10678f,0.16904f,0.23631f,0.30682f,0.37793f,0.44633f,0.50867f,0.56231f,0.60584f,0.56231f,0.50867f,0.44633f,0.37793f,0.30682f,0.23631f,0.16904f,0.10678f,0.050371f,0.000000f}, {0.000000f,0.05917f,0.12586f,0.19972f,0.27937f,0.36214f,0.44414f,0.52085f,0.58817f,0.64347f,0.68599f,0.64347f,0.58817f,0.52085f,0.44414f,0.36214f,0.27937f,0.19972f,0.12586f,0.05917f,0.000000f}, {0.000000f,0.067855f,0.14491f,0.23057f,0.32277f,0.41759f,0.50957f,0.59285f,0.66281f,0.71728f,0.7566f,0.71728f,0.66281f,0.59285f,0.50957f,0.41759f,0.32277f,0.23057f,0.14491f,0.067855f,0.000000f}, {0.000000f,0.076139f,0.1633f,0.26062f,0.36515f,0.4714f,0.57208f,0.65997f,0.7303f,0.78187f,0.8165f,0.78187f,0.7303f,0.65997f,0.57208f,0.4714f,0.36515f,0.26062f,0.1633f,0.076139f,0.000000f}, {0.000000f,0.083747f,0.18041f,0.28885f,0.40505f,0.52174f,0.62957f,0.72015f,0.78899f,0.83633f,0.86558f,0.83633f,0.78899f,0.72015f,0.62957f,0.52174f,0.40505f,0.28885f,0.18041f,0.083747f,0.000000f}, {0.000000f,0.090453f,0.1957f,0.31429f,0.44113f,0.56695f,0.68034f,0.77198f,0.83812f,0.88064f,0.90453f,0.88064f,0.83812f,0.77198f,0.68034f,0.56695f,0.44113f,0.31429f,0.1957f,0.090453f,0.000000f}, {0.000000f,0.096118f,0.20877f,0.33625f,0.47234f,0.6058f,0.72328f,0.81483f,0.87771f,0.9155f,0.93455f,0.9155f,0.87771f,0.81483f,0.72328f,0.6058f,0.47234f,0.33625f,0.20877f,0.096118f,0.000000f}, {0.000000f,0.1007f,0.21945f,0.35433f,0.4981f,0.63768f,0.75802f,0.84881f,0.90844f,0.94203f,0.95702f,0.94203f,0.90844f,0.84881f,0.75802f,0.63768f,0.4981f,0.35433f,0.21945f,0.1007f,0.000000f}, {0.000000f,0.10423f,0.22776f,0.3685f,0.51832f,0.66259f,0.78484f,0.87462f,0.93138f,0.96153f,0.97333f,0.96153f,0.93138f,0.87462f,0.78484f,0.66259f,0.51832f,0.3685f,0.22776f,0.10423f,0.000000f}, {0.000000f,0.10681f,0.23388f,0.379f,0.53333f,0.68101f,0.80448f,0.89329f,0.94776f,0.97529f,0.98473f,0.97529f,0.94776f,0.89329f,0.80448f,0.68101f,0.53333f,0.379f,0.23388f,0.10681f,0.000000f}, {0.000000f,0.10858f,0.23811f,0.38627f,0.54374f,0.69373f,0.81797f,0.90598f,0.95879f,0.98449f,0.9923f,0.98449f,0.95879f,0.90598f,0.81797f,0.69373f,0.54374f,0.38627f,0.23811f,0.10858f,0.000000f}, {0.000000f,0.10969f,0.24075f,0.39083f,0.55028f,0.70171f,0.82638f,0.91386f,0.9656f,0.99013f,0.99693f,0.99013f,0.9656f,0.91386f,0.82638f,0.70171f,0.55028f,0.39083f,0.24075f,0.10969f,0.000000f}, {0.000000f,0.11026f,0.24213f,0.39322f,0.5537f,0.70589f,0.83077f,0.91795f,0.96912f,0.99304f,0.99931f,0.99304f,0.96912f,0.91795f,0.83077f,0.70589f,0.5537f,0.39322f,0.24213f,0.11026f,0.000000f}, {0.000000f,0.11043f,0.24254f,0.39392f,0.5547f,0.70711f,0.83205f,0.91915f,0.97014f,0.99388f,1.000000f,0.99388f,0.97014f,0.91915f,0.83205f,0.70711f,0.5547f,0.39392f,0.24254f,0.11043f,0.000000f}}; static float map_legacy_rf[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.0073897f,0.014571f,0.021357f,0.027609f,0.03325f,0.038255f,0.042638f,0.046444f,0.04973f,0.052559f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.015481f,0.030571f,0.044859f,0.058038f,0.069928f,0.080466f,0.089681f,0.097663f,0.10453f,0.11043f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.024228f,0.047977f,0.070553f,0.091419f,0.11024f,0.1269f,0.14141f,0.15393f,0.16464f,0.17379f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.03352f,0.066667f,0.098374f,0.12778f,0.1543f,0.1777f,0.19799f,0.21535f,0.23009f,0.24254f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.043173f,0.086387f,0.1281f,0.16696f,0.20203f,0.23285f,0.25935f,0.28179f,0.30059f,0.31623f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.05293f,0.10674f,0.15929f,0.20858f,0.25309f,0.292f,0.3251f,0.35271f,0.37542f,0.39392f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.062479f,0.12717f,0.19128f,0.25196f,0.30682f,0.35446f,0.39444f,0.42712f,0.45334f,0.4741f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.071497f,0.14704f,0.22322f,0.29609f,0.36214f,0.41906f,0.46602f,0.50345f,0.53253f,0.5547f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.079698f,0.1657f,0.25408f,0.33971f,0.41759f,0.48415f,0.538f,0.57963f,0.61069f,0.63324f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.086874f,0.18257f,0.28284f,0.38139f,0.4714f,0.54772f,0.60812f,0.6532f,0.68525f,0.70711f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.092925f,0.19725f,0.30863f,0.41971f,0.52174f,0.60758f,0.67398f,0.72165f,0.75372f,0.77396f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.097849f,0.20953f,0.33085f,0.45356f,0.56695f,0.66169f,0.73335f,0.78279f,0.81408f,0.83205f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.10172f,0.21943f,0.34921f,0.48218f,0.6058f,0.70851f,0.78458f,0.83508f,0.86507f,0.88047f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.10467f,0.22711f,0.36378f,0.50535f,0.63768f,0.74715f,0.82678f,0.87779f,0.90626f,0.91915f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.10684f,0.23285f,0.37484f,0.52322f,0.66259f,0.77748f,0.85983f,0.91103f,0.93803f,0.94868f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.10837f,0.23694f,0.38284f,0.53632f,0.68101f,0.8f,0.88433f,0.93553f,0.96128f,0.97014f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.10939f,0.2397f,0.38828f,0.54531f,0.69373f,0.81561f,0.9013f,0.95242f,0.97723f,0.98478f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.11001f,0.2414f,0.39165f,0.55092f,0.70171f,0.82541f,0.91194f,0.963f,0.98718f,0.99388f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.11034f,0.24228f,0.39341f,0.55385f,0.70589f,0.83055f,0.91751f,0.96853f,0.99237f,0.99862f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.11043f,0.24254f,0.39392f,0.5547f,0.70711f,0.83205f,0.91915f,0.97014f,0.99388f,1.000000f}}; static float map_legacy_ls[21][21] = { {1.000000f,0.99862f,0.99388f,0.98478f,0.97014f,0.94868f,0.91915f,0.88047f,0.83205f,0.77396f,0.70711f,0.63324f,0.5547f,0.4741f,0.39392f,0.31623f,0.24254f,0.17379f,0.11043f,0.052559f,0.000000f}, {0.99862f,0.99737f,0.99274f,0.98372f,0.96912f,0.94763f,0.91801f,0.87918f,0.83055f,0.77222f,0.70516f,0.63182f,0.5537f,0.4734f,0.39343f,0.31588f,0.24228f,0.1736f,0.1103f,0.052493f,0.000000f}, {0.99388f,0.99308f,0.98883f,0.98008f,0.9656f,0.94403f,0.9141f,0.87474f,0.82541f,0.76631f,0.69854f,0.62698f,0.55028f,0.47102f,0.39176f,0.31468f,0.2414f,0.17296f,0.10987f,0.052267f,0.000000f}, {0.98478f,0.98482f,0.98129f,0.97306f,0.95879f,0.93708f,0.90658f,0.86623f,0.81561f,0.7551f,0.68606f,0.61781f,0.54374f,0.46643f,0.38853f,0.31236f,0.2397f,0.17172f,0.10903f,0.051833f,0.000000f}, {0.97014f,0.97149f,0.96909f,0.96167f,0.94776f,0.92582f,0.89443f,0.85257f,0.8f,0.73744f,0.66667f,0.60336f,0.53333f,0.45908f,0.38333f,0.30861f,0.23694f,0.16971f,0.10768f,0.051131f,0.000000f}, {0.94868f,0.95185f,0.95103f,0.94477f,0.93138f,0.90914f,0.87652f,0.83262f,0.77748f,0.71236f,0.6396f,0.58284f,0.51832f,0.44833f,0.37565f,0.30305f,0.23285f,0.16672f,0.10567f,0.050098f,0.000000f}, {0.91915f,0.92464f,0.92587f,0.92113f,0.90844f,0.88583f,0.85169f,0.80528f,0.74715f,0.67926f,0.60471f,0.55576f,0.4981f,0.43361f,0.36501f,0.29528f,0.22711f,0.16255f,0.10287f,0.048665f,0.000000f}, {0.88047f,0.88868f,0.89238f,0.8895f,0.87771f,0.85472f,0.81886f,0.76969f,0.70851f,0.63818f,0.56257f,0.52214f,0.47234f,0.41445f,0.35094f,0.28491f,0.21943f,0.15697f,0.099153f,0.046773f,0.000000f}, {0.83205f,0.84317f,0.84958f,0.84882f,0.83812f,0.81482f,0.77724f,0.72546f,0.66169f,0.58985f,0.5145f,0.4826f,0.44113f,0.39063f,0.3331f,0.27161f,0.20953f,0.14979f,0.094398f,0.044378f,0.000000f}, {0.77396f,0.78787f,0.79699f,0.79846f,0.78899f,0.76558f,0.72661f,0.67284f,0.60758f,0.53574f,0.46236f,0.43834f,0.40505f,0.3623f,0.3114f,0.25519f,0.19725f,0.1409f,0.088554f,0.041467f,0.000000f}, {0.70711f,0.72332f,0.73485f,0.73843f,0.7303f,0.70711f,0.66742f,0.61283f,0.54772f,0.47781f,0.40825f,0.39094f,0.36515f,0.32998f,0.28604f,0.2357f,0.18257f,0.13031f,0.08165f,0.038069f,0.000000f}, {0.63324f,0.65094f,0.66425f,0.6696f,0.66281f,0.64032f,0.60095f,0.54712f,0.48415f,0.41816f,0.3541f,0.34213f,0.32277f,0.2946f,0.25755f,0.21344f,0.1657f,0.11816f,0.073805f,0.03426f,0.000000f}, {0.5547f,0.57287f,0.5871f,0.59367f,0.58817f,0.56695f,0.52915f,0.47789f,0.41906f,0.35878f,0.30151f,0.29355f,0.27937f,0.25733f,0.22678f,0.18898f,0.14704f,0.10476f,0.065233f,0.030151f,0.000000f}, {0.4741f,0.49168f,0.50587f,0.513f,0.50867f,0.4893f,0.45437f,0.40741f,0.35446f,0.30126f,0.25161f,0.24648f,0.23631f,0.21938f,0.19473f,0.1631f,0.12717f,0.090529f,0.056207f,0.025878f,0.000000f}, {0.39392f,0.40998f,0.42322f,0.43026f,0.42694f,0.40994f,0.37901f,0.33779f,0.292f,0.24672f,0.20508f,0.20186f,0.19467f,0.18189f,0.16243f,0.13665f,0.10674f,0.075928f,0.047024f,0.021578f,0.000000f}, {0.31623f,0.33005f,0.34164f,0.34803f,0.34555f,0.33129f,0.30521f,0.27072f,0.23285f,0.19587f,0.16222f,0.16026f,0.15523f,0.14577f,0.13081f,0.11043f,0.086387f,0.061417f,0.037959f,0.017371f,0.000000f}, {0.24254f,0.25367f,0.26312f,0.26846f,0.26667f,0.25538f,0.23464f,0.20737f,0.1777f,0.149f,0.12309f,0.12191f,0.11847f,0.11166f,0.10056f,0.085126f,0.066667f,0.047375f,0.029235f,0.013351f,0.000000f}, {0.17379f,0.18203f,0.18908f,0.19313f,0.19191f,0.18364f,0.1684f,0.14846f,0.1269f,0.10617f,0.087556f,0.086867f,0.084599f,0.07994f,0.072173f,0.061212f,0.047977f,0.034083f,0.021009f,0.0095807f,0.000000f}, {0.11043f,0.11578f,0.12038f,0.12304f,0.12228f,0.11695f,0.10712f,0.094287f,0.080466f,0.067231f,0.055385f,0.055007f,0.053644f,0.05077f,0.04591f,0.038984f,0.030571f,0.021713f,0.013375f,0.0060937f,0.000000f}, {0.052559f,0.055132f,0.057347f,0.058638f,0.058284f,0.055728f,0.051012f,0.044862f,0.038255f,0.03194f,0.026298f,0.026133f,0.025503f,0.024157f,0.021862f,0.018576f,0.014571f,0.010348f,0.0063719f,0.0029017f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_legacy_rs[21][21] = { {0.000000f,0.052559f,0.11043f,0.17379f,0.24254f,0.31623f,0.39392f,0.4741f,0.5547f,0.63324f,0.70711f,0.77396f,0.83205f,0.88047f,0.91915f,0.94868f,0.97014f,0.98478f,0.99388f,0.99862f,1.000000f}, {0.000000f,0.052493f,0.1103f,0.1736f,0.24228f,0.31588f,0.39343f,0.4734f,0.5537f,0.63182f,0.70516f,0.77222f,0.83055f,0.87918f,0.91801f,0.94763f,0.96912f,0.98372f,0.99274f,0.99737f,0.99862f}, {0.000000f,0.052267f,0.10987f,0.17296f,0.2414f,0.31468f,0.39176f,0.47102f,0.55028f,0.62698f,0.69854f,0.76631f,0.82541f,0.87474f,0.9141f,0.94403f,0.9656f,0.98008f,0.98883f,0.99308f,0.99388f}, {0.000000f,0.051833f,0.10903f,0.17172f,0.2397f,0.31236f,0.38853f,0.46643f,0.54374f,0.61781f,0.68606f,0.7551f,0.81561f,0.86623f,0.90658f,0.93708f,0.95879f,0.97306f,0.98129f,0.98482f,0.98478f}, {0.000000f,0.051131f,0.10768f,0.16971f,0.23694f,0.30861f,0.38333f,0.45908f,0.53333f,0.60336f,0.66667f,0.73744f,0.8f,0.85257f,0.89443f,0.92582f,0.94776f,0.96167f,0.96909f,0.97149f,0.97014f}, {0.000000f,0.050098f,0.10567f,0.16672f,0.23285f,0.30305f,0.37565f,0.44833f,0.51832f,0.58284f,0.6396f,0.71236f,0.77748f,0.83262f,0.87652f,0.90914f,0.93138f,0.94477f,0.95103f,0.95185f,0.94868f}, {0.000000f,0.048665f,0.10287f,0.16255f,0.22711f,0.29528f,0.36501f,0.43361f,0.4981f,0.55576f,0.60471f,0.67926f,0.74715f,0.80528f,0.85169f,0.88583f,0.90844f,0.92113f,0.92587f,0.92464f,0.91915f}, {0.000000f,0.046773f,0.099153f,0.15697f,0.21943f,0.28491f,0.35094f,0.41445f,0.47234f,0.52214f,0.56257f,0.63818f,0.70851f,0.76969f,0.81886f,0.85472f,0.87771f,0.8895f,0.89238f,0.88868f,0.88047f}, {0.000000f,0.044378f,0.094398f,0.14979f,0.20953f,0.27161f,0.3331f,0.39063f,0.44113f,0.4826f,0.5145f,0.58985f,0.66169f,0.72546f,0.77724f,0.81482f,0.83812f,0.84882f,0.84958f,0.84317f,0.83205f}, {0.000000f,0.041467f,0.088554f,0.1409f,0.19725f,0.25519f,0.3114f,0.3623f,0.40505f,0.43834f,0.46236f,0.53574f,0.60758f,0.67284f,0.72661f,0.76558f,0.78899f,0.79846f,0.79699f,0.78787f,0.77396f}, {0.000000f,0.038069f,0.08165f,0.13031f,0.18257f,0.2357f,0.28604f,0.32998f,0.36515f,0.39094f,0.40825f,0.47781f,0.54772f,0.61283f,0.66742f,0.70711f,0.7303f,0.73843f,0.73485f,0.72332f,0.70711f}, {0.000000f,0.03426f,0.073805f,0.11816f,0.1657f,0.21344f,0.25755f,0.2946f,0.32277f,0.34213f,0.3541f,0.41816f,0.48415f,0.54712f,0.60095f,0.64032f,0.66281f,0.6696f,0.66425f,0.65094f,0.63324f}, {0.000000f,0.030151f,0.065233f,0.10476f,0.14704f,0.18898f,0.22678f,0.25733f,0.27937f,0.29355f,0.30151f,0.35878f,0.41906f,0.47789f,0.52915f,0.56695f,0.58817f,0.59367f,0.5871f,0.57287f,0.5547f}, {0.000000f,0.025878f,0.056207f,0.090529f,0.12717f,0.1631f,0.19473f,0.21938f,0.23631f,0.24648f,0.25161f,0.30126f,0.35446f,0.40741f,0.45437f,0.4893f,0.50867f,0.513f,0.50587f,0.49168f,0.4741f}, {0.000000f,0.021578f,0.047024f,0.075928f,0.10674f,0.13665f,0.16243f,0.18189f,0.19467f,0.20186f,0.20508f,0.24672f,0.292f,0.33779f,0.37901f,0.40994f,0.42694f,0.43026f,0.42322f,0.40998f,0.39392f}, {0.000000f,0.017371f,0.037959f,0.061417f,0.086387f,0.11043f,0.13081f,0.14577f,0.15523f,0.16026f,0.16222f,0.19587f,0.23285f,0.27072f,0.30521f,0.33129f,0.34555f,0.34803f,0.34164f,0.33005f,0.31623f}, {0.000000f,0.013351f,0.029235f,0.047375f,0.066667f,0.085126f,0.10056f,0.11166f,0.11847f,0.12191f,0.12309f,0.149f,0.1777f,0.20737f,0.23464f,0.25538f,0.26667f,0.26846f,0.26312f,0.25367f,0.24254f}, {0.000000f,0.0095807f,0.021009f,0.034083f,0.047977f,0.061212f,0.072173f,0.07994f,0.084599f,0.086867f,0.087556f,0.10617f,0.1269f,0.14846f,0.1684f,0.18364f,0.19191f,0.19313f,0.18908f,0.18203f,0.17379f}, {0.000000f,0.0060937f,0.013375f,0.021713f,0.030571f,0.038984f,0.04591f,0.05077f,0.053644f,0.055007f,0.055385f,0.067231f,0.080466f,0.094287f,0.10712f,0.11695f,0.12228f,0.12304f,0.12038f,0.11578f,0.11043f}, {0.000000f,0.0029017f,0.0063719f,0.010348f,0.014571f,0.018576f,0.021862f,0.024157f,0.025503f,0.026133f,0.026298f,0.03194f,0.038255f,0.044862f,0.051012f,0.055728f,0.058284f,0.058638f,0.057347f,0.055132f,0.052559f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; static float map_lfe_lfe[21][21] = { {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}, {0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f,0.000000f}}; std::map chn_alloc; std::map > chn_angle; std::map > chn_xsf; std::map > chn_ysf; std::map > chn_id; static bool init_maps() { chn_angle[cs_stereo] = std::vector(&map_stereo_ang[0],&map_stereo_ang[sizeof(map_stereo_ang)/sizeof(map_stereo_ang[0])]); chn_xsf[cs_stereo] = std::vector(&map_stereo_xsf[0],&map_stereo_xsf[sizeof(map_stereo_xsf)/sizeof(map_stereo_xsf[0])]); chn_ysf[cs_stereo] = std::vector(&map_stereo_ysf[0],&map_stereo_ysf[sizeof(map_stereo_ysf)/sizeof(map_stereo_ysf[0])]); chn_id[cs_stereo] = std::vector(&map_stereo_id[0],&map_stereo_id[sizeof(map_stereo_id)/sizeof(map_stereo_id[0])]); chn_alloc[cs_stereo].push_back(std::vector(&map_stereo_lf[0],&map_stereo_lf[21])); chn_alloc[cs_stereo].push_back(std::vector(&map_stereo_rf[0],&map_stereo_rf[21])); chn_alloc[cs_stereo].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_3stereo] = std::vector(&map_3stereo_ang[0],&map_3stereo_ang[sizeof(map_3stereo_ang)/sizeof(map_3stereo_ang[0])]); chn_xsf[cs_3stereo] = std::vector(&map_3stereo_xsf[0],&map_3stereo_xsf[sizeof(map_3stereo_xsf)/sizeof(map_3stereo_xsf[0])]); chn_ysf[cs_3stereo] = std::vector(&map_3stereo_ysf[0],&map_3stereo_ysf[sizeof(map_3stereo_ysf)/sizeof(map_3stereo_ysf[0])]); chn_id[cs_3stereo] = std::vector(&map_3stereo_id[0],&map_3stereo_id[sizeof(map_3stereo_id)/sizeof(map_3stereo_id[0])]); chn_alloc[cs_3stereo].push_back(std::vector(&map_3stereo_lf[0],&map_3stereo_lf[21])); chn_alloc[cs_3stereo].push_back(std::vector(&map_3stereo_cf[0],&map_3stereo_cf[21])); chn_alloc[cs_3stereo].push_back(std::vector(&map_3stereo_rf[0],&map_3stereo_rf[21])); chn_alloc[cs_3stereo].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); /* chn_angle[cs_5stereo] = std::vector(&map_5stereo_ang[0],&map_5stereo_ang[sizeof(map_5stereo_ang)/sizeof(map_5stereo_ang[0])]); chn_xsf[cs_5stereo] = std::vector(&map_5stereo_xsf[0],&map_5stereo_xsf[sizeof(map_5stereo_xsf)/sizeof(map_5stereo_xsf[0])]); chn_ysf[cs_5stereo] = std::vector(&map_5stereo_ysf[0],&map_5stereo_ysf[sizeof(map_5stereo_ysf)/sizeof(map_5stereo_ysf[0])]); chn_id[cs_5stereo] = std::vector(&map_5stereo_id[0],&map_5stereo_id[sizeof(map_5stereo_id)/sizeof(map_5stereo_id[0])]); chn_alloc[cs_5stereo].push_back(std::vector(&map_5stereo_lf[0],&map_5stereo_lf[21])); chn_alloc[cs_5stereo].push_back(std::vector(&map_5stereo_lcf[0],&map_5stereo_lcf[21])); chn_alloc[cs_5stereo].push_back(std::vector(&map_5stereo_cf[0],&map_5stereo_cf[21])); chn_alloc[cs_5stereo].push_back(std::vector(&map_5stereo_rcf[0],&map_5stereo_rcf[21])); chn_alloc[cs_5stereo].push_back(std::vector(&map_5stereo_rf[0],&map_5stereo_rf[21])); chn_alloc[cs_5stereo].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21]));*/ chn_angle[cs_4point1] = std::vector(&map_4point1_ang[0],&map_4point1_ang[sizeof(map_4point1_ang)/sizeof(map_4point1_ang[0])]); chn_xsf[cs_4point1] = std::vector(&map_4point1_xsf[0],&map_4point1_xsf[sizeof(map_4point1_xsf)/sizeof(map_4point1_xsf[0])]); chn_ysf[cs_4point1] = std::vector(&map_4point1_ysf[0],&map_4point1_ysf[sizeof(map_4point1_ysf)/sizeof(map_4point1_ysf[0])]); chn_id[cs_4point1] = std::vector(&map_4point1_id[0],&map_4point1_id[sizeof(map_4point1_id)/sizeof(map_4point1_id[0])]); chn_alloc[cs_4point1].push_back(std::vector(&map_4point1_lf[0],&map_4point1_lf[21])); chn_alloc[cs_4point1].push_back(std::vector(&map_4point1_rf[0],&map_4point1_rf[21])); chn_alloc[cs_4point1].push_back(std::vector(&map_4point1_ls[0],&map_4point1_ls[21])); chn_alloc[cs_4point1].push_back(std::vector(&map_4point1_rs[0],&map_4point1_rs[21])); chn_alloc[cs_4point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_5point1] = std::vector(&map_5point1_ang[0],&map_5point1_ang[sizeof(map_5point1_ang)/sizeof(map_5point1_ang[0])]); chn_xsf[cs_5point1] = std::vector(&map_5point1_xsf[0],&map_5point1_xsf[sizeof(map_5point1_xsf)/sizeof(map_5point1_xsf[0])]); chn_ysf[cs_5point1] = std::vector(&map_5point1_ysf[0],&map_5point1_ysf[sizeof(map_5point1_ysf)/sizeof(map_5point1_ysf[0])]); chn_id[cs_5point1] = std::vector(&map_5point1_id[0],&map_5point1_id[sizeof(map_5point1_id)/sizeof(map_5point1_id[0])]); chn_alloc[cs_5point1].push_back(std::vector(&map_5point1_lf[0],&map_5point1_lf[21])); chn_alloc[cs_5point1].push_back(std::vector(&map_5point1_cf[0],&map_5point1_cf[21])); chn_alloc[cs_5point1].push_back(std::vector(&map_5point1_rf[0],&map_5point1_rf[21])); chn_alloc[cs_5point1].push_back(std::vector(&map_5point1_ls[0],&map_5point1_ls[21])); chn_alloc[cs_5point1].push_back(std::vector(&map_5point1_rs[0],&map_5point1_rs[21])); chn_alloc[cs_5point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_6point1] = std::vector(&map_6point1_ang[0],&map_6point1_ang[sizeof(map_6point1_ang)/sizeof(map_6point1_ang[0])]); chn_xsf[cs_6point1] = std::vector(&map_6point1_xsf[0],&map_6point1_xsf[sizeof(map_6point1_xsf)/sizeof(map_6point1_xsf[0])]); chn_ysf[cs_6point1] = std::vector(&map_6point1_ysf[0],&map_6point1_ysf[sizeof(map_6point1_ysf)/sizeof(map_6point1_ysf[0])]); chn_id[cs_6point1] = std::vector(&map_6point1_id[0],&map_6point1_id[sizeof(map_6point1_id)/sizeof(map_6point1_id[0])]); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_lf[0],&map_6point1_lf[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_cf[0],&map_6point1_cf[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_rf[0],&map_6point1_rf[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_lsm[0],&map_6point1_lsm[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_rsm[0],&map_6point1_rsm[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_6point1_cs[0],&map_6point1_cs[21])); chn_alloc[cs_6point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_7point1] = std::vector(&map_7point1_ang[0],&map_7point1_ang[sizeof(map_7point1_ang)/sizeof(map_7point1_ang[0])]); chn_xsf[cs_7point1] = std::vector(&map_7point1_xsf[0],&map_7point1_xsf[sizeof(map_7point1_xsf)/sizeof(map_7point1_xsf[0])]); chn_ysf[cs_7point1] = std::vector(&map_7point1_ysf[0],&map_7point1_ysf[sizeof(map_7point1_ysf)/sizeof(map_7point1_ysf[0])]); chn_id[cs_7point1] = std::vector(&map_7point1_id[0],&map_7point1_id[sizeof(map_7point1_id)/sizeof(map_7point1_id[0])]); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_lf[0],&map_7point1_lf[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_cf[0],&map_7point1_cf[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_rf[0],&map_7point1_rf[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_lsm[0],&map_7point1_lsm[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_rsm[0],&map_7point1_rsm[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_ls[0],&map_7point1_ls[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_7point1_rs[0],&map_7point1_rs[21])); chn_alloc[cs_7point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); /* chn_angle[cs_7point1_panorama] = std::vector(&map_7point1_panorama_ang[0],&map_7point1_panorama_ang[sizeof(map_7point1_panorama_ang)/sizeof(map_7point1_panorama_ang[0])]); chn_xsf[cs_7point1_panorama] = std::vector(&map_7point1_panorama_xsf[0],&map_7point1_panorama_xsf[sizeof(map_7point1_panorama_xsf)/sizeof(map_7point1_panorama_xsf[0])]); chn_ysf[cs_7point1_panorama] = std::vector(&map_7point1_panorama_ysf[0],&map_7point1_panorama_ysf[sizeof(map_7point1_panorama_ysf)/sizeof(map_7point1_panorama_ysf[0])]); chn_id[cs_7point1_panorama] = std::vector(&map_7point1_panorama_id[0],&map_7point1_panorama_id[sizeof(map_7point1_panorama_id)/sizeof(map_7point1_panorama_id[0])]); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_lf[0],&map_7point1_panorama_lf[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_lcf[0],&map_7point1_panorama_lcf[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_cf[0],&map_7point1_panorama_cf[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_rcf[0],&map_7point1_panorama_rcf[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_rf[0],&map_7point1_panorama_rf[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_lsm[0],&map_7point1_panorama_lsm[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_7point1_panorama_rsm[0],&map_7point1_panorama_rsm[21])); chn_alloc[cs_7point1_panorama].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_7point1_tricenter] = std::vector(&map_7point1_tricenter_ang[0],&map_7point1_tricenter_ang[sizeof(map_7point1_tricenter_ang)/sizeof(map_7point1_tricenter_ang[0])]); chn_xsf[cs_7point1_tricenter] = std::vector(&map_7point1_tricenter_xsf[0],&map_7point1_tricenter_xsf[sizeof(map_7point1_tricenter_xsf)/sizeof(map_7point1_tricenter_xsf[0])]); chn_ysf[cs_7point1_tricenter] = std::vector(&map_7point1_tricenter_ysf[0],&map_7point1_tricenter_ysf[sizeof(map_7point1_tricenter_ysf)/sizeof(map_7point1_tricenter_ysf[0])]); chn_id[cs_7point1_tricenter] = std::vector(&map_7point1_tricenter_id[0],&map_7point1_tricenter_id[sizeof(map_7point1_tricenter_id)/sizeof(map_7point1_tricenter_id[0])]); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_lf[0],&map_7point1_tricenter_lf[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_lcf[0],&map_7point1_tricenter_lcf[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_cf[0],&map_7point1_tricenter_cf[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_rcf[0],&map_7point1_tricenter_rcf[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_rf[0],&map_7point1_tricenter_rf[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_ls[0],&map_7point1_tricenter_ls[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_7point1_tricenter_rs[0],&map_7point1_tricenter_rs[21])); chn_alloc[cs_7point1_tricenter].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_8point1] = std::vector(&map_8point1_ang[0],&map_8point1_ang[sizeof(map_8point1_ang)/sizeof(map_8point1_ang[0])]); chn_xsf[cs_8point1] = std::vector(&map_8point1_xsf[0],&map_8point1_xsf[sizeof(map_8point1_xsf)/sizeof(map_8point1_xsf[0])]); chn_ysf[cs_8point1] = std::vector(&map_8point1_ysf[0],&map_8point1_ysf[sizeof(map_8point1_ysf)/sizeof(map_8point1_ysf[0])]); chn_id[cs_8point1] = std::vector(&map_8point1_id[0],&map_8point1_id[sizeof(map_8point1_id)/sizeof(map_8point1_id[0])]); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_lf[0],&map_8point1_lf[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_cf[0],&map_8point1_cf[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_rf[0],&map_8point1_rf[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_lsm[0],&map_8point1_lsm[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_rsm[0],&map_8point1_rsm[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_ls[0],&map_8point1_ls[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_cs[0],&map_8point1_cs[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_8point1_rs[0],&map_8point1_rs[21])); chn_alloc[cs_8point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_9point1_densepanorama] = std::vector(&map_9point1_densepanorama_ang[0],&map_9point1_densepanorama_ang[sizeof(map_9point1_densepanorama_ang)/sizeof(map_9point1_densepanorama_ang[0])]); chn_xsf[cs_9point1_densepanorama] = std::vector(&map_9point1_densepanorama_xsf[0],&map_9point1_densepanorama_xsf[sizeof(map_9point1_densepanorama_xsf)/sizeof(map_9point1_densepanorama_xsf[0])]); chn_ysf[cs_9point1_densepanorama] = std::vector(&map_9point1_densepanorama_ysf[0],&map_9point1_densepanorama_ysf[sizeof(map_9point1_densepanorama_ysf)/sizeof(map_9point1_densepanorama_ysf[0])]); chn_id[cs_9point1_densepanorama] = std::vector(&map_9point1_densepanorama_id[0],&map_9point1_densepanorama_id[sizeof(map_9point1_densepanorama_id)/sizeof(map_9point1_densepanorama_id[0])]); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_lf[0],&map_9point1_densepanorama_lf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_lcf[0],&map_9point1_densepanorama_lcf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_cf[0],&map_9point1_densepanorama_cf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_rcf[0],&map_9point1_densepanorama_rcf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_rf[0],&map_9point1_densepanorama_rf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_lsf[0],&map_9point1_densepanorama_lsf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_rsf[0],&map_9point1_densepanorama_rsf[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_lsm[0],&map_9point1_densepanorama_lsm[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_9point1_densepanorama_rsm[0],&map_9point1_densepanorama_rsm[21])); chn_alloc[cs_9point1_densepanorama].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_9point1_wrap] = std::vector(&map_9point1_wrap_ang[0],&map_9point1_wrap_ang[sizeof(map_9point1_wrap_ang)/sizeof(map_9point1_wrap_ang[0])]); chn_xsf[cs_9point1_wrap] = std::vector(&map_9point1_wrap_xsf[0],&map_9point1_wrap_xsf[sizeof(map_9point1_wrap_xsf)/sizeof(map_9point1_wrap_xsf[0])]); chn_ysf[cs_9point1_wrap] = std::vector(&map_9point1_wrap_ysf[0],&map_9point1_wrap_ysf[sizeof(map_9point1_wrap_ysf)/sizeof(map_9point1_wrap_ysf[0])]); chn_id[cs_9point1_wrap] = std::vector(&map_9point1_wrap_id[0],&map_9point1_wrap_id[sizeof(map_9point1_wrap_id)/sizeof(map_9point1_wrap_id[0])]); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_lf[0],&map_9point1_wrap_lf[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_lcf[0],&map_9point1_wrap_lcf[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_cf[0],&map_9point1_wrap_cf[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_rcf[0],&map_9point1_wrap_rcf[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_rf[0],&map_9point1_wrap_rf[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_lsm[0],&map_9point1_wrap_lsm[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_rsm[0],&map_9point1_wrap_rsm[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_ls[0],&map_9point1_wrap_ls[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_9point1_wrap_rs[0],&map_9point1_wrap_rs[21])); chn_alloc[cs_9point1_wrap].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_11point1_densewrap] = std::vector(&map_11point1_densewrap_ang[0],&map_11point1_densewrap_ang[sizeof(map_11point1_densewrap_ang)/sizeof(map_11point1_densewrap_ang[0])]); chn_xsf[cs_11point1_densewrap] = std::vector(&map_11point1_densewrap_xsf[0],&map_11point1_densewrap_xsf[sizeof(map_11point1_densewrap_xsf)/sizeof(map_11point1_densewrap_xsf[0])]); chn_ysf[cs_11point1_densewrap] = std::vector(&map_11point1_densewrap_ysf[0],&map_11point1_densewrap_ysf[sizeof(map_11point1_densewrap_ysf)/sizeof(map_11point1_densewrap_ysf[0])]); chn_id[cs_11point1_densewrap] = std::vector(&map_11point1_densewrap_id[0],&map_11point1_densewrap_id[sizeof(map_11point1_densewrap_id)/sizeof(map_11point1_densewrap_id[0])]); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_lf[0],&map_11point1_densewrap_lf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_lcf[0],&map_11point1_densewrap_lcf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_cf[0],&map_11point1_densewrap_cf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_rcf[0],&map_11point1_densewrap_rcf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_rf[0],&map_11point1_densewrap_rf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_lsf[0],&map_11point1_densewrap_lsf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_rsf[0],&map_11point1_densewrap_rsf[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_lsm[0],&map_11point1_densewrap_lsm[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_rsm[0],&map_11point1_densewrap_rsm[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_lsb[0],&map_11point1_densewrap_lsb[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_11point1_densewrap_rsb[0],&map_11point1_densewrap_rsb[21])); chn_alloc[cs_11point1_densewrap].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_13point1_totalwrap] = std::vector(&map_13point1_totalwrap_ang[0],&map_13point1_totalwrap_ang[sizeof(map_13point1_totalwrap_ang)/sizeof(map_13point1_totalwrap_ang[0])]); chn_xsf[cs_13point1_totalwrap] = std::vector(&map_13point1_totalwrap_xsf[0],&map_13point1_totalwrap_xsf[sizeof(map_13point1_totalwrap_xsf)/sizeof(map_13point1_totalwrap_xsf[0])]); chn_ysf[cs_13point1_totalwrap] = std::vector(&map_13point1_totalwrap_ysf[0],&map_13point1_totalwrap_ysf[sizeof(map_13point1_totalwrap_ysf)/sizeof(map_13point1_totalwrap_ysf[0])]); chn_id[cs_13point1_totalwrap] = std::vector(&map_13point1_totalwrap_id[0],&map_13point1_totalwrap_id[sizeof(map_13point1_totalwrap_id)/sizeof(map_13point1_totalwrap_id[0])]); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_lf[0],&map_13point1_totalwrap_lf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_lcf[0],&map_13point1_totalwrap_lcf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_cf[0],&map_13point1_totalwrap_cf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rcf[0],&map_13point1_totalwrap_rcf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rf[0],&map_13point1_totalwrap_rf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_lsf[0],&map_13point1_totalwrap_lsf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rsf[0],&map_13point1_totalwrap_rsf[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_lsm[0],&map_13point1_totalwrap_lsm[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rsm[0],&map_13point1_totalwrap_rsm[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_lsb[0],&map_13point1_totalwrap_lsb[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rsb[0],&map_13point1_totalwrap_rsb[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_ls[0],&map_13point1_totalwrap_ls[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_13point1_totalwrap_rs[0],&map_13point1_totalwrap_rs[21])); chn_alloc[cs_13point1_totalwrap].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_16point1] = std::vector(&map_16point1_ang[0],&map_16point1_ang[sizeof(map_16point1_ang)/sizeof(map_16point1_ang[0])]); chn_xsf[cs_16point1] = std::vector(&map_16point1_xsf[0],&map_16point1_xsf[sizeof(map_16point1_xsf)/sizeof(map_16point1_xsf[0])]); chn_ysf[cs_16point1] = std::vector(&map_16point1_ysf[0],&map_16point1_ysf[sizeof(map_16point1_ysf)/sizeof(map_16point1_ysf[0])]); chn_id[cs_16point1] = std::vector(&map_16point1_id[0],&map_16point1_id[sizeof(map_16point1_id)/sizeof(map_16point1_id[0])]); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lf[0],&map_16point1_lf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lcf[0],&map_16point1_lcf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_cf[0],&map_16point1_cf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rcf[0],&map_16point1_rcf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rf[0],&map_16point1_rf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lsf[0],&map_16point1_lsf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rsf[0],&map_16point1_rsf[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lsm[0],&map_16point1_lsm[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rsm[0],&map_16point1_rsm[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lsb[0],&map_16point1_lsb[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rsb[0],&map_16point1_rsb[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_ls[0],&map_16point1_ls[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_lcs[0],&map_16point1_lcs[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_cs[0],&map_16point1_cs[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rcs[0],&map_16point1_rcs[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_16point1_rs[0],&map_16point1_rs[21])); chn_alloc[cs_16point1].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21])); chn_angle[cs_legacy] = std::vector(&map_legacy_ang[0],&map_legacy_ang[sizeof(map_legacy_ang)/sizeof(map_legacy_ang[0])]); chn_xsf[cs_legacy] = std::vector(&map_legacy_xsf[0],&map_legacy_xsf[sizeof(map_legacy_xsf)/sizeof(map_legacy_xsf[0])]); chn_ysf[cs_legacy] = std::vector(&map_legacy_ysf[0],&map_legacy_ysf[sizeof(map_legacy_ysf)/sizeof(map_legacy_ysf[0])]); chn_id[cs_legacy] = std::vector(&map_legacy_id[0],&map_legacy_id[sizeof(map_legacy_id)/sizeof(map_legacy_id[0])]); chn_alloc[cs_legacy].push_back(std::vector(&map_legacy_lf[0],&map_legacy_lf[21])); chn_alloc[cs_legacy].push_back(std::vector(&map_legacy_cf[0],&map_legacy_cf[21])); chn_alloc[cs_legacy].push_back(std::vector(&map_legacy_rf[0],&map_legacy_rf[21])); chn_alloc[cs_legacy].push_back(std::vector(&map_legacy_ls[0],&map_legacy_ls[21])); chn_alloc[cs_legacy].push_back(std::vector(&map_legacy_rs[0],&map_legacy_rs[21])); chn_alloc[cs_legacy].push_back(std::vector(&map_lfe_lfe[0],&map_lfe_lfe[21]));*/ return true; } namespace { bool success = init_maps(); }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/channelmaps.h000066400000000000000000000025061516712004000302100ustar00rootroot00000000000000/* Copyright (C) 2010 Christian Kothe 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 Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CHANNELMAPS_H #define CHANNELMAPS_H #include "freesurround_decoder.h" #include #include const int grid_res = 21; // resolution of the lookup grid // channel allocation maps (per setup) typedef std::vector > alloc_lut; extern std::map chn_alloc; // channel metadata maps (per setup) extern std::map > chn_angle; extern std::map > chn_xsf; extern std::map > chn_ysf; extern std::map > chn_id; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/freesurround_decoder.cpp000066400000000000000000000302421516712004000324600ustar00rootroot00000000000000/* Copyright (C) 2007-2010 Christian Kothe 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 Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "kiss_fftr.h" #include "freesurround_decoder.h" #include "channelmaps.h" typedef std::complex cplx; const float pi = 3.141592654f; const float epsilon = 0.000001f; using namespace std; #undef min #undef max // FreeSurround implementation class decoder_impl { public: // instantiate the decoder with a given channel setup and processing block size (in samples) decoder_impl(channel_setup setup, unsigned N): N(N), C((unsigned)chn_alloc[setup].size()), setup(setup), lt(N), rt(N), dst(N), lf(N/2+1), rf(N/2+1), forward(kiss_fftr_alloc(N,0,0,0)), inverse(kiss_fftr_alloc(N,1,0,0)), buffer_empty(true), inbuf(3*N), wnd(N) { // allocate per-channel buffers outbuf.resize((N+N/2)*C); signal.resize(C,vector(N)); // init the window function for (unsigned k=0;kb?a:b; } static inline float clamp(double x) { return max(-1,min(1,x)); } static inline float sign(double x) { return x<0?-1:(x>0?1:0); } // get the distance of the soundfield edge, along a given angle static inline double edgedistance(double a) { return min(sqrt(1+sqr(tan(a))),sqrt(1+sqr(1/tan(a)))); } // get the index (and fractional offset!) in a piecewise-linear channel allocation grid int map_to_grid(double &x) { double gp=((x+1)*0.5)*(grid_res-1), i=min(grid_res-2,floor(gp)); x = gp-i; return i; } // decode a block of data and overlap-add it into outbuf void buffered_decode(float *input) { // demultiplex and apply window function for (unsigned k=0;k pi) phaseDiff = 2*pi - phaseDiff; // decode into x/y soundfield position double x,y; transform_decode(ampDiff,phaseDiff,x,y); // add wrap control transform_circular_wrap(x,y,circular_wrap); // add shift control y = clamp(y - shift); // add depth control y = clamp(1 - (1-y)*depth); // add focus control transform_focus(x,y,focus); // add crossfeed control x = clamp(x * (front_separation*(1+y)/2 + rear_separation*(1-y)/2)); // get total signal amplitude double amp_total = sqrt(ampL*ampL + ampR*ampR); // and total L/C/R signal phases double phase_of[] = {phaseL,atan2(lf[f].imag()+rf[f].imag(),lf[f].real()+rf[f].real()),phaseR}; // compute 2d channel map indexes p/q and update x/y to fractional offsets in the map grid int p=map_to_grid(x), q=map_to_grid(y); // map position to channel volumes for (unsigned c=0;c &a = chn_alloc[setup][c]; signal[c][f] = polar(amp_total*((1-x)*(1-y)*a[q][p] + x*(1-y)*a[q][p+1] + (1-x)*y*a[q+1][p] + x*y*a[q+1][p+1]), phase_of[1+(int)sign(chn_xsf[setup][c])]); } // optionally redirect bass if (use_lfe && f < hi_cut) { // level of LFE channel according to normalized frequency double lfe_level = f < lo_cut ? 1 : 0.5*(1+cos(pi*(f-lo_cut)/(hi_cut-lo_cut))); // assign LFE channel signal[C-1][f] = lfe_level * polar(amp_total,phase_of[1]); // subtract the signal from the other channels for (unsigned c=0;c 0 ? 1-pow(1-len,1+focus*20) : pow(len,1-focus*20); // back-transform into euclidian soundfield position len = len * edgedistance(ang); x = clamp(sin(ang)*len); y = clamp(cos(ang)*len); } // constants unsigned N,C; // number of samples per input/output block, number of output channels channel_setup setup; // the channel setup // parameters float circular_wrap; // angle of the front soundstage around the listener (90°=default) float shift; // forward/backward offset of the soundstage float depth; // backward extension of the soundstage float focus; // localization of the sound events float center_image; // presence of the center speaker float front_separation; // front stereo separation float rear_separation; // rear stereo separation float lo_cut, hi_cut; // LFE cutoff frequencies bool use_lfe; // whether to use the LFE channel // FFT data structures vector lt,rt,dst; // left total, right total (source arrays), time-domain destination buffer array vector lf,rf; // left total / right total in frequency domain kiss_fftr_cfg forward,inverse; // FFT buffers // buffers bool buffer_empty; // whether the buffer is currently empty or dirty vector inbuf; // stereo input buffer (multiplexed) vector outbuf; // multichannel output buffer (multiplexed) vector wnd; // the window function, precomputed vector > signal; // the signal to be constructed in every channel, in the frequency domain }; // implementation of the shell class freesurround_decoder::freesurround_decoder(channel_setup setup, unsigned blocksize): impl(new decoder_impl(setup,blocksize)) { } freesurround_decoder::~freesurround_decoder() { delete impl; } float *freesurround_decoder::decode(float *input) { return impl->decode(input); } void freesurround_decoder::flush() { impl->flush(); } void freesurround_decoder::circular_wrap(float v) { impl->set_circular_wrap(v); } void freesurround_decoder::shift(float v) { impl->set_shift(v); } void freesurround_decoder::depth(float v) { impl->set_depth(v); } void freesurround_decoder::focus(float v) { impl->set_focus(v); } void freesurround_decoder::center_image(float v) { impl->set_center_image(v); } void freesurround_decoder::front_separation(float v) { impl->set_front_separation(v); } void freesurround_decoder::rear_separation(float v) { impl->set_rear_separation(v); } void freesurround_decoder::low_cutoff(float v) { impl->set_low_cutoff(v); } void freesurround_decoder::high_cutoff(float v) { impl->set_high_cutoff(v); } void freesurround_decoder::bass_redirection(bool v) { impl->set_bass_redirection(v); } unsigned freesurround_decoder::buffered() { return impl->buffered(); } unsigned freesurround_decoder::num_channels(channel_setup s) { return chn_id[s].size(); } channel_id freesurround_decoder::channel_at(channel_setup s, unsigned i) { return i < chn_id[s].size() ? chn_id[s][i] : ci_none; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/freesurround_decoder.h000066400000000000000000000216601516712004000321310ustar00rootroot00000000000000/* Copyright (C) 2007-2010 Christian Kothe 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 Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FREESURROUND_DECODER_H #define FREESURROUND_DECODER_H /** * Identifiers for the supported output channels (from front to back, left to right). * The ordering here also determines the ordering of interleaved samples in the output signal. */ enum channel_id { ci_none = 0, ci_front_left = 1<<1, ci_front_center_left = 1<<2, ci_front_center = 1<<3, ci_front_center_right = 1<<4, ci_front_right = 1<<5, ci_side_front_left = 1<<6, ci_side_front_right = 1<<7, ci_side_center_left = 1<<8, ci_side_center_right = 1<<9, ci_side_back_left = 1<<10, ci_side_back_right = 1<<11, ci_back_left = 1<<12, ci_back_center_left = 1<<13, ci_back_center = 1<<14, ci_back_center_right = 1<<15, ci_back_right = 1<<16, ci_lfe = 1<<31 }; /** * The supported output channel setups. * A channel setup is defined by the set of channels that are present. Here is a graphic * of the cs_5point1 setup: http://en.wikipedia.org/wiki/File:5_1_channels_(surround_sound)_label.svg */ enum channel_setup { cs_stereo = ci_front_left | ci_front_right | ci_lfe, cs_3stereo = ci_front_left | ci_front_center | ci_front_right | ci_lfe, // cs_5stereo = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | ci_lfe, cs_4point1 = ci_front_left | ci_front_right | ci_back_left | ci_back_right | ci_lfe, cs_5point1 = ci_front_left | ci_front_center | ci_front_right | ci_back_left | ci_back_right | ci_lfe, cs_6point1 = ci_front_left | ci_front_center | ci_front_right | ci_side_center_left | ci_side_center_right | ci_back_center | ci_lfe, cs_7point1 = ci_front_left | ci_front_center | ci_front_right | ci_side_center_left | ci_side_center_right | ci_back_left | ci_back_right | ci_lfe, // cs_7point1_panorama = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_center_left | ci_side_center_right | ci_lfe, // cs_7point1_tricenter = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_back_left | ci_back_right | ci_lfe, // cs_8point1 = ci_front_left | ci_front_center | ci_front_right | ci_side_center_left | ci_side_center_right | // ci_back_left | ci_back_center | ci_back_right | ci_lfe, // cs_9point1_densepanorama = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | ci_lfe, // cs_9point1_wrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_center_left | ci_side_center_right | ci_back_left | ci_back_right | ci_lfe, // cs_11point1_densewrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | // ci_side_back_left | ci_side_back_right | ci_lfe, // cs_13point1_totalwrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | // ci_side_back_left | ci_side_back_right | ci_back_left | ci_back_right | ci_lfe, // cs_16point1 = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | // ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | ci_side_back_left | // ci_side_back_right | ci_back_left | ci_back_center_left | ci_back_center | ci_back_center_right | ci_back_right | ci_lfe, // cs_legacy = 0 // same channels as cs_5point1 but different upmixing transform; does not support the focus control }; /** * The FreeSurround decoder. */ class freesurround_decoder { public: /** * Create an instance of the decoder. * @param setup The output channel setup -- determines the number of output channels * and their place in the sound field. * @param blocksize Granularity at which data is processed by the decode() function. * Must be a power of two and should correspond to ca. 10ms worth of single-channel * samples (default is 4096 for 44.1Khz data). Do not make it shorter or longer * than 5ms to 20ms since the granularity at which locations are decoded * changes with this. */ freesurround_decoder(channel_setup setup=cs_5point1, unsigned blocksize=4096); ~freesurround_decoder(); /** * Decode a chunk of stereo sound. The output is delayed by half of the blocksize. * This function is the only one needed for straightforward decoding. * @param input Contains exactly blocksize (multiplexed) stereo samples, i.e. 2*blocksize numbers. * @return A pointer to an internal buffer of exactly blocksize (multiplexed) multichannel samples. * The actual number of values depends on the number of output channels in the chosen * channel setup. */ float *decode(float *input); /** * Flush the internal buffer. */ void flush(); // --- soundfield transformations // These functions allow to set up geometric transformations of the sound field after it has been decoded. // The sound field is best pictured as a 2-dimensional square with the listener in its // center which can be shifted or stretched in various ways before it is sent to the // speakers. The order in which these transformations are applied is as listed below. /** * Allows to wrap the soundfield around the listener in a circular manner. * Determines the angle of the frontal sound stage relative to the listener, in degrees. * A setting of 90° corresponds to standard surround decoding, 180° stretches the front stage from * ear to ear, 270° wraps it around most of the head. The side and rear content of the sound * field is compressed accordingly behind the listerer. (default: 90, range: [0°..360°]) */ void circular_wrap(float v); /** * Allows to shift the soundfield forward or backward. * Value range: [-1.0..+1.0]. 0 is no offset, positive values move the sound * forward, negative values move it backwards. (default: 0) */ void shift(float v); /** * Allows to scale the soundfield backwards. * Value range: [0.0..+5.0] -- 0 is all compressed to the front, 1 is no change, 5 is scaled 5x backwards (default: 1) */ void depth(float v); /** * Allows to control the localization (i.e., focality) of sources. * Value range: [-1.0..+1.0] -- 0 means unchanged, positive means more localized, negative means more ambient (default: 0) */ void focus(float v); // --- rendering parameters // These parameters control how the sound field is mapped onto speakers. /** * Set the presence of the front center channel(s). * Value range: [0.0..1.0] -- fully present at 1.0, fully replaced by left/right at 0.0 (default: 1). * The default of 1.0 results in spec-conformant decoding ("movie mode") while a value of 0.7 is * better suited for music reproduction (which is usually mixed without a center channel). */ void center_image(float v); /** * Set the front stereo separation. * Value range: [0.0..inf] -- 1.0 is default, 0.0 is mono. */ void front_separation(float v); /** * Set the rear stereo separation. * Value range: [0.0..inf] -- 1.0 is default, 0.0 is mono. */ void rear_separation(float v); // --- bass redirection (to LFE) /** * Enable/disable LFE channel (default: false = disabled) */ void bass_redirection(bool v); /** * Set the lower end of the transition band, in Hz/Nyquist (default: 40/22050). */ void low_cutoff(float v); /** * Set the upper end of the transition band, in Hz/Nyquist (default: 90/22050). */ void high_cutoff(float v); // --- info /** * Number of samples currently held in the buffer. */ unsigned buffered(); /** * Number of channels in the given setup. */ static unsigned num_channels(channel_setup s); /** * Channel id of the i'th channel in the given setup. */ static channel_id channel_at(channel_setup s, unsigned i); private: class decoder_impl *impl; // private implementation }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/000077500000000000000000000000001516712004000273535ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/CHANGELOG000066400000000000000000000117161516712004000305730ustar00rootroot000000000000001.3.0 2012-07-18 removed non-standard malloc.h from kiss_fft.h moved -lm to end of link line checked various return values converted python Numeric code to NumPy fixed test of int32_t on 64 bit OS added padding in a couple of places to allow SIMD alignment of structs 1.2.9 2010-05-27 threadsafe ( including OpenMP ) first edition of kissfft.hh the C++ template fft engine 1.2.8 Changed memory.h to string.h -- apparently more standard Added openmp extensions. This can have fairly linear speedups for larger FFT sizes. 1.2.7 Shrank the real-fft memory footprint. Thanks to Galen Seitz. 1.2.6 (Nov 14, 2006) The "thanks to GenArts" release. Added multi-dimensional real-optimized FFT, see tools/kiss_fftndr Thanks go to GenArts, Inc. for sponsoring the development. 1.2.5 (June 27, 2006) The "release for no good reason" release. Changed some harmless code to make some compilers' warnings go away. Added some more digits to pi -- why not. Added kiss_fft_next_fast_size() function to help people decide how much to pad. Changed multidimensional test from 8 dimensions to only 3 to avoid testing problems with fixed point (sorry Buckaroo Banzai). 1.2.4 (Oct 27, 2005) The "oops, inverse fixed point real fft was borked" release. Fixed scaling bug for inverse fixed point real fft -- also fixed test code that should've been failing. Thanks to Jean-Marc Valin for bug report. Use sys/types.h for more portable types than short,int,long => int16_t,int32_t,int64_t If your system does not have these, you may need to define them -- but at least it breaks in a loud and easily fixable way -- unlike silently using the wrong size type. Hopefully tools/psdpng.c is fixed -- thanks to Steve Kellog for pointing out the weirdness. 1.2.3 (June 25, 2005) The "you want to use WHAT as a sample" release. Added ability to use 32 bit fixed point samples -- requires a 64 bit intermediate result, a la 'long long' Added ability to do 4 FFTs in parallel by using SSE SIMD instructions. This is accomplished by using the __m128 (vector of 4 floats) as kiss_fft_scalar. Define USE_SIMD to use this. I know, I know ... this is drifting a bit from the "kiss" principle, but the speed advantages make it worth it for some. Also recent gcc makes it SOO easy to use vectors of 4 floats like a POD type. 1.2.2 (May 6, 2005) The Matthew release Replaced fixed point division with multiply&shift. Thanks to Jean-Marc Valin for discussions regarding. Considerable speedup for fixed-point. Corrected overflow protection in real fft routines when using fixed point. Finder's Credit goes to Robert Oschler of robodance for pointing me at the bug. This also led to the CHECK_OVERFLOW_OP macro. 1.2.1 (April 4, 2004) compiles cleanly with just about every -W warning flag under the sun reorganized kiss_fft_state so it could be read-only/const. This may be useful for embedded systems that are willing to predeclare twiddle factors, factorization. Fixed C_MUL,S_MUL on 16-bit platforms. tmpbuf will only be allocated if input & output buffers are same scratchbuf will only be allocated for ffts that are not multiples of 2,3,5 NOTE: The tmpbuf,scratchbuf changes may require synchronization code for multi-threaded apps. 1.2 (Feb 23, 2004) interface change -- cfg object is forward declaration of struct instead of void* This maintains type saftey and lets the compiler warn/error about stupid mistakes. (prompted by suggestion from Erik de Castro Lopo) small speed improvements added psdpng.c -- sample utility that will create png spectrum "waterfalls" from an input file ( not terribly useful yet) 1.1.1 (Feb 1, 2004 ) minor bug fix -- only affects odd rank, in-place, multi-dimensional FFTs 1.1 : (Jan 30,2004) split sample_code/ into test/ and tools/ Removed 2-D fft and added N-D fft (arbitrary) modified fftutil.c to allow multi-d FFTs Modified core fft routine to allow an input stride via kiss_fft_stride() (eased support of multi-D ffts) Added fast convolution filtering (FIR filtering using overlap-scrap method, with tail scrap) Add kfc.[ch]: the KISS FFT Cache. It takes care of allocs for you ( suggested by Oscar Lesta ). 1.0.1 (Dec 15, 2003) fixed bug that occurred when nfft==1. Thanks to Steven Johnson. 1.0 : (Dec 14, 2003) changed kiss_fft function from using a single buffer, to two buffers. If the same buffer pointer is supplied for both in and out, kiss will manage the buffer copies. added kiss_fft2d and kiss_fftr as separate source files (declarations in kiss_fft.h ) 0.4 :(Nov 4,2003) optimized for radix 2,3,4,5 0.3 :(Oct 28, 2003) woops, version 2 didn't actually factor out any radices other than 2. Thanks to Steven Johnson for finding this one. 0.2 :(Oct 27, 2003) added mixed radix, only radix 2,4 optimized versions 0.1 :(May 19 2003) initial release, radix 2 only boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/COPYING000066400000000000000000000003661516712004000304130ustar00rootroot00000000000000Copyright (c) 2003-2010 Mark Borgerding . All rights reserved. KISS FFT is provided under: SPDX-License-Identifier: BSD-3-Clause Being under the terms of the BSD 3-clause "New" or "Revised" License, according with: LICENSES/BSD-3-Clause boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/README.md000066400000000000000000000221131516712004000306310ustar00rootroot00000000000000# KISS FFT [![Build Status](https://travis-ci.com/mborgerding/kissfft.svg?branch=master)](https://travis-ci.com/mborgerding/kissfft) KISS FFT - A mixed-radix Fast Fourier Transform based up on the principle, "Keep It Simple, Stupid." There are many great fft libraries already around. Kiss FFT is not trying to be better than any of them. It only attempts to be a reasonably efficient, moderately useful FFT that can use fixed or floating data types and can be incorporated into someone's C program in a few minutes with trivial licensing. ## USAGE: The basic usage for 1-d complex FFT is: ```c #include "kiss_fft.h" kiss_fft_cfg cfg = kiss_fft_alloc( nfft ,is_inverse_fft ,0,0 ); while ... ... // put kth sample in cx_in[k].r and cx_in[k].i kiss_fft( cfg , cx_in , cx_out ); ... // transformed. DC is in cx_out[0].r and cx_out[0].i kiss_fft_free(cfg); ``` - **Note**: frequency-domain data is stored from dc up to 2pi. so cx_out[0] is the dc bin of the FFT and cx_out[nfft/2] is the Nyquist bin (if exists) Declarations are in "kiss_fft.h", along with a brief description of the functions you'll need to use. Code definitions for 1d complex FFTs are in kiss_fft.c. You can do other cool stuff with the extras you'll find in tools/ > - multi-dimensional FFTs > - real-optimized FFTs (returns the positive half-spectrum: (nfft/2+1) complex frequency bins) > - fast convolution FIR filtering (not available for fixed point) > - spectrum image creation The core fft and most tools/ code can be compiled to use float, double, Q15 short or Q31 samples. The default is float. ## BUILDING: There are two functionally-equivalent build systems supported by kissfft: - Make (traditional Makefiles for Unix / Linux systems) - CMake (more modern and feature-rich build system developed by Kitware) To build kissfft, the following build environment can be used: - GNU build environment with GCC, Clang and GNU Make or CMake (>= 3.6) - Microsoft Visual C++ (MSVC) with CMake (>= 3.6) Additional libraries required to build and test kissfft include: - libpng for psdpng tool, - libfftw3 to validate kissfft results against it, - python 2/3 with Numpy to validate kissfft results against it. - OpenMP supported by GCC, Clang or MSVC for multi-core FFT transformations Environments like Cygwin and MinGW can be highly likely used to build kissfft targeting Windows platform, but no tests were performed to the date. Both Make and CMake builds are easily configurable: - `KISSFFT_DATATYPE=` (for Make) or `-DKISSFFT_DATATYPE=` (for CMake) denote the principal datatype used by kissfft. It can be one of the following: - float (default) - double - int16_t - int32_t - SIMD (requires SSE instruction set support on target CPU) - `KISSFFT_OPENMP=1` (for Make) or `-DKISSFFT_OPENMP=ON` (for CMake) builds kissfft with OpenMP support. Please note that a supported compiler is required and this option is turned off by default. - `KISSFFT_STATIC=1` (for Make) or `-DKISSFFT_STATIC=ON` (for CMake) instructs the builder to create static library ('.lib' for Windows / '.a' for Unix or Linux). By default, this option is turned off and the shared library is created ('.dll' for Windows, '.so' for Linux or Unix, '.dylib' for Mac OSX) - `-DKISSFFT_TEST=OFF` (for CMake) disables building tests for kissfft. On Make, building tests is done separately by 'make testall' or 'make testsingle', so no specific setting is required. - `KISSFFT_TOOLS=0` (for Make) or `-DKISSFFT_TOOLS=OFF` (for CMake) builds kissfft without command-line tools like 'fastconv'. By default the tools are built. - `KISSFFT_USE_ALLOCA=1` (for Make) or `-DKISSFFT_USE_ALLOCA=ON` (for CMake) build kissfft with 'alloca' usage instead of 'malloc' / 'free'. - `PREFIX=/full/path/to/installation/prefix/directory` (for Make) or `-DCMAKE_INSTALL_PREFIX=/full/path/to/installation/prefix/directory` (for CMake) specifies the prefix directory to install kissfft into. For example, to build kissfft as a static library with 'int16_t' datatype and OpenMP support using Make, run the command from kissfft source tree: ``` make KISSFFT_DATATYPE=int16_t KISSFFT_STATIC=1 KISSFFT_OPENMP=1 all ``` The same configuration for CMake is: ``` mkdir build && cd build cmake -DKISSFFT_DATATYPE=int16_t -DKISSFFT_STATIC=ON -DKISSFFT_OPENMP=ON .. make all ``` To specify '/tmp/1234' as installation prefix directory, run: ``` make PREFIX=/tmp/1234 KISSFFT_DATATYPE=int16_t KISSFFT_STATIC=1 KISSFFT_OPENMP=1 install ``` or ``` mkdir build && cd build cmake -DCMAKE_INSTALL_PREFIX=/tmp/1234 -DKISSFFT_DATATYPE=int16_t -DKISSFFT_STATIC=ON -DKISSFFT_OPENMP=ON .. make all make install ``` ## TESTING: To validate the build configured as an example above, run the following command from kissfft source tree: ``` make KISSFFT_DATATYPE=int16_t KISSFFT_STATIC=1 KISSFFT_OPENMP=1 testsingle ``` if using Make, or: ``` make test ``` if using CMake. To test all possible build configurations, please run an extended testsuite from kissfft source tree: ``` sh test/kissfft-testsuite.sh ``` Please note that the extended testsuite takes around 20-40 minutes depending on device it runs on. This testsuite is useful for reporting bugs or testing the pull requests. ## BACKGROUND I started coding this because I couldn't find a fixed point FFT that didn't use assembly code. I started with floating point numbers so I could get the theory straight before working on fixed point issues. In the end, I had a little bit of code that could be recompiled easily to do ffts with short, float or double (other types should be easy too). Once I got my FFT working, I was curious about the speed compared to a well respected and highly optimized fft library. I don't want to criticize this great library, so let's call it FFT_BRANDX. During this process, I learned: > 1. FFT_BRANDX has more than 100K lines of code. The core of kiss_fft is about 500 lines (cpx 1-d). > 2. It took me an embarrassingly long time to get FFT_BRANDX working. > 3. A simple program using FFT_BRANDX is 522KB. A similar program using kiss_fft is 18KB (without optimizing for size). > 4. FFT_BRANDX is roughly twice as fast as KISS FFT in default mode. It is wonderful that free, highly optimized libraries like FFT_BRANDX exist. But such libraries carry a huge burden of complexity necessary to extract every last bit of performance. **Sometimes simpler is better, even if it's not better.** ## FREQUENTLY ASKED QUESTIONS: > Q: Can I use kissfft in a project with a ___ license?
> A: Yes. See LICENSE below. > Q: Why don't I get the output I expect?
> A: The two most common causes of this are > 1) scaling : is there a constant multiplier between what you got and what you want? > 2) mixed build environment -- all code must be compiled with same preprocessor > definitions for FIXED_POINT and kiss_fft_scalar > Q: Will you write/debug my code for me?
> A: Probably not unless you pay me. I am happy to answer pointed and topical questions, but > I may refer you to a book, a forum, or some other resource. ## PERFORMANCE (on Athlon XP 2100+, with gcc 2.96, float data type) Kiss performed 10000 1024-pt cpx ffts in .63 s of cpu time. For comparison, it took md5sum twice as long to process the same amount of data. Transforming 5 minutes of CD quality audio takes less than a second (nfft=1024). **DO NOT:** - use Kiss if you need the Fastest Fourier Transform in the World - ask me to add features that will bloat the code ## UNDER THE HOOD Kiss FFT uses a time decimation, mixed-radix, out-of-place FFT. If you give it an input buffer and output buffer that are the same, a temporary buffer will be created to hold the data. No static data is used. The core routines of kiss_fft are thread-safe (but not all of the tools directory).[ No scaling is done for the floating point version (for speed). Scaling is done both ways for the fixed-point version (for overflow prevention). Optimized butterflies are used for factors 2,3,4, and 5. The real (i.e. not complex) optimization code only works for even length ffts. It does two half-length FFTs in parallel (packed into real&imag), and then combines them via twiddling. The result is nfft/2+1 complex frequency bins from DC to Nyquist. If you don't know what this means, search the web. The fast convolution filtering uses the overlap-scrap method, slightly modified to put the scrap at the tail. ## LICENSE Revised BSD License, see COPYING for verbiage. Basically, "free to use&change, give credit where due, no guarantees" Note this license is compatible with GPL at one end of the spectrum and closed, commercial software at the other end. See http://www.fsf.org/licensing/licenses ## TODO - Add real optimization for odd length FFTs - Document/revisit the input/output fft scaling - Make doc describing the overlap (tail) scrap fast convolution filtering in kiss_fastfir.c - Test all the ./tools/ code with fixed point (kiss_fastfir.c doesn't work, maybe others) ## AUTHOR Mark Borgerding Mark@Borgerding.net boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/README.simd000066400000000000000000000045631516712004000311760ustar00rootroot00000000000000If you are reading this, it means you think you may be interested in using the SIMD extensions in kissfft to do 4 *separate* FFTs at once. Beware! Beyond here there be dragons! This API is not easy to use, is not well documented, and breaks the KISS principle. Still reading? Okay, you may get rewarded for your patience with a considerable speedup (2-3x) on intel x86 machines with SSE if you are willing to jump through some hoops. The basic idea is to use the packed 4 float __m128 data type as a scalar element. This means that the format is pretty convoluted. It performs 4 FFTs per fft call on signals A,B,C,D. For complex data, the data is interlaced as follows: rA0,rB0,rC0,rD0, iA0,iB0,iC0,iD0, rA1,rB1,rC1,rD1, iA1,iB1,iC1,iD1 ... where "rA0" is the real part of the zeroth sample for signal A Real-only data is laid out: rA0,rB0,rC0,rD0, rA1,rB1,rC1,rD1, ... Compile with gcc flags something like -O3 -mpreferred-stack-boundary=4 -DUSE_SIMD=1 -msse Be aware of SIMD alignment. This is the most likely cause of segfaults. The code within kissfft uses scratch variables on the stack. With SIMD, these must have addresses on 16 byte boundaries. Search on "SIMD alignment" for more info. Robin at Divide Concept was kind enough to share his code for formatting to/from the SIMD kissfft. I have not run it -- use it at your own risk. It appears to do 4xN and Nx4 transpositions (out of place). void SSETools::pack128(float* target, float* source, unsigned long size128) { __m128* pDest = (__m128*)target; __m128* pDestEnd = pDest+size128; float* source0=source; float* source1=source0+size128; float* source2=source1+size128; float* source3=source2+size128; while(pDest #define MAXFACTORS 32 /* e.g. an fft of length 128 has 4 factors as far as kissfft is concerned 4*4*4*2 */ struct kiss_fft_state{ int nfft; int inverse; int factors[2*MAXFACTORS]; kiss_fft_cpx twiddles[1]; }; /* Explanation of macros dealing with complex math: C_MUL(m,a,b) : m = a*b C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise C_SUB( res, a,b) : res = a - b C_SUBFROM( res , a) : res -= a C_ADDTO( res , a) : res += a * */ #ifdef FIXED_POINT #include #if (FIXED_POINT==32) # define FRACBITS 31 # define SAMPPROD int64_t #define SAMP_MAX INT32_MAX #define SAMP_MIN INT32_MIN #else # define FRACBITS 15 # define SAMPPROD int32_t #define SAMP_MAX INT16_MAX #define SAMP_MIN INT16_MIN #endif #if defined(CHECK_OVERFLOW) # define CHECK_OVERFLOW_OP(a,op,b) \ if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ KISS_FFT_WARNING("overflow (%d " #op" %d) = %ld", (a),(b),(SAMPPROD)(a) op (SAMPPROD)(b)); } #endif # define smul(a,b) ( (SAMPPROD)(a)*(b) ) # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) # define S_MUL(a,b) sround( smul(a,b) ) # define C_MUL(m,a,b) \ do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) # define DIVSCALAR(x,k) \ (x) = sround( smul( x, SAMP_MAX/k ) ) # define C_FIXDIV(c,div) \ do { DIVSCALAR( (c).r , div); \ DIVSCALAR( (c).i , div); }while (0) # define C_MULBYSCALAR( c, s ) \ do{ (c).r = sround( smul( (c).r , s ) ) ;\ (c).i = sround( smul( (c).i , s ) ) ; }while(0) #else /* not FIXED_POINT*/ # define S_MUL(a,b) ( (a)*(b) ) #define C_MUL(m,a,b) \ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) # define C_FIXDIV(c,div) /* NOOP */ # define C_MULBYSCALAR( c, s ) \ do{ (c).r *= (s);\ (c).i *= (s); }while(0) #endif #ifndef CHECK_OVERFLOW_OP # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ #endif #define C_ADD( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,+,(b).r)\ CHECK_OVERFLOW_OP((a).i,+,(b).i)\ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ }while(0) #define C_SUB( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,-,(b).r)\ CHECK_OVERFLOW_OP((a).i,-,(b).i)\ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ }while(0) #define C_ADDTO( res , a)\ do { \ CHECK_OVERFLOW_OP((res).r,+,(a).r)\ CHECK_OVERFLOW_OP((res).i,+,(a).i)\ (res).r += (a).r; (res).i += (a).i;\ }while(0) #define C_SUBFROM( res , a)\ do {\ CHECK_OVERFLOW_OP((res).r,-,(a).r)\ CHECK_OVERFLOW_OP((res).i,-,(a).i)\ (res).r -= (a).r; (res).i -= (a).i; \ }while(0) #ifdef FIXED_POINT # define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) # define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) # define HALF_OF(x) ((x)>>1) #elif defined(USE_SIMD) # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) # define HALF_OF(x) ((x)*_mm_set1_ps(.5)) #else # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) # define HALF_OF(x) ((x)*((kiss_fft_scalar).5)) #endif #define kf_cexp(x,phase) \ do{ \ (x)->r = KISS_FFT_COS(phase);\ (x)->i = KISS_FFT_SIN(phase);\ }while(0) /* a debugging function */ #define pcpx(c)\ KISS_FFT_DEBUG("%g + %gi\n",(double)((c)->r),(double)((c)->i)) #ifdef KISS_FFT_USE_ALLOCA // define this to allow use of alloca instead of malloc for temporary buffers // Temporary buffers are used in two case: // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. #include #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) #define KISS_FFT_TMP_FREE(ptr) #else #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) #endif #endif /* _kiss_fft_guts_h */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/kiss_fft.c000066400000000000000000000270121516712004000313310ustar00rootroot00000000000000/* * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. * This file is part of KISS FFT - https://github.com/mborgerding/kissfft * * SPDX-License-Identifier: BSD-3-Clause * See COPYING file for more information. */ #include "_kiss_fft_guts.h" /* The guts header contains all the multiplication and addition macros that are defined for fixed or floating point complex numbers. It also delares the kf_ internal functions. */ static void kf_bfly2( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx * Fout2; kiss_fft_cpx * tw1 = st->twiddles; kiss_fft_cpx t; Fout2 = Fout + m; do{ C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); C_MUL (t, *Fout2 , *tw1); tw1 += fstride; C_SUB( *Fout2 , *Fout , t ); C_ADDTO( *Fout , t ); ++Fout2; ++Fout; }while (--m); } static void kf_bfly4( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, const size_t m ) { kiss_fft_cpx *tw1,*tw2,*tw3; kiss_fft_cpx scratch[6]; size_t k=m; const size_t m2=2*m; const size_t m3=3*m; tw3 = tw2 = tw1 = st->twiddles; do { C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); C_MUL(scratch[0],Fout[m] , *tw1 ); C_MUL(scratch[1],Fout[m2] , *tw2 ); C_MUL(scratch[2],Fout[m3] , *tw3 ); C_SUB( scratch[5] , *Fout, scratch[1] ); C_ADDTO(*Fout, scratch[1]); C_ADD( scratch[3] , scratch[0] , scratch[2] ); C_SUB( scratch[4] , scratch[0] , scratch[2] ); C_SUB( Fout[m2], *Fout, scratch[3] ); tw1 += fstride; tw2 += fstride*2; tw3 += fstride*3; C_ADDTO( *Fout , scratch[3] ); if(st->inverse) { Fout[m].r = scratch[5].r - scratch[4].i; Fout[m].i = scratch[5].i + scratch[4].r; Fout[m3].r = scratch[5].r + scratch[4].i; Fout[m3].i = scratch[5].i - scratch[4].r; }else{ Fout[m].r = scratch[5].r + scratch[4].i; Fout[m].i = scratch[5].i - scratch[4].r; Fout[m3].r = scratch[5].r - scratch[4].i; Fout[m3].i = scratch[5].i + scratch[4].r; } ++Fout; }while(--k); } static void kf_bfly3( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, size_t m ) { size_t k=m; const size_t m2 = 2*m; kiss_fft_cpx *tw1,*tw2; kiss_fft_cpx scratch[5]; kiss_fft_cpx epi3; epi3 = st->twiddles[fstride*m]; tw1=tw2=st->twiddles; do{ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); C_MUL(scratch[1],Fout[m] , *tw1); C_MUL(scratch[2],Fout[m2] , *tw2); C_ADD(scratch[3],scratch[1],scratch[2]); C_SUB(scratch[0],scratch[1],scratch[2]); tw1 += fstride; tw2 += fstride*2; Fout[m].r = Fout->r - HALF_OF(scratch[3].r); Fout[m].i = Fout->i - HALF_OF(scratch[3].i); C_MULBYSCALAR( scratch[0] , epi3.i ); C_ADDTO(*Fout,scratch[3]); Fout[m2].r = Fout[m].r + scratch[0].i; Fout[m2].i = Fout[m].i - scratch[0].r; Fout[m].r -= scratch[0].i; Fout[m].i += scratch[0].r; ++Fout; }while(--k); } static void kf_bfly5( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; int u; kiss_fft_cpx scratch[13]; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx *tw; kiss_fft_cpx ya,yb; ya = twiddles[fstride*m]; yb = twiddles[fstride*2*m]; Fout0=Fout; Fout1=Fout0+m; Fout2=Fout0+2*m; Fout3=Fout0+3*m; Fout4=Fout0+4*m; tw=st->twiddles; for ( u=0; ur += scratch[7].r + scratch[8].r; Fout0->i += scratch[7].i + scratch[8].i; scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); C_SUB(*Fout1,scratch[5],scratch[6]); C_ADD(*Fout4,scratch[5],scratch[6]); scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); C_ADD(*Fout2,scratch[11],scratch[12]); C_SUB(*Fout3,scratch[11],scratch[12]); ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; } } /* perform the butterfly for one stage of a mixed radix FFT */ static void kf_bfly_generic( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m, int p ) { int u,k,q1,q; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx t; int Norig = st->nfft; kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); if (scratch == NULL){ KISS_FFT_ERROR("Memory allocation failed."); return; } for ( u=0; u=Norig) twidx-=Norig; C_MUL(t,scratch[q] , twiddles[twidx] ); C_ADDTO( Fout[ k ] ,t); } k += m; } } KISS_FFT_TMP_FREE(scratch); } static void kf_work( kiss_fft_cpx * Fout, const kiss_fft_cpx * f, const size_t fstride, int in_stride, int * factors, const kiss_fft_cfg st ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; #ifdef _OPENMP // use openmp extensions at the // top-level (not recursive) if (fstride==1 && p<=5 && m!=1) { int k; // execute the p different work units in different threads # pragma omp parallel for for (k=0;k floor_sqrt) p = n; /* no more factors, skip to end */ } n /= p; *facbuf++ = p; *facbuf++ = n; } while (n > 1); } /* * * User-callable function to allocate all necessary storage space for the fft. * * The return value is a contiguous block of memory, allocated with malloc. As such, * It can be freed with free(), rather than a kiss_fft-specific function. * */ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) { KISS_FFT_ALIGN_CHECK(mem) kiss_fft_cfg st=NULL; size_t memneeded = KISS_FFT_ALIGN_SIZE_UP(sizeof(struct kiss_fft_state) + sizeof(kiss_fft_cpx)*(nfft-1)); /* twiddle factors*/ if ( lenmem==NULL ) { st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); }else{ if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_cfg)mem; *lenmem = memneeded; } if (st) { int i; st->nfft=nfft; st->inverse = inverse_fft; for (i=0;iinverse) phase *= -1; kf_cexp(st->twiddles+i, phase ); } kf_factor(nfft,st->factors); } return st; } void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { //NOTE: this is not really an in-place FFT algorithm. //It just performs an out-of-place FFT into a temp buffer if (fout == NULL){ KISS_FFT_ERROR("fout buffer NULL."); return; } kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); if (tmpbuf == NULL){ KISS_FFT_ERROR("Memory allocation error."); return; } kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); KISS_FFT_TMP_FREE(tmpbuf); }else{ kf_work( fout, fin, 1,in_stride, st->factors,st ); } } void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { kiss_fft_stride(cfg,fin,fout,1); } void kiss_fft_cleanup(void) { // nothing needed any more } int kiss_fft_next_fast_size(int n) { while(1) { int m=n; while ( (m%2) == 0 ) m/=2; while ( (m%3) == 0 ) m/=3; while ( (m%5) == 0 ) m/=5; if (m<=1) break; /* n is completely factorable by twos, threes, and fives */ n++; } return n; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/kiss_fft.h000066400000000000000000000103521516712004000313350ustar00rootroot00000000000000/* * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. * This file is part of KISS FFT - https://github.com/mborgerding/kissfft * * SPDX-License-Identifier: BSD-3-Clause * See COPYING file for more information. */ #ifndef KISS_FFT_H #define KISS_FFT_H #include #include #include #include // Define KISS_FFT_SHARED macro to properly export symbols #ifdef KISS_FFT_SHARED # ifdef _WIN32 # ifdef KISS_FFT_BUILD # define KISS_FFT_API __declspec(dllexport) # else # define KISS_FFT_API __declspec(dllimport) # endif # else # define KISS_FFT_API __attribute__ ((visibility ("default"))) # endif #else # define KISS_FFT_API #endif #ifdef __cplusplus extern "C" { #endif /* ATTENTION! If you would like a : -- a utility that will handle the caching of fft objects -- real-only (no imaginary time component ) FFT -- a multi-dimensional FFT -- a command-line utility to perform ffts -- a command-line utility to perform fast-convolution filtering Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c in the tools/ directory. */ /* User may override KISS_FFT_MALLOC and/or KISS_FFT_FREE. */ #ifdef USE_SIMD # include # define kiss_fft_scalar __m128 # ifndef KISS_FFT_MALLOC # define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) # define KISS_FFT_ALIGN_CHECK(ptr) # define KISS_FFT_ALIGN_SIZE_UP(size) ((size + 15UL) & ~0xFUL) # endif # ifndef KISS_FFT_FREE # define KISS_FFT_FREE _mm_free # endif #else # define KISS_FFT_ALIGN_CHECK(ptr) # define KISS_FFT_ALIGN_SIZE_UP(size) (size) # ifndef KISS_FFT_MALLOC # define KISS_FFT_MALLOC malloc # endif # ifndef KISS_FFT_FREE # define KISS_FFT_FREE free # endif #endif #ifdef FIXED_POINT #include # if (FIXED_POINT == 32) # define kiss_fft_scalar int32_t # else # define kiss_fft_scalar int16_t # endif #else # ifndef kiss_fft_scalar /* default is float */ # define kiss_fft_scalar float # endif #endif typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; typedef struct kiss_fft_state* kiss_fft_cfg; /* * kiss_fft_alloc * * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. * * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); * * The return value from fft_alloc is a cfg buffer used internally * by the fft routine or NULL. * * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. * The returned value should be free()d when done to avoid memory leaks. * * The state can be placed in a user supplied buffer 'mem': * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, * then the function places the cfg in mem and the size used in *lenmem * and returns mem. * * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), * then the function returns NULL and places the minimum cfg * buffer size in *lenmem. * */ kiss_fft_cfg KISS_FFT_API kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); /* * kiss_fft(cfg,in_out_buf) * * Perform an FFT on a complex input buffer. * for a forward FFT, * fin should be f[0] , f[1] , ... ,f[nfft-1] * fout will be F[0] , F[1] , ... ,F[nfft-1] * Note that each element is complex and can be accessed like f[k].r and f[k].i * */ void KISS_FFT_API kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); /* A more generic version of the above function. It reads its input from every Nth sample. * */ void KISS_FFT_API kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); /* If kiss_fft_alloc allocated a buffer, it is one contiguous buffer and can be simply free()d when no longer needed*/ #define kiss_fft_free KISS_FFT_FREE /* Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up your compiler output to call this before you exit. */ void KISS_FFT_API kiss_fft_cleanup(void); /* * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) */ int KISS_FFT_API kiss_fft_next_fast_size(int n); /* for real ffts, we need an even size */ #define kiss_fftr_next_fast_size_real(n) \ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/kiss_fft_log.h000066400000000000000000000017121516712004000321760ustar00rootroot00000000000000/* * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. * This file is part of KISS FFT - https://github.com/mborgerding/kissfft * * SPDX-License-Identifier: BSD-3-Clause * See COPYING file for more information. */ #ifndef kiss_fft_log_h #define kiss_fft_log_h #define ERROR 1 #define WARNING 2 #define INFO 3 #define DEBUG 4 #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #if defined(NDEBUG) # define KISS_FFT_LOG_MSG(severity, ...) ((void)0) #else # define KISS_FFT_LOG_MSG(severity, ...) \ fprintf(stderr, "[" #severity "] " __FILE__ ":" TOSTRING(__LINE__) " "); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n") #endif #define KISS_FFT_ERROR(...) KISS_FFT_LOG_MSG(ERROR, __VA_ARGS__) #define KISS_FFT_WARNING(...) KISS_FFT_LOG_MSG(WARNING, __VA_ARGS__) #define KISS_FFT_INFO(...) KISS_FFT_LOG_MSG(INFO, __VA_ARGS__) #define KISS_FFT_DEBUG(...) KISS_FFT_LOG_MSG(DEBUG, __VA_ARGS__) #endif /* kiss_fft_log_h */boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/kiss_fftr.c000066400000000000000000000112771516712004000315210ustar00rootroot00000000000000/* * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved. * This file is part of KISS FFT - https://github.com/mborgerding/kissfft * * SPDX-License-Identifier: BSD-3-Clause * See COPYING file for more information. */ #include "kiss_fftr.h" #include "_kiss_fft_guts.h" struct kiss_fftr_state{ kiss_fft_cfg substate; kiss_fft_cpx * tmpbuf; kiss_fft_cpx * super_twiddles; #ifdef USE_SIMD void * pad; #endif }; kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) { KISS_FFT_ALIGN_CHECK(mem) int i; kiss_fftr_cfg st = NULL; size_t subsize = 0, memneeded; if (nfft & 1) { KISS_FFT_ERROR("Real FFT optimization must be even."); return NULL; } nfft >>= 1; kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); if (lenmem == NULL) { st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); } else { if (*lenmem >= memneeded) st = (kiss_fftr_cfg) mem; *lenmem = memneeded; } if (!st) return NULL; st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); st->super_twiddles = st->tmpbuf + nfft; kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); for (i = 0; i < nfft/2; ++i) { double phase = -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); if (inverse_fft) phase *= -1; kf_cexp (st->super_twiddles+i,phase); } return st; } void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) { /* input buffer timedata is stored row-wise */ int k,ncfft; kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; if ( st->substate->inverse) { KISS_FFT_ERROR("kiss fft usage error: improper alloc"); return;/* The caller did not call the correct function */ } ncfft = st->substate->nfft; /*perform the parallel fft of two real signals packed in real,imag*/ kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); /* The real part of the DC element of the frequency spectrum in st->tmpbuf * contains the sum of the even-numbered elements of the input time sequence * The imag part is the sum of the odd-numbered elements * * The sum of tdc.r and tdc.i is the sum of the input time sequence. * yielding DC of input time sequence * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... * yielding Nyquist bin of input time sequence */ tdc.r = st->tmpbuf[0].r; tdc.i = st->tmpbuf[0].i; C_FIXDIV(tdc,2); CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); freqdata[0].r = tdc.r + tdc.i; freqdata[ncfft].r = tdc.r - tdc.i; #ifdef USE_SIMD freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); #else freqdata[ncfft].i = freqdata[0].i = 0; #endif for ( k=1;k <= ncfft/2 ; ++k ) { fpk = st->tmpbuf[k]; fpnk.r = st->tmpbuf[ncfft-k].r; fpnk.i = - st->tmpbuf[ncfft-k].i; C_FIXDIV(fpk,2); C_FIXDIV(fpnk,2); C_ADD( f1k, fpk , fpnk ); C_SUB( f2k, fpk , fpnk ); C_MUL( tw , f2k , st->super_twiddles[k-1]); freqdata[k].r = HALF_OF(f1k.r + tw.r); freqdata[k].i = HALF_OF(f1k.i + tw.i); freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); } } void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) { /* input buffer timedata is stored row-wise */ int k, ncfft; if (st->substate->inverse == 0) { KISS_FFT_ERROR("kiss fft usage error: improper alloc"); return;/* The caller did not call the correct function */ } ncfft = st->substate->nfft; st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; C_FIXDIV(st->tmpbuf[0],2); for (k = 1; k <= ncfft / 2; ++k) { kiss_fft_cpx fk, fnkc, fek, fok, tmp; fk = freqdata[k]; fnkc.r = freqdata[ncfft - k].r; fnkc.i = -freqdata[ncfft - k].i; C_FIXDIV( fk , 2 ); C_FIXDIV( fnkc , 2 ); C_ADD (fek, fk, fnkc); C_SUB (tmp, fk, fnkc); C_MUL (fok, tmp, st->super_twiddles[k-1]); C_ADD (st->tmpbuf[k], fek, fok); C_SUB (st->tmpbuf[ncfft - k], fek, fok); #ifdef USE_SIMD st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); #else st->tmpbuf[ncfft - k].i *= -1; #endif } kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/freesurround/kiss_fft/kiss_fftr.h000066400000000000000000000021701516712004000315160ustar00rootroot00000000000000/* * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved. * This file is part of KISS FFT - https://github.com/mborgerding/kissfft * * SPDX-License-Identifier: BSD-3-Clause * See COPYING file for more information. */ #ifndef KISS_FTR_H #define KISS_FTR_H #include "kiss_fft.h" #ifdef __cplusplus extern "C" { #endif /* Real optimized version can save about 45% cpu time vs. complex fft of a real seq. */ typedef struct kiss_fftr_state *kiss_fftr_cfg; kiss_fftr_cfg KISS_FFT_API kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); /* nfft must be even If you don't care to allocate space, use mem = lenmem = NULL */ void KISS_FFT_API kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); /* input timedata has nfft scalar points output freqdata has nfft/2+1 complex points */ void KISS_FFT_API kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); /* input freqdata has nfft/2+1 complex points output timedata has nfft scalar points */ #define kiss_fftr_free KISS_FFT_FREE #ifdef __cplusplus } #endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/surround.cpp000066400000000000000000000175451516712004000254210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "surround.h" #include "config.h" namespace BoCA { namespace Channel { const Layout FreeSurround_2_1 = { FrontLeft, FrontRight, LFE }; const Layout FreeSurround_3_1 = { FrontLeft, FrontCenter, FrontRight, LFE }; const Layout FreeSurround_4_1 = { FrontLeft, FrontRight, RearLeft, RearRight, LFE }; const Layout FreeSurround_5_1 = { FrontLeft, FrontCenter, FrontRight, RearLeft, RearRight, LFE }; const Layout FreeSurround_6_1 = { FrontLeft, FrontCenter, FrontRight, SideLeft, SideRight, RearCenter, LFE }; const Layout FreeSurround_7_1 = { FrontLeft, FrontCenter, FrontRight, SideLeft, SideRight, RearLeft, RearRight, LFE }; }; }; const String &BoCA::DSPSurround::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Matrix Surround Decoder")).Append(" \ 1.0 \ surround-dsp \ dsp \ \ \ \ \ \ "); return componentSpecs; } BoCA::DSPSurround::DSPSurround() { configLayer = NIL; decoder = NIL; first = True; blockSize = 4096; channelSetup = (Int) cs_5point1; } BoCA::DSPSurround::~DSPSurround() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPSurround::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); channelSetup = config->GetIntValue(ConfigureSurround::ConfigID, "ChannelSetup", 6); Bool redirectBass = config->GetIntValue(ConfigureSurround::ConfigID, "RedirectBass", True); switch (channelSetup) { case 3: channelSetup = (Int) cs_stereo; break; case 4: channelSetup = (Int) cs_3stereo; break; case 5: channelSetup = (Int) cs_4point1; break; case 6: channelSetup = (Int) cs_5point1; break; case 7: channelSetup = (Int) cs_6point1; break; case 8: channelSetup = (Int) cs_7point1; break; } /* Instantiate FreeSurround decoder. */ const Format &format = track.GetFormat(); Int minBlockSize = Math::Pow(Int(2), Int(Math::Floor(Math::Log2(format.rate / 10)))); Int maxBlockSize = Math::Pow(Int(2), Int(Math::Ceil(Math::Log2(format.rate / 10)))); blockSize = Math::Abs(format.rate / 10 - minBlockSize) < Math::Abs(format.rate / 10 - maxBlockSize) ? minBlockSize : maxBlockSize; decoder = new freesurround_decoder(channel_setup(channelSetup), blockSize); decoder->bass_redirection(redirectBass); first = True; /* Set output channels. */ if (format.channels == 2) this->format.channels = freesurround_decoder::num_channels(channel_setup(channelSetup)); return True; } Bool BoCA::DSPSurround::Deactivate() { /* Free FreeSurround decoder. */ delete decoder; return True; } Int BoCA::DSPSurround::TransformData(Buffer &data) { const Format &format = track.GetFormat(); /* Only work on stereo input. */ if (format.channels != 2) return data.Size(); /* Copy data to samples buffer. */ Int size = data.Size() / sizeof(Float32); samplesBuffer.Resize(samplesBuffer.Size() + size); memcpy(samplesBuffer + samplesBuffer.Size() - size, data, data.Size()); data.Resize(0); /* Decode samples. */ Int numInputSamples = blockSize * format.channels; Int numOutputSamples = blockSize * this->format.channels; while (samplesBuffer.Size() >= numInputSamples) { Float32 *samples = decoder->decode(samplesBuffer); Int offset = 0; if (first) { numOutputSamples /= 2; offset = numOutputSamples; first = False; } /* Append output samples to data. */ Int numOutputBytes = numOutputSamples * sizeof(Float32); data.Resize(data.Size() + numOutputBytes); memcpy(data + data.Size() - numOutputBytes, samples + offset, numOutputBytes); /* Remove input samples from buffer. */ memmove(samplesBuffer, samplesBuffer + numInputSamples, (samplesBuffer.Size() - numInputSamples) * sizeof(Float32)); samplesBuffer.Resize(samplesBuffer.Size() - numInputSamples); } /* Reorder channels to BoCA default order. */ if (channelSetup == (Int) cs_stereo ) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_2_1, Channel::Default_2_1); else if (channelSetup == (Int) cs_3stereo) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_3_1, Channel::Default_3_1); else if (channelSetup == (Int) cs_4point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_4_1, Channel::Default_4_1); else if (channelSetup == (Int) cs_5point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_5_1, Channel::Default_5_1); else if (channelSetup == (Int) cs_6point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_6_1, Channel::Default_6_1); else if (channelSetup == (Int) cs_7point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_7_1, Channel::Default_7_1); return data.Size(); } Int BoCA::DSPSurround::Flush(Buffer &data) { const Format &format = track.GetFormat(); /* Only work on stereo input. */ if (format.channels != 2) return 0; /* Prepare samples buffer. */ Int inputSamplesLeft = samplesBuffer.Size(); Int outputSamplesLeft = (inputSamplesLeft / format.channels + blockSize / 2) * this->format.channels; samplesBuffer.Resize(blockSize * format.channels); memset(samplesBuffer + inputSamplesLeft, 0, (samplesBuffer.Size() - inputSamplesLeft) * sizeof(Float32)); /* Pass final samples to decoder. */ while (outputSamplesLeft) { Float32 *samples = decoder->decode(samplesBuffer); /* Append output samples to data. */ Int numOutputSamples = Math::Min(outputSamplesLeft, blockSize * this->format.channels); Int numOutputBytes = numOutputSamples * sizeof(Float32); data.Resize(data.Size() + numOutputBytes); memcpy(data + data.Size() - numOutputBytes, samples, numOutputBytes); outputSamplesLeft -= numOutputSamples; /* Clear input buffer. */ memset(samplesBuffer, 0, samplesBuffer.Size() * sizeof(Float32)); } /* Reorder channels to BoCA default order. */ if (channelSetup == (Int) cs_stereo ) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_2_1, Channel::Default_2_1); else if (channelSetup == (Int) cs_3stereo) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_3_1, Channel::Default_3_1); else if (channelSetup == (Int) cs_4point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_4_1, Channel::Default_4_1); else if (channelSetup == (Int) cs_5point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_5_1, Channel::Default_5_1); else if (channelSetup == (Int) cs_6point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_6_1, Channel::Default_6_1); else if (channelSetup == (Int) cs_7point1) Utilities::ChangeChannelOrder(data, this->format, Channel::FreeSurround_7_1, Channel::Default_7_1); return data.Size(); } ConfigLayer *BoCA::DSPSurround::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureSurround(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/surround/surround.h000066400000000000000000000023751516712004000250610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include BoCA_BEGIN_COMPONENT(DSPSurround) namespace BoCA { class DSPSurround : public CS::DSPComponent { private: ConfigLayer *configLayer; freesurround_decoder *decoder; Bool first; Int blockSize; Int channelSetup; Buffer samplesBuffer; public: static const String &GetComponentSpecs(); DSPSurround(); ~DSPSurround(); Bool Activate(); Bool Deactivate(); Int TransformData(Buffer &); Int Flush(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPSurround) BoCA_END_COMPONENT(DSPSurround) boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/000077500000000000000000000000001516712004000224465ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/Makefile000066400000000000000000000011311516712004000241020ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = volume TYPE = dsp VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o volume.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/config.cpp000066400000000000000000000045551516712004000244300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureVolume::ConfigID = "Volume"; BoCA::ConfigureVolume::ConfigureVolume() { const Config *config = Config::Get(); qdB = config->GetIntValue(ConfigID, "qdB", 0); I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Volume"); group_volume = new GroupBox(i18n->TranslateString("Volume adjustment"), Point(7, 11), Size(350, 40)); text_volume = new Text(i18n->AddColon(i18n->TranslateString("Adjustment")), Point(10, 15)); text_db_value = new Text(i18n->TranslateString("%1 dB").Replace("%1", "+24.00"), Point(12, 15)); text_db_value->SetX(text_db_value->GetUnscaledTextWidth() + 8); text_db_value->SetOrientation(OR_UPPERRIGHT); slider_db = new Slider(Point(text_volume->GetUnscaledTextWidth() + 16, 13), Size(group_volume->GetWidth() - text_volume->GetUnscaledTextWidth() - text_db_value->GetUnscaledTextWidth() - 32, 0), OR_HORZ, &qdB, -96, 96); slider_db->onValueChange.Connect(&ConfigureVolume::OnChangeValue, this); OnChangeValue(); group_volume->Add(text_volume); group_volume->Add(slider_db); group_volume->Add(text_db_value); Add(group_volume); SetSize(Size(364, 58)); } BoCA::ConfigureVolume::~ConfigureVolume() { DeleteObject(group_volume); DeleteObject(text_volume); DeleteObject(slider_db); DeleteObject(text_db_value); } Int BoCA::ConfigureVolume::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "qdB", qdB); return Success(); } Void BoCA::ConfigureVolume::OnChangeValue() { I18n *i18n = I18n::Get(); i18n->SetContext("DSP::Volume"); text_db_value->SetText(i18n->TranslateString("%1 dB").Replace("%1", String(qdB > 0 ? "+" : NIL).Append(String::FromFloat(qdB / 4.0)) .Append( qdB % 4 == 0 ? ".00" : NIL) .Append(Math::Abs(qdB % 4) == 2 ? "0" : NIL))); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/config.h000066400000000000000000000021321516712004000240620ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_VOLUMECONFIG #define H_VOLUMECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureVolume : public ConfigLayer { private: GroupBox *group_volume; Text *text_volume; Slider *slider_db; Text *text_db_value; Int qdB; public: static const String ConfigID; ConfigureVolume(); ~ConfigureVolume(); Int SaveSettings(); slots: Void OnChangeValue(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/volume.cpp000066400000000000000000000041451516712004000244650ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "volume.h" #include "config.h" const String &BoCA::DSPVolume::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::DSP"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Volume Adjustment")).Append(" \ 1.0 \ volume-dsp \ dsp \ \ \ \ "); return componentSpecs; } BoCA::DSPVolume::DSPVolume() { configLayer = NIL; scaleFactor = 1.0; } BoCA::DSPVolume::~DSPVolume() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DSPVolume::Activate() { /* Get configuration. */ const Config *config = GetConfiguration(); scaleFactor = Math::Sqrt(Math::Pow(10.0, config->GetIntValue(ConfigureVolume::ConfigID, "qdB", 0) / 40.0)); return True; } Int BoCA::DSPVolume::TransformData(Buffer &data) { /* Check if we need to do anything. */ if (Math::Abs(scaleFactor - 1.0) < 0.00001) return data.Size(); /* Adjust volume. */ Int numSamples = data.Size() / sizeof(Float32); Float32 *samples = (Float32 *) (UnsignedByte *) data; for (Int i = 0; i < numSamples; i++) samples[i] *= scaleFactor; return data.Size(); } ConfigLayer *BoCA::DSPVolume::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureVolume(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/dsp/volume/volume.h000066400000000000000000000020341516712004000241250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(DSPVolume) namespace BoCA { class DSPVolume : public CS::DSPComponent { private: ConfigLayer *configLayer; Float scaleFactor; public: static const String &GetComponentSpecs(); DSPVolume(); ~DSPVolume(); Bool Activate(); Int TransformData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_DSP_COMPONENT(DSPVolume) BoCA_END_COMPONENT(DSPVolume) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/000077500000000000000000000000001516712004000217705ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/Makefile000077500000000000000000000017111516712004000234330ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = fdkaac flac lame mac meh opus sndfile speex vorbis ifeq ($(USE_WINE),True) FOLDERS += coreaudioconnect endif ifeq ($(BUILD_OSX),True) FOLDERS += coreaudio else ifeq ($(BUILD_WIN32),True) FOLDERS += coreaudio wma ifeq ($(BUILD_ARM64),True) FOLDERS += coreaudioconnect endif endif .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/000077500000000000000000000000001516712004000235255ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/Makefile000077500000000000000000000012331516712004000251670ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = bladeenc TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = bladeenc.o config.o dllinterface.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/bladeenc.cpp000066400000000000000000000200511516712004000257640ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "bladeenc.h" #include "config.h" const String &BoCA::EncoderBlade::GetComponentSpecs() { static String componentSpecs; if (bladedll != NIL) { componentSpecs = " \ \ \ \ BladeEnc MP3 Encoder %VERSION% \ 1.0 \ bladeenc-enc \ encoder \ \ MPEG 1 Audio Layer 3 \ mp3 \ ID3v1 \ ID3v2 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "; BE_VERSION beVer; ex_beVersion(&beVer); componentSpecs.Replace("%VERSION%", String("v").Append(String::FromInt(beVer.byMajorVersion)).Append(".").Append(String::FromInt(beVer.byMinorVersion))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadBladeDLL(); } Void smooth::DetachDLL() { FreeBladeDLL(); } BoCA::EncoderBlade::EncoderBlade() : beConfig() { configLayer = NIL; config = NIL; handle = NIL; frameSize = 0; } BoCA::EncoderBlade::~EncoderBlade() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderBlade::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Create and configure BladeEnc encoder. */ beConfig.dwConfig = BE_CONFIG_MP3; beConfig.format.mp3.dwSampleRate = format.rate; if (format.channels == 2) { if (config->GetIntValue(ConfigureBlade::ConfigID, "DualChannel", 0)) beConfig.format.mp3.byMode = BE_MP3_MODE_DUALCHANNEL; else beConfig.format.mp3.byMode = BE_MP3_MODE_STEREO; } else if (format.channels == 1) { beConfig.format.mp3.byMode = BE_MP3_MODE_MONO; } beConfig.format.mp3.wBitrate = config->GetIntValue(ConfigureBlade::ConfigID, "Bitrate", 0); beConfig.format.mp3.bCopyright = config->GetIntValue(ConfigureBlade::ConfigID, "Copyright", 0); beConfig.format.mp3.bCRC = config->GetIntValue(ConfigureBlade::ConfigID, "CRC", 0); beConfig.format.mp3.bOriginal = config->GetIntValue(ConfigureBlade::ConfigID, "Original", 1); beConfig.format.mp3.bPrivate = config->GetIntValue(ConfigureBlade::ConfigID, "Private", 0); unsigned long bufferSize = 0; ex_beInitStream(&beConfig, &frameSize, &bufferSize, &handle); outBuffer.Resize(bufferSize); /* Write ID3v2 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v2", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } return True; } Bool BoCA::EncoderBlade::Deactivate() { const Info &info = track.GetInfo(); /* Output remaining samples. */ unsigned long bytes = 0; if (ex_beEncodeChunk(handle, samplesBuffer.Size(), (short *) samplesBuffer, outBuffer, &bytes) == BE_ERR_SUCCESSFUL) { driver->WriteData(outBuffer, bytes); } /* Finalize stream. */ if (ex_beDeinitStream(handle, outBuffer, &bytes) == BE_ERR_SUCCESSFUL) { driver->WriteData(outBuffer, bytes); } ex_beCloseStream(handle); /* Write ID3v1 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v1", False) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } /* Update ID3v2 tag with correct chapter marks. */ if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True) && config->GetIntValue("Tags", "EnableID3v2", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderBlade::WriteData(Buffer &data) { /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ Int dataLength = 0; Int framesProcessed = 0; while (samplesBuffer.Size() - framesProcessed * frameSize >= frameSize) { unsigned long bytes = 0; if (ex_beEncodeChunk(handle, frameSize, (short *) samplesBuffer + framesProcessed * frameSize, outBuffer, &bytes) == BE_ERR_SUCCESSFUL) { dataLength += bytes; driver->WriteData(outBuffer, bytes); } framesProcessed++; } memmove(samplesBuffer, samplesBuffer + framesProcessed * frameSize, sizeof(short) * (samplesBuffer.Size() - framesProcessed * frameSize)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * frameSize); return dataLength; } Bool BoCA::EncoderBlade::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "bladeenc-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureBlade::ConfigID, "Bitrate", 192); } /* Get command line settings. */ Int bitrate = config->GetIntValue(ConfigureBlade::ConfigID, "Bitrate", 192); if (config->GetIntValue(encoderID, "Set Bitrate", False)) bitrate = config->GetIntValue(encoderID, "Bitrate", bitrate); /* Set configuration values. */ config->SetIntValue(ConfigureBlade::ConfigID, "Bitrate", Math::Max(32, Math::Min(320, bitrate))); return True; } ConfigLayer *BoCA::EncoderBlade::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureBlade(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/bladeenc.h000066400000000000000000000024521516712004000254360ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderBlade) namespace BoCA { class EncoderBlade : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; BE_CONFIG beConfig; unsigned long handle; unsigned long frameSize; Buffer outBuffer; Buffer samplesBuffer; static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderBlade(); ~EncoderBlade(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderBlade) BoCA_END_COMPONENT(EncoderBlade) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/config.cpp000077500000000000000000000134551516712004000255110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureBlade::ConfigID = "BladeEnc"; BoCA::ConfigureBlade::ConfigureBlade() { const Config *config = Config::Get(); bitrate = GetSliderValue(); crc = config->GetIntValue(ConfigID, "CRC", 0); copyright = config->GetIntValue(ConfigID, "Copyright", 0); original = config->GetIntValue(ConfigID, "Original", 1); priv = config->GetIntValue(ConfigID, "Private", 0); dualchannel = config->GetIntValue(ConfigID, "DualChannel", 0); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::BladeEnc"); group_bit = new GroupBox(i18n->TranslateString("Bitrate"), Point(7, 11), Size(179, 43)); slider_bit = new Slider(Point(10, 13), Size(114, 0), OR_HORZ, &bitrate, 0, 13); slider_bit->onValueChange.Connect(&ConfigureBlade::SetBitrate, this); text_bit = new Text("320 kbit", Point(131, 15)); group_bit->Add(slider_bit); group_bit->Add(text_bit); group_copyright = new GroupBox(i18n->TranslateString("Copyright bit"), Point(194, 11), Size(179, 43)); check_copyright = new CheckBox(i18n->TranslateString("Set Copyright bit"), Point(10, 13), Size(158, 0), ©right); group_copyright->Add(check_copyright); group_crc = new GroupBox(i18n->TranslateString("CRC"), Point(7, 66), Size(179, 43)); check_crc = new CheckBox(i18n->TranslateString("Enable CRC"), Point(10, 13), Size(158, 0), &crc); group_crc->Add(check_crc); group_original = new GroupBox(i18n->TranslateString("Original bit"), Point(194, 66), Size(179, 43)); check_original = new CheckBox(i18n->TranslateString("Set Original bit"), Point(10, 13), Size(158, 0), &original); group_original->Add(check_original); group_dualchannel = new GroupBox(i18n->TranslateString("Channels"), Point(7, 121), Size(179, 43)); check_dualchannel = new CheckBox(i18n->TranslateString("Dual channel encoding"), Point(10, 13), Size(158, 0), &dualchannel); group_dualchannel->Add(check_dualchannel); group_private = new GroupBox(i18n->TranslateString("Private bit"), Point(194, 121), Size(179, 43)); check_private = new CheckBox(i18n->TranslateString("Set Private bit"), Point(10, 13), Size(158, 0), &priv); group_private->Add(check_private); Int maxTextSize = Math::Max(Math::Max(Math::Max(check_copyright->GetUnscaledTextWidth(), check_private->GetUnscaledTextWidth()), check_crc->GetUnscaledTextWidth()), Math::Max(check_original->GetUnscaledTextWidth(), check_dualchannel->GetUnscaledTextWidth())); check_copyright->SetWidth(Math::Max(158, maxTextSize + 21)); check_original->SetWidth(check_copyright->GetWidth()); check_private->SetWidth(check_copyright->GetWidth()); check_crc->SetWidth(check_copyright->GetWidth()); check_dualchannel->SetWidth(check_copyright->GetWidth()); group_bit->SetWidth(check_copyright->GetWidth() + 20); group_copyright->SetWidth(group_bit->GetWidth()); group_original->SetWidth(group_bit->GetWidth()); group_private->SetWidth(group_bit->GetWidth()); group_crc->SetWidth(group_bit->GetWidth()); group_dualchannel->SetWidth(group_bit->GetWidth()); group_copyright->SetX(group_bit->GetWidth() + 15); group_original->SetX(group_bit->GetWidth() + 15); group_private->SetX(group_bit->GetWidth() + 15); text_bit->SetX(group_bit->GetWidth() - 10 - text_bit->GetUnscaledTextWidth()); slider_bit->SetWidth(group_bit->GetWidth() - 28 - text_bit->GetUnscaledTextWidth()); SetBitrate(); Add(group_bit); Add(group_crc); Add(group_copyright); Add(group_original); Add(group_private); Add(group_dualchannel); SetSize(Size(2 * group_bit->GetWidth() + 22, 171)); } BoCA::ConfigureBlade::~ConfigureBlade() { DeleteObject(group_bit); DeleteObject(slider_bit); DeleteObject(text_bit); DeleteObject(group_crc); DeleteObject(check_crc); DeleteObject(group_copyright); DeleteObject(check_copyright); DeleteObject(group_original); DeleteObject(check_original); DeleteObject(group_private); DeleteObject(check_private); DeleteObject(group_dualchannel); DeleteObject(check_dualchannel); } Int BoCA::ConfigureBlade::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Bitrate", GetBitrate()); config->SetIntValue(ConfigID, "CRC", crc); config->SetIntValue(ConfigID, "Copyright", copyright); config->SetIntValue(ConfigID, "Original", original); config->SetIntValue(ConfigID, "Private", priv); config->SetIntValue(ConfigID, "DualChannel", dualchannel); return Success(); } Void BoCA::ConfigureBlade::SetBitrate() { text_bit->SetText(String::FromInt(GetBitrate()).Append(" kbit")); } Int BoCA::ConfigureBlade::GetBitrate() { switch (bitrate) { case 0: return 32; case 1: return 40; case 2: return 48; case 3: return 56; case 4: return 64; case 5: return 80; case 6: return 96; case 7: return 112; case 8: return 128; case 9: return 160; case 10: return 192; case 11: return 224; case 12: return 256; case 13: return 320; default: return 128; } } Int BoCA::ConfigureBlade::GetSliderValue() { switch (Config::Get()->GetIntValue("BladeEnc", "Bitrate", 192)) { case 32: return 0; case 40: return 1; case 48: return 2; case 56: return 3; case 64: return 4; case 80: return 5; case 96: return 6; case 112: return 7; case 128: return 8; case 160: return 9; case 192: return 10; case 224: return 11; case 256: return 12; case 320: return 13; default: return 8; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/config.h000077500000000000000000000027731516712004000251570ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BLADECONFIG #define H_BLADECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureBlade : public ConfigLayer { private: GroupBox *group_bit; Slider *slider_bit; Text *text_bit; GroupBox *group_crc; CheckBox *check_crc; GroupBox *group_copyright; CheckBox *check_copyright; GroupBox *group_original; CheckBox *check_original; GroupBox *group_private; CheckBox *check_private; GroupBox *group_dualchannel; CheckBox *check_dualchannel; Int bitrate; Bool crc; Bool copyright; Bool original; Bool priv; Bool dualchannel; slots: Void SetBitrate(); Int GetBitrate(); Int GetSliderValue(); public: static const String ConfigID; ConfigureBlade(); ~ConfigureBlade(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/dllinterface.cpp000077500000000000000000000031611516712004000266710ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BEINITSTREAM ex_beInitStream = NIL; BEENCODECHUNK ex_beEncodeChunk = NIL; BEDEINITSTREAM ex_beDeinitStream = NIL; BECLOSESTREAM ex_beCloseStream = NIL; BEVERSION ex_beVersion = NIL; DynamicLoader *bladedll = NIL; Bool LoadBladeDLL() { bladedll = BoCA::Utilities::LoadCodecDLL("BladeEnc"); if (bladedll == NIL) return False; ex_beInitStream = (BEINITSTREAM) bladedll->GetFunctionAddress("beInitStream"); ex_beEncodeChunk = (BEENCODECHUNK) bladedll->GetFunctionAddress("beEncodeChunk"); ex_beDeinitStream = (BEDEINITSTREAM) bladedll->GetFunctionAddress("beDeinitStream"); ex_beCloseStream = (BECLOSESTREAM) bladedll->GetFunctionAddress("beCloseStream"); ex_beVersion = (BEVERSION) bladedll->GetFunctionAddress("beVersion"); if (ex_beInitStream == NIL || ex_beEncodeChunk == NIL || ex_beDeinitStream == NIL || ex_beCloseStream == NIL || ex_beVersion == NIL) { FreeBladeDLL(); return False; } return True; } Void FreeBladeDLL() { Object::DeleteObject(bladedll); bladedll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bladeenc/dllinterface.h000077500000000000000000000024041516712004000263350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *bladedll; Bool LoadBladeDLL(); Void FreeBladeDLL(); typedef BE_ERR (*BEINITSTREAM) (PBE_CONFIG, PDWORD, PDWORD, PHBE_STREAM); typedef BE_ERR (*BEENCODECHUNK) (HBE_STREAM, DWORD, PSHORT, PBYTE, PDWORD); typedef BE_ERR (*BEDEINITSTREAM) (HBE_STREAM, PBYTE, PDWORD); typedef BE_ERR (*BECLOSESTREAM) (HBE_STREAM); typedef VOID (*BEVERSION) (PBE_VERSION); extern BEINITSTREAM ex_beInitStream; extern BEENCODECHUNK ex_beEncodeChunk; extern BEDEINITSTREAM ex_beDeinitStream; extern BECLOSESTREAM ex_beCloseStream; extern BEVERSION ex_beVersion; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/000077500000000000000000000000001516712004000227215ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/Makefile000077500000000000000000000012231516712004000243620ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = bonk TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = bonk.o config.o dllinterface.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/bonk.cpp000066400000000000000000000223101516712004000243540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "bonk.h" #include "config.h" const String &BoCA::EncoderBonk::GetComponentSpecs() { static String componentSpecs; if (bonkdll != NIL) { componentSpecs = " \ \ \ \ Bonk Audio Encoder %VERSION% \ 1.0 \ bonk-enc \ encoder \ \ Bonk Audio Files \ bonk \ \ \ \ \ 0 \ 2 \ \ \ 0 \ 512 \ \ \ 1 \ 10 \ \ \ \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(ex_bonk_get_version_string())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadBonkDLL(); } Void smooth::DetachDLL() { FreeBonkDLL(); } BoCA::EncoderBonk::EncoderBonk() { configLayer = NIL; config = NIL; encoder = NIL; frameSize = 0; } BoCA::EncoderBonk::~EncoderBonk() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderBonk::IsLossless() const { const Config *config = GetConfiguration(); return config->GetIntValue(ConfigureBonk::ConfigID, "Lossless", 0); } Bool BoCA::EncoderBonk::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Configure and create Bonk encoder. */ frameSize = Int(1024.0 * format.rate / 44100) * format.channels * (config->GetIntValue(ConfigureBonk::ConfigID, "Lossless", 0) ? 1 : config->GetIntValue(ConfigureBonk::ConfigID, "Downsampling", 2)); dataBuffer.Resize(131072); encoder = ex_bonk_encoder_create(); /* Write ID3v2 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v2", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); ex_bonk_encoder_set_id3_data(encoder, id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); dataBuffer.Resize(dataBuffer.Size() + id3Buffer.Size()); } } /* Init Bonk encoder. */ ex_bonk_encoder_init(encoder, (unsigned int) Math::Max(track.length * format.channels, (Int64) 0), format.rate, format.channels, config->GetIntValue(ConfigureBonk::ConfigID, "Lossless", 0), config->GetIntValue(ConfigureBonk::ConfigID, "JointStereo", 0), config->GetIntValue(ConfigureBonk::ConfigID, "Predictor", 32), config->GetIntValue(ConfigureBonk::ConfigID, "Lossless", 0) ? 1 : config->GetIntValue(ConfigureBonk::ConfigID, "Downsampling", 2), int(1024.0 * format.rate / 44100), 0.05 * (double) config->GetIntValue(ConfigureBonk::ConfigID, "Quantization", 8)); return True; } Bool BoCA::EncoderBonk::Deactivate() { static Endianness endianness = CPU().GetEndianness(); /* Output remaining samples. */ Int bytes = ex_bonk_encoder_encode_packet(encoder, samplesBuffer, samplesBuffer.Size(), dataBuffer, dataBuffer.Size()); driver->WriteData(dataBuffer, bytes); /* Finalize stream. */ bytes = ex_bonk_encoder_finish(encoder, dataBuffer, dataBuffer.Size()); if (bytes > dataBuffer.Size()) { dataBuffer.Resize(bytes); bytes = ex_bonk_encoder_finish(encoder, dataBuffer, dataBuffer.Size()); } driver->WriteData(dataBuffer, bytes); if (track.length == -1) { Int sample_count = ex_bonk_encoder_get_sample_count(encoder); driver->Seek(ex_bonk_encoder_get_sample_count_offset(encoder)); if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &sample_count) + i, 1); else for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &sample_count) + i, 1); } ex_bonk_encoder_close(encoder); /* Update ID3v2 tag with correct chapter marks. */ if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True) && config->GetIntValue("Tags", "EnableID3v2", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(2); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderBonk::WriteData(Buffer &data) { /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ Int dataLength = 0; Int framesProcessed = 0; while (samplesBuffer.Size() - framesProcessed * frameSize >= frameSize) { Int bytes = ex_bonk_encoder_encode_packet(encoder, samplesBuffer + framesProcessed * frameSize, frameSize, dataBuffer, dataBuffer.Size()); dataLength += bytes; driver->WriteData(dataBuffer, bytes); framesProcessed++; } memmove(samplesBuffer, samplesBuffer + framesProcessed * frameSize, sizeof(short) * (samplesBuffer.Size() - framesProcessed * frameSize)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * frameSize); return dataLength; } Bool BoCA::EncoderBonk::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "bonk-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureBonk::ConfigID, "JointStereo", False); config->SetIntValue(ConfigureBonk::ConfigID, "Lossless", False); config->SetIntValue(ConfigureBonk::ConfigID, "Quantization", 8); config->SetIntValue(ConfigureBonk::ConfigID, "Predictor", 32); config->SetIntValue(ConfigureBonk::ConfigID, "Downsampling", 2); } /* Get command line settings. */ Bool jointStereo = config->GetIntValue(encoderID, "Use Joint Stereo", config->GetIntValue(ConfigureBonk::ConfigID, "JointStereo", False)); Bool lossless = config->GetIntValue(encoderID, "Use lossless compression", config->GetIntValue(ConfigureBonk::ConfigID, "Lossless", False)); Int quantization = config->GetIntValue(ConfigureBonk::ConfigID, "Quantization", 8); Int predictor = config->GetIntValue(ConfigureBonk::ConfigID, "Predictor", 32); Int downsampling = config->GetIntValue(ConfigureBonk::ConfigID, "Downsampling", 2); if (config->GetIntValue(encoderID, "Set Quantization factor", False)) quantization = config->GetIntValue(encoderID, "Quantization factor", quantization); if (config->GetIntValue(encoderID, "Set Predictor size", False)) predictor = config->GetIntValue(encoderID, "Predictor size", predictor); if (config->GetIntValue(encoderID, "Set Downsampling ratio", False)) downsampling = config->GetIntValue(encoderID, "Downsampling ratio", downsampling); /* Set configuration values. */ config->SetIntValue(ConfigureBonk::ConfigID, "JointStereo", jointStereo); config->SetIntValue(ConfigureBonk::ConfigID, "Lossless", lossless); config->SetIntValue(ConfigureBonk::ConfigID, "Quantization", Math::Max(0, Math::Min(40, quantization))); config->SetIntValue(ConfigureBonk::ConfigID, "Predictor", Math::Max(0, Math::Min(512, predictor))); config->SetIntValue(ConfigureBonk::ConfigID, "Downsampling", Math::Max(0, Math::Min(10, downsampling))); return True; } ConfigLayer *BoCA::EncoderBonk::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureBonk(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/bonk.h000066400000000000000000000024341516712004000240260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderBonk) namespace BoCA { class EncoderBonk : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; void *encoder; Int frameSize; Buffer dataBuffer; Buffer samplesBuffer; static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderBonk(); ~EncoderBonk(); Bool IsLossless() const; Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderBonk) BoCA_END_COMPONENT(EncoderBonk) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/config.cpp000077500000000000000000000140471516712004000247030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureBonk::ConfigID = "Bonk"; BoCA::ConfigureBonk::ConfigureBonk() { const Config *config = Config::Get(); quant = config->GetIntValue(ConfigID, "Quantization", 8); predictor = config->GetIntValue(ConfigID, "Predictor", 32); downsampling = config->GetIntValue(ConfigID, "Downsampling", 2); jstereo = config->GetIntValue(ConfigID, "JointStereo", 0); lossless = config->GetIntValue(ConfigID, "Lossless", 0); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::Bonk"); group_mode = new GroupBox(i18n->TranslateString("Encoder mode"), Point(7, 11), Size(179, 43)); check_lossless = new CheckBox(i18n->TranslateString("Enable lossless encoding"), Point(10, 13), Size(158, 0), &lossless); check_lossless->onAction.Connect(&ConfigureBonk::SetEncoderMode, this); group_mode->Add(check_lossless); group_stereo = new GroupBox(i18n->TranslateString("Stereo mode"), Point(194, 11), Size(179, 43)); check_joint = new CheckBox(i18n->TranslateString("Enable Joint Stereo"), Point(10, 13), Size(158, 0), &jstereo); group_stereo->Add(check_joint); Int maxTextSize = Math::Max(check_lossless->GetUnscaledTextWidth(), check_joint->GetUnscaledTextWidth()); check_lossless->SetWidth(Math::Max(158, maxTextSize + 21)); check_joint->SetWidth(check_lossless->GetWidth()); group_mode->SetWidth(check_lossless->GetWidth() + 20); group_stereo->SetX(group_mode->GetWidth() + 15); group_stereo->SetWidth(group_mode->GetWidth()); group_quant = new GroupBox(i18n->TranslateString("Quantization"), Point(7, 66), Size(group_mode->GetWidth(), 43)); slider_quant = new Slider(Point(10, 13), Size(group_quant->GetWidth() - 48, 0), OR_HORZ, &quant, 0, 40); slider_quant->onValueChange.Connect(&ConfigureBonk::SetQuantization, this); text_quant = new Text("0.00", Point(slider_quant->GetWidth() + 17, 15)); text_quant->SetX(group_quant->GetWidth() - 10 - text_quant->GetUnscaledTextWidth()); slider_quant->SetWidth(group_quant->GetWidth() - 28 - text_quant->GetUnscaledTextWidth()); group_quant->Add(slider_quant); group_quant->Add(text_quant); SetQuantization(); group_downsampling = new GroupBox(i18n->TranslateString("Downsampling ratio"), Point(group_stereo->GetX(), 66), Size(group_stereo->GetWidth(), 43)); slider_downsampling = new Slider(Point(10, 13), Size(group_downsampling->GetWidth() - 48, 0), OR_HORZ, &downsampling, 1, 10); slider_downsampling->onValueChange.Connect(&ConfigureBonk::SetDownsamplingRatio, this); text_downsampling = new Text("00:0", Point(slider_downsampling->GetWidth() + 17, 15)); text_downsampling->SetX(group_downsampling->GetWidth() - 10 - text_downsampling->GetUnscaledTextWidth()); slider_downsampling->SetWidth(group_downsampling->GetWidth() - 28 - text_downsampling->GetUnscaledTextWidth()); group_downsampling->Add(slider_downsampling); group_downsampling->Add(text_downsampling); SetDownsamplingRatio(); group_predictor = new GroupBox(i18n->TranslateString("Predictor size"), Point(7, 121), Size(2 * group_mode->GetWidth() + 8, 43)); slider_predictor = new Slider(Point(10, 13), Size(group_predictor->GetWidth() - 48, 0), OR_HORZ, &predictor, 0, 512); slider_predictor->onValueChange.Connect(&ConfigureBonk::SetPredictorSize, this); text_predictor = new Text("00:0", Point(slider_predictor->GetWidth() + 17, 15)); text_predictor->SetX(group_predictor->GetWidth() - 10 - text_predictor->GetUnscaledTextWidth()); slider_predictor->SetWidth(group_predictor->GetWidth() - 28 - text_predictor->GetUnscaledTextWidth()); group_predictor->Add(slider_predictor); group_predictor->Add(text_predictor); SetPredictorSize(); SetEncoderMode(); Add(group_quant); Add(group_stereo); Add(group_mode); Add(group_downsampling); Add(group_predictor); SetSize(Size(group_predictor->GetWidth() + 14, 171)); } BoCA::ConfigureBonk::~ConfigureBonk() { DeleteObject(group_quant); DeleteObject(slider_quant); DeleteObject(text_quant); DeleteObject(group_stereo); DeleteObject(check_joint); DeleteObject(group_mode); DeleteObject(check_lossless); DeleteObject(group_downsampling); DeleteObject(slider_downsampling); DeleteObject(text_downsampling); DeleteObject(group_predictor); DeleteObject(slider_predictor); DeleteObject(text_predictor); } Int BoCA::ConfigureBonk::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Quantization", quant); config->SetIntValue(ConfigID, "Predictor", predictor); config->SetIntValue(ConfigID, "Downsampling", downsampling); config->SetIntValue(ConfigID, "JointStereo", jstereo); config->SetIntValue(ConfigID, "Lossless", lossless); return Success(); } Void BoCA::ConfigureBonk::SetQuantization() { String val = String::FromFloat(0.05 * (double) quant); switch (val.Length()) { case 1: val.Append(".00"); break; case 3: val.Append("0"); break; } text_quant->SetText(val); } Void BoCA::ConfigureBonk::SetPredictorSize() { text_predictor->SetText(String::FromInt(predictor)); } Void BoCA::ConfigureBonk::SetDownsamplingRatio() { text_downsampling->SetText(String::FromInt(downsampling).Append(":1")); } Void BoCA::ConfigureBonk::SetEncoderMode() { if (lossless) { group_quant->Deactivate(); slider_quant->Deactivate(); text_quant->Deactivate(); group_downsampling->Deactivate(); slider_downsampling->Deactivate(); text_downsampling->Deactivate(); } else { group_quant->Activate(); slider_quant->Activate(); text_quant->Activate(); group_downsampling->Activate(); slider_downsampling->Activate(); text_downsampling->Activate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/config.h000077500000000000000000000030351516712004000243430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BONKCONFIG #define H_BONKCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureBonk : public ConfigLayer { private: GroupBox *group_quant; Slider *slider_quant; Text *text_quant; GroupBox *group_stereo; CheckBox *check_joint; GroupBox *group_mode; CheckBox *check_lossless; GroupBox *group_downsampling; Slider *slider_downsampling; Text *text_downsampling; GroupBox *group_predictor; Slider *slider_predictor; Text *text_predictor; Int quant; Int predictor; Int downsampling; Bool jstereo; Bool lossless; slots: Void SetQuantization(); Void SetPredictorSize(); Void SetDownsamplingRatio(); Void SetEncoderMode(); public: static const String ConfigID; ConfigureBonk(); ~ConfigureBonk(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/dllinterface.cpp000077500000000000000000000054471516712004000260760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; BONKENCODERCREATE ex_bonk_encoder_create = NIL; BONKENCODERINIT ex_bonk_encoder_init = NIL; BONKENCODERENCODEPACKET ex_bonk_encoder_encode_packet = NIL; BONKENCODERFINISH ex_bonk_encoder_finish = NIL; BONKENCODERCLOSE ex_bonk_encoder_close = NIL; BONKENCODERGETSAMPLECOUNT ex_bonk_encoder_get_sample_count = NIL; BONKENCODERGETSAMPLECOUNTOFFSET ex_bonk_encoder_get_sample_count_offset= NIL; BONKENCODERSETID3DATA ex_bonk_encoder_set_id3_data = NIL; BONKGETVERSIONSTRING ex_bonk_get_version_string = NIL; DynamicLoader *bonkdll = NIL; Bool LoadBonkDLL() { bonkdll = BoCA::Utilities::LoadCodecDLL("bonk"); if (bonkdll == NIL) return False; ex_bonk_encoder_create = (BONKENCODERCREATE) bonkdll->GetFunctionAddress("bonk_encoder_create"); ex_bonk_encoder_init = (BONKENCODERINIT) bonkdll->GetFunctionAddress("bonk_encoder_init"); ex_bonk_encoder_encode_packet = (BONKENCODERENCODEPACKET) bonkdll->GetFunctionAddress("bonk_encoder_encode_packet"); ex_bonk_encoder_finish = (BONKENCODERFINISH) bonkdll->GetFunctionAddress("bonk_encoder_finish"); ex_bonk_encoder_close = (BONKENCODERCLOSE) bonkdll->GetFunctionAddress("bonk_encoder_close"); ex_bonk_encoder_get_sample_count = (BONKENCODERGETSAMPLECOUNT) bonkdll->GetFunctionAddress("bonk_encoder_get_sample_count"); ex_bonk_encoder_get_sample_count_offset = (BONKENCODERGETSAMPLECOUNTOFFSET) bonkdll->GetFunctionAddress("bonk_encoder_get_sample_count_offset"); ex_bonk_encoder_set_id3_data = (BONKENCODERSETID3DATA) bonkdll->GetFunctionAddress("bonk_encoder_set_id3_data"); ex_bonk_get_version_string = (BONKGETVERSIONSTRING) bonkdll->GetFunctionAddress("bonk_get_version_string"); if (ex_bonk_encoder_create == NIL || ex_bonk_encoder_init == NIL || ex_bonk_encoder_encode_packet == NIL || ex_bonk_encoder_finish == NIL || ex_bonk_encoder_close == NIL || ex_bonk_encoder_get_sample_count == NIL || ex_bonk_encoder_get_sample_count_offset == NIL || ex_bonk_encoder_set_id3_data == NIL || ex_bonk_get_version_string == NIL) { FreeBonkDLL(); return False; } return True; } Void FreeBonkDLL() { BoCA::Utilities::FreeCodecDLL(bonkdll); bonkdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/bonk/dllinterface.h000077500000000000000000000037071516712004000255400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *bonkdll; Bool LoadBonkDLL(); Void FreeBonkDLL(); typedef void * (BONKCONV *BONKENCODERCREATE) (); typedef bool (BONKCONV *BONKENCODERINIT) (void *, unsigned int, unsigned int, int, bool, bool, int, int, int, double); typedef int (BONKCONV *BONKENCODERENCODEPACKET) (void *, signed short *, int, unsigned char *, int); typedef int (BONKCONV *BONKENCODERFINISH) (void *, unsigned char *, int); typedef bool (BONKCONV *BONKENCODERCLOSE) (void *); typedef int (BONKCONV *BONKENCODERGETSAMPLECOUNT) (void *); typedef int (BONKCONV *BONKENCODERGETSAMPLECOUNTOFFSET) (void *); typedef bool (BONKCONV *BONKENCODERSETID3DATA) (void *, unsigned char *, int); typedef const char * (BONKCONV *BONKGETVERSIONSTRING) (); extern BONKENCODERCREATE ex_bonk_encoder_create; extern BONKENCODERINIT ex_bonk_encoder_init; extern BONKENCODERENCODEPACKET ex_bonk_encoder_encode_packet; extern BONKENCODERFINISH ex_bonk_encoder_finish; extern BONKENCODERCLOSE ex_bonk_encoder_close; extern BONKENCODERGETSAMPLECOUNT ex_bonk_encoder_get_sample_count; extern BONKENCODERGETSAMPLECOUNTOFFSET ex_bonk_encoder_get_sample_count_offset; extern BONKENCODERSETID3DATA ex_bonk_encoder_set_id3_data; extern BONKGETVERSIONSTRING ex_bonk_get_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/000077500000000000000000000000001516712004000237425ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/Makefile000066400000000000000000000020251516712004000254010ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = coreaudio TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = config.o coreaudio.o dllinterface.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -Wno-multichar ifneq ($(BUILD_OSX),True) DEFINE += -I"$(SRCDIR)"/$(BOCA_PATH)/include/support/apple endif ifeq ($(BUILD_WIN32),True) DEFINE += -DUNICODE endif # Enter additional library dependencies here: ifeq ($(BUILD_WIN32),True) LIBS = -lole32 else ifeq ($(BUILD_OSX),True) LIBS = -framework CoreFoundation -framework AudioToolbox endif # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/config.cpp000066400000000000000000000302041516712004000257120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureCoreAudio::ConfigID = "CoreAudio"; BoCA::ConfigureCoreAudio::ConfigureCoreAudio() { const Config *config = Config::Get(); bitrate = config->GetIntValue(ConfigID, "Bitrate", 64); allowID3 = config->GetIntValue(ConfigID, "AllowID3v2", False); fileFormat = config->GetIntValue(ConfigID, "MP4Container", True); fileExtension = config->GetIntValue(ConfigID, "MP4FileExtension", 0); I18n *i18n = I18n::Get(); tabwidget = new TabWidget(Point(7, 7), Size(500, 208)); i18n->SetContext("Encoders::AAC::Format"); layer_format = new Layer(i18n->TranslateString("Format")); group_id3v2 = new GroupBox(i18n->TranslateString("Tags"), Point(7, 88), Size(279, 90)); check_id3v2 = new CheckBox(i18n->TranslateString("Allow ID3v2 tags in AAC files"), Point(10, 13), Size(200, 0), &allowID3); check_id3v2->SetWidth(check_id3v2->GetUnscaledTextWidth() + 20); text_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(10, 38)); text_id3v2 = new Text(i18n->TranslateString("Some players may have problems playing AAC\nfiles with ID3 tags attached. Please use this option only\nif you are sure that your player can handle these tags."), Point(text_note->GetUnscaledTextWidth() + 12, 38)); group_id3v2->SetSize(Size(Math::Max(240, text_note->GetUnscaledTextWidth() + text_id3v2->GetUnscaledTextWidth() + 22), Math::Max(text_note->GetUnscaledTextHeight(), text_id3v2->GetUnscaledTextHeight()) + 48)); group_id3v2->Add(check_id3v2); group_id3v2->Add(text_note); group_id3v2->Add(text_id3v2); group_mp4 = new GroupBox(i18n->TranslateString("File format"), Point(7, 11), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_mp4 = new OptionBox("MP4", Point(10, 13), Size(group_mp4->GetWidth() - 20, 0), &fileFormat, 1); option_mp4->onAction.Connect(&ConfigureCoreAudio::SetFileFormat, this); option_aac = new OptionBox("AAC", Point(10, 38), Size(group_mp4->GetWidth() - 20, 0), &fileFormat, 0); option_aac->onAction.Connect(&ConfigureCoreAudio::SetFileFormat, this); group_mp4->Add(option_mp4); group_mp4->Add(option_aac); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(group_mp4->GetWidth() + 15 + (group_id3v2->GetWidth() % 2), 11), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_extension_m4a = new OptionBox(".m4a", Point(10, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 0); option_extension_m4b = new OptionBox(".m4b", Point(10, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 1); option_extension_m4r = new OptionBox(".m4r", Point(group_extension->GetWidth() / 2 + 4, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 2); option_extension_mp4 = new OptionBox(".mp4", Point(group_extension->GetWidth() / 2 + 4, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 3); group_extension->Add(option_extension_m4a); group_extension->Add(option_extension_m4b); group_extension->Add(option_extension_m4r); group_extension->Add(option_extension_mp4); i18n->SetContext("Encoders::AAC::Codec"); layer_quality = new Layer(i18n->TranslateString("Codec")); group_codec = new GroupBox(i18n->TranslateString("Audio codec"), Point(7, 11), Size(group_id3v2->GetWidth(), 43)); text_codec = new Text(i18n->AddColon(i18n->TranslateString("Audio codec")), Point(10, 15)); combo_codec = new ComboBox(Point(text_codec->GetUnscaledTextSize().cx + 17, 12), Size(group_codec->GetWidth() - text_codec->GetUnscaledTextSize().cx - 27, 0)); /* Query supported formats from Core Audio * and add them to the combo box list. */ CA::UInt32 size = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_EncodeFormatIDs, 0, NIL, &size); CA::UInt32 *formats = new CA::UInt32 [size / sizeof(CA::UInt32)]; CA::AudioFormatGetProperty(CA::kAudioFormatProperty_EncodeFormatIDs, 0, NIL, &size, formats); for (UnsignedInt i = 0; i < size / sizeof(CA::UInt32); i++) { if (formats[i] == CA::kAudioFormatMPEG4AAC) combo_codec->AddEntry("MPEG4 AAC Low Complexity"); else if (formats[i] == CA::kAudioFormatMPEG4AAC_HE) combo_codec->AddEntry("MPEG4 AAC High Efficiency"); else if (formats[i] == CA::kAudioFormatMPEG4AAC_HE_V2) combo_codec->AddEntry("MPEG4 AAC High Efficiency v2"); else if (formats[i] == CA::kAudioFormatMPEG4AAC_LD) combo_codec->AddEntry("MPEG4 AAC Low Delay"); else if (formats[i] == CA::kOptionalAudioFormatMPEG4AAC_ELD) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay"); else if (formats[i] == CA::kOptionalAudioFormatMPEG4AAC_ELD_SBR) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay SBR"); else if (formats[i] == CA::kOptionalAudioFormatMPEG4AAC_ELD_V2) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay v2"); else if (formats[i] == CA::kAudioFormatMPEG4AAC_Spatial) combo_codec->AddEntry("MPEG4 AAC Spatial"); else if (formats[i] == CA::kAudioFormatAppleLossless) combo_codec->AddEntry("Apple Lossless Audio Codec"); else continue; codecs.Add(formats[i]); if ((UnsignedInt) config->GetIntValue(ConfigID, "Codec", CA::kAudioFormatMPEG4AAC) == formats[i]) combo_codec->SelectNthEntry(combo_codec->Length() - 1); } delete [] formats; combo_codec->onSelectEntry.Connect(&ConfigureCoreAudio::SetCodec, this); group_codec->Add(text_codec); group_codec->Add(combo_codec); i18n->SetContext("Encoders::AAC::Quality"); group_bitrate = new GroupBox(i18n->TranslateString("Bitrate"), Point(7, 66), Size(group_id3v2->GetWidth(), 43)); text_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Bitrate per channel")), Point(10, 15)); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 15)); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); edit_bitrate = new EditBox(String::FromInt(bitrate), Point(text_bitrate_kbps->GetX() + 32, 12), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetOrientation(OR_UPPERRIGHT); edit_bitrate->onInput.Connect(&ConfigureCoreAudio::SetBitrateByEditBox, this); slider_bitrate = new Slider(Point(text_bitrate->GetUnscaledTextSize().cx + 17, 13), Size(group_bitrate->GetWidth() - edit_bitrate->GetX() - 25 - text_bitrate->GetUnscaledTextSize().cx, 0), OR_HORZ, &bitrate, 1, 256); slider_bitrate->onValueChange.Connect(&ConfigureCoreAudio::SetBitrate, this); group_bitrate->Add(text_bitrate); group_bitrate->Add(slider_bitrate); group_bitrate->Add(edit_bitrate); group_bitrate->Add(text_bitrate_kbps); SetCodec(); tabwidget->SetSize(group_id3v2->GetSize() + Size(18, 118)); Add(tabwidget); tabwidget->Add(layer_quality); tabwidget->Add(layer_format); layer_format->Add(group_mp4); layer_format->Add(group_extension); layer_format->Add(group_id3v2); layer_quality->Add(group_codec); layer_quality->Add(group_bitrate); SetSize(group_id3v2->GetSize() + Size(32, 132)); } BoCA::ConfigureCoreAudio::~ConfigureCoreAudio() { DeleteObject(tabwidget); DeleteObject(layer_format); DeleteObject(layer_quality); DeleteObject(group_mp4); DeleteObject(option_mp4); DeleteObject(option_aac); DeleteObject(group_extension); DeleteObject(option_extension_m4a); DeleteObject(option_extension_m4b); DeleteObject(option_extension_m4r); DeleteObject(option_extension_mp4); DeleteObject(group_id3v2); DeleteObject(check_id3v2); DeleteObject(text_note); DeleteObject(text_id3v2); DeleteObject(group_codec); DeleteObject(text_codec); DeleteObject(combo_codec); DeleteObject(group_bitrate); DeleteObject(text_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); } Int BoCA::ConfigureCoreAudio::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Codec", codecs.GetNth(combo_codec->GetSelectedEntryNumber())); if (bitrates.Length() == 2) { if (bitrate < bitrates.GetNth(0)) bitrate = bitrates.GetNth(0); if (bitrate > bitrates.GetNth(1)) bitrate = bitrates.GetNth(1); } if (bitrates.Length() == 2) config->SetIntValue(ConfigID, "Bitrate", bitrate); else if (bitrates.Length() > 2) config->SetIntValue(ConfigID, "Bitrate", bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1)); config->SetIntValue(ConfigID, "MP4Container", fileFormat); config->SetIntValue(ConfigID, "MP4FileExtension", fileExtension); config->SetIntValue(ConfigID, "AllowID3v2", allowID3); return Success(); } Void BoCA::ConfigureCoreAudio::SetCodec() { CA::UInt32 format = codecs.GetNth(combo_codec->GetSelectedEntryNumber()); CA::UInt32 size = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_AvailableEncodeBitRates, sizeof(format), &format, &size); CA::AudioValueRange *bitrateValues = new CA::AudioValueRange [size / sizeof(CA::AudioValueRange)]; CA::AudioFormatGetProperty(CA::kAudioFormatProperty_AvailableEncodeBitRates, sizeof(format), &format, &size, bitrateValues); if (size > 0 && bitrates.Length() > 2) bitrate = bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1); bitrates.RemoveAll(); for (UnsignedInt i = 0; i < size / sizeof(CA::AudioValueRange); i++) { if (bitrateValues[i].mMinimum / 1000 > 192 && bitrateValues[i].mMaximum / 1000 > 192) continue; if ( bitrateValues[i].mMaximum / 1000 > 192) bitrateValues[i].mMaximum = 192 * 1000; bitrates.Add(bitrateValues[i].mMinimum / 1000); bitrates.Add(bitrateValues[i].mMaximum / 1000); } delete [] bitrateValues; if (bitrates.Length() > 0) group_bitrate->Activate(); else group_bitrate->Deactivate(); for (Int i = 0; i < bitrates.Length() / 2; i++) { if (bitrate == bitrates.GetNth(i * 2 + 1)) bitrate = -(bitrates.Length() / 2) + i; } if (bitrates.Length() == 2) { edit_bitrate->Activate(); slider_bitrate->SetRange(bitrates.GetNth(0), bitrates.GetNth(1)); } else if (bitrates.Length() > 2) { edit_bitrate->Deactivate(); slider_bitrate->SetRange(-bitrates.Length() / 2, -1); } if (codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatAppleLossless) { group_mp4->Deactivate(); fileFormat = 1; option_extension_m4r->Deactivate(); if (fileExtension == 2) fileExtension = 0; } else if (codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_HE || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_HE_V2 || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_LD || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kOptionalAudioFormatMPEG4AAC_ELD || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kOptionalAudioFormatMPEG4AAC_ELD_SBR || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kOptionalAudioFormatMPEG4AAC_ELD_V2 || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_Spatial) { group_mp4->Activate(); option_extension_m4r->Activate(); } SetBitrate(); SetFileFormat(); } Void BoCA::ConfigureCoreAudio::SetBitrate() { if (bitrates.Length() == 0) return; if (!edit_bitrate->IsFocussed()) { if (bitrates.Length() == 2) edit_bitrate->SetText(String::FromInt(bitrate)); else edit_bitrate->SetText(String::FromInt(bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1))); } } Void BoCA::ConfigureCoreAudio::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt()); } Void BoCA::ConfigureCoreAudio::SetFileFormat() { if (fileFormat == 1) // MP4 container { group_id3v2->Deactivate(); group_extension->Activate(); } else // raw AAC file format { group_id3v2->Activate(); group_extension->Deactivate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/config.h000066400000000000000000000035531516712004000253660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_COREAUDIOCONFIG #define H_COREAUDIOCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCoreAudio : public ConfigLayer { private: TabWidget *tabwidget; Layer *layer_format; GroupBox *group_id3v2; CheckBox *check_id3v2; Text *text_note; Text *text_id3v2; GroupBox *group_mp4; OptionBox *option_mp4; OptionBox *option_aac; GroupBox *group_extension; OptionBox *option_extension_m4a; OptionBox *option_extension_m4b; OptionBox *option_extension_m4r; OptionBox *option_extension_mp4; Layer *layer_quality; GroupBox *group_codec; Text *text_codec; ComboBox *combo_codec; GroupBox *group_bitrate; Text *text_bitrate; Slider *slider_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; Array codecs; Array bitrates; Int bitrate; Bool allowID3; Int fileFormat; Int fileExtension; slots: Void SetCodec(); Void SetBitrate(); Void SetBitrateByEditBox(); Void SetFileFormat(); public: static const String ConfigID; ConfigureCoreAudio(); ~ConfigureCoreAudio(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/coreaudio.cpp000066400000000000000000000641501516712004000264260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "coreaudio.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderCoreAudio::GetComponentSpecs() { static String componentSpecs; #ifndef __APPLE__ if (coreaudiodll != NIL) #endif { componentSpecs = " \ \ \ \ Core Audio AAC/ALAC Encoder \ 1.0 \ coreaudio-enc \ encoder \ faac-enc \ voaacenc-enc \ ffmpeg-alac-enc \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ MP4 Metadata \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ Apple Lossless Files \ true \ m4a \ m4b \ mp4 \ MP4 Metadata \ \ \ \ \ \ \ \ 8 \ 192 \ \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadCoreAudioDLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeCoreAudioDLL(); FreeMP4v2DLL(); } namespace BoCA { CA::OSStatus AudioFileReadProc(void *, CA::SInt64, CA::UInt32, void *, CA::UInt32 *); CA::OSStatus AudioFileWriteProc(void *, CA::SInt64, CA::UInt32, const void *, CA::UInt32 *); CA::SInt64 AudioFileGetSizeProc(void *); CA::OSStatus AudioFileSetSizeProc(void *, CA::SInt64); }; BoCA::EncoderCoreAudio::EncoderCoreAudio() { configLayer = NIL; config = NIL; audioFile = NIL; fileType = 0; dataOffset = 0; frameSize = 0; blockSize = 256; overlap = 24; nextWorker = 0; packetsWritten = 0; packetsMissing = 0; totalSamples = 0; } BoCA::EncoderCoreAudio::~EncoderCoreAudio() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderCoreAudio::IsLossless() const { /* Get configuration. */ const Config *config = GetConfiguration(); CA::UInt32 codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); /* Signal lossless for ALAC. */ if (codec == CA::kAudioFormatAppleLossless) return True; return False; } Bool BoCA::EncoderCoreAudio::Activate() { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); CA::UInt32 codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); Int kbps = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); Bool mp4Container = config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); /* Fall back to HE/ELD-SBR if HEv2/ELDv2 is selected for non-stereo input. */ if (codec == CA::kAudioFormatMPEG4AAC_HE_V2 && format.channels != 2) codec = CA::kAudioFormatMPEG4AAC_HE; if (codec == CA::kOptionalAudioFormatMPEG4AAC_ELD_V2 && format.channels != 2) codec = CA::kOptionalAudioFormatMPEG4AAC_ELD_SBR; /* Fill out source format description. */ CA::AudioStreamBasicDescription sourceFormat = { 0 }; sourceFormat.mFormatID = CA::kAudioFormatLinearPCM; sourceFormat.mFormatFlags = CA::kLinearPCMFormatFlagIsPacked; sourceFormat.mFormatFlags |= format.fp ? CA::kLinearPCMFormatFlagIsFloat : 0; sourceFormat.mFormatFlags |= format.sign && !format.fp ? CA::kLinearPCMFormatFlagIsSignedInteger : 0; sourceFormat.mFormatFlags |= endianness == EndianBig ? CA::kLinearPCMFormatFlagIsBigEndian : 0; sourceFormat.mSampleRate = format.rate; sourceFormat.mChannelsPerFrame = format.channels; sourceFormat.mBitsPerChannel = format.bits; sourceFormat.mFramesPerPacket = 1; sourceFormat.mBytesPerFrame = sourceFormat.mChannelsPerFrame * sourceFormat.mBitsPerChannel / 8; sourceFormat.mBytesPerPacket = sourceFormat.mFramesPerPacket * sourceFormat.mBytesPerFrame; /* Fill out destination format description. */ CA::AudioStreamBasicDescription destinationFormat = { 0 }; destinationFormat.mFormatID = codec; destinationFormat.mSampleRate = SuperWorker::GetOutputSampleRate(destinationFormat.mFormatID, format.rate); destinationFormat.mChannelsPerFrame = format.channels; CA::UInt32 formatSize = sizeof(destinationFormat); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_FormatInfo, 0, NIL, &formatSize, &destinationFormat); /* Create audio converter object. */ CA::AudioConverterRef converter = NIL; if (CA::AudioConverterNew(&sourceFormat, &destinationFormat, &converter) != 0) { errorString = "Could not create converter component!"; errorState = True; return False; } frameSize = destinationFormat.mFramesPerPacket; /* Set bitrate if format does support bitrates. */ CA::UInt32 size = 0; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, NIL) == 0) { /* Get applicable bitrate values. */ CA::UInt32 bitrate = kbps * 1000 * format.channels; CA::AudioValueRange *bitrateValues = new CA::AudioValueRange [size / sizeof(CA::AudioValueRange)]; CA::AudioConverterGetProperty(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, bitrateValues); /* Find best supported bitrate. */ CA::Float64 nearest = 0xFFFFFFFF; for (UnsignedInt i = 0; i < size / sizeof(CA::AudioValueRange); i++) { if (bitrate >= bitrateValues[i].mMinimum && bitrate <= bitrateValues[i].mMaximum) nearest = bitrate; if (Math::Abs(bitrate - bitrateValues[i].mMinimum) < Math::Abs(bitrate - nearest)) nearest = bitrateValues[i].mMinimum; if (Math::Abs(bitrate - bitrateValues[i].mMaximum) < Math::Abs(bitrate - nearest)) nearest = bitrateValues[i].mMaximum; } bitrate = nearest; delete [] bitrateValues; /* Set bitrate on converter. */ CA::AudioConverterSetProperty(converter, CA::kAudioConverterEncodeBitRate, sizeof(CA::UInt32), &bitrate); } /* Get file type of output file. */ fileType = mp4Container ? CA::kAudioFileM4AType : CA::kAudioFileAAC_ADTSType; /* Write ID3v2 tag if requested. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureCoreAudio::ConfigID, "AllowID3v2", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); dataOffset = id3Buffer.Size(); boca.DeleteComponent(tagger); } } } /* Create audio file object for output file. */ CA::AudioFileInitializeWithCallbacks(this, AudioFileReadProc, AudioFileWriteProc, AudioFileGetSizeProc, AudioFileSetSizeProc, fileType, &destinationFormat, 0, &audioFile); /* Get magic cookie and supply it to audio file. */ CA::UInt32 cookieSize = 0; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, NIL) == 0) { unsigned char *cookie = new unsigned char [cookieSize]; CA::AudioConverterGetProperty(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, cookie); CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyMagicCookieData, cookieSize, cookie); delete [] cookie; } CA::AudioConverterDispose(converter); packetsWritten = 0; packetsMissing = 0; totalSamples = 0; /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True) && format.rate == destinationFormat.mSampleRate; Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = 24; /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, format)); foreach (SuperWorker *worker, workers) worker->Start(); return True; } Bool BoCA::EncoderCoreAudio::Deactivate() { /* Get configuration. */ CA::UInt32 codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); /* Convert final frames. */ EncodeFrames(True); /* Calculate frame size divider. */ const Format &format = track.GetFormat(); Int rate = SuperWorker::GetOutputSampleRate(codec, format.rate); if (rate == 0) rate = format.rate; Float divider = Float(format.rate) / rate; if (codec == CA::kAudioFormatMPEG4AAC_HE || codec == CA::kAudioFormatMPEG4AAC_HE_V2) divider *= 2.0; /* Write priming and remainder info. */ CA::AudioConverterPrimeInfo initialInfo = workers.GetNth(0 )->GetPrimeInfo(); CA::AudioConverterPrimeInfo finalInfo = workers.GetNth((nextWorker - 1) % workers.Length())->GetPrimeInfo(); if (initialInfo.leadingFrames != 0xFFFFFFFF && finalInfo.trailingFrames != 0xFFFFFFFF) { CA::AudioFilePacketTableInfo pti; pti.mPrimingFrames = initialInfo.leadingFrames; pti.mRemainderFrames = finalInfo.trailingFrames; pti.mNumberValidFrames = Math::Ceil(totalSamples / divider); CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyPacketTableInfo, sizeof(pti), &pti); } /* Get and set magic cookie again as some * encoders may change it during encoding. */ CA::UInt32 cookieSize = 4; unsigned char *cookie = workers.GetFirst()->GetMagicCookie(&cookieSize); if (cookie != NIL) { CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyMagicCookieData, cookieSize, cookie); delete [] cookie; } /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Close audio file. */ CA::AudioFileClose(audioFile); /* Finish MP4 writing. */ if (fileType == CA::kAudioFileM4AType) { driver->Close(); /* Fix mhdr atom for long running tracks. */ Int64 duration = Int64(packetsWritten) * frameSize / divider; if (duration > 0xFFFFFFFF) { String tempFile = String(track.outputFile).Append(".temp"); InStream in(STREAM_FILE, track.outputFile, IS_READ); OutStream out(STREAM_FILE, tempFile, OS_REPLACE); Bool result = FixupDurationAtoms(duration, in, out, in.Size()); in.Close(); out.Close(); if (result) { File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } File(tempFile).Delete(); } /* Fix number of channels in sound atom. */ if (mp4v2dll != NIL) { MP4FileHandle mp4File = ex_MP4Modify(track.outputFile, 0); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); ex_MP4SetTrackIntegerProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.*[0].channels", format.channels); ex_MP4Close(mp4File, 0); } /* Write metadata to file. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableMP4Metadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } else if (mp4v2dll != NIL) { /* Optimize file even when no tags are written. */ String tempFile = String(track.outputFile).Append(".temp"); ex_MP4Optimize(track.outputFile.ConvertTo("UTF-8"), tempFile.ConvertTo("UTF-8")); File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } } /* Write ID3v1 tag if requested. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v1", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Update ID3v2 tag with correct chapter marks. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureCoreAudio::ConfigID, "AllowID3v2", False)) { if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Int BoCA::EncoderCoreAudio::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Change to AAC channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Default_3_0, Channel::AAC_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::AAC_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::AAC_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Default_6_1, Channel::AAC_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Default_7_1, Channel::AAC_7_1); /* Copy data to samples buffer. */ samplesBuffer.Resize(samplesBuffer.Size() + data.Size()); memcpy(samplesBuffer + samplesBuffer.Size() - data.Size(), data, data.Size()); /* Output samples to encoder. */ totalSamples += data.Size() / format.channels / (format.bits / 8); return EncodeFrames(False); } Int BoCA::EncoderCoreAudio::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int bytesPerFrame = frameSize * format.channels * (format.bits / 8); if (flush) framesToProcess = Math::Floor(samplesBuffer.Size() / bytesPerFrame); while (samplesBuffer.Size() - framesProcessed * bytesPerFrame >= bytesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), workerToUse->GetPacketInfos(), nextWorker == workers.Length(), nextWorker >= 2 * workers.Length()); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * bytesPerFrame, flush ? samplesBuffer.Size() : bytesPerFrame * framesToProcess, flush); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } memmove(samplesBuffer, samplesBuffer + framesProcessed * bytesPerFrame, samplesBuffer.Size() - framesProcessed * bytesPerFrame); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * bytesPerFrame); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), workerToUse->GetPacketInfos(), nextWorker == workers.Length(), nextWorker >= 2 * workers.Length()); nextWorker++; } return dataLength; } Int BoCA::EncoderCoreAudio::ProcessPackets(const Buffer &packetData, const Array &packetSizes, const Array &packetInfos, Bool first, Bool discardMissing) { Int offset = 0; Int dataLength = 0; if (discardMissing) packetsMissing = 0; if (!first) for (Int i = 0; i < overlap - packetsMissing; i++) offset += packetSizes.GetNth(i); for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap - packetsMissing && !first) continue; if (packetSizes.GetNth(i) == 0) continue; CA::UInt32 packets = 1; CA::AudioStreamPacketDescription *packet = packetInfos.GetNth(i); CA::AudioFileWritePackets(audioFile, False, packetSizes.GetNth(i), packet, packetsWritten, &packets, (unsigned char *) packetData + offset); offset += packetSizes.GetNth(i); dataLength += packetSizes.GetNth(i); packetsWritten += packets; } packetsMissing = blockSize - packetSizes.Length(); return dataLength; } Bool BoCA::EncoderCoreAudio::SetOutputFormat(Int n) { Config *config = Config::Get(); if (n != 1) config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); else config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", False); if (n != 2 && (CA::UInt32) config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC) == CA::kAudioFormatAppleLossless) config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); else if (n == 2) config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatAppleLossless); return True; } String BoCA::EncoderCoreAudio::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True)) { switch (config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4FileExtension", 0)) { default: case 0: return "m4a"; case 1: return "m4b"; case 2: return "m4r"; case 3: return "mp4"; } } return "aac"; } Bool BoCA::EncoderCoreAudio::FixupDurationAtoms(Int64 duration, InStream &in, OutStream &out, Int64 size, Bool seenMdat) { Int64 bytesLeft = size; Buffer buffer(65536); while (bytesLeft > 0) { UnsignedInt64 bytes = UnsignedInt32(in.InputNumberRaw(4)); UnsignedInt32 id = in.InputNumberRaw(4); Bool use64bit = (bytes == 1); Int grow = 0; if (use64bit == 1) bytes = in.InputNumberRaw(8); if (id == 'moov') grow = 36; else if (id == 'trak') grow = 24; else if (id == 'mdia' || id == 'tkhd' || id == 'mdhd' || id == 'mvhd') grow = 12; out.OutputNumberRaw(use64bit ? 1 : bytes + grow, 4); out.OutputNumberRaw(id, 4); if (use64bit) { out.OutputNumberRaw(bytes + grow, 8); bytes -= 8; bytesLeft -= 8; } bytes -= 8; bytesLeft -= 8; /* Recurse into moov, trak, mdia, minf and stbl boxes. */ if (id == 'moov' || id == 'trak' || id == 'mdia' || id == 'minf' || id == 'stbl') { if (!FixupDurationAtoms(duration, in, out, bytes, seenMdat)) return False; bytesLeft -= bytes; continue; } /* Fixup duration atoms. */ if (id == 'tkhd' || id == 'mdhd' || id == 'mvhd') { Int size = 0; // Version. if (in.InputNumberRaw(1) >= 1) return False; out.OutputNumberRaw(1, 1); size += 1; // Flags. out.OutputNumberRaw(in.InputNumberRaw(3), 3); size += 3; // Creation time. out.OutputNumberRaw(0, 4); out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Modification time. out.OutputNumberRaw(0, 4); out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Time scale. out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Reserved. if (id == 'tkhd') { out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; } // Duration. in.RelSeek(4); out.OutputNumberRaw(duration, 8); size += 4; // Rest of atom. in.InputData(buffer, bytes - size); out.OutputData(buffer, bytes - size); bytesLeft -= bytes; continue; } /* Fixup chunk offset atoms. */ if (!seenMdat && (id == 'stco' || id == 'co64')) { // Version. out.OutputNumberRaw(in.InputNumberRaw(1), 1); // Flags. out.OutputNumberRaw(in.InputNumberRaw(3), 3); // Number of entries. UnsignedInt32 numEntries = in.InputNumberRaw(4); out.OutputNumberRaw(numEntries, 4); // Entries. if (id == 'stco') for (UnsignedInt32 i = 0; i < numEntries; i++) out.OutputNumberRaw(in.InputNumberRaw(4) + 36, 4); else for (UnsignedInt32 i = 0; i < numEntries; i++) out.OutputNumberRaw(in.InputNumberRaw(8) + 36, 8); bytesLeft -= bytes; continue; } /* Copy other boxes/atoms. */ if (id == 'mdat') seenMdat = True; while (bytes > 0) { Int size = Math::Min(bytes, buffer.Size()); in.InputData(buffer, size); out.OutputData(buffer, size); bytes -= size; bytesLeft -= size; } } return True; } Bool BoCA::EncoderCoreAudio::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "coreaudio-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); } /* Get command line settings. */ Bool rawAAC = config->GetIntValue(encoderID, "Create ADTS AAC files (no MP4 container)", !config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True)); Int bitrate = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); Int format = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); String formatName = "AAC"; if (format == CA::kAudioFormatAppleLossless) formatName = "ALAC"; if (config->GetIntValue(encoderID, "Set Bitrate per channel", False)) bitrate = config->GetIntValue(encoderID, "Bitrate per channel", bitrate); if (config->GetIntValue(encoderID, "Set Output format", False)) formatName = config->GetStringValue(encoderID, "Output format", formatName).ToUpper(); /* Set configuration values. */ config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", !rawAAC || formatName == "ALAC"); if (formatName == "AAC" ) format = CA::kAudioFormatMPEG4AAC; else if (formatName == "ALAC") format = CA::kAudioFormatAppleLossless; config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", format); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", Math::Max(8, Math::Min(256, bitrate))); return True; } ConfigLayer *BoCA::EncoderCoreAudio::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureCoreAudio(); return configLayer; } CA::OSStatus BoCA::AudioFileReadProc(void *inClientData, CA::SInt64 inPosition, CA::UInt32 requestCount, void *buffer, CA::UInt32 *actualCount) { EncoderCoreAudio *filter = (EncoderCoreAudio *) inClientData; filter->driver->Seek(inPosition + filter->dataOffset); *actualCount = filter->driver->ReadData((UnsignedByte *) buffer, requestCount); return 0; } CA::OSStatus BoCA::AudioFileWriteProc(void *inClientData, CA::SInt64 inPosition, CA::UInt32 requestCount, const void *buffer, CA::UInt32 *actualCount) { EncoderCoreAudio *filter = (EncoderCoreAudio *) inClientData; filter->driver->Seek(inPosition + filter->dataOffset); *actualCount = filter->driver->WriteData((UnsignedByte *) buffer, requestCount); return 0; } CA::SInt64 BoCA::AudioFileGetSizeProc(void *inClientData) { EncoderCoreAudio *filter = (EncoderCoreAudio *) inClientData; return filter->driver->GetSize() - filter->dataOffset; } CA::OSStatus BoCA::AudioFileSetSizeProc(void *inClientData, CA::SInt64 inSize) { EncoderCoreAudio *filter = (EncoderCoreAudio *) inClientData; filter->driver->Truncate(inSize + filter->dataOffset); return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/coreaudio.h000066400000000000000000000042401516712004000260650ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" BoCA_BEGIN_COMPONENT(EncoderCoreAudio) namespace BoCA { class EncoderCoreAudio : public CS::EncoderComponent { friend CA::OSStatus AudioFileReadProc(void *, CA::SInt64, CA::UInt32, void *, CA::UInt32 *); friend CA::OSStatus AudioFileWriteProc(void *, CA::SInt64, CA::UInt32, const void *, CA::UInt32 *); friend CA::SInt64 AudioFileGetSizeProc(void *); friend CA::OSStatus AudioFileSetSizeProc(void *, CA::SInt64); private: ConfigLayer *configLayer; Config *config; Array workers; CA::AudioFileID audioFile; CA::UInt32 fileType; UnsignedInt dataOffset; Buffer samplesBuffer; Int nextWorker; Int frameSize; Int blockSize; Int overlap; Int packetsWritten; Int packetsMissing; Int64 totalSamples; Int EncodeFrames(Bool); Int ProcessPackets(const Buffer &, const Array &, const Array &, Bool, Bool); Bool FixupDurationAtoms(Int64, IO::InStream &, IO::OutStream &, Int64, Bool = False); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderCoreAudio(); ~EncoderCoreAudio(); Bool IsLossless() const; Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderCoreAudio) BoCA_END_COMPONENT(EncoderCoreAudio) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/dllinterface.cpp000066400000000000000000000260631516712004000271110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" #ifdef __WIN32__ # include # include #endif using namespace BoCA; using namespace smooth::IO; using namespace smooth::XML; #ifndef __APPLE__ using namespace CA; namespace CA { AUDIOFILEINITIALIZEWITHCALLBACKS AudioFileInitializeWithCallbacks = NIL; AUDIOFILECLOSE AudioFileClose = NIL; AUDIOFILESETPROPERTY AudioFileSetProperty = NIL; AUDIOFILEWRITEPACKETS AudioFileWritePackets = NIL; AUDIOCONVERTERNEW AudioConverterNew = NIL; AUDIOCONVERTERDISPOSE AudioConverterDispose = NIL; AUDIOCONVERTERGETPROPERTY AudioConverterGetProperty = NIL; AUDIOCONVERTERGETPROPERTYINFO AudioConverterGetPropertyInfo = NIL; AUDIOCONVERTERSETPROPERTY AudioConverterSetProperty = NIL; AUDIOCONVERTERFILLCOMPLEXBUFFER AudioConverterFillComplexBuffer = NIL; AUDIOFORMATGETPROPERTY AudioFormatGetProperty = NIL; AUDIOFORMATGETPROPERTYINFO AudioFormatGetPropertyInfo = NIL; }; #endif MP4MODIFY ex_MP4Modify = NIL; MP4CLOSE ex_MP4Close = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4FINDTRACKID ex_MP4FindTrackId = NIL; MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty = NIL; DynamicLoader *coreaudiodll = NIL; DynamicLoader *mp4v2dll = NIL; #ifdef __WIN32__ static const String coreAudioToolbox = "CoreAudioToolbox.dll"; static String GetSystemDirectory(int id) { String commonFilesDir; ITEMIDLIST *idlist; Buffer buffer(32768 + 1); SHGetSpecialFolderLocation(NIL, id, &idlist); SHGetPathFromIDList(idlist, buffer); commonFilesDir = buffer; CoTaskMemFree(idlist); if (commonFilesDir != NIL && !commonFilesDir.EndsWith("\\")) commonFilesDir.Append("\\"); return commonFilesDir; } # if defined __i386__ || defined _M_IX86 static const String architecture = "x86"; #elif defined __x86_64__ || defined _M_AMD64 static const String architecture = "x64"; #elif defined __arm__ || defined _M_ARM static const String architecture = "arm"; #elif defined __aarch64__ || defined _M_ARM64 static const String architecture = "arm64"; #endif static Void GetPackageFolders(const String &, Array &); static Void FindDependenciesFolders(const String &packageFolder, Array &packageFolders) { if (!File(packageFolder.Append("AppxManifest.xml")).Exists()) return; /* Load app manifest. */ Document document; document.LoadFile(packageFolder.Append("AppxManifest.xml")); /* Get root node. */ Node *root = document.GetRootNode(); if (root == NIL) return; /* Get Dependencies node. */ Node *dependencies = root->GetNodeByName("Dependencies"); if (dependencies == NIL) return; for (Int i = 0; i < dependencies->GetNOfNodes(); i++) { Node *node = dependencies->GetNthNode(i); if (node->GetName() != "PackageDependency") continue; Attribute *name = node->GetAttributeByName("Name"); if (name == NIL) continue; GetPackageFolders(name->GetContent(), packageFolders); } } static Void GetPackageFolders(const String &packageName, Array &packageFolders) { /* Open Packages key. */ HKEY packagesKey; if (RegOpenKey(HKEY_CLASSES_ROOT, L"Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppModel\\Repository\\Packages", &packagesKey) != ERROR_SUCCESS) return; /* Enumerate registered packages. */ Int index = 0; wchar_t name[256]; while (RegEnumKey(packagesKey, index++, name, sizeof(name) / sizeof(wchar_t)) == ERROR_SUCCESS) { if (!String(name).StartsWith(packageName)) continue; if (!String(name).Contains(String("_").Append(architecture).Append("_"))) continue; /* Found package, open key. */ HKEY packageKey; if (RegOpenKey(packagesKey, name, &packageKey) != ERROR_SUCCESS) continue; /* Query folder. */ const DWORD size = 2048; DWORD bytes = size * sizeof(wchar_t); wchar_t folder[size] = { 0 }; RegQueryValueEx(packageKey, L"PackageRootFolder", 0, 0, (BYTE *) folder, &bytes); RegCloseKey(packageKey); /* Add folder and dependencies to list. */ String packageFolder = folder; if (!packageFolder.EndsWith("\\")) packageFolder.Append("\\"); if (packageFolders.Add(packageFolder, packageFolder.ComputeCRC32())) FindDependenciesFolders(packageFolder, packageFolders); break; } RegCloseKey(packagesKey); } static Void CopyLibrary(const String &libName, const Array &packageFolders, const String &cacheFolder) { /* Find source and target file names. */ String sourceFile; String targetFile = cacheFolder.Append(libName); foreach (const String &packageFolder, packageFolders) { if (!File(packageFolder.Append(libName)).Exists()) continue; sourceFile = packageFolder.Append(libName); } /* Check file existence and skip already existing files. */ if (!File(sourceFile).Exists() || File(targetFile).Exists()) return; /* Prepare input and output files. */ InStream in(STREAM_FILE, sourceFile); OutStream out(STREAM_FILE, targetFile, OS_REPLACE); /* Copy chunks of 128kB. */ Buffer buffer(131072); Int overlap = 0; Bool foundSelf = False; for (Int i = 0; i < in.Size(); i += buffer.Size() - overlap) { memcpy(buffer, buffer + buffer.Size() - overlap, overlap); Int bytes = in.InputData(buffer + overlap, Math::Min(buffer.Size() - overlap, in.Size() - in.GetPos())); out.OutputData(buffer + overlap, bytes); /* Check for referenced DLLs. */ for (Int n = 0; n < overlap + bytes - 5; n++) { if (buffer[n] != '.' || buffer[n + 1] != 'd' || buffer[n + 2] != 'l' || buffer[n + 3] != 'l' || buffer[n + 4] != 0) continue; for (Int m = n; m >= 0; m--) { if (buffer[m] >= 0x20) continue; /* Get DLL name and copy it if it looks like a reference. */ String dllName = (char *) (UnsignedByte *) buffer + m + 1; if (foundSelf) CopyLibrary(dllName, packageFolders, cacheFolder); else if (dllName == libName) foundSelf = True; break; } } /* Overlap 128 bytes when wrapping around so we do not miss any relevant DLLs. */ overlap = 128; } } static Void CacheCoreAudioLibraries(const String &cacheFolder) { Array iTunesFolders; GetPackageFolders("AppleInc.iTunes", iTunesFolders); if (iTunesFolders.Length() == 0) return; /* Check if package ID has changed. */ const String packageId = Directory(iTunesFolders.GetFirst()).GetDirectoryName(); const String packageIdFile = cacheFolder.Append("PackageId"); if (File(packageIdFile).Exists()) { InStream in(STREAM_FILE, packageIdFile); if (in.InputLine() == packageId) return; } /* Create cache folder and make sure it's empty. */ Directory(cacheFolder).Create(); Directory(cacheFolder).Empty(); /* Recursively copy CoreAudioToolbox.dll and referenced DLLs. */ CopyLibrary(coreAudioToolbox, iTunesFolders, cacheFolder); /* Store package ID. */ OutStream out(STREAM_FILE, packageIdFile, OS_REPLACE); out.OutputLine(packageId); } #endif Bool LoadCoreAudioDLL() { #ifndef __APPLE__ # ifdef __WIN32__ String coreAudioDir = GetSystemDirectory(CSIDL_PROGRAM_FILES_COMMON).Append("Apple\\Apple Application Support\\"); if (!File(String(coreAudioDir).Append(coreAudioToolbox)).Exists()) { coreAudioDir = GetSystemDirectory(CSIDL_PROGRAM_FILES).Append("iTunes\\"); } if (!File(String(coreAudioDir).Append(coreAudioToolbox)).Exists()) { coreAudioDir = String(BoCA::Config::Get()->cacheDir).Append("boca\\boca.encoder.coreaudio\\").Append(architecture).Append("\\"); CacheCoreAudioLibraries(coreAudioDir); } /* Add Apple Application Services directory to DLL search path. */ SetDllDirectory(coreAudioDir); coreaudiodll = new DynamicLoader(String(coreAudioDir).Append(coreAudioToolbox)); # endif if (coreaudiodll == NIL) return False; AudioFileInitializeWithCallbacks = (AUDIOFILEINITIALIZEWITHCALLBACKS) coreaudiodll->GetFunctionAddress("AudioFileInitializeWithCallbacks"); AudioFileClose = (AUDIOFILECLOSE) coreaudiodll->GetFunctionAddress("AudioFileClose"); AudioFileSetProperty = (AUDIOFILESETPROPERTY) coreaudiodll->GetFunctionAddress("AudioFileSetProperty"); AudioFileWritePackets = (AUDIOFILEWRITEPACKETS) coreaudiodll->GetFunctionAddress("AudioFileWritePackets"); AudioConverterNew = (AUDIOCONVERTERNEW) coreaudiodll->GetFunctionAddress("AudioConverterNew"); AudioConverterDispose = (AUDIOCONVERTERDISPOSE) coreaudiodll->GetFunctionAddress("AudioConverterDispose"); AudioConverterGetProperty = (AUDIOCONVERTERGETPROPERTY) coreaudiodll->GetFunctionAddress("AudioConverterGetProperty"); AudioConverterGetPropertyInfo = (AUDIOCONVERTERGETPROPERTYINFO) coreaudiodll->GetFunctionAddress("AudioConverterGetPropertyInfo"); AudioConverterSetProperty = (AUDIOCONVERTERSETPROPERTY) coreaudiodll->GetFunctionAddress("AudioConverterSetProperty"); AudioConverterFillComplexBuffer = (AUDIOCONVERTERFILLCOMPLEXBUFFER) coreaudiodll->GetFunctionAddress("AudioConverterFillComplexBuffer"); AudioFormatGetProperty = (AUDIOFORMATGETPROPERTY) coreaudiodll->GetFunctionAddress("AudioFormatGetProperty"); AudioFormatGetPropertyInfo = (AUDIOFORMATGETPROPERTYINFO) coreaudiodll->GetFunctionAddress("AudioFormatGetPropertyInfo"); if (AudioFileInitializeWithCallbacks == NIL || AudioFileClose == NIL || AudioFileSetProperty == NIL || AudioFileWritePackets == NIL || AudioConverterNew == NIL || AudioConverterDispose == NIL || AudioConverterGetProperty == NIL || AudioConverterGetPropertyInfo == NIL || AudioConverterSetProperty == NIL || AudioConverterFillComplexBuffer == NIL || AudioFormatGetProperty == NIL || AudioFormatGetPropertyInfo == NIL) { FreeCoreAudioDLL(); return False; } #endif return True; } Void FreeCoreAudioDLL() { #ifndef __APPLE__ BoCA::Utilities::FreeCodecDLL(coreaudiodll); #endif coreaudiodll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Modify = (MP4MODIFY) mp4v2dll->GetFunctionAddress("MP4Modify"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4FindTrackId = (MP4FINDTRACKID) mp4v2dll->GetFunctionAddress("MP4FindTrackId"); ex_MP4SetTrackIntegerProperty = (MP4SETTRACKINTEGERPROPERTY) mp4v2dll->GetFunctionAddress("MP4SetTrackIntegerProperty"); if (ex_MP4Modify == NIL || ex_MP4Close == NIL || ex_MP4Optimize == NIL || ex_MP4FindTrackId == NIL || ex_MP4SetTrackIntegerProperty == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/dllinterface.h000066400000000000000000000101041516712004000265430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #ifdef __APPLE__ /* Prevent math functions from landing in the CA namespace. */ # include #endif namespace CA { #include #include #include enum { kOptionalAudioFormatMPEG4AAC_ELD = 'aace', kOptionalAudioFormatMPEG4AAC_ELD_SBR = 'aacf', kOptionalAudioFormatMPEG4AAC_ELD_V2 = 'aacg' }; }; #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *coreaudiodll; extern DynamicLoader *mp4v2dll; Bool LoadCoreAudioDLL(); Void FreeCoreAudioDLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); #ifndef __APPLE__ namespace CA { typedef OSStatus (*AUDIOFILEINITIALIZEWITHCALLBACKS) (void *, AudioFile_ReadProc, AudioFile_WriteProc, AudioFile_GetSizeProc, AudioFile_SetSizeProc, AudioFileTypeID, const AudioStreamBasicDescription *, UInt32, AudioFileID *); typedef OSStatus (*AUDIOFILECLOSE) (AudioFileID); typedef OSStatus (*AUDIOFILESETPROPERTY) (AudioFileID, AudioFilePropertyID, UInt32, const void *); typedef OSStatus (*AUDIOFILEWRITEPACKETS) (AudioFileID, Boolean, UInt32, const AudioStreamPacketDescription *, SInt64, UInt32 *, const void *); typedef OSStatus (*AUDIOCONVERTERNEW) (const AudioStreamBasicDescription *, const AudioStreamBasicDescription *, AudioConverterRef *); typedef OSStatus (*AUDIOCONVERTERDISPOSE) (AudioConverterRef); typedef OSStatus (*AUDIOCONVERTERGETPROPERTY) (AudioConverterRef, AudioConverterPropertyID, UInt32 *, void *); typedef OSStatus (*AUDIOCONVERTERGETPROPERTYINFO) (AudioConverterRef, AudioConverterPropertyID, UInt32 *, Boolean *); typedef OSStatus (*AUDIOCONVERTERSETPROPERTY) (AudioConverterRef, AudioConverterPropertyID, UInt32, const void *); typedef OSStatus (*AUDIOCONVERTERFILLCOMPLEXBUFFER) (AudioConverterRef, AudioConverterComplexInputDataProc, void *, UInt32 *, AudioBufferList *, AudioStreamPacketDescription *); typedef OSStatus (*AUDIOFORMATGETPROPERTY) (AudioFormatPropertyID, UInt32, const void *, UInt32 *, void *); typedef OSStatus (*AUDIOFORMATGETPROPERTYINFO) (AudioFormatPropertyID, UInt32, const void *, UInt32 *); extern AUDIOFILEINITIALIZEWITHCALLBACKS AudioFileInitializeWithCallbacks; extern AUDIOFILECLOSE AudioFileClose; extern AUDIOFILESETPROPERTY AudioFileSetProperty; extern AUDIOFILEWRITEPACKETS AudioFileWritePackets; extern AUDIOCONVERTERNEW AudioConverterNew; extern AUDIOCONVERTERDISPOSE AudioConverterDispose; extern AUDIOCONVERTERGETPROPERTY AudioConverterGetProperty; extern AUDIOCONVERTERGETPROPERTYINFO AudioConverterGetPropertyInfo; extern AUDIOCONVERTERSETPROPERTY AudioConverterSetProperty; extern AUDIOCONVERTERFILLCOMPLEXBUFFER AudioConverterFillComplexBuffer; extern AUDIOFORMATGETPROPERTY AudioFormatGetProperty; extern AUDIOFORMATGETPROPERTYINFO AudioFormatGetPropertyInfo; }; #endif typedef MP4FileHandle (*MP4MODIFY) (const char *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef MP4TrackId (*MP4FINDTRACKID) (MP4FileHandle, uint16_t, const char *, uint8_t); typedef bool (*MP4SETTRACKINTEGERPROPERTY) (MP4FileHandle, MP4TrackId, const char *, int64_t); extern MP4MODIFY ex_MP4Modify; extern MP4CLOSE ex_MP4Close; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4FINDTRACKID ex_MP4FindTrackId; extern MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/worker.cpp000066400000000000000000000241671516712004000257710ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "config.h" namespace BoCA { CA::OSStatus AudioConverterComplexInputDataProc(CA::AudioConverterRef, CA::UInt32 *, CA::AudioBufferList *, CA::AudioStreamPacketDescription **, void *); }; BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat) : processSignal(1), readySignal(1) { static Endianness endianness = CPU().GetEndianness(); processSignal.Wait(); flush = False; quit = False; format = iFormat; threadMain.Connect(&SuperWorker::Run, this); /* Get configuration. */ CA::UInt32 codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); Int kbps = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); /* Fall back to HE/ELD-SBR if HEv2/ELDv2 is selected for non-stereo input. */ if (codec == CA::kAudioFormatMPEG4AAC_HE_V2 && format.channels != 2) codec = CA::kAudioFormatMPEG4AAC_HE; if (codec == CA::kOptionalAudioFormatMPEG4AAC_ELD_V2 && format.channels != 2) codec = CA::kOptionalAudioFormatMPEG4AAC_ELD_SBR; /* Fill out source format description. */ CA::AudioStreamBasicDescription sourceFormat = { 0 }; sourceFormat.mFormatID = CA::kAudioFormatLinearPCM; sourceFormat.mFormatFlags = CA::kLinearPCMFormatFlagIsPacked; sourceFormat.mFormatFlags |= format.fp ? CA::kLinearPCMFormatFlagIsFloat : 0; sourceFormat.mFormatFlags |= format.sign && !format.fp ? CA::kLinearPCMFormatFlagIsSignedInteger : 0; sourceFormat.mFormatFlags |= endianness == EndianBig ? CA::kLinearPCMFormatFlagIsBigEndian : 0; sourceFormat.mSampleRate = format.rate; sourceFormat.mChannelsPerFrame = format.channels; sourceFormat.mBitsPerChannel = format.bits; sourceFormat.mFramesPerPacket = 1; sourceFormat.mBytesPerFrame = sourceFormat.mChannelsPerFrame * sourceFormat.mBitsPerChannel / 8; sourceFormat.mBytesPerPacket = sourceFormat.mFramesPerPacket * sourceFormat.mBytesPerFrame; /* Fill out destination format description. */ CA::AudioStreamBasicDescription destinationFormat = { 0 }; destinationFormat.mFormatID = codec; destinationFormat.mSampleRate = GetOutputSampleRate(destinationFormat.mFormatID, format.rate); destinationFormat.mChannelsPerFrame = format.channels; CA::UInt32 formatSize = sizeof(destinationFormat); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_FormatInfo, 0, NIL, &formatSize, &destinationFormat); /* Create audio converter object. */ CA::AudioConverterNew(&sourceFormat, &destinationFormat, &converter); frameSize = destinationFormat.mFramesPerPacket; sampleRate = destinationFormat.mSampleRate; /* Set bitrate if format does support bitrates. */ CA::UInt32 size = 0; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, NIL) == 0) { /* Get applicable bitrate values. */ CA::UInt32 bitrate = kbps * 1000 * format.channels; CA::AudioValueRange *bitrateValues = new CA::AudioValueRange [size / sizeof(CA::AudioValueRange)]; CA::AudioConverterGetProperty(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, bitrateValues); /* Find best supported bitrate. */ CA::Float64 nearest = 0xFFFFFFFF; for (UnsignedInt i = 0; i < size / sizeof(CA::AudioValueRange); i++) { if (bitrate >= bitrateValues[i].mMinimum && bitrate <= bitrateValues[i].mMaximum) nearest = bitrate; if (Math::Abs(bitrate - bitrateValues[i].mMinimum) < Math::Abs(bitrate - nearest)) nearest = bitrateValues[i].mMinimum; if (Math::Abs(bitrate - bitrateValues[i].mMaximum) < Math::Abs(bitrate - nearest)) nearest = bitrateValues[i].mMaximum; } bitrate = nearest; delete [] bitrateValues; /* Set bitrate on converter. */ CA::AudioConverterSetProperty(converter, CA::kAudioConverterEncodeBitRate, sizeof(CA::UInt32), &bitrate); } /* Get maximum output packet size. */ CA::UInt32 valueSize = 4; CA::AudioConverterGetProperty(converter, CA::kAudioConverterPropertyMaximumOutputPacketSize, &valueSize, &bufferSize); /* Set up buffer for Core Audio. */ buffers = (CA::AudioBufferList *) new unsigned char [sizeof(CA::AudioBufferList) + sizeof(CA::AudioBuffer)]; buffers->mNumberBuffers = 1; buffers->mBuffers[0].mData = new unsigned char [bufferSize]; buffers->mBuffers[0].mDataByteSize = bufferSize; buffers->mBuffers[0].mNumberChannels = format.channels; bytesConsumed = 0; } BoCA::SuperWorker::~SuperWorker() { /* Free buffer. */ delete [] (unsigned char *) buffers->mBuffers[0].mData; delete [] (unsigned char *) buffers; /* Close converter. */ CA::AudioConverterDispose(converter); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); foreach (CA::AudioStreamPacketDescription *packet, packetInfos) delete packet; packetInfos.RemoveAll(); Int bytesPerFrame = Math::Ceil(frameSize * format.channels * (format.bits / 8) * (Float(format.rate) / sampleRate)); CA::UInt32 packets = 1; CA::AudioStreamPacketDescription packet; buffers->mBuffers[0].mDataByteSize = bufferSize; while ((flush || samplesBuffer.Size() - bytesConsumed >= bytesPerFrame) && CA::AudioConverterFillComplexBuffer(converter, &AudioConverterComplexInputDataProc, this, &packets, buffers, &packet) == 0) { if (buffers->mBuffers[0].mDataByteSize == 0) break; packetBuffer.Resize(packetBuffer.Size() + buffers->mBuffers[0].mDataByteSize); memcpy(packetBuffer + packetBuffer.Size() - buffers->mBuffers[0].mDataByteSize, buffers->mBuffers[0].mData, buffers->mBuffers[0].mDataByteSize); packetSizes.Add(buffers->mBuffers[0].mDataByteSize); packetInfos.Add(new CA::AudioStreamPacketDescription(packet)); buffers->mBuffers[0].mDataByteSize = bufferSize; } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int size, Bool last) { samplesBuffer.Resize(samplesBuffer.Size() + size); memmove(samplesBuffer, samplesBuffer + bytesConsumed, samplesBuffer.Size() - bytesConsumed - size); memcpy(samplesBuffer + samplesBuffer.Size() - bytesConsumed - size, buffer + offset, size); samplesBuffer.Resize(samplesBuffer.Size() - bytesConsumed); bytesConsumed = 0; flush = last; processSignal.Release(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } CA::AudioConverterPrimeInfo BoCA::SuperWorker::GetPrimeInfo() const { CA::AudioConverterPrimeInfo primeInfo; CA::UInt32 size = sizeof(primeInfo); if (CA::AudioConverterGetProperty(converter, CA::kAudioConverterPrimeInfo, &size, &primeInfo) != 0) { primeInfo.leadingFrames = 0xFFFFFFFF; primeInfo.trailingFrames = 0xFFFFFFFF; } return primeInfo; } unsigned char *BoCA::SuperWorker::GetMagicCookie(CA::UInt32 *cookieSize) const { if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterCompressionMagicCookie, cookieSize, NIL) == 0) { unsigned char *cookie = new unsigned char [*cookieSize]; CA::AudioConverterGetProperty(converter, CA::kAudioConverterCompressionMagicCookie, cookieSize, cookie); return cookie; } return NIL; } Int BoCA::SuperWorker::GetOutputSampleRate(CA::UInt32 format, Int inputRate) { /* Get supported sample rate ranges for selected codec. */ CA::UInt32 size = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_AvailableEncodeSampleRates, sizeof(format), &format, &size); if (size == 0) return inputRate; CA::AudioValueRange *sampleRates = new CA::AudioValueRange [size / sizeof(CA::AudioValueRange)]; CA::AudioFormatGetProperty(CA::kAudioFormatProperty_AvailableEncodeSampleRates, sizeof(format), &format, &size, sampleRates); /* Find best fit output sample rate. */ Int outputRate = 0; for (UnsignedInt i = 0; i < size / sizeof(CA::AudioValueRange); i++) { /* Check if encoder supports arbitrary sample rate. */ if (sampleRates[i].mMinimum == 0 && sampleRates[i].mMaximum == 0) { outputRate = inputRate; break; } /* Check if input rate falls into current sample rate range. */ if (inputRate >= sampleRates[i].mMinimum && inputRate <= sampleRates[i].mMaximum) { outputRate = inputRate; break; } /* Check if current sample rate range fits better than previous best. */ if (Math::Abs(inputRate - sampleRates[i].mMinimum) < Math::Abs(inputRate - outputRate)) outputRate = sampleRates[i].mMinimum; if (Math::Abs(inputRate - sampleRates[i].mMaximum) < Math::Abs(inputRate - outputRate)) outputRate = sampleRates[i].mMaximum; } delete [] sampleRates; return outputRate; } CA::OSStatus BoCA::AudioConverterComplexInputDataProc(CA::AudioConverterRef inAudioConverter, CA::UInt32 *ioNumberDataPackets, CA::AudioBufferList *ioData, CA::AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) { SuperWorker *worker = (SuperWorker *) inUserData; const Format &format = worker->format; worker->suppliedData.Resize(Math::Min(worker->samplesBuffer.Size() - worker->bytesConsumed, *ioNumberDataPackets * format.channels * (format.bits / 8))); memcpy(worker->suppliedData, worker->samplesBuffer + worker->bytesConsumed, worker->suppliedData.Size()); *ioNumberDataPackets = worker->suppliedData.Size() / format.channels / (format.bits / 8); ioData->mBuffers[0].mData = worker->suppliedData; ioData->mBuffers[0].mDataByteSize = worker->suppliedData.Size(); ioData->mBuffers[0].mNumberChannels = format.channels; worker->bytesConsumed += ioData->mBuffers[0].mDataByteSize; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudio/worker.h000066400000000000000000000040521516712004000254250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { friend CA::OSStatus AudioConverterComplexInputDataProc(CA::AudioConverterRef, CA::UInt32 *, CA::AudioBufferList *, CA::AudioStreamPacketDescription **, void *); private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; CA::AudioConverterRef converter; CA::AudioBufferList *buffers; Format format; Int frameSize; Int sampleRate; Buffer samplesBuffer; CA::UInt32 bufferSize; Int bytesConsumed; Buffer suppliedData; Buffer packetBuffer; Array packetSizes; Array packetInfos; Bool flush; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &); ~SuperWorker(); Void Encode(const Buffer &, Int, Int, Bool); Void WaitUntilReady(); Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; const Array &GetPacketInfos() const { return packetInfos; }; CA::AudioConverterPrimeInfo GetPrimeInfo() const; unsigned char *GetMagicCookie(CA::UInt32 *) const; static Int GetOutputSampleRate(CA::UInt32, Int); }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/000077500000000000000000000000001516712004000253145ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/Makefile000066400000000000000000000016711516712004000267610ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = coreaudioconnect TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = config.o coreaudioconnect.o dllinterface.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -I"$(SRCDIR)"/$(BOCA_PATH)/include/support/apple -Iconnector -Wno-multichar # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = $(call makein,connector) ALLCMD2 = CLEANCMD1 = $(call cleanin,connector) CLEANCMD2 = INSTCMD1 = $(call makein,connector,install) INSTCMD2 = UINSTCMD1 = $(call makein,connector,uninstall) UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/config.cpp000066400000000000000000000267561516712004000273050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureCoreAudio::ConfigID = "CoreAudio"; BoCA::ConfigureCoreAudio::ConfigureCoreAudio(const CoreAudioCommCodecs &iFormats) { const Config *config = Config::Get(); formats = iFormats; bitrate = config->GetIntValue(ConfigID, "Bitrate", 64); allowID3 = config->GetIntValue(ConfigID, "AllowID3v2", False); fileFormat = config->GetIntValue(ConfigID, "MP4Container", True); fileExtension = config->GetIntValue(ConfigID, "MP4FileExtension", 0); I18n *i18n = I18n::Get(); tabwidget = new TabWidget(Point(7, 7), Size(500, 208)); i18n->SetContext("Encoders::AAC::Format"); layer_format = new Layer(i18n->TranslateString("Format")); group_id3v2 = new GroupBox(i18n->TranslateString("Tags"), Point(7, 88), Size(279, 90)); check_id3v2 = new CheckBox(i18n->TranslateString("Allow ID3v2 tags in AAC files"), Point(10, 13), Size(200, 0), &allowID3); check_id3v2->SetWidth(check_id3v2->GetUnscaledTextWidth() + 20); text_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(10, 38)); text_id3v2 = new Text(i18n->TranslateString("Some players may have problems playing AAC\nfiles with ID3 tags attached. Please use this option only\nif you are sure that your player can handle these tags."), Point(text_note->GetUnscaledTextWidth() + 12, 38)); group_id3v2->SetSize(Size(Math::Max(240, text_note->GetUnscaledTextWidth() + text_id3v2->GetUnscaledTextWidth() + 22), Math::Max(text_note->GetUnscaledTextHeight(), text_id3v2->GetUnscaledTextHeight()) + 48)); group_id3v2->Add(check_id3v2); group_id3v2->Add(text_note); group_id3v2->Add(text_id3v2); group_mp4 = new GroupBox(i18n->TranslateString("File format"), Point(7, 11), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_mp4 = new OptionBox("MP4", Point(10, 13), Size(group_mp4->GetWidth() - 20, 0), &fileFormat, 1); option_mp4->onAction.Connect(&ConfigureCoreAudio::SetFileFormat, this); option_aac = new OptionBox("AAC", Point(10, 38), Size(group_mp4->GetWidth() - 20, 0), &fileFormat, 0); option_aac->onAction.Connect(&ConfigureCoreAudio::SetFileFormat, this); group_mp4->Add(option_mp4); group_mp4->Add(option_aac); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(group_mp4->GetWidth() + 15 + (group_id3v2->GetWidth() % 2), 11), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_extension_m4a = new OptionBox(".m4a", Point(10, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 0); option_extension_m4b = new OptionBox(".m4b", Point(10, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 1); option_extension_m4r = new OptionBox(".m4r", Point(group_extension->GetWidth() / 2 + 4, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 2); option_extension_mp4 = new OptionBox(".mp4", Point(group_extension->GetWidth() / 2 + 4, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 3); group_extension->Add(option_extension_m4a); group_extension->Add(option_extension_m4b); group_extension->Add(option_extension_m4r); group_extension->Add(option_extension_mp4); i18n->SetContext("Encoders::AAC::Codec"); layer_quality = new Layer(i18n->TranslateString("Codec")); group_codec = new GroupBox(i18n->TranslateString("Audio codec"), Point(7, 11), Size(group_id3v2->GetWidth(), 43)); text_codec = new Text(i18n->AddColon(i18n->TranslateString("Audio codec")), Point(10, 15)); combo_codec = new ComboBox(Point(text_codec->GetUnscaledTextSize().cx + 17, 12), Size(group_codec->GetWidth() - text_codec->GetUnscaledTextSize().cx - 27, 0)); /* Query supported formats from Core Audio * and add them to the combo box list. */ for (Int i = 0; i < 32 && formats.codecs[i] != 0; i++) { if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC) combo_codec->AddEntry("MPEG4 AAC Low Complexity"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_HE) combo_codec->AddEntry("MPEG4 AAC High Efficiency"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_HE_V2) combo_codec->AddEntry("MPEG4 AAC High Efficiency v2"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_LD) combo_codec->AddEntry("MPEG4 AAC Low Delay"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_ELD) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_ELD_SBR) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay SBR"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_ELD_V2) combo_codec->AddEntry("MPEG4 AAC Enhanced Low Delay v2"); else if (formats.codecs[i] == CA::kAudioFormatMPEG4AAC_Spatial) combo_codec->AddEntry("MPEG4 AAC Spatial"); else if (formats.codecs[i] == CA::kAudioFormatAppleLossless) combo_codec->AddEntry("Apple Lossless Audio Codec"); else continue; codecs.Add(formats.codecs[i]); if ((UnsignedInt) config->GetIntValue(ConfigID, "Codec", CA::kAudioFormatMPEG4AAC) == formats.codecs[i]) combo_codec->SelectNthEntry(combo_codec->Length() - 1); } combo_codec->onSelectEntry.Connect(&ConfigureCoreAudio::SetCodec, this); group_codec->Add(text_codec); group_codec->Add(combo_codec); i18n->SetContext("Encoders::AAC::Quality"); group_bitrate = new GroupBox(i18n->TranslateString("Bitrate"), Point(7, 66), Size(group_id3v2->GetWidth(), 43)); text_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Bitrate per channel")), Point(10, 15)); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 15)); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); edit_bitrate = new EditBox(String::FromInt(bitrate), Point(text_bitrate_kbps->GetX() + 32, 12), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetOrientation(OR_UPPERRIGHT); edit_bitrate->onInput.Connect(&ConfigureCoreAudio::SetBitrateByEditBox, this); slider_bitrate = new Slider(Point(text_bitrate->GetUnscaledTextSize().cx + 17, 13), Size(group_bitrate->GetWidth() - edit_bitrate->GetX() - 25 - text_bitrate->GetUnscaledTextSize().cx, 0), OR_HORZ, &bitrate, 1, 256); slider_bitrate->onValueChange.Connect(&ConfigureCoreAudio::SetBitrate, this); group_bitrate->Add(text_bitrate); group_bitrate->Add(slider_bitrate); group_bitrate->Add(edit_bitrate); group_bitrate->Add(text_bitrate_kbps); SetCodec(); tabwidget->SetSize(group_id3v2->GetSize() + Size(18, 118)); Add(tabwidget); tabwidget->Add(layer_quality); tabwidget->Add(layer_format); layer_format->Add(group_mp4); layer_format->Add(group_extension); layer_format->Add(group_id3v2); layer_quality->Add(group_codec); layer_quality->Add(group_bitrate); SetSize(group_id3v2->GetSize() + Size(32, 132)); } BoCA::ConfigureCoreAudio::~ConfigureCoreAudio() { DeleteObject(tabwidget); DeleteObject(layer_format); DeleteObject(layer_quality); DeleteObject(group_mp4); DeleteObject(option_mp4); DeleteObject(option_aac); DeleteObject(group_extension); DeleteObject(option_extension_m4a); DeleteObject(option_extension_m4b); DeleteObject(option_extension_m4r); DeleteObject(option_extension_mp4); DeleteObject(group_id3v2); DeleteObject(check_id3v2); DeleteObject(text_note); DeleteObject(text_id3v2); DeleteObject(group_codec); DeleteObject(text_codec); DeleteObject(combo_codec); DeleteObject(group_bitrate); DeleteObject(text_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); } Int BoCA::ConfigureCoreAudio::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Codec", codecs.GetNth(combo_codec->GetSelectedEntryNumber())); if (bitrates.Length() == 2) { if (bitrate < bitrates.GetNth(0)) bitrate = bitrates.GetNth(0); if (bitrate > bitrates.GetNth(1)) bitrate = bitrates.GetNth(1); } if (bitrates.Length() == 2) config->SetIntValue(ConfigID, "Bitrate", bitrate); else if (bitrates.Length() > 2) config->SetIntValue(ConfigID, "Bitrate", bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1)); config->SetIntValue(ConfigID, "MP4Container", fileFormat); config->SetIntValue(ConfigID, "MP4FileExtension", fileExtension); config->SetIntValue(ConfigID, "AllowID3v2", allowID3); return Success(); } Void BoCA::ConfigureCoreAudio::SetCodec() { UnsignedInt format = codecs.GetNth(combo_codec->GetSelectedEntryNumber()); for (Int i = 0; i < 32 && formats.codecs[i] != 0; i++) { if (formats.codecs[i] != format) continue; Int numBitrates = 0; for (Int j = 0; j < 64; j++) if (formats.bitrates[i][2 * j + 1] != 0) numBitrates++; if (numBitrates > 0 && bitrates.Length() > 2) bitrate = bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1); bitrates.RemoveAll(); for (Int j = 0; j < 64 && formats.bitrates[i][2 * j + 1] != 0; j++) { bitrates.Add(formats.bitrates[i][2 * j ] / 1000); bitrates.Add(formats.bitrates[i][2 * j + 1] / 1000); if (bitrate == bitrates.GetNth(j * 2 + 1)) bitrate = -numBitrates + j; } break; } if (bitrates.Length() > 0) group_bitrate->Activate(); else group_bitrate->Deactivate(); if (bitrates.Length() == 2) { edit_bitrate->Activate(); slider_bitrate->SetRange(bitrates.GetNth(0), bitrates.GetNth(1)); } else if (bitrates.Length() > 2) { edit_bitrate->Deactivate(); slider_bitrate->SetRange(-bitrates.Length() / 2, -1); } if (codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatAppleLossless) { group_mp4->Deactivate(); fileFormat = 1; option_extension_m4r->Deactivate(); if (fileExtension == 2) fileExtension = 0; } else if (codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_HE || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_HE_V2 || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_LD || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_ELD || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_ELD_SBR || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_ELD_V2 || codecs.GetNth(combo_codec->GetSelectedEntryNumber()) == CA::kAudioFormatMPEG4AAC_Spatial) { group_mp4->Activate(); option_extension_m4r->Activate(); } SetBitrate(); SetFileFormat(); } Void BoCA::ConfigureCoreAudio::SetBitrate() { if (bitrates.Length() == 0) return; if (!edit_bitrate->IsFocussed()) { if (bitrates.Length() == 2) edit_bitrate->SetText(String::FromInt(bitrate)); else edit_bitrate->SetText(String::FromInt(bitrates.GetNth((bitrates.Length() / 2 + bitrate) * 2 + 1))); } } Void BoCA::ConfigureCoreAudio::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt()); } Void BoCA::ConfigureCoreAudio::SetFileFormat() { if (fileFormat == 1) // MP4 container { group_id3v2->Deactivate(); group_extension->Activate(); } else // raw AAC file format { group_id3v2->Activate(); group_extension->Deactivate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/config.h000066400000000000000000000040101516712004000267250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_COREAUDIOCONFIG #define H_COREAUDIOCONFIG #include #include #include "connector/communication.h" namespace CA { # include }; using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureCoreAudio : public ConfigLayer { private: TabWidget *tabwidget; Layer *layer_format; GroupBox *group_id3v2; CheckBox *check_id3v2; Text *text_note; Text *text_id3v2; GroupBox *group_mp4; OptionBox *option_mp4; OptionBox *option_aac; GroupBox *group_extension; OptionBox *option_extension_m4a; OptionBox *option_extension_m4b; OptionBox *option_extension_m4r; OptionBox *option_extension_mp4; Layer *layer_quality; GroupBox *group_codec; Text *text_codec; ComboBox *combo_codec; GroupBox *group_bitrate; Text *text_bitrate; Slider *slider_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; CoreAudioCommCodecs formats; Array codecs; Array bitrates; Int bitrate; Bool allowID3; Int fileFormat; Int fileExtension; slots: Void SetCodec(); Void SetBitrate(); Void SetBitrateByEditBox(); Void SetFileFormat(); public: static const String ConfigID; ConfigureCoreAudio(const CoreAudioCommCodecs &); ~ConfigureCoreAudio(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/000077500000000000000000000000001516712004000273065ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/Makefile000066400000000000000000000032401516712004000307450ustar00rootroot00000000000000########## Core Audio connector makefile ########## # Change these variables to fit your project: TARGET = coreaudioconnect TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options ifeq ($(BUILD_X86_64),True) X64 = 64 endif OBJECTS = dllinterface.o main.o BINARY = $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET)$(X64).$(VERSION)$(EXECUTABLE) DEFINE = -DUNICODE LIBS = -lole32 -lshell32 CCOPTS = -Wno-multichar -I"$(SRCDIR)"/$(BOCA_PATH)/include -I"$(SRCDIR)"/$(BOCA_PATH)/include/support/apple $(DEFINE) LDOPTS = -L $(BOCA_PATH)/$(LIBDIR) $(LIBS) ifneq ($(BUILD_WIN32),True) override CXX = winegcc override LD = winegcc endif ifeq ($(BUILD_FREEBSD),True) ifeq ($(BUILD_X86),True) ifneq (,$(wildcard ~/.i386-wine-pkg/usr/local/bin/winegcc)) override CXX = ~/.i386-wine-pkg/usr/local/bin/winegcc override LD = ~/.i386-wine-pkg/usr/local/bin/winegcc endif endif endif ifeq ($(BUILD_LINUX),True) LDOPTS += -lrt endif ifeq ($(BUILD_X86),True) CCOPTS += -m32 LDOPTS += -m32 endif all: $(BINARY) $(BINARY): $(OBJECTS) ifeq ($(BUILD_WIN32),True) $(LD) -o $@ $(OBJECTS) $(LDOPTS) $(LDFLAGS) else $(LD) -o $@$(SHARED) $(OBJECTS) $(LDOPTS) $(LDFLAGS) mv $@$(SHARED) $@ endif clean: rm -f $(BINARY) $(OBJECTS) install: all ifneq ($(BUILD_WIN32),True) $(INSTALL) -d "$(DESTDIR)"$(libdir)/boca $(INSTALL_DATA) $(BOCA_PATH)/$(BINDIR)/boca_$(TYPE)_$(TARGET)$(X64).$(VERSION)$(EXECUTABLE) "$(DESTDIR)"$(libdir)/boca endif uninstall: ifneq ($(BUILD_WIN32),True) rm -f "$(DESTDIR)"$(libdir)/boca/boca_$(TYPE)_$(TARGET)$(X64).$(VERSION)$(EXECUTABLE) endif .cpp.o: $(CXX) $(CCOPTS) $(CXXFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/Readme000066400000000000000000000032541516712004000304320ustar00rootroot00000000000000This is the connector part of the Core Audio Connect encoder component. It is a Winelib binary that loads the Core Audio codec installed with iTunes or iCloud in Wine and connects to a running instance of the Core Audio Connect component via shared memory. The Core Audio Connect component can load two versions of the connector, a 64 bit or 32 bit variant. Due to incompatiblities between the Core Audio codecs and recent versions of Wine, the 32 bit variant is needed in most cases. Building this on a 64 bit system requires some additional steps as only the 64 bit variant is built by default. Prerequisites ------------- To successfully build the 32 bit connector on a 64 bit system, the following components are needed in addition to the components needed to build BoCA and the Wine development tools needed to build the Core Audio Connect component: - A multilib version of g++ - The 32 bit libwine development package On Debian based systems, these can be installed using: sudo apt install g++-multilib libwine-dev:i386 Building -------- After building BoCA on a 64 bit system, you should find the following two files belonging to the Core Audio Connect encoder in the BoCA/bin folder: - boca_encoder_coreaudioconnect.1.0.so (the encoder component) - boca_encoder_coreaudioconnect64.1.0 (the 64 bit connector part) To build the 32 bit connector part, enter the following commands: cd components/encoder/coreaudioconnect/connector make BUILD_X86=True clean make BUILD_X86=True This should create a boca_encoder_coreaudioconnect.1.0 binary in the BoCA/bin folder. To install it, run the following command: sudo make BUILD_X86=True install boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/communication.h000066400000000000000000000042711516712004000323300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_COREAUDIOCOMMUNICATION #define H_COREAUDIOCOMMUNICATION #include /* Status codes. */ const int32_t CommStatusIssued = 0; // Command has been issued by the host process. const int32_t CommStatusProcessing = 1; // Connector process is processing a command. const int32_t CommStatusReady = 2; // Connector process finished processing a command. const int32_t CommStatusError = 3; // Error while processing a command. /* Adapter commands. */ const int32_t CommCommandHello = 'HELO'; // Hello -> Say hello. const int32_t CommCommandCodecs = 'CDCS'; // Codecs <- Get available codecs. const int32_t CommCommandSetup = 'STUP'; // Setup -> Setup encoder. const int32_t CommCommandEncode = 'ENCD'; // Raw -> Encode audio samples. const int32_t CommCommandFinish = 'FNSH'; // Finish encoding. const int32_t CommCommandDuration = 'DURA'; // Int64 <- Get total duration in samples. const int32_t CommCommandQuit = 'QUIT'; // Quit adapter process. /* General command data structure. */ struct CoreAudioCommBuffer { int32_t status; int32_t command; int32_t length; int32_t data[65536]; }; /* Data structure for Hello command. */ struct CoreAudioCommHello { int32_t version; }; /* Data structure for Codecs command. */ struct CoreAudioCommCodecs { uint32_t codecs[32]; int32_t bitrates[32][128]; }; /* Data structure for Setup command. */ struct CoreAudioCommSetup { uint32_t codec; int32_t bitrate; int32_t format; int32_t channels; int32_t rate; int32_t bits; int8_t fp; int8_t sign; char file[32768]; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/dllinterface.cpp000066400000000000000000000352111516712004000324500ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" #include #include #include #ifdef __WINE__ # include # include # include # define wchar_t char # define wstring(s) s # define wcslen(x) strlen(x) # define wcscpy(x, y) strcpy(x, y) # define wcsncpy(x, y, z) strncpy(x, y, z) # define wcscat(x, y) strcat(x, y) # define wcscmp(x, y) strcmp(x, y) # define wcsncmp(x, y, z) strncmp(x, y, z) # define wcsrchr(x, y) strrchr(x, y) # define wcsstr(x, y) strstr(x, y) # define _wfopen(x, y) fopen(x, y) # define _wmkdir(x) mkdir(x, 0777) # define GetEnvironmentVariableW GetEnvironmentVariableA # define SetEnvironmentVariableW SetEnvironmentVariableA # define SHGetPathFromIDListW SHGetPathFromIDListA # define SetDllDirectoryW SetDllDirectoryA # define LoadLibraryW LoadLibraryA # define FindFirstFileW FindFirstFileA # define FindNextFileW FindNextFileA # define DeleteFileW DeleteFileA # define RegOpenKeyW RegOpenKeyA # define RegEnumKeyW RegEnumKeyA # define RegQueryValueExW RegQueryValueExA # define WIN32_FIND_DATAW WIN32_FIND_DATAA #else # define wstring(s) L##s #endif namespace CA { AUDIOFILEINITIALIZEWITHCALLBACKS AudioFileInitializeWithCallbacks = NULL; AUDIOFILECLOSE AudioFileClose = NULL; AUDIOFILESETPROPERTY AudioFileSetProperty = NULL; AUDIOFILEWRITEPACKETS AudioFileWritePackets = NULL; AUDIOCONVERTERNEW AudioConverterNew = NULL; AUDIOCONVERTERDISPOSE AudioConverterDispose = NULL; AUDIOCONVERTERGETPROPERTY AudioConverterGetProperty = NULL; AUDIOCONVERTERGETPROPERTYINFO AudioConverterGetPropertyInfo = NULL; AUDIOCONVERTERSETPROPERTY AudioConverterSetProperty = NULL; AUDIOCONVERTERFILLCOMPLEXBUFFER AudioConverterFillComplexBuffer = NULL; AUDIOFORMATGETPROPERTY AudioFormatGetProperty = NULL; AUDIOFORMATGETPROPERTYINFO AudioFormatGetPropertyInfo = NULL; }; using namespace CA; HINSTANCE coreaudiodll = NULL; #define PATH_LENGTH 2048 static bool FileSystemEntryExists(const wchar_t *path) { WIN32_FIND_DATAW findData; HANDLE handle = FindFirstFileW(path, &findData); FindClose(handle); return (handle != INVALID_HANDLE_VALUE); } static const wchar_t *GetSystemDirectory(int id) { static wchar_t commonFilesDir[PATH_LENGTH] = { 0 }; ITEMIDLIST *idlist; SHGetSpecialFolderLocation(NULL, id, &idlist); SHGetPathFromIDListW(idlist, commonFilesDir); CoTaskMemFree(idlist); if (wcslen(commonFilesDir) > 0 && commonFilesDir[wcslen(commonFilesDir) - 1] != '\\') wcscat(commonFilesDir, wstring("\\")); return commonFilesDir; } static const wchar_t *GetCacheFolder(const char *applicationPrefix) { static wchar_t cacheFolder[PATH_LENGTH] = { 0 }; #ifdef __WINE__ char *cacheHome = getenv("XDG_CACHE_HOME"); if (cacheHome == NULL) { passwd *pw = getpwuid(getuid()); if (pw != NULL) strcpy(cacheFolder, pw->pw_dir); else strcpy(cacheFolder, "~"); strcat(cacheFolder, "/.cache/"); } else { strcpy(cacheFolder, cacheHome); if (cacheFolder[strlen(cacheFolder) - 1] != '/') strcat(cacheFolder, "/"); } strcat(cacheFolder, applicationPrefix); strcat(cacheFolder, "/"); #else GetModuleFileName(NULL, cacheFolder, PATH_LENGTH - 1); if (cacheFolder[0] != 0) wcsrchr(cacheFolder, '\\')[1] = 0; /* Don't use program files folder as cache folder. */ static wchar_t programFilesFolder[PATH_LENGTH]; wcscpy(programFilesFolder, GetSystemDirectory(CSIDL_PROGRAM_FILES)); if (wcsncmp(cacheFolder, programFilesFolder, wcslen(programFilesFolder)) != 0) { /* Test if application folder is writable. */ wcscat(cacheFolder, wstring("\\coreaudioconnect.cache")); fclose(_wfopen(cacheFolder, wstring("w"))); if (FileSystemEntryExists(cacheFolder)) { DeleteFileW(cacheFolder); wcsrchr(cacheFolder, '\\')[1] = 0; return cacheFolder; } } /* Otherwise use application data folder. */ wcscpy(cacheFolder, GetSystemDirectory(CSIDL_APPDATA)); for (unsigned int offset = wcslen(cacheFolder), i = 0; i < strlen(applicationPrefix) + 1; i++) cacheFolder[offset + i] = applicationPrefix[i]; wcscat(cacheFolder, wstring("\\")); #endif return cacheFolder; } static void CreateFolder(const wchar_t *path) { wchar_t folder[PATH_LENGTH] = { 0 }; for (unsigned int i = 0; i < wcslen(path); i++) { if (path[i] != '\\') continue; wcsncpy(folder, path, i); _wmkdir(folder); } _wmkdir(path); } static size_t GetFileSize(FILE *file) { fseek(file, 0, SEEK_END); size_t size = ftell(file); fseek(file, 0, SEEK_SET); return size; } # if defined __i386__ || defined _M_IX86 static const wchar_t *architecture = wstring("x86"); #elif defined __x86_64__ || defined _M_AMD64 static const wchar_t *architecture = wstring("x64"); #elif defined __arm__ || defined _M_ARM static const wchar_t *architecture = wstring("arm"); #elif defined __aarch64__ || defined _M_ARM64 static const wchar_t *architecture = wstring("arm64"); #endif #define NUM_FOLDERS 32 static void GetPackageFolders(const wchar_t *, wchar_t **); static void FindDependenciesFolders(const wchar_t *packageFolder, wchar_t **packageFolders) { wchar_t manifestPath[PATH_LENGTH]; wcscpy(manifestPath, packageFolder); wcscat(manifestPath, wstring("AppxManifest.xml")); if (!FileSystemEntryExists(manifestPath)) return; /* Load app manifest. */ FILE *manifest = _wfopen(manifestPath, wstring("r")); size_t size = GetFileSize(manifest); /* Find PackageDependency nodes. */ char line[1024]; while (ftell(manifest) < (int) size) { if (!fgets(line, 1024, manifest)) break; if (!strstr(line, "= 0; m--) { if (buffer[m] >= 0x20) continue; /* Get DLL name and copy it if it looks like a reference. */ char *dllName = (char *) buffer + m + 1; wchar_t dllNameW[256] = { 0 }; for (unsigned int i = 0; i < strlen(dllName); i++) dllNameW[i] = dllName[i]; if (foundSelf) CopyLibrary(dllNameW, packageFolders, cacheFolder); else if (wcscmp(dllNameW, libName) == 0) foundSelf = true; break; } } /* Overlap 128 bytes when wrapping around so we do not miss any relevant DLLs. */ overlap = 128; } fclose(out); fclose(in); } static void CacheCoreAudioLibraries(const wchar_t *cacheFolder) { wchar_t *iTunesFolders[NUM_FOLDERS] = { NULL }; GetPackageFolders(wstring("AppleInc.iTunes"), iTunesFolders); if (iTunesFolders[0] == NULL) return; /* Check if package ID has changed. */ wchar_t packageFolder[PATH_LENGTH]; wcscpy(packageFolder, iTunesFolders[0]); wcsrchr(packageFolder, '\\')[0] = 0; wchar_t *packageIdW = wcsrchr(packageFolder, '\\') + 1; char packageId[256] = { 0 }; for (unsigned int i = 0; i < wcslen(packageIdW); i++) packageId[i] = packageIdW[i]; wchar_t packageIdFile[PATH_LENGTH] = { 0 }; wcscpy(packageIdFile, cacheFolder); wcscat(packageIdFile, wstring("PackageId")); if (FileSystemEntryExists(packageIdFile)) { FILE *in = _wfopen(packageIdFile, wstring("r")); char line[256] = { 0 }; fgets(line, 256, in); fclose(in); if (strcmp(line, packageId) == 0) return; } /* Create cache folder and make sure it's empty. */ CreateFolder(cacheFolder); wchar_t pattern[PATH_LENGTH]; wcscpy(pattern, cacheFolder); wcscat(pattern, wstring("*")); WIN32_FIND_DATAW findData; HANDLE handle = FindFirstFileW(pattern, &findData); do { if (wcscmp(findData.cFileName, wstring(".")) == 0 || wcscmp(findData.cFileName, wstring("..")) == 0) continue; DeleteFileW(findData.cFileName); } while (FindNextFileW(handle, &findData)); FindClose(handle); /* Recursively copy CoreAudioToolbox.dll and referenced DLLs. */ CopyLibrary(wstring("CoreAudioToolbox.dll"), iTunesFolders, cacheFolder); for (int i = 0; i < NUM_FOLDERS; i++) free(iTunesFolders[i]); /* Store package ID. */ FILE *out = _wfopen(packageIdFile, wstring("w")); fprintf(out, "%s\n", packageId); fclose(out); } bool LoadCoreAudioDLL(const char *applicationPrefix) { wchar_t coreAudioDir[PATH_LENGTH]; wcscpy(coreAudioDir, GetSystemDirectory(CSIDL_PROGRAM_FILES_COMMON)); wcscat(coreAudioDir, wstring("Apple\\Apple Application Support\\")); if (!FileSystemEntryExists(coreAudioDir)) { wcscpy(coreAudioDir, GetSystemDirectory(CSIDL_PROGRAM_FILES)); wcscat(coreAudioDir, wstring("iTunes\\")); } if (!FileSystemEntryExists(coreAudioDir)) { wcscpy(coreAudioDir, GetCacheFolder(applicationPrefix)); wcscat(coreAudioDir, wstring("boca.encoder.coreaudio\\")); wcscat(coreAudioDir, architecture); wcscat(coreAudioDir, wstring("\\")); CacheCoreAudioLibraries(coreAudioDir); } /* Add Apple Application Services directory to DLL search path. */ SetDllDirectoryW(coreAudioDir); coreaudiodll = LoadLibraryW(wcscat(coreAudioDir, wstring("CoreAudioToolbox.dll"))); if (coreaudiodll == NULL) return false; AudioFileInitializeWithCallbacks = (AUDIOFILEINITIALIZEWITHCALLBACKS) GetProcAddress(coreaudiodll, "AudioFileInitializeWithCallbacks"); AudioFileClose = (AUDIOFILECLOSE) GetProcAddress(coreaudiodll, "AudioFileClose"); AudioFileSetProperty = (AUDIOFILESETPROPERTY) GetProcAddress(coreaudiodll, "AudioFileSetProperty"); AudioFileWritePackets = (AUDIOFILEWRITEPACKETS) GetProcAddress(coreaudiodll, "AudioFileWritePackets"); AudioConverterNew = (AUDIOCONVERTERNEW) GetProcAddress(coreaudiodll, "AudioConverterNew"); AudioConverterDispose = (AUDIOCONVERTERDISPOSE) GetProcAddress(coreaudiodll, "AudioConverterDispose"); AudioConverterGetProperty = (AUDIOCONVERTERGETPROPERTY) GetProcAddress(coreaudiodll, "AudioConverterGetProperty"); AudioConverterGetPropertyInfo = (AUDIOCONVERTERGETPROPERTYINFO) GetProcAddress(coreaudiodll, "AudioConverterGetPropertyInfo"); AudioConverterSetProperty = (AUDIOCONVERTERSETPROPERTY) GetProcAddress(coreaudiodll, "AudioConverterSetProperty"); AudioConverterFillComplexBuffer = (AUDIOCONVERTERFILLCOMPLEXBUFFER) GetProcAddress(coreaudiodll, "AudioConverterFillComplexBuffer"); AudioFormatGetProperty = (AUDIOFORMATGETPROPERTY) GetProcAddress(coreaudiodll, "AudioFormatGetProperty"); AudioFormatGetPropertyInfo = (AUDIOFORMATGETPROPERTYINFO) GetProcAddress(coreaudiodll, "AudioFormatGetPropertyInfo"); if (AudioFileInitializeWithCallbacks == NULL || AudioFileClose == NULL || AudioFileSetProperty == NULL || AudioFileWritePackets == NULL || AudioConverterNew == NULL || AudioConverterDispose == NULL || AudioConverterGetProperty == NULL || AudioConverterGetPropertyInfo == NULL || AudioConverterSetProperty == NULL || AudioConverterFillComplexBuffer == NULL || AudioFormatGetProperty == NULL || AudioFormatGetPropertyInfo == NULL) { FreeCoreAudioDLL(); return false; } return true; } void FreeCoreAudioDLL() { FreeLibrary(coreaudiodll); coreaudiodll = NULL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/dllinterface.h000066400000000000000000000060071516712004000321160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include namespace CA { #include #include #include }; extern HINSTANCE coreaudiodll; bool LoadCoreAudioDLL(const char *); void FreeCoreAudioDLL(); namespace CA { typedef OSStatus (*AUDIOFILEINITIALIZEWITHCALLBACKS) (void *, AudioFile_ReadProc, AudioFile_WriteProc, AudioFile_GetSizeProc, AudioFile_SetSizeProc, AudioFileTypeID, const AudioStreamBasicDescription *, UInt32, AudioFileID *); typedef OSStatus (*AUDIOFILECLOSE) (AudioFileID); typedef OSStatus (*AUDIOFILESETPROPERTY) (AudioFileID, AudioFilePropertyID, UInt32, const void *); typedef OSStatus (*AUDIOFILEWRITEPACKETS) (AudioFileID, Boolean, UInt32, const AudioStreamPacketDescription *, SInt64, UInt32 *, const void *); typedef OSStatus (*AUDIOCONVERTERNEW) (const AudioStreamBasicDescription *, const AudioStreamBasicDescription *, AudioConverterRef *); typedef OSStatus (*AUDIOCONVERTERDISPOSE) (AudioConverterRef); typedef OSStatus (*AUDIOCONVERTERGETPROPERTY) (AudioConverterRef, AudioConverterPropertyID, UInt32 *, void *); typedef OSStatus (*AUDIOCONVERTERGETPROPERTYINFO) (AudioConverterRef, AudioConverterPropertyID, UInt32 *, Boolean *); typedef OSStatus (*AUDIOCONVERTERSETPROPERTY) (AudioConverterRef, AudioConverterPropertyID, UInt32, const void *); typedef OSStatus (*AUDIOCONVERTERFILLCOMPLEXBUFFER) (AudioConverterRef, AudioConverterComplexInputDataProc, void *, UInt32 *, AudioBufferList *, AudioStreamPacketDescription *); typedef OSStatus (*AUDIOFORMATGETPROPERTY) (AudioFormatPropertyID, UInt32, const void *, UInt32 *, void *); typedef OSStatus (*AUDIOFORMATGETPROPERTYINFO) (AudioFormatPropertyID, UInt32, const void *, UInt32 *); extern AUDIOFILEINITIALIZEWITHCALLBACKS AudioFileInitializeWithCallbacks; extern AUDIOFILECLOSE AudioFileClose; extern AUDIOFILESETPROPERTY AudioFileSetProperty; extern AUDIOFILEWRITEPACKETS AudioFileWritePackets; extern AUDIOCONVERTERNEW AudioConverterNew; extern AUDIOCONVERTERDISPOSE AudioConverterDispose; extern AUDIOCONVERTERGETPROPERTY AudioConverterGetProperty; extern AUDIOCONVERTERGETPROPERTYINFO AudioConverterGetPropertyInfo; extern AUDIOCONVERTERSETPROPERTY AudioConverterSetProperty; extern AUDIOCONVERTERFILLCOMPLEXBUFFER AudioConverterFillComplexBuffer; extern AUDIOFORMATGETPROPERTY AudioFormatGetProperty; extern AUDIOFORMATGETPROPERTYINFO AudioFormatGetPropertyInfo; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/connector/main.cpp000066400000000000000000000431611516712004000307430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #define _FILE_OFFSET_BITS 64 #include "dllinterface.h" #include "communication.h" #include #include #ifdef __WINE__ # include # include # include # include #else # include # if !defined __MINGW32__ # define fseeko _fseeki64 # define ftello _ftelli64 # endif # define ftruncate chsize #endif #ifndef min # define min(n, m) ((n) < (m) ? (n) : (m)) #endif static CoreAudioCommSetup setup = { 0 }; static unsigned int dataOffset = 0; static unsigned char *buffer = NULL; static unsigned int bufferSize = 0; static unsigned int bytesConsumed = 0; static CA::SInt64 totalSamples = 0; void QueryCoreAudioCodecs(CoreAudioCommCodecs *comm) { ZeroMemory(comm, sizeof(CoreAudioCommCodecs)); /* Get supported codecs. */ CA::UInt32 size = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_EncodeFormatIDs, 0, NULL, &size); CA::UInt32 *formats = (CA::UInt32 *) malloc(size); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_EncodeFormatIDs, 0, NULL, &size, formats); for (CA::UInt32 i = 0; i < size / sizeof(CA::UInt32) && i < 32; i++) { comm->codecs[i] = formats[i]; /* Get bitrate ranges for each codec. */ CA::UInt32 brSize = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_AvailableEncodeBitRates, sizeof(CA::UInt32), &formats[i], &brSize); CA::AudioValueRange *bitrateValues = (CA::AudioValueRange *) malloc(brSize); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_AvailableEncodeBitRates, sizeof(CA::UInt32), &formats[i], &brSize, bitrateValues); for (CA::UInt32 j = 0; j < brSize / sizeof(CA::AudioValueRange) && j < 64; j++) { if (bitrateValues[j].mMinimum / 1000 > 192 && bitrateValues[j].mMaximum / 1000 > 192) continue; if ( bitrateValues[j].mMaximum / 1000 > 192) bitrateValues[j].mMaximum = 192 * 1000; comm->bitrates[i][j * 2 ] = bitrateValues[j].mMinimum; comm->bitrates[i][j * 2 + 1] = bitrateValues[j].mMaximum; } free(bitrateValues); } free(formats); } int GetOutputSampleRate(const CoreAudioCommSetup &setup) { /* Get supported sample rate ranges for selected codec. */ CA::UInt32 format = setup.codec; CA::UInt32 size = 0; CA::AudioFormatGetPropertyInfo(CA::kAudioFormatProperty_AvailableEncodeSampleRates, sizeof(format), &format, &size); if (size == 0) return setup.rate; CA::AudioValueRange *sampleRates = (CA::AudioValueRange *) malloc(size); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_AvailableEncodeSampleRates, sizeof(format), &format, &size, sampleRates); /* Find best fit output sample rate. */ int outputRate = 0; for (CA::UInt32 i = 0; i < size / sizeof(CA::AudioValueRange); i++) { /* Check if encoder supports arbitrary sample rate. */ if (sampleRates[i].mMinimum == 0 && sampleRates[i].mMaximum == 0) { outputRate = setup.rate; break; } /* Check if input rate falls into current sample rate range. */ if (setup.rate >= sampleRates[i].mMinimum && setup.rate <= sampleRates[i].mMaximum) { outputRate = setup.rate; break; } /* Check if current sample rate range fits better than previous best. */ if (abs(setup.rate - (int) sampleRates[i].mMinimum) < abs(setup.rate - outputRate)) outputRate = sampleRates[i].mMinimum; if (abs(setup.rate - (int) sampleRates[i].mMaximum) < abs(setup.rate - outputRate)) outputRate = sampleRates[i].mMaximum; } free(sampleRates); return outputRate; } CA::OSStatus AudioFileReadProc(void *inClientData, CA::SInt64 inPosition, CA::UInt32 requestCount, void *buffer, CA::UInt32 *actualCount) { FILE *file = (FILE *) inClientData; fseeko(file, inPosition + dataOffset, SEEK_SET); *actualCount = fread(buffer, 1, requestCount, file); return 0; } CA::OSStatus AudioFileWriteProc(void *inClientData, CA::SInt64 inPosition, CA::UInt32 requestCount, const void *buffer, CA::UInt32 *actualCount) { FILE *file = (FILE *) inClientData; fseeko(file, inPosition + dataOffset, SEEK_SET); *actualCount = fwrite(buffer, 1, requestCount, file); return 0; } CA::SInt64 AudioFileGetSizeProc(void *inClientData) { FILE *file = (FILE *) inClientData; int64_t pos = ftello(file); fseeko(file, 0, SEEK_END); int64_t size = ftello(file); fseeko(file, pos, SEEK_SET); return size - dataOffset; } CA::OSStatus AudioFileSetSizeProc(void *inClientData, CA::SInt64 inSize) { FILE *file = (FILE *) inClientData; fflush(file); ftruncate(fileno(file), inSize + dataOffset); return 0; } CA::OSStatus AudioConverterComplexInputDataProc(CA::AudioConverterRef inAudioConverter, CA::UInt32 *ioNumberDataPackets, CA::AudioBufferList *ioData, CA::AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) { static unsigned char *suppliedData = NULL; static unsigned int suppliedDataSize = 0; suppliedDataSize = min(bufferSize - bytesConsumed, (unsigned int) *ioNumberDataPackets * setup.channels * (setup.bits / 8)); suppliedData = (unsigned char *) realloc(suppliedData, suppliedDataSize); memcpy(suppliedData, buffer + bytesConsumed, suppliedDataSize); *ioNumberDataPackets = suppliedDataSize / setup.channels / (setup.bits / 8); ioData->mBuffers[0].mData = suppliedData; ioData->mBuffers[0].mDataByteSize = suppliedDataSize; ioData->mBuffers[0].mNumberChannels = setup.channels; totalSamples += *ioNumberDataPackets; bytesConsumed += ioData->mBuffers[0].mDataByteSize; return 0; } int main(int argc, char *argv[]) { /* Get application prefix from mapping name. */ char applicationPrefix[128] = { 0 }; #ifndef __WINE__ strcpy(applicationPrefix, argv[1]); strchr(applicationPrefix, ':')[0] = 0; #else strcpy(applicationPrefix, argv[1] + 1); strchr(applicationPrefix, ':')[0] = 0; #endif /* Open shared memory object and map view to communication buffer. */ #ifndef __WINE__ char semaphoreName[128] = { 0 }; strcpy(semaphoreName, argv[1]); strcat(semaphoreName, "-sem"); HANDLE semaphore = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, false, semaphoreName); HANDLE mapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, argv[1]); if (semaphore == NULL || mapping == NULL) return 1; CoreAudioCommBuffer *comm = (CoreAudioCommBuffer *) MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); #else sembuf opWait[1] = { 0, -1, SEM_UNDO }; sembuf opPost[1] = { 0, 1, SEM_UNDO }; int semaphore = semget(atoi(argv[2]), 1, IPC_PRIVATE); int mapping = shm_open(argv[1], O_RDWR, 0666); if (semaphore == -1 || mapping == -1) return 1; CoreAudioCommBuffer *comm = (CoreAudioCommBuffer *) mmap(NULL, sizeof(CoreAudioCommBuffer), PROT_READ | PROT_WRITE, MAP_SHARED, mapping, 0); #endif /* Load Core Audio DLLs. */ LoadCoreAudioDLL(applicationPrefix); /* Main processing loop. */ FILE *file = NULL; CA::AudioFileID audioFile = NULL; CA::AudioConverterRef converter = NULL; CA::AudioBufferList *buffers = NULL; int frameSize = 0; int64_t duration = 0; CA::UInt32 dataSize = 0; CA::UInt32 packetsWritten = 0; while (true) { #ifndef __WINE__ WaitForSingleObject(semaphore, INFINITE); #else semop(semaphore, opWait, 1); #endif if (comm->status != CommStatusIssued) { #ifndef __WINE__ ReleaseSemaphore(semaphore, 1, NULL); #else semop(semaphore, opPost, 1); #endif continue; } switch (comm->command) { case CommCommandHello: if (((CoreAudioCommHello *) &comm->data)->version == 1 && coreaudiodll != NULL) { /* Check whether any codecs are available. */ CoreAudioCommCodecs codecs; memset(&codecs, 0, sizeof(CoreAudioCommCodecs)); QueryCoreAudioCodecs(&codecs); if (codecs.codecs[0] != 0) comm->status = CommStatusReady; } if (comm->status != CommStatusReady) comm->status = CommStatusError; break; case CommCommandCodecs: QueryCoreAudioCodecs((CoreAudioCommCodecs *) &comm->data); comm->length = sizeof(CoreAudioCommCodecs); comm->status = CommStatusReady; break; case CommCommandSetup: memcpy(&setup, comm->data, sizeof(CoreAudioCommSetup)); /* Setup encoder for first packet. */ { /* Fill out source format description. */ CA::AudioStreamBasicDescription sourceFormat = { 0 }; sourceFormat.mFormatID = CA::kAudioFormatLinearPCM; sourceFormat.mFormatFlags = CA::kLinearPCMFormatFlagIsPacked; sourceFormat.mFormatFlags |= setup.fp ? CA::kLinearPCMFormatFlagIsFloat : 0; sourceFormat.mFormatFlags |= setup.sign && !setup.fp ? CA::kLinearPCMFormatFlagIsSignedInteger : 0; sourceFormat.mSampleRate = setup.rate; sourceFormat.mChannelsPerFrame = setup.channels; sourceFormat.mBitsPerChannel = setup.bits; sourceFormat.mFramesPerPacket = 1; sourceFormat.mBytesPerFrame = sourceFormat.mChannelsPerFrame * sourceFormat.mBitsPerChannel / 8; sourceFormat.mBytesPerPacket = sourceFormat.mFramesPerPacket * sourceFormat.mBytesPerFrame; /* Fill out destination format description. */ CA::AudioStreamBasicDescription destinationFormat = { 0 }; destinationFormat.mFormatID = setup.codec; destinationFormat.mSampleRate = GetOutputSampleRate(setup); destinationFormat.mChannelsPerFrame = setup.channels; CA::UInt32 formatSize = sizeof(destinationFormat); CA::AudioFormatGetProperty(CA::kAudioFormatProperty_FormatInfo, 0, NULL, &formatSize, &destinationFormat); /* Create audio converter object. */ if (CA::AudioConverterNew(&sourceFormat, &destinationFormat, &converter) != 0) { comm->status = CommStatusError; break; } frameSize = destinationFormat.mFramesPerPacket; /* Set bitrate if format does support bitrates. */ CA::UInt32 size = 0; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, NULL) == 0) { /* Get applicable bitrate values. */ CA::UInt32 bitrate = setup.bitrate; CA::AudioValueRange *bitrateValues = (CA::AudioValueRange *) malloc(size); CA::AudioConverterGetProperty(converter, CA::kAudioConverterApplicableEncodeBitRates, &size, bitrateValues); /* Find best supported bitrate. */ CA::Float64 nearest = 0xFFFFFFFF; for (unsigned int i = 0; i < size / sizeof(CA::AudioValueRange); i++) { if (bitrate >= bitrateValues[i].mMinimum && bitrate <= bitrateValues[i].mMaximum) nearest = bitrate; if (fabs(bitrate - bitrateValues[i].mMinimum) < fabs(bitrate - nearest)) nearest = bitrateValues[i].mMinimum; if (fabs(bitrate - bitrateValues[i].mMaximum) < fabs(bitrate - nearest)) nearest = bitrateValues[i].mMaximum; } bitrate = nearest; free(bitrateValues); /* Set bitrate on converter. */ CA::AudioConverterSetProperty(converter, CA::kAudioConverterEncodeBitRate, sizeof(CA::UInt32), &bitrate); } /* Create audio file object for output file. */ CA::UInt32 fileType = setup.format ? CA::kAudioFileM4AType : CA::kAudioFileAAC_ADTSType; #ifdef __WINE__ file = fopen(setup.file, "r+b"); #else wchar_t fileName[32768] = L"\\\\?\\"; MultiByteToWideChar(CP_UTF8, 0, setup.file, -1, fileName + 4, sizeof(fileName) / sizeof(wchar_t) - 4); file = _wfopen(fileName, L"r+b"); #endif fseeko(file, 0, SEEK_END); dataOffset = ftello(file); CA::AudioFileInitializeWithCallbacks(file, AudioFileReadProc, AudioFileWriteProc, AudioFileGetSizeProc, AudioFileSetSizeProc, fileType, &destinationFormat, 0, &audioFile); /* Get magic cookie and supply it to audio file. */ CA::UInt32 cookieSize = 0; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, NULL) == 0) { unsigned char *cookie = (unsigned char *) malloc(cookieSize); CA::AudioConverterGetProperty(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, cookie); CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyMagicCookieData, cookieSize, cookie); free(cookie); } /* Get maximum output packet size. */ CA::UInt32 valueSize = 4; CA::AudioConverterGetProperty(converter, CA::kAudioConverterPropertyMaximumOutputPacketSize, &valueSize, &dataSize); /* Set up buffer for Core Audio. */ buffers = (CA::AudioBufferList *) malloc(sizeof(CA::AudioBufferList) + sizeof(CA::AudioBuffer)); buffers->mNumberBuffers = 1; buffers->mBuffers[0].mData = (unsigned char *) malloc(dataSize); buffers->mBuffers[0].mDataByteSize = dataSize; buffers->mBuffers[0].mNumberChannels = setup.channels; } packetsWritten = 0; totalSamples = 0; comm->status = CommStatusReady; break; case CommCommandEncode: if (converter == NULL) { comm->status = CommStatusError; break; } /* Encode supplied packet. */ { /* Configure buffer. */ bufferSize += comm->length; buffer = (unsigned char *) realloc(buffer, bufferSize); memmove(buffer, buffer + bytesConsumed, bufferSize - bytesConsumed - comm->length); memcpy(buffer + bufferSize - bytesConsumed - comm->length, comm->data, comm->length); bufferSize -= bytesConsumed; buffer = (unsigned char *) realloc(buffer, bufferSize); bytesConsumed = 0; /* Convert frames. */ CA::UInt32 packets = 1; CA::AudioStreamPacketDescription packet; buffers->mBuffers[0].mDataByteSize = dataSize; while (CA::AudioConverterFillComplexBuffer(converter, &AudioConverterComplexInputDataProc, NULL, &packets, buffers, &packet) == 0) { if (buffers->mBuffers[0].mDataByteSize == 0) break; CA::AudioFileWritePackets(audioFile, false, buffers->mBuffers[0].mDataByteSize, &packet, packetsWritten, &packets, buffers->mBuffers[0].mData); packetsWritten += packets; if (bufferSize - bytesConsumed < 65536) break; buffers->mBuffers[0].mDataByteSize = dataSize; } } comm->status = CommStatusReady; break; case CommCommandFinish: if (converter == NULL) { comm->status = CommStatusError; break; } /* Finish encoding after last packet. */ { /* Convert final frames. */ CA::UInt32 packets = 1; CA::AudioStreamPacketDescription packet; buffers->mBuffers[0].mDataByteSize = dataSize; while (CA::AudioConverterFillComplexBuffer(converter, &AudioConverterComplexInputDataProc, NULL, &packets, buffers, &packet) == 0) { if (buffers->mBuffers[0].mDataByteSize == 0) break; CA::AudioFileWritePackets(audioFile, false, buffers->mBuffers[0].mDataByteSize, &packet, packetsWritten, &packets, buffers->mBuffers[0].mData); packetsWritten += packets; buffers->mBuffers[0].mDataByteSize = dataSize; } free(buffers->mBuffers[0].mData); free(buffers); /* Calculate frame size divider and duration. */ int rate = GetOutputSampleRate(setup); if (rate == 0) rate = setup.rate; float divider = float(setup.rate) / rate; if (setup.codec == CA::kAudioFormatMPEG4AAC_HE || setup.codec == CA::kAudioFormatMPEG4AAC_HE_V2) divider *= 2.0; duration = int64_t(packetsWritten) * frameSize / divider; /* Write priming and remainder info. */ CA::AudioConverterPrimeInfo primeInfo; CA::UInt32 size = sizeof(primeInfo); if (CA::AudioConverterGetProperty(converter, CA::kAudioConverterPrimeInfo, &size, &primeInfo) == 0) { CA::AudioFilePacketTableInfo pti; pti.mPrimingFrames = primeInfo.leadingFrames; pti.mRemainderFrames = primeInfo.trailingFrames; pti.mNumberValidFrames = ceil(totalSamples / divider); CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyPacketTableInfo, sizeof(pti), &pti); } /* Get and set magic cookie again as some * encoders may change it during encoding. */ CA::UInt32 cookieSize = 4; if (CA::AudioConverterGetPropertyInfo(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, NULL) == 0) { unsigned char *cookie = (unsigned char *) malloc(cookieSize); CA::AudioConverterGetProperty(converter, CA::kAudioConverterCompressionMagicCookie, &cookieSize, cookie); CA::AudioFileSetProperty(audioFile, CA::kAudioFilePropertyMagicCookieData, cookieSize, cookie); free(cookie); } /* Close converter and audio file. */ CA::AudioConverterDispose(converter); CA::AudioFileClose(audioFile); fclose(file); } comm->status = CommStatusReady; break; case CommCommandDuration: comm->length = sizeof(int64_t); comm->data[0] = duration >> 32; comm->data[1] = duration & 0xFFFFFFFF; comm->status = CommStatusReady; break; case CommCommandQuit: comm->status = CommStatusReady; break; } #ifndef __WINE__ ReleaseSemaphore(semaphore, 1, NULL); #else semop(semaphore, opPost, 1); #endif if (comm->command == CommCommandQuit) break; } /* Free Core Audio DLLs. */ FreeCoreAudioDLL(); /* Unmap view and close shared memory object. */ #ifndef __WINE__ UnmapViewOfFile(comm); CloseHandle(mapping); CloseHandle(semaphore); #else munmap(comm, sizeof(CoreAudioCommBuffer)); close(mapping); #endif return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/coreaudioconnect.cpp000066400000000000000000000546371516712004000313630ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #ifdef __WIN32__ # include #else # include # include # include # include # include # include # include #endif #include "coreaudioconnect.h" #include "dllinterface.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderCoreAudioConnect::GetComponentSpecs() { static String componentSpecs; #ifndef __WIN32__ const Array &args = GUI::Application::GetArguments(); foreach (const String &arg, args) { if (arg == "--disable-wine") return componentSpecs; } #endif if (EncoderCoreAudioConnect().IsReady()) { componentSpecs = " \ \ \ \ Core Audio AAC/ALAC Encoder \ 1.0 \ coreaudio-enc \ encoder \ faac-enc \ voaacenc-enc \ ffmpeg-alac-enc \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ MP4 Metadata \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ Apple Lossless Files \ m4a \ m4b \ mp4 \ MP4 Metadata \ \ \ \ \ \ \ \ 8 \ 192 \ \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeMP4v2DLL(); } BoCA::EncoderCoreAudioConnect::EncoderCoreAudioConnect() { #ifdef __WIN32__ connector = NIL; mapping = NIL; #else connector = -1; mapping = -1; #endif comm = NIL; connected = False; ready = False; fileType = 0; configLayer = NIL; config = NIL; } BoCA::EncoderCoreAudioConnect::~EncoderCoreAudioConnect() { if (connected) Disconnect(); if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderCoreAudioConnect::IsReady() const { if (!connected) const_cast(this)->Connect(); return ready; } Bool BoCA::EncoderCoreAudioConnect::IsLossless() const { /* Get configuration. */ const Config *config = GetConfiguration(); Int codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); /* Signal lossless for ALAC. */ if (codec == CA::kAudioFormatAppleLossless) return True; return False; } Bool BoCA::EncoderCoreAudioConnect::Activate() { const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); Int codec = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); Int kbps = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); Bool mp4Container = config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); /* Fall back to HE/ELD-SBR if HEv2/ELDv2 is selected for non-stereo input. */ if (codec == CA::kAudioFormatMPEG4AAC_HE_V2 && format.channels != 2) codec = CA::kAudioFormatMPEG4AAC_HE; if (codec == CA::kAudioFormatMPEG4AAC_ELD_V2 && format.channels != 2) codec = CA::kAudioFormatMPEG4AAC_ELD_SBR; /* Get file type of output file. */ fileType = mp4Container ? CA::kAudioFileM4AType : CA::kAudioFileAAC_ADTSType; /* Write ID3v2 tag if requested. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureCoreAudio::ConfigID, "AllowID3v2", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } driver->Close(); /* Send Setup command. */ if (!connected) Connect(); comm->command = CommCommandSetup; comm->length = sizeof(CoreAudioCommSetup); ((CoreAudioCommSetup *) &comm->data)->codec = codec; ((CoreAudioCommSetup *) &comm->data)->bitrate = kbps * 1000 * format.channels; ((CoreAudioCommSetup *) &comm->data)->format = mp4Container; ((CoreAudioCommSetup *) &comm->data)->channels = format.channels; ((CoreAudioCommSetup *) &comm->data)->rate = format.rate; ((CoreAudioCommSetup *) &comm->data)->bits = format.bits; ((CoreAudioCommSetup *) &comm->data)->fp = format.fp; ((CoreAudioCommSetup *) &comm->data)->sign = format.sign; char *outfile = track.outputFile.ConvertTo("UTF-8"); memcpy(((CoreAudioCommSetup *) &comm->data)->file, outfile, strlen(outfile) + 1); ProcessConnectorCommand(); if (comm->status != CommStatusReady) return False; return True; } Bool BoCA::EncoderCoreAudioConnect::Deactivate() { /* Send Finish command. */ if (!connected) Connect(); comm->command = CommCommandFinish; comm->length = 0; ProcessConnectorCommand(); if (comm->status != CommStatusReady) return False; /* Finish MP4 writing. */ if (fileType == CA::kAudioFileM4AType) { /* Get total duration. */ comm->command = CommCommandDuration; comm->length = 0; ProcessConnectorCommand(); if (comm->status != CommStatusReady) return False; Int64 duration = Int64(comm->data[0]) << 32 | comm->data[1]; /* Fix mhdr atom for long running tracks. */ if (duration > 0xFFFFFFFF) { String tempFile = String(track.outputFile).Append(".temp"); InStream in(STREAM_FILE, track.outputFile, IS_READ); OutStream out(STREAM_FILE, tempFile, OS_REPLACE); Bool result = FixupDurationAtoms(duration, in, out, in.Size()); in.Close(); out.Close(); if (result) { File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } File(tempFile).Delete(); } /* Fix number of channels in sound atom. */ if (mp4v2dll != NIL) { const Format &format = track.GetFormat(); MP4FileHandle mp4File = ex_MP4Modify(track.outputFile, 0); MP4TrackId mp4Track = ex_MP4FindTrackId(mp4File, 0, MP4_AUDIO_TRACK_TYPE, 0); ex_MP4SetTrackIntegerProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.*[0].channels", format.channels); ex_MP4Close(mp4File, 0); } /* Write metadata to file. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableMP4Metadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } else if (mp4v2dll != NIL) { /* Optimize file even when no tags are written. */ String tempFile = String(track.outputFile).Append(".temp"); ex_MP4Optimize(track.outputFile.ConvertTo("UTF-8"), tempFile.ConvertTo("UTF-8")); File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } } /* Write ID3v1 tag if requested. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v1", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { OutStream out(STREAM_FILE, track.outputFile, OS_APPEND); Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); out.OutputData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Update ID3v2 tag with correct chapter marks. */ if (fileType == CA::kAudioFileAAC_ADTSType && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureCoreAudio::ConfigID, "AllowID3v2", False)) { if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { OutStream out(STREAM_FILE, track.outputFile, OS_APPEND); Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); out.Seek(0); out.OutputData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Int BoCA::EncoderCoreAudioConnect::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Change to AAC channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Default_3_0, Channel::AAC_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::AAC_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::AAC_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Default_6_1, Channel::AAC_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Default_7_1, Channel::AAC_7_1); /* Send Encode command. */ if (!connected) Connect(); comm->command = CommCommandEncode; comm->length = data.Size(); memcpy(comm->data, data, data.Size()); ProcessConnectorCommand(); if (comm->status != CommStatusReady) return -1; else return data.Size(); } Bool BoCA::EncoderCoreAudioConnect::SetOutputFormat(Int n) { Config *config = Config::Get(); if (n != 1) config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); else config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", False); if (n != 2 && config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC) == CA::kAudioFormatAppleLossless) config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); else if (n == 2) config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatAppleLossless); return True; } String BoCA::EncoderCoreAudioConnect::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True)) { switch (config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4FileExtension", 0)) { default: case 0: return "m4a"; case 1: return "m4b"; case 2: return "m4r"; case 3: return "mp4"; } } return "aac"; } Bool BoCA::EncoderCoreAudioConnect::FixupDurationAtoms(Int64 duration, InStream &in, OutStream &out, Int64 size, Bool seenMdat) { Int64 bytesLeft = size; Buffer buffer(65536); while (bytesLeft > 0) { UnsignedInt64 bytes = UnsignedInt32(in.InputNumberRaw(4)); UnsignedInt32 id = in.InputNumberRaw(4); Bool use64bit = (bytes == 1); Int grow = 0; if (use64bit == 1) bytes = in.InputNumberRaw(8); if (id == 'moov') grow = 36; else if (id == 'trak') grow = 24; else if (id == 'mdia' || id == 'tkhd' || id == 'mdhd' || id == 'mvhd') grow = 12; out.OutputNumberRaw(use64bit ? 1 : bytes + grow, 4); out.OutputNumberRaw(id, 4); if (use64bit) { out.OutputNumberRaw(bytes + grow, 8); bytes -= 8; bytesLeft -= 8; } bytes -= 8; bytesLeft -= 8; /* Recurse into moov, trak, mdia, minf and stbl boxes. */ if (id == 'moov' || id == 'trak' || id == 'mdia' || id == 'minf' || id == 'stbl') { if (!FixupDurationAtoms(duration, in, out, bytes, seenMdat)) return False; bytesLeft -= bytes; continue; } /* Fixup duration atoms. */ if (id == 'tkhd' || id == 'mdhd' || id == 'mvhd') { Int size = 0; // Version. if (in.InputNumberRaw(1) >= 1) return False; out.OutputNumberRaw(1, 1); size += 1; // Flags. out.OutputNumberRaw(in.InputNumberRaw(3), 3); size += 3; // Creation time. out.OutputNumberRaw(0, 4); out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Modification time. out.OutputNumberRaw(0, 4); out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Time scale. out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; // Reserved. if (id == 'tkhd') { out.OutputNumberRaw(in.InputNumberRaw(4), 4); size += 4; } // Duration. in.RelSeek(4); out.OutputNumberRaw(duration, 8); size += 4; // Rest of atom. in.InputData(buffer, bytes - size); out.OutputData(buffer, bytes - size); bytesLeft -= bytes; continue; } /* Fixup chunk offset atoms. */ if (!seenMdat && (id == 'stco' || id == 'co64')) { // Version. out.OutputNumberRaw(in.InputNumberRaw(1), 1); // Flags. out.OutputNumberRaw(in.InputNumberRaw(3), 3); // Number of entries. UnsignedInt32 numEntries = in.InputNumberRaw(4); out.OutputNumberRaw(numEntries, 4); // Entries. if (id == 'stco') for (UnsignedInt32 i = 0; i < numEntries; i++) out.OutputNumberRaw(in.InputNumberRaw(4) + 36, 4); else for (UnsignedInt32 i = 0; i < numEntries; i++) out.OutputNumberRaw(in.InputNumberRaw(8) + 36, 8); bytesLeft -= bytes; continue; } /* Copy other boxes/atoms. */ if (id == 'mdat') seenMdat = True; while (bytes > 0) { Int size = Math::Min(bytes, buffer.Size()); in.InputData(buffer, size); out.OutputData(buffer, size); bytes -= size; bytesLeft -= size; } } return True; } Bool BoCA::EncoderCoreAudioConnect::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "coreaudio-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); } /* Get command line settings. */ Bool rawAAC = config->GetIntValue(encoderID, "Create ADTS AAC files (no MP4 container)", !config->GetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", True)); Int bitrate = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", 64); Int format = config->GetIntValue(ConfigureCoreAudio::ConfigID, "Codec", CA::kAudioFormatMPEG4AAC); String formatName = "AAC"; if (format == CA::kAudioFormatAppleLossless) formatName = "ALAC"; if (config->GetIntValue(encoderID, "Set Bitrate per channel", False)) bitrate = config->GetIntValue(encoderID, "Bitrate per channel", bitrate); if (config->GetIntValue(encoderID, "Set Output format", False)) formatName = config->GetStringValue(encoderID, "Output format", formatName).ToUpper(); /* Set configuration values. */ config->SetIntValue(ConfigureCoreAudio::ConfigID, "MP4Container", !rawAAC || formatName == "ALAC"); if (formatName == "AAC" ) format = CA::kAudioFormatMPEG4AAC; else if (formatName == "ALAC") format = CA::kAudioFormatAppleLossless; config->SetIntValue(ConfigureCoreAudio::ConfigID, "Codec", format); config->SetIntValue(ConfigureCoreAudio::ConfigID, "Bitrate", Math::Max(8, Math::Min(256, bitrate))); return True; } ConfigLayer *BoCA::EncoderCoreAudioConnect::GetConfigurationLayer() { if (configLayer == NIL) { static CoreAudioCommCodecs codecs; static Bool initialized = False; if (!initialized) { /* Send Codecs command. */ if (!connected) Connect(); comm->command = CommCommandCodecs; comm->length = sizeof(CoreAudioCommCodecs); ProcessConnectorCommand(); if (comm->status == CommStatusReady) memcpy(&codecs, comm->data, comm->length); else codecs.codecs[0] = 0; initialized = True; } configLayer = new ConfigureCoreAudio(codecs); } return configLayer; } Bool BoCA::EncoderCoreAudioConnect::Connect() { static multithread (intptr_t) count = 0; if (connected) return False; /* Try 32 and 64 bit connector. */ Array files; #ifdef __WIN32__ files.Add(GUI::Application::GetApplicationDirectory().Append("boca\\boca_encoder_coreaudioconnect.1.0.exe")); files.Add(GUI::Application::GetApplicationDirectory().Append("boca\\boca_encoder_coreaudioconnect64.1.0.exe")); #else files.Add(Utilities::GetBoCADirectory().Append("/boca_encoder_coreaudioconnect.1.0")); files.Add(Utilities::GetBoCADirectory().Append("/boca_encoder_coreaudioconnect64.1.0")); #endif foreachreverse (const String &file, files) if (!File(file).Exists()) files.RemoveNth(foreachindex); foreach (const String &file, files) { /* Disconnect any previously established connections. */ Disconnect(); /* Create shared memory object and map view to communication buffer. */ #ifdef __WIN32__ mappingName = BoCA::GetApplicationPrefix().Append(":").Append(Number((Int64) GetCurrentProcessId()).ToHexString()).Append("-").Append(Number((Int64) GetCurrentThreadId()).ToHexString()).Append("-").Append(Number((Int64) count++).ToHexString()); semaphore = CreateSemaphoreA(NIL, 0, 1, String(mappingName).Append("-sem")); mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NIL, PAGE_READWRITE, 0, sizeof(CoreAudioCommBuffer), mappingName); comm = (CoreAudioCommBuffer *) MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); #else mappingName = String("/").Append(BoCA::GetApplicationPrefix()).Append(":").Append(Number((Int64) getpid()).ToHexString()).Append("-").Append(Number((Int64) pthread_self()).ToHexString()).Append("-").Append(Number((Int64) count++).ToHexString()); key_t key = mappingName.ComputeCRC32(); semaphore = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666); mapping = shm_open(mappingName, O_CREAT | O_EXCL | O_RDWR, 0666); semctl(semaphore, 0, SETVAL, 0); ftruncate(mapping, sizeof(CoreAudioCommBuffer)); comm = (CoreAudioCommBuffer *) mmap(NULL, sizeof(CoreAudioCommBuffer), PROT_READ | PROT_WRITE, MAP_SHARED, mapping, 0); #endif /* Start connector process. */ #ifdef __WIN32__ SHELLEXECUTEINFOA execInfo; ZeroMemory(&execInfo, sizeof(execInfo)); execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS; execInfo.lpVerb = "open"; execInfo.lpDirectory = GUI::Application::GetApplicationDirectory(); execInfo.nShow = SW_HIDE; execInfo.lpFile = file; execInfo.lpParameters = mappingName; ShellExecuteExA(&execInfo); connector = execInfo.hProcess; #else const char *cmd = String("wine ").Append(file).Append(" ").Append(mappingName).Append(" ").Append(String::FromInt(key)).Append(" 2> /dev/null"); connector = fork(); if (!connector) { execl("/bin/sh", "sh", "-c", cmd, NULL); exit(0); } #endif connected = True; /* Send Hello command. */ comm->command = CommCommandHello; comm->length = sizeof(CoreAudioCommHello); ((CoreAudioCommHello *) &comm->data)->version = 1; ProcessConnectorCommand(); if (comm->status == CommStatusReady) ready = True; else ready = False; if (ready) break; } return True; } Bool BoCA::EncoderCoreAudioConnect::Disconnect() { if (!connected) return False; /* Send Quit command. */ comm->command = CommCommandQuit; comm->length = 0; ProcessConnectorCommand(); /* Wait until the connector exits. */ #ifdef __WIN32__ while (WaitForSingleObject(connector, 0) == WAIT_TIMEOUT) S::System::System::Sleep(1); #else int status = 0; waitpid(connector, &status, 0); #endif /* Unmap view and close shared memory object. */ #ifdef __WIN32__ UnmapViewOfFile(comm); CloseHandle(mapping); CloseHandle(semaphore); #else munmap(comm, sizeof(CoreAudioCommBuffer)); close(mapping); shm_unlink(mappingName); semctl(semaphore, 0, IPC_RMID, 0); #endif connected = False; return True; } Bool BoCA::EncoderCoreAudioConnect::ProcessConnectorCommand() { if (!connected) return False; #ifndef __WIN32__ static sembuf opWait[1] = { 0, -1, SEM_UNDO }; static sembuf opPost[1] = { 0, 1, SEM_UNDO }; #endif comm->status = CommStatusIssued; while (True) { #ifdef __WIN32__ ReleaseSemaphore(semaphore, 1, NULL); while (WaitForSingleObject(semaphore, 1000) != WAIT_OBJECT_0) { /* Check if the connector still exists. */ if (WaitForSingleObject(connector, 0) != WAIT_TIMEOUT) return False; } #else semop(semaphore, opPost, 1); if (semop(semaphore, opWait, 1) != 0) return False; /* Check if the connector still exists. */ int status = 0; if (waitpid(connector, &status, WNOHANG) != 0) return False; #endif if (comm->status != CommStatusIssued) break; } return True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/coreaudioconnect.h000066400000000000000000000040521516712004000310120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "connector/communication.h" namespace CA { # include # include }; BoCA_BEGIN_COMPONENT(EncoderCoreAudioConnect) namespace BoCA { class EncoderCoreAudioConnect : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; String mappingName; #ifdef __WIN32__ HANDLE connector; HANDLE semaphore; HANDLE mapping; #else pid_t connector; int semaphore; int mapping; #endif CoreAudioCommBuffer *comm; Bool connected; Bool ready; CA::UInt32 fileType; Bool Connect(); Bool Disconnect(); Bool ProcessConnectorCommand(); Bool FixupDurationAtoms(Int64, IO::InStream &, IO::OutStream &, Int64, Bool = False); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderCoreAudioConnect(); ~EncoderCoreAudioConnect(); Bool IsReady() const; Bool IsLossless() const; Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; /* This is declared in BoCA's core.h which is not included for component builds. */ BOCA_DLL_EXPORT const String &GetApplicationPrefix(); }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderCoreAudioConnect) BoCA_END_COMPONENT(EncoderCoreAudioConnect) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/dllinterface.cpp000066400000000000000000000033271516712004000304610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; MP4MODIFY ex_MP4Modify = NIL; MP4CLOSE ex_MP4Close = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4FINDTRACKID ex_MP4FindTrackId = NIL; MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Modify = (MP4MODIFY) mp4v2dll->GetFunctionAddress("MP4Modify"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4FindTrackId = (MP4FINDTRACKID) mp4v2dll->GetFunctionAddress("MP4FindTrackId"); ex_MP4SetTrackIntegerProperty = (MP4SETTRACKINTEGERPROPERTY) mp4v2dll->GetFunctionAddress("MP4SetTrackIntegerProperty"); if (ex_MP4Modify == NIL || ex_MP4Close == NIL || ex_MP4Optimize == NIL || ex_MP4FindTrackId == NIL || ex_MP4SetTrackIntegerProperty == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/coreaudioconnect/dllinterface.h000066400000000000000000000025711516712004000301260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *mp4v2dll; Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef MP4FileHandle (*MP4MODIFY) (const char *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef MP4TrackId (*MP4FINDTRACKID) (MP4FileHandle, uint16_t, const char *, uint8_t); typedef bool (*MP4SETTRACKINTEGERPROPERTY) (MP4FileHandle, MP4TrackId, const char *, int64_t); extern MP4MODIFY ex_MP4Modify; extern MP4CLOSE ex_MP4Close; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4FINDTRACKID ex_MP4FindTrackId; extern MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/000077500000000000000000000000001516712004000226625ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/Makefile000077500000000000000000000012471516712004000243310ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = faac TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o faac.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support -DFAACAPI= # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/config.cpp000077500000000000000000000267561516712004000246560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureFAAC::ConfigID = "FAAC"; BoCA::ConfigureFAAC::ConfigureFAAC() { const Config *config = Config::Get(); mpegVersion = config->GetIntValue(ConfigID, "MPEGVersion", 0); bitrate = config->GetIntValue(ConfigID, "Bitrate", 96); allowjs = config->GetIntValue(ConfigID, "AllowJS", True); usetns = config->GetIntValue(ConfigID, "UseTNS", False); setQuality = config->GetIntValue(ConfigID, "SetQuality", True); aacQuality = config->GetIntValue(ConfigID, "AACQuality", 150); allowID3 = config->GetIntValue(ConfigID, "AllowID3v2", False); fileFormat = config->GetIntValue(ConfigID, "MP4Container", True); fileExtension = config->GetIntValue(ConfigID, "MP4FileExtension", 0); I18n *i18n = I18n::Get(); tabwidget = new TabWidget(Point(7, 7), Size(525, 208)); i18n->SetContext("Encoders::AAC::Format"); layer_format = new Layer(i18n->TranslateString("Format")); group_mp4 = new GroupBox(i18n->TranslateString("File format"), Point(7, 11), Size(120, 65)); option_mp4 = new OptionBox("MP4", Point(10, 13), Size(99, 0), &fileFormat, 1); option_mp4->onAction.Connect(&ConfigureFAAC::SetFileFormat, this); if (mp4v2dll == NIL) { option_mp4->Deactivate(); fileFormat = 0; } option_aac = new OptionBox("AAC", Point(10, 38), Size(99, 0), &fileFormat, 0); option_aac->onAction.Connect(&ConfigureFAAC::SetFileFormat, this); group_mp4->Add(option_mp4); group_mp4->Add(option_aac); group_id3v2 = new GroupBox(i18n->TranslateString("Tags"), Point(7, 88), Size(279, 90)); check_id3v2 = new CheckBox(i18n->TranslateString("Allow ID3v2 tags in AAC files"), Point(10, 13), Size(200, 0), &allowID3); check_id3v2->SetWidth(check_id3v2->GetUnscaledTextWidth() + 20); text_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(10, 38)); text_id3v2 = new Text(i18n->TranslateString("Some players may have problems playing AAC\nfiles with ID3 tags attached. Please use this option only\nif you are sure that your player can handle these tags."), Point(text_note->GetUnscaledTextWidth() + 12, 38)); group_id3v2->SetSize(Size(Math::Max(368, text_note->GetUnscaledTextWidth() + text_id3v2->GetUnscaledTextWidth() + 22), Math::Max(text_note->GetUnscaledTextHeight(), text_id3v2->GetUnscaledTextHeight()) + 48)); group_id3v2->Add(check_id3v2); group_id3v2->Add(text_note); group_id3v2->Add(text_id3v2); group_version = new GroupBox(i18n->TranslateString("MPEG version"), Point(135, 11), Size(group_id3v2->GetWidth() / 2 - 68, 65)); option_version_mpeg2 = new OptionBox("MPEG 2", Point(10, 13), Size(group_version->GetWidth() - 21, 0), &mpegVersion, 1); option_version_mpeg4 = new OptionBox("MPEG 4", Point(10, 38), Size(group_version->GetWidth() - 21, 0), &mpegVersion, 0); group_version->Add(option_version_mpeg2); group_version->Add(option_version_mpeg4); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(group_version->GetWidth() + 143 + (group_id3v2->GetWidth() % 2), 11), Size(group_id3v2->GetWidth() / 2 - 68, 65)); option_extension_m4a = new OptionBox(".m4a", Point(10, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 0); option_extension_m4b = new OptionBox(".m4b", Point(10, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 1); option_extension_m4r = new OptionBox(".m4r", Point(group_extension->GetWidth() / 2 + 4, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 2); option_extension_mp4 = new OptionBox(".mp4", Point(group_extension->GetWidth() / 2 + 4, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 3); group_extension->Add(option_extension_m4a); group_extension->Add(option_extension_m4b); group_extension->Add(option_extension_m4r); group_extension->Add(option_extension_mp4); i18n->SetContext("Encoders::AAC::Quality"); layer_quality = new Layer(i18n->TranslateString("Quality")); group_bitrate = new GroupBox(i18n->TranslateString("Bitrate / Quality"), Point(7, 11), Size(320, 65)); option_bitrate = new OptionBox(i18n->AddColon(i18n->TranslateString("Bitrate per channel")), Point(10, 13), Size(150, 0), &setQuality, 0); option_bitrate->onAction.Connect(&ConfigureFAAC::ToggleBitrateQuality, this); option_bitrate->SetWidth(option_bitrate->GetUnscaledTextWidth() + 19); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 15)); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); edit_bitrate = new EditBox(Point(text_bitrate_kbps->GetX() + 32, 12), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetOrientation(OR_UPPERRIGHT); edit_bitrate->onInput.Connect(&ConfigureFAAC::SetBitrateByEditBox, this); slider_bitrate = new Slider(Point(option_bitrate->GetWidth() + 18, 13), Size(group_bitrate->GetWidth() - edit_bitrate->GetX() - 26 - option_bitrate->GetWidth(), 0), OR_HORZ, &bitrate, 8, 256); slider_bitrate->onValueChange.Connect(&ConfigureFAAC::SetBitrate, this); option_quality = new OptionBox(i18n->AddColon(i18n->TranslateString("Set quality")), Point(10, 38), Size(150, 0), &setQuality, 1); option_quality->onAction.Connect(&ConfigureFAAC::ToggleBitrateQuality, this); option_quality->SetWidth(option_bitrate->GetWidth()); slider_quality = new Slider(Point(option_quality->GetWidth() + 18, 38), Size(slider_bitrate->GetWidth(), 0), OR_HORZ, &aacQuality, 10, 500); slider_quality->onValueChange.Connect(&ConfigureFAAC::SetQuality, this); edit_quality = new EditBox(Point(edit_bitrate->GetX(), 37), Size(25, 0), 3); edit_quality->SetFlags(EDB_NUMERIC); edit_quality->SetOrientation(OR_UPPERRIGHT); edit_quality->onInput.Connect(&ConfigureFAAC::SetQualityByEditBox, this); text_quality_percent = new Text(i18n->TranslateString("%1%", "Technical").Replace("%1", NIL).Trim(), Point(text_bitrate_kbps->GetX(), 40)); text_quality_percent->SetOrientation(OR_UPPERRIGHT); group_bitrate->Add(option_bitrate); group_bitrate->Add(slider_bitrate); group_bitrate->Add(edit_bitrate); group_bitrate->Add(text_bitrate_kbps); group_bitrate->Add(option_quality); group_bitrate->Add(slider_quality); group_bitrate->Add(edit_quality); group_bitrate->Add(text_quality_percent); group_js = new GroupBox(i18n->TranslateString("Stereo mode"), Point(335, 11), Size(189, 42)); check_js = new CheckBox(i18n->TranslateString("Allow Joint Stereo"), Point(10, 13), Size(168, 0), &allowjs); group_js->Add(check_js); group_tns = new GroupBox(i18n->TranslateString("Temporal Noise Shaping"), Point(335, 65), Size(189, 42)); check_tns = new CheckBox(i18n->TranslateString("Use Temporal Noise Shaping"), Point(10, 13), Size(168, 0), &usetns); group_tns->Add(check_tns); group_bandwidth = new GroupBox(i18n->TranslateString("Maximum bandwidth"), Point(7, 88), Size(320, 43)); text_bandwidth = new Text(i18n->AddColon(i18n->TranslateString("Maximum AAC frequency bandwidth to use (Hz)")), Point(11, 15)); edit_bandwidth = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "BandWidth", 18500)), Point(text_bandwidth->GetUnscaledTextWidth() + 19, 12), Size(291 - text_bandwidth->GetUnscaledTextWidth(), 0), 5); edit_bandwidth->SetFlags(EDB_NUMERIC); group_bandwidth->Add(text_bandwidth); group_bandwidth->Add(edit_bandwidth); SetBitrate(); SetQuality(); SetFileFormat(); ToggleBitrateQuality(); tabwidget->SetSize(Size(Math::Max(535, group_id3v2->GetWidth() + 18), Math::Max(193, group_id3v2->GetHeight() + 118))); Add(tabwidget); tabwidget->Add(layer_quality); tabwidget->Add(layer_format); layer_format->Add(group_version); layer_format->Add(group_mp4); layer_format->Add(group_extension); layer_format->Add(group_id3v2); layer_quality->Add(group_bitrate); layer_quality->Add(group_js); layer_quality->Add(group_tns); layer_quality->Add(group_bandwidth); SetSize(tabwidget->GetSize() + Size(14, 14)); } BoCA::ConfigureFAAC::~ConfigureFAAC() { DeleteObject(tabwidget); DeleteObject(layer_format); DeleteObject(layer_quality); DeleteObject(group_version); DeleteObject(option_version_mpeg2); DeleteObject(option_version_mpeg4); DeleteObject(group_mp4); DeleteObject(option_mp4); DeleteObject(option_aac); DeleteObject(group_extension); DeleteObject(option_extension_m4a); DeleteObject(option_extension_m4b); DeleteObject(option_extension_m4r); DeleteObject(option_extension_mp4); DeleteObject(group_id3v2); DeleteObject(check_id3v2); DeleteObject(text_note); DeleteObject(text_id3v2); DeleteObject(group_bitrate); DeleteObject(option_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); DeleteObject(option_quality); DeleteObject(slider_quality); DeleteObject(edit_quality); DeleteObject(text_quality_percent); DeleteObject(group_js); DeleteObject(check_js); DeleteObject(group_tns); DeleteObject(check_tns); DeleteObject(group_bandwidth); DeleteObject(text_bandwidth); DeleteObject(edit_bandwidth); } Int BoCA::ConfigureFAAC::SaveSettings() { Config *config = Config::Get(); if (bitrate < 8) bitrate = 8; if (bitrate > 256) bitrate = 256; if (aacQuality < 10) aacQuality = 10; if (aacQuality > 500) aacQuality = 500; config->SetIntValue(ConfigID, "MPEGVersion", mpegVersion); config->SetIntValue(ConfigID, "Bitrate", bitrate); config->SetIntValue(ConfigID, "AllowJS", allowjs); config->SetIntValue(ConfigID, "UseTNS", usetns); config->SetIntValue(ConfigID, "BandWidth", edit_bandwidth->GetText().ToInt()); config->SetIntValue(ConfigID, "SetQuality", setQuality); config->SetIntValue(ConfigID, "AACQuality", aacQuality); config->SetIntValue(ConfigID, "AllowID3v2", allowID3); config->SetIntValue(ConfigID, "MP4Container", fileFormat); config->SetIntValue(ConfigID, "MP4FileExtension", fileExtension); return Success(); } Void BoCA::ConfigureFAAC::SetBitrate() { if (!edit_bitrate->IsFocussed()) edit_bitrate->SetText(String::FromInt(bitrate)); } Void BoCA::ConfigureFAAC::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt()); } Void BoCA::ConfigureFAAC::SetQuality() { if (!edit_quality->IsFocussed()) edit_quality->SetText(String::FromInt(aacQuality)); } Void BoCA::ConfigureFAAC::SetQualityByEditBox() { slider_quality->SetValue(edit_quality->GetText().ToInt()); } Void BoCA::ConfigureFAAC::SetFileFormat() { if (fileFormat == 1) // MP4 container { group_version->Deactivate(); group_id3v2->Deactivate(); group_extension->Activate(); if (mpegVersion == 1) // MPEG2 { mpegVersion = 0; OptionBox::internalCheckValues.Emit(); } } else // raw AAC file format { group_version->Activate(); group_id3v2->Activate(); group_extension->Deactivate(); } } Void BoCA::ConfigureFAAC::ToggleBitrateQuality() { if (setQuality) { slider_bitrate->Deactivate(); edit_bitrate->Deactivate(); slider_quality->Activate(); edit_quality->Activate(); } else { slider_quality->Deactivate(); edit_quality->Deactivate(); slider_bitrate->Activate(); edit_bitrate->Activate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/config.h000077500000000000000000000044371516712004000243130ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_FAACCONFIG #define H_FAACCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureFAAC : public ConfigLayer { private: TabWidget *tabwidget; Layer *layer_format; GroupBox *group_version; OptionBox *option_version_mpeg2; OptionBox *option_version_mpeg4; GroupBox *group_id3v2; CheckBox *check_id3v2; Text *text_note; Text *text_id3v2; GroupBox *group_mp4; OptionBox *option_mp4; OptionBox *option_aac; GroupBox *group_extension; OptionBox *option_extension_m4a; OptionBox *option_extension_m4b; OptionBox *option_extension_m4r; OptionBox *option_extension_mp4; Layer *layer_quality; GroupBox *group_bitrate; Slider *slider_bitrate; OptionBox *option_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; Slider *slider_quality; OptionBox *option_quality; EditBox *edit_quality; Text *text_quality_percent; GroupBox *group_js; CheckBox *check_js; GroupBox *group_tns; CheckBox *check_tns; GroupBox *group_bandwidth; Text *text_bandwidth; EditBox *edit_bandwidth; Int mpegVersion; Int bitrate; Bool allowjs; Bool usetns; Int setQuality; Int aacQuality; Bool allowID3; Int fileFormat; Int fileExtension; slots: Void SetBitrate(); Void SetBitrateByEditBox(); Void SetQuality(); Void SetQualityByEditBox(); Void SetFileFormat(); Void ToggleBitrateQuality(); public: static const String ConfigID; ConfigureFAAC(); ~ConfigureFAAC(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/dllinterface.cpp000077500000000000000000000104771516712004000260360ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; FAACENCOPEN ex_faacEncOpen = NIL; FAACENCGETCURRENTCONFIGURATION ex_faacEncGetCurrentConfiguration = NIL; FAACENCSETCONFIGURATION ex_faacEncSetConfiguration = NIL; FAACENCGETDECODERSPECIFICINFO ex_faacEncGetDecoderSpecificInfo = NIL; FAACENCENCODE ex_faacEncEncode = NIL; FAACENCCLOSE ex_faacEncClose = NIL; MP4CREATECALLBACKS ex_MP4CreateCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration = NIL; MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty = NIL; MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel = NIL; MP4ADDAUDIOTRACK ex_MP4AddAudioTrack = NIL; MP4WRITESAMPLE ex_MP4WriteSample = NIL; MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc = NIL; MP4ITMFITEMFREE ex_MP4ItmfItemFree = NIL; MP4ITMFADDITEM ex_MP4ItmfAddItem = NIL; DynamicLoader *faacdll = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadFAACDLL() { faacdll = BoCA::Utilities::LoadCodecDLL("faac"); if (faacdll == NIL) return False; ex_faacEncOpen = (FAACENCOPEN) faacdll->GetFunctionAddress("faacEncOpen"); ex_faacEncGetCurrentConfiguration = (FAACENCGETCURRENTCONFIGURATION) faacdll->GetFunctionAddress("faacEncGetCurrentConfiguration"); ex_faacEncSetConfiguration = (FAACENCSETCONFIGURATION) faacdll->GetFunctionAddress("faacEncSetConfiguration"); ex_faacEncGetDecoderSpecificInfo = (FAACENCGETDECODERSPECIFICINFO) faacdll->GetFunctionAddress("faacEncGetDecoderSpecificInfo"); ex_faacEncEncode = (FAACENCENCODE) faacdll->GetFunctionAddress("faacEncEncode"); ex_faacEncClose = (FAACENCCLOSE) faacdll->GetFunctionAddress("faacEncClose"); if (ex_faacEncOpen == NIL || ex_faacEncGetCurrentConfiguration == NIL || ex_faacEncSetConfiguration == NIL || ex_faacEncGetDecoderSpecificInfo == NIL || ex_faacEncEncode == NIL || ex_faacEncClose == NIL) { FreeFAACDLL(); return False; } return True; } Void FreeFAACDLL() { BoCA::Utilities::FreeCodecDLL(faacdll); faacdll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4CreateCallbacks = (MP4CREATECALLBACKS) mp4v2dll->GetFunctionAddress("MP4CreateCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4SetTrackESConfiguration = (MP4SETTRACKESCONFIGURATION) mp4v2dll->GetFunctionAddress("MP4SetTrackESConfiguration"); ex_MP4SetTrackIntegerProperty = (MP4SETTRACKINTEGERPROPERTY) mp4v2dll->GetFunctionAddress("MP4SetTrackIntegerProperty"); ex_MP4SetAudioProfileLevel = (MP4SETAUDIOPROFILELEVEL) mp4v2dll->GetFunctionAddress("MP4SetAudioProfileLevel"); ex_MP4AddAudioTrack = (MP4ADDAUDIOTRACK) mp4v2dll->GetFunctionAddress("MP4AddAudioTrack"); ex_MP4WriteSample = (MP4WRITESAMPLE) mp4v2dll->GetFunctionAddress("MP4WriteSample"); ex_MP4ItmfItemAlloc = (MP4ITMFITEMALLOC) mp4v2dll->GetFunctionAddress("MP4ItmfItemAlloc"); ex_MP4ItmfItemFree = (MP4ITMFITEMFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemFree"); ex_MP4ItmfAddItem = (MP4ITMFADDITEM) mp4v2dll->GetFunctionAddress("MP4ItmfAddItem"); if (ex_MP4CreateCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Optimize == NIL || ex_MP4SetTrackESConfiguration == NIL || ex_MP4SetTrackIntegerProperty == NIL || ex_MP4SetAudioProfileLevel == NIL || ex_MP4AddAudioTrack == NIL || ex_MP4WriteSample == NIL || ex_MP4ItmfItemAlloc == NIL || ex_MP4ItmfItemFree == NIL || ex_MP4ItmfAddItem == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/dllinterface.h000077500000000000000000000063201516712004000254730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *faacdll; extern DynamicLoader *mp4v2dll; Bool LoadFAACDLL(); Void FreeFAACDLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef faacEncHandle (FAACAPI *FAACENCOPEN) (unsigned long, unsigned int, unsigned long *, unsigned long *); typedef faacEncConfigurationPtr (FAACAPI *FAACENCGETCURRENTCONFIGURATION) (faacEncHandle); typedef int (FAACAPI *FAACENCSETCONFIGURATION) (faacEncHandle, faacEncConfigurationPtr); typedef int (FAACAPI *FAACENCGETDECODERSPECIFICINFO) (faacEncHandle, unsigned char **, unsigned long *); typedef int (FAACAPI *FAACENCENCODE) (faacEncHandle, int32_t *, unsigned int, unsigned char *, unsigned int); typedef int (FAACAPI *FAACENCCLOSE) (faacEncHandle); extern FAACENCOPEN ex_faacEncOpen; extern FAACENCGETCURRENTCONFIGURATION ex_faacEncGetCurrentConfiguration; extern FAACENCSETCONFIGURATION ex_faacEncSetConfiguration; extern FAACENCGETDECODERSPECIFICINFO ex_faacEncGetDecoderSpecificInfo; extern FAACENCENCODE ex_faacEncEncode; extern FAACENCCLOSE ex_faacEncClose; typedef MP4FileHandle (*MP4CREATECALLBACKS) (const MP4IOCallbacks *, void *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef bool (*MP4SETTRACKESCONFIGURATION) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t); typedef bool (*MP4SETTRACKINTEGERPROPERTY) (MP4FileHandle, MP4TrackId, const char *, int64_t); typedef void (*MP4SETAUDIOPROFILELEVEL) (MP4FileHandle, uint8_t); typedef MP4TrackId (*MP4ADDAUDIOTRACK) (MP4FileHandle, uint32_t, MP4Duration, uint8_t); typedef bool (*MP4WRITESAMPLE) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t, MP4Duration, MP4Duration, bool); typedef MP4ItmfItem * (*MP4ITMFITEMALLOC) (const char *, uint32_t); typedef void (*MP4ITMFITEMFREE) (MP4ItmfItem *); typedef bool (*MP4ITMFADDITEM) (MP4FileHandle, const MP4ItmfItem *); extern MP4CREATECALLBACKS ex_MP4CreateCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration; extern MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty; extern MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel; extern MP4ADDAUDIOTRACK ex_MP4AddAudioTrack; extern MP4WRITESAMPLE ex_MP4WriteSample; extern MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc; extern MP4ITMFITEMFREE ex_MP4ItmfItemFree; extern MP4ITMFADDITEM ex_MP4ItmfAddItem; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/faac.cpp000066400000000000000000000420751516712004000242700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "faac.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderFAAC::GetComponentSpecs() { static String componentSpecs; if (faacdll != NIL) { componentSpecs = " \ \ \ \ FAAC MP4/AAC Encoder %VERSION% \ 1.0 \ faac-enc \ encoder \ voaacenc-enc \ \ "; if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ MP4 Metadata \ \ \ "); } componentSpecs.Append(" \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ \ \ 10 \ 500 \ \ \ 8 \ 256 \ \ \ "); if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ \ "); } componentSpecs.Append(" \ \ \ \ \ "); unsigned long samplesSize; unsigned long bufferSize; faacEncHandle faac = ex_faacEncOpen(44100, 2, &samplesSize, &bufferSize); componentSpecs.Replace("%VERSION%", String("v").Append(ex_faacEncGetCurrentConfiguration(faac)->name)); ex_faacEncClose(faac); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFAACDLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeFAACDLL(); FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_write(void *, const void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, NIL, MP4IO_write, NIL }; }; BoCA::EncoderFAAC::EncoderFAAC() { configLayer = NIL; config = NIL; mp4File = NIL; mp4Track = MP4_INVALID_TRACK_ID; frameSize = 0; blockSize = 128; overlap = 8; totalSamples = 0; nextWorker = 0; } BoCA::EncoderFAAC::~EncoderFAAC() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderFAAC::Activate() { const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); if (mp4v2dll == NIL) config->SetIntValue(ConfigureFAAC::ConfigID, "MP4Container", False); Bool mp4Container = config->GetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True); Int mpegVersion = config->GetIntValue(ConfigureFAAC::ConfigID, "MPEGVersion", 0); /* Create FAAC encoder. */ unsigned long samplesSize = 0; unsigned long bufferSize = 0; faacEncHandle handle = ex_faacEncOpen(format.rate, format.channels, &samplesSize, &bufferSize); /* Set encoder parameters. */ faacEncConfigurationPtr fConfig = ex_faacEncGetCurrentConfiguration(handle); fConfig->mpegVersion = mp4Container ? MPEG4 : mpegVersion; fConfig->aacObjectType = LOW; ex_faacEncSetConfiguration(handle, fConfig); frameSize = samplesSize / format.channels; /* Check whether to use MP4 container. */ if (mp4Container) { /* Create MP4 file. */ uint32_t flags = (track.length >= 0xFFFF0000 || track.approxLength >= 0xFFFF0000) ? MP4_CREATE_64BIT_DATA | MP4_CREATE_64BIT_TIME : 0; mp4File = ex_MP4CreateCallbacks(&mp4Callbacks, driver, flags); mp4Track = ex_MP4AddAudioTrack(mp4File, format.rate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); ex_MP4SetAudioProfileLevel(mp4File, 0x0F); ex_MP4SetTrackIntegerProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.mp4a.channels", format.channels); unsigned char *buffer = NIL; ex_faacEncGetDecoderSpecificInfo(handle, &buffer, &bufferSize); ex_MP4SetTrackESConfiguration(mp4File, mp4Track, (uint8_t *) buffer, bufferSize); totalSamples = 0; } ex_faacEncClose(handle); /* Write ID3v2 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureFAAC::ConfigID, "AllowID3v2", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = 8; /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, format)); foreach (SuperWorker *worker, workers) worker->Start(); return True; } Bool BoCA::EncoderFAAC::Deactivate() { /* Output remaining samples to encoder. */ EncodeFrames(True); /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Finish MP4 writing. */ if (mp4File != NIL) { /* Write iTunes metadata with gapless information. */ MP4ItmfItem *item = ex_MP4ItmfItemAlloc("----", 1); String value = String().Append(" 00000000") .Append(" ").Append(Number((Int64) frameSize).ToHexString(8).ToUpper()) .Append(" ").Append(Number((Int64) frameSize - totalSamples % frameSize).ToHexString(8).ToUpper()) .Append(" ").Append(Number((Int64) totalSamples).ToHexString(16).ToUpper()) .Append(" 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000"); item->mean = (char *) "com.apple.iTunes"; item->name = (char *) "iTunSMPB"; item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8; item->dataList.elements[0].value = (uint8_t *) value.ConvertTo("UTF-8"); item->dataList.elements[0].valueSize = value.Length(); ex_MP4ItmfAddItem(mp4File, item); item->mean = NIL; item->name = NIL; item->dataList.elements[0].typeCode = MP4_ITMF_BT_IMPLICIT; item->dataList.elements[0].value = NIL; item->dataList.elements[0].valueSize = 0; ex_MP4ItmfItemFree(item); ex_MP4Close(mp4File, 0); /* Close output file as tagger needs to modify it. */ driver->Close(); /* Write metadata to file. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableMP4Metadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } else { /* Optimize file even when no tags are written. */ String tempFile = String(track.outputFile).Append(".temp"); ex_MP4Optimize(track.outputFile.ConvertTo("UTF-8"), tempFile.ConvertTo("UTF-8")); File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } } /* Write ID3v1 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v1", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Update ID3v2 tag with correct chapter marks. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureFAAC::ConfigID, "AllowID3v2", False)) { if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Int BoCA::EncoderFAAC::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Change to AAC channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Default_3_0, Channel::AAC_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::AAC_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::AAC_5_1); /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ totalSamples += data.Size() / format.channels / (format.bits / 8); return EncodeFrames(False); } Int BoCA::EncoderFAAC::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int samplesPerFrame = frameSize * format.channels; if (flush) framesToProcess = Math::Floor(samplesBuffer.Size() / samplesPerFrame); while (samplesBuffer.Size() - framesProcessed * samplesPerFrame >= samplesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length()); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * samplesPerFrame, flush ? samplesBuffer.Size() : samplesPerFrame * framesToProcess, flush); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } memmove(samplesBuffer, samplesBuffer + framesProcessed * samplesPerFrame, sizeof(int16_t) * (samplesBuffer.Size() - framesProcessed * samplesPerFrame)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * samplesPerFrame); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length()); nextWorker++; } return dataLength; } Int BoCA::EncoderFAAC::ProcessPackets(const Buffer &packets, const Array &packetSizes, Bool first) { Int offset = 0; Int dataLength = 0; if (!first) for (Int i = 0; i < overlap; i++) offset += packetSizes.GetNth(i); for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap && !first) continue; if (packetSizes.GetNth(i) == 0) continue; if (mp4File != NIL) ex_MP4WriteSample(mp4File, mp4Track, (uint8_t *) (unsigned char *) packets + offset, packetSizes.GetNth(i), frameSize, 0, true); else driver->WriteData(packets + offset, packetSizes.GetNth(i)); offset += packetSizes.GetNth(i); dataLength += packetSizes.GetNth(i); } return dataLength; } Bool BoCA::EncoderFAAC::SetOutputFormat(Int n) { Config *config = Config::Get(); if (n == 0 && mp4v2dll != NIL) { config->SetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureFAAC::ConfigID, "MPEGVersion", 0); } else { config->SetIntValue(ConfigureFAAC::ConfigID, "MP4Container", False); } return True; } String BoCA::EncoderFAAC::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True)) { switch (config->GetIntValue(ConfigureFAAC::ConfigID, "MP4FileExtension", 0)) { default: case 0: return "m4a"; case 1: return "m4b"; case 2: return "m4r"; case 3: return "mp4"; } } return "aac"; } Bool BoCA::EncoderFAAC::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "faac-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureFAAC::ConfigID, "MPEGVersion", 0); config->SetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureFAAC::ConfigID, "SetQuality", True); config->SetIntValue(ConfigureFAAC::ConfigID, "AACQuality", 150); config->SetIntValue(ConfigureFAAC::ConfigID, "Bitrate", 96); } /* Get command line settings. */ Bool rawAAC = config->GetIntValue(encoderID, "Create ADTS AAC files (no MP4 container)", !config->GetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True)); Bool useABR = config->GetIntValue(encoderID, "Set ABR bitrate per channel", !config->GetIntValue(ConfigureFAAC::ConfigID, "SetQuality", True)); Int quality = config->GetIntValue(ConfigureFAAC::ConfigID, "AACQuality", 150); Int bitrate = config->GetIntValue(ConfigureFAAC::ConfigID, "Bitrate", 96); if (config->GetIntValue(encoderID, "Set VBR quality", False)) quality = config->GetIntValue(encoderID, "VBR quality", quality); if (config->GetIntValue(encoderID, "Set ABR bitrate per channel", False)) bitrate = config->GetIntValue(encoderID, "ABR bitrate per channel", bitrate); /* Set configuration values. */ config->SetIntValue(ConfigureFAAC::ConfigID, "MP4Container", !rawAAC); config->SetIntValue(ConfigureFAAC::ConfigID, "SetQuality", !useABR); config->SetIntValue(ConfigureFAAC::ConfigID, "AACQuality", Math::Max(10, Math::Min(500, quality))); config->SetIntValue(ConfigureFAAC::ConfigID, "Bitrate", Math::Max(8, Math::Min(256, bitrate))); return True; } ConfigLayer *BoCA::EncoderFAAC::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureFAAC(); return configLayer; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_write(void *handle, const void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->WriteData((const UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/faac.h000066400000000000000000000031151516712004000237250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderFAAC) namespace BoCA { class EncoderFAAC : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; Array workers; MP4FileHandle mp4File; MP4TrackId mp4Track; Int nextWorker; Int frameSize; Int blockSize; Int overlap; Int64 totalSamples; Buffer samplesBuffer; Int EncodeFrames(Bool); Int ProcessPackets(const Buffer &, const Array &, Bool); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderFAAC(); ~EncoderFAAC(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderFAAC) BoCA_END_COMPONENT(EncoderFAAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/worker.cpp000066400000000000000000000077611516712004000247120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "config.h" BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat) : processSignal(1), readySignal(1) { processSignal.Wait(); flush = False; quit = False; format = iFormat; threadMain.Connect(&SuperWorker::Run, this); /* Get configuration. */ Bool mp4Container = config->GetIntValue(ConfigureFAAC::ConfigID, "MP4Container", True); Int mpegVersion = config->GetIntValue(ConfigureFAAC::ConfigID, "MPEGVersion", 0); Bool setQuality = config->GetIntValue(ConfigureFAAC::ConfigID, "SetQuality", True); Int aacQuality = config->GetIntValue(ConfigureFAAC::ConfigID, "AACQuality", 150); Int bitrate = config->GetIntValue(ConfigureFAAC::ConfigID, "Bitrate", 96); Bool allowJS = config->GetIntValue(ConfigureFAAC::ConfigID, "AllowJS", True); Bool useTNS = config->GetIntValue(ConfigureFAAC::ConfigID, "UseTNS", False); Int bandwidth = config->GetIntValue(ConfigureFAAC::ConfigID, "BandWidth", 18500); /* Create FAAC encoder. */ unsigned long samplesSize = 0; unsigned long bufferSize = 0; handle = ex_faacEncOpen(format.rate, format.channels, &samplesSize, &bufferSize); /* Set encoder parameters. */ faacEncConfigurationPtr fConfig = ex_faacEncGetCurrentConfiguration(handle); fConfig->inputFormat = FAAC_INPUT_16BIT; fConfig->outputFormat = mp4Container ? RAW_STREAM : ADTS_STREAM; fConfig->mpegVersion = mp4Container ? MPEG4 : mpegVersion; fConfig->aacObjectType = LOW; fConfig->quantqual = setQuality ? aacQuality : 0; fConfig->bitRate = setQuality ? 0 : bitrate * 1000; fConfig->bandWidth = bandwidth; fConfig->jointmode = allowJS ? JOINT_IS : JOINT_NONE; fConfig->useTns = useTNS; ex_faacEncSetConfiguration(handle, fConfig); frameSize = samplesSize / format.channels; maxPacketSize = bufferSize; } BoCA::SuperWorker::~SuperWorker() { /* Destroy FAAC encoder. */ ex_faacEncClose(handle); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); Int samplesLeft = samplesBuffer.Size(); Int samplesPerFrame = frameSize * format.channels; Int framesProcessed = 0; while (flush || samplesLeft >= samplesPerFrame) { packetBuffer.Resize(packetBuffer.Size() + maxPacketSize); Int dataLength = 0; if (samplesLeft > 0) dataLength = ex_faacEncEncode(handle, (int32_t *) (int16_t *) (samplesBuffer + framesProcessed * samplesPerFrame), Math::Min(samplesLeft, samplesPerFrame), packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); else dataLength = ex_faacEncEncode(handle, NULL, 0, packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); packetBuffer.Resize(packetBuffer.Size() - maxPacketSize + dataLength); if (samplesLeft < 0 && dataLength == 0) break; packetSizes.Add(dataLength); framesProcessed++; samplesLeft -= samplesPerFrame; } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int size, Bool last) { samplesBuffer.Resize(size); memcpy(samplesBuffer, buffer + offset, size * sizeof(int16_t)); flush = last; processSignal.Release(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/faac/worker.h000066400000000000000000000025661516712004000243550ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; faacEncHandle handle; Format format; Int frameSize; Int maxPacketSize; Buffer samplesBuffer; Buffer packetBuffer; Array packetSizes; Bool flush; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &); ~SuperWorker(); Void Encode(const Buffer &, Int, Int, Bool); Void WaitUntilReady(); Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/000077500000000000000000000000001516712004000232015ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/Makefile000066400000000000000000000012401516712004000246360ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = fdkaac TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o fdkaac.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/config.cpp000066400000000000000000000371051516712004000251600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureFDKAAC::ConfigID = "FDKAAC"; BoCA::ConfigureFDKAAC::ConfigureFDKAAC() { const Config *config = Config::Get(); Int aacType = config->GetIntValue(ConfigID, "AACType", AOT_AAC_LC); mpegVersion = config->GetIntValue(ConfigID, "MPEGVersion", 0); mode = config->GetIntValue(ConfigID, "Mode", 0); bitrate = config->GetIntValue(ConfigID, "Bitrate", 64); quality = config->GetIntValue(ConfigID, "Quality", 4); afterburner = config->GetIntValue(ConfigID, "Afterburner", True); bandwidth = config->GetIntValue(ConfigID, "Bandwidth", 0); allowID3 = config->GetIntValue(ConfigID, "AllowID3v2", False); fileFormat = config->GetIntValue(ConfigID, "MP4Container", True); fileExtension = config->GetIntValue(ConfigID, "MP4FileExtension", 0); if (bandwidth) bandwidth = (bandwidth - 7900) / 100; previousBandwidth = 0; I18n *i18n = I18n::Get(); tabwidget = new TabWidget(Point(7, 7), Size(500, 258)); i18n->SetContext("Encoders::AAC::Format"); layer_format = new Layer(i18n->TranslateString("Format")); group_mp4 = new GroupBox(i18n->TranslateString("File format"), Point(7, 11), Size(120, 65)); option_mp4 = new OptionBox("MP4", Point(10, 13), Size(99, 0), &fileFormat, 1); option_mp4->onAction.Connect(&ConfigureFDKAAC::SetFileFormat, this); if (mp4v2dll == NIL) { option_mp4->Deactivate(); fileFormat = 0; } option_aac = new OptionBox("AAC", Point(10, 38), Size(99, 0), &fileFormat, 0); option_aac->onAction.Connect(&ConfigureFDKAAC::SetFileFormat, this); group_mp4->Add(option_mp4); group_mp4->Add(option_aac); group_version = new GroupBox(i18n->TranslateString("MPEG version"), Point(135, 11), Size(120, 65)); option_version_mpeg2 = new OptionBox("MPEG 2", Point(10, 13), Size(group_version->GetWidth() - 21, 0), &mpegVersion, 127); option_version_mpeg2->onAction.Connect(&ConfigureFDKAAC::SetMPEGVersion, this); option_version_mpeg4 = new OptionBox("MPEG 4", Point(10, 38), Size(group_version->GetWidth() - 21, 0), &mpegVersion, 0); option_version_mpeg4->onAction.Connect(&ConfigureFDKAAC::SetMPEGVersion, this); group_version->Add(option_version_mpeg2); group_version->Add(option_version_mpeg4); group_id3v2 = new GroupBox(i18n->TranslateString("Tags"), Point(7, 88), Size(279, 90)); check_id3v2 = new CheckBox(i18n->TranslateString("Allow ID3v2 tags in AAC files"), Point(10, 13), Size(200, 0), &allowID3); check_id3v2->SetWidth(check_id3v2->GetUnscaledTextWidth() + 20); text_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(10, 38)); text_id3v2 = new Text(i18n->TranslateString("Some players may have problems playing AAC\nfiles with ID3 tags attached. Please use this option only\nif you are sure that your player can handle these tags."), Point(text_note->GetUnscaledTextWidth() + 12, 38)); group_id3v2->SetSize(Size(Math::Max(384, text_note->GetUnscaledTextWidth() + text_id3v2->GetUnscaledTextWidth() + 22), Math::Max(text_note->GetUnscaledTextHeight(), text_id3v2->GetUnscaledTextHeight()) + 48)); group_id3v2->Add(check_id3v2); group_id3v2->Add(text_note); group_id3v2->Add(text_id3v2); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(263, 11), Size(group_id3v2->GetWidth() - 256, 65)); option_extension_m4a = new OptionBox(".m4a", Point(10, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 0); option_extension_m4b = new OptionBox(".m4b", Point(10, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 1); option_extension_m4r = new OptionBox(".m4r", Point(group_extension->GetWidth() / 2 + 4, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 2); option_extension_mp4 = new OptionBox(".mp4", Point(group_extension->GetWidth() / 2 + 4, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 3); group_extension->Add(option_extension_m4a); group_extension->Add(option_extension_m4b); group_extension->Add(option_extension_m4r); group_extension->Add(option_extension_mp4); i18n->SetContext("Encoders::AAC::Codec"); layer_quality = new Layer(i18n->TranslateString("Codec")); group_codec = new GroupBox(i18n->TranslateString("Audio codec"), Point(7, 11), Size(group_id3v2->GetWidth(), 43)); text_codec = new Text(i18n->AddColon(i18n->TranslateString("Audio codec")), Point(10, 15)); combo_codec = new ComboBox(Point(text_codec->GetUnscaledTextSize().cx + 17, 12), Size(group_codec->GetWidth() - text_codec->GetUnscaledTextSize().cx - 27, 0)); FillCodecs(); foreach (Int codec, codecs) if (aacType == codec) combo_codec->SelectNthEntry(foreachindex); combo_codec->onSelectEntry.Connect(&ConfigureFDKAAC::SetCodec, this); group_codec->Add(text_codec); group_codec->Add(combo_codec); i18n->SetContext("Encoders::AAC::Quality"); group_bitrate = new GroupBox(i18n->TranslateString("Bitrate / Quality"), Point(7, 66), Size(group_id3v2->GetWidth(), 103)); option_bitrate = new OptionBox(i18n->AddColon(i18n->TranslateString("Bitrate per channel")), Point(10, 13), Size(150, 0), &mode, 0); option_bitrate->onAction.Connect(&ConfigureFDKAAC::SetMode, this); option_bitrate->SetWidth(option_bitrate->GetUnscaledTextWidth() + 19); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 15)); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); edit_bitrate = new EditBox(Point(text_bitrate_kbps->GetX() + 32, 12), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetOrientation(OR_UPPERRIGHT); edit_bitrate->onInput.Connect(&ConfigureFDKAAC::SetBitrateByEditBox, this); slider_bitrate = new Slider(Point(option_bitrate->GetWidth() + 18, 13), Size(group_bitrate->GetWidth() - edit_bitrate->GetX() - 26 - option_bitrate->GetWidth(), 0), OR_HORZ, &bitrate, 8, 256); slider_bitrate->onValueChange.Connect(&ConfigureFDKAAC::SetBitrate, this); option_quality = new OptionBox(i18n->AddColon(i18n->TranslateString("Set quality")), Point(10, 38), Size(150, 0), &mode, 1); option_quality->onAction.Connect(&ConfigureFDKAAC::SetMode, this); option_quality->SetWidth(option_bitrate->GetWidth()); slider_quality = new Slider(Point(option_quality->GetWidth() + 18, 38), Size(slider_bitrate->GetWidth(), 0), OR_HORZ, &quality, 1, 5); slider_quality->onValueChange.Connect(&ConfigureFDKAAC::SetQuality, this); text_quality_level = new Text(NIL, Point(edit_bitrate->GetX(), 40)); text_quality_level->SetOrientation(OR_UPPERRIGHT); text_quality_worse = new Text(i18n->TranslateString("worse"), Point(slider_quality->GetX(), 57)); text_quality_worse->SetX(text_quality_worse->GetX() - text_quality_worse->GetUnscaledTextWidth() / 2); text_quality_better = new Text(i18n->TranslateString("better"), Point(slider_quality->GetX() + slider_quality->GetWidth(), 57)); text_quality_better->SetX(text_quality_better->GetX() - text_quality_better->GetUnscaledTextWidth() / 2); check_afterburner = new CheckBox(i18n->TranslateString("Enable Afterburner processing"), Point(10, 76), Size(group_bitrate->GetWidth() - 20, 0), &afterburner); group_bitrate->Add(option_bitrate); group_bitrate->Add(slider_bitrate); group_bitrate->Add(edit_bitrate); group_bitrate->Add(text_bitrate_kbps); group_bitrate->Add(option_quality); group_bitrate->Add(slider_quality); group_bitrate->Add(text_quality_level); group_bitrate->Add(text_quality_worse); group_bitrate->Add(text_quality_better); group_bitrate->Add(check_afterburner); group_bandwidth = new GroupBox(i18n->TranslateString("Maximum bandwidth"), Point(7, group_bitrate->GetHeight() + 78), Size(group_id3v2->GetWidth(), 40)); text_bandwidth = new Text(i18n->AddColon(i18n->TranslateString("Maximum AAC frequency bandwidth to use (Hz)")), Point(9, 15)); text_bandwidth_hz = new Text(i18n->TranslateString("%1 Hz", "Technical").Replace("%1", "20000"), Point(35, 15)); text_bandwidth_hz->SetX(Math::Max(text_bandwidth_hz->GetUnscaledTextWidth(), text_bandwidth_hz->GetFont().GetUnscaledTextSizeX(i18n->TranslateString("auto"))) + 10); text_bandwidth_hz->SetOrientation(OR_UPPERRIGHT); slider_bandwidth = new Slider(Point(text_bandwidth->GetUnscaledTextWidth() + 16, 13), Size(group_bandwidth->GetWidth() - text_bandwidth->GetUnscaledTextWidth() - text_bandwidth_hz->GetX() - 24, 0), OR_HORZ, &bandwidth, 0, 121); slider_bandwidth->onValueChange.Connect(&ConfigureFDKAAC::SetBandwidth, this); group_bandwidth->Add(text_bandwidth); group_bandwidth->Add(slider_bandwidth); group_bandwidth->Add(text_bandwidth_hz); SetCodec(); SetFileFormat(); SetMPEGVersion(); SetMode(); SetBitrate(); SetQuality(); SetBandwidth(); tabwidget->SetSize(Size(group_id3v2->GetWidth() + 18, Math::Max(251, group_id3v2->GetHeight() + 118))); Add(tabwidget); tabwidget->Add(layer_quality); tabwidget->Add(layer_format); layer_format->Add(group_version); layer_format->Add(group_mp4); layer_format->Add(group_extension); layer_format->Add(group_id3v2); layer_quality->Add(group_codec); layer_quality->Add(group_bitrate); layer_quality->Add(group_bandwidth); SetSize(tabwidget->GetSize() + Size(14, 14)); } BoCA::ConfigureFDKAAC::~ConfigureFDKAAC() { DeleteObject(tabwidget); DeleteObject(layer_format); DeleteObject(layer_quality); DeleteObject(group_version); DeleteObject(option_version_mpeg2); DeleteObject(option_version_mpeg4); DeleteObject(group_mp4); DeleteObject(option_mp4); DeleteObject(option_aac); DeleteObject(group_extension); DeleteObject(option_extension_m4a); DeleteObject(option_extension_m4b); DeleteObject(option_extension_m4r); DeleteObject(option_extension_mp4); DeleteObject(group_id3v2); DeleteObject(check_id3v2); DeleteObject(text_note); DeleteObject(text_id3v2); DeleteObject(group_codec); DeleteObject(text_codec); DeleteObject(combo_codec); DeleteObject(group_bitrate); DeleteObject(option_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); DeleteObject(option_quality); DeleteObject(slider_quality); DeleteObject(text_quality_level); DeleteObject(text_quality_worse); DeleteObject(text_quality_better); DeleteObject(check_afterburner); DeleteObject(group_bandwidth); DeleteObject(text_bandwidth); DeleteObject(slider_bandwidth); DeleteObject(text_bandwidth_hz); } Int BoCA::ConfigureFDKAAC::SaveSettings() { Config *config = Config::Get(); if (bitrate < 8) bitrate = 8; if (bitrate > 256) bitrate = 256; Int aacType = codecs.GetNth(combo_codec->GetSelectedEntryNumber()); if (aacType != AOT_AAC_LC && aacType != AOT_ER_AAC_LD) bandwidth = previousBandwidth; if (bandwidth) bandwidth = 7900 + 100 * bandwidth; config->SetIntValue(ConfigID, "MPEGVersion", mpegVersion); config->SetIntValue(ConfigID, "AACType", aacType); config->SetIntValue(ConfigID, "Mode", mode); config->SetIntValue(ConfigID, "Bitrate", bitrate); config->SetIntValue(ConfigID, "Quality", quality); config->SetIntValue(ConfigID, "Afterburner", afterburner); config->SetIntValue(ConfigID, "Bandwidth", bandwidth); config->SetIntValue(ConfigID, "AllowID3v2", allowID3); config->SetIntValue(ConfigID, "MP4Container", fileFormat); config->SetIntValue(ConfigID, "MP4FileExtension", fileExtension); return Success(); } Void BoCA::ConfigureFDKAAC::FillCodecs() { LIB_INFO info[FDK_MODULE_LAST]; FDKinitLibInfo(info); ex_aacEncGetLibInfo(info); UINT sbrFlags = FDKlibInfo_getCapabilities(info, FDK_SBRENC); codecs.RemoveAll(); combo_codec->RemoveAllEntries(); { combo_codec->AddEntry("MPEG AAC Low Complexity"); codecs.Add(AOT_AAC_LC); } if (sbrFlags ) { combo_codec->AddEntry("MPEG AAC High Efficiency"); codecs.Add(AOT_SBR); } if (sbrFlags & CAPF_SBR_PS_MPEG ) { combo_codec->AddEntry("MPEG AAC High Efficiency v2"); codecs.Add(AOT_PS); } if (mpegVersion == 0 ) { combo_codec->AddEntry("MPEG AAC Low Delay"); codecs.Add(AOT_ER_AAC_LD); } if (mpegVersion == 0 && sbrFlags) { combo_codec->AddEntry("MPEG AAC Enhanced Low Delay"); codecs.Add(AOT_ER_AAC_ELD); } } Void BoCA::ConfigureFDKAAC::SetMPEGVersion() { Int aacType = codecs.GetNth(combo_codec->GetSelectedEntryNumber()); FillCodecs(); if (mpegVersion == 127 && (aacType == AOT_ER_AAC_LD || aacType == AOT_ER_AAC_ELD)) aacType = AOT_AAC_LC; foreach (Int codec, codecs) if (aacType == codec) combo_codec->SelectNthEntry(foreachindex); } Void BoCA::ConfigureFDKAAC::SetCodec() { Int aacType = codecs.GetNth(combo_codec->GetSelectedEntryNumber()); if (aacType == AOT_ER_AAC_LD || aacType == AOT_ER_AAC_ELD) option_version_mpeg2->Deactivate(); else option_version_mpeg2->Activate(); /* Toggle bandwidth controls. */ if (aacType == AOT_AAC_LC || aacType == AOT_ER_AAC_LD) { if (!group_bandwidth->IsActive()) bandwidth = previousBandwidth; group_bandwidth->Activate(); } else { if (group_bandwidth->IsActive()) previousBandwidth = bandwidth; group_bandwidth->Deactivate(); bandwidth = 0; } SetQuality(); SetBandwidth(); /* Set bitrate range for AAC type. */ switch (aacType) { case AOT_AAC_LC: slider_bitrate->SetRange(8, 256); slider_quality->SetRange(3, 5); break; case AOT_SBR: slider_bitrate->SetRange(8, 64); slider_quality->SetRange(2, 5); break; case AOT_PS: slider_bitrate->SetRange(8, 32); slider_quality->SetRange(1, 5); break; case AOT_ER_AAC_LD: slider_bitrate->SetRange(8, 256); slider_quality->SetRange(3, 5); break; case AOT_ER_AAC_ELD: slider_bitrate->SetRange(8, 256); slider_quality->SetRange(1, 5); break; } SetBitrate(); } Void BoCA::ConfigureFDKAAC::SetMode() { if (mode == 0) // bitrate { slider_quality->Deactivate(); text_quality_level->Deactivate(); text_quality_worse->Deactivate(); text_quality_better->Deactivate(); slider_bitrate->Activate(); edit_bitrate->Activate(); text_bitrate_kbps->Activate(); } else // quality { slider_bitrate->Deactivate(); edit_bitrate->Deactivate(); text_bitrate_kbps->Deactivate(); slider_quality->Activate(); text_quality_level->Activate(); text_quality_worse->Activate(); text_quality_better->Activate(); } } Void BoCA::ConfigureFDKAAC::SetBitrate() { if (!edit_bitrate->IsFocussed()) edit_bitrate->SetText(String::FromInt(bitrate)); } Void BoCA::ConfigureFDKAAC::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt()); } Void BoCA::ConfigureFDKAAC::SetQuality() { text_quality_level->SetText(String::FromInt(quality)); } Void BoCA::ConfigureFDKAAC::SetBandwidth() { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::AAC::Quality"); if (bandwidth) text_bandwidth_hz->SetText(i18n->TranslateString("%1 Hz", "Technical").Replace("%1", String::FromInt(7900 + 100 * bandwidth))); else text_bandwidth_hz->SetText(i18n->TranslateString("auto")); } Void BoCA::ConfigureFDKAAC::SetFileFormat() { if (fileFormat == 1) // MP4 container { group_version->Deactivate(); group_id3v2->Deactivate(); group_extension->Activate(); if (mpegVersion == 127) // MPEG2 { mpegVersion = 0; SetMPEGVersion(); } } else // raw AAC file format { group_version->Activate(); group_id3v2->Activate(); group_extension->Deactivate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/config.h000066400000000000000000000047501516712004000246250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_FDKAACCONFIG #define H_FDKAACCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureFDKAAC : public ConfigLayer { private: TabWidget *tabwidget; Layer *layer_format; GroupBox *group_version; OptionBox *option_version_mpeg2; OptionBox *option_version_mpeg4; GroupBox *group_id3v2; CheckBox *check_id3v2; Text *text_note; Text *text_id3v2; GroupBox *group_mp4; OptionBox *option_mp4; OptionBox *option_aac; GroupBox *group_extension; OptionBox *option_extension_m4a; OptionBox *option_extension_m4b; OptionBox *option_extension_m4r; OptionBox *option_extension_mp4; Layer *layer_quality; GroupBox *group_codec; Text *text_codec; ComboBox *combo_codec; GroupBox *group_bitrate; OptionBox *option_bitrate; Slider *slider_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; OptionBox *option_quality; Slider *slider_quality; Text *text_quality_level; Text *text_quality_worse; Text *text_quality_better; CheckBox *check_afterburner; GroupBox *group_bandwidth; Text *text_bandwidth; Slider *slider_bandwidth; Text *text_bandwidth_hz; Array codecs; Int mpegVersion; Int mode; Int bitrate; Int quality; Bool afterburner; Int bandwidth; Int previousBandwidth; Bool allowID3; Int fileFormat; Int fileExtension; Void FillCodecs(); slots: Void SetMPEGVersion(); Void SetMode(); Void SetCodec(); Void SetBitrate(); Void SetBitrateByEditBox(); Void SetQuality(); Void SetBandwidth(); Void SetFileFormat(); public: static const String ConfigID; ConfigureFDKAAC(); ~ConfigureFDKAAC(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/dllinterface.cpp000066400000000000000000000104421516712004000263420ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; AACENCOPEN ex_aacEncOpen = NIL; AACENCCLOSE ex_aacEncClose = NIL; AACENCENCODE ex_aacEncEncode = NIL; AACENCINFO ex_aacEncInfo = NIL; AACENCGETLIBINFO ex_aacEncGetLibInfo = NIL; AACENCODER_GETPARAM ex_aacEncoder_GetParam = NIL; AACENCODER_SETPARAM ex_aacEncoder_SetParam = NIL; MP4CREATECALLBACKS ex_MP4CreateCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration = NIL; MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty = NIL; MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel = NIL; MP4ADDAUDIOTRACK ex_MP4AddAudioTrack = NIL; MP4WRITESAMPLE ex_MP4WriteSample = NIL; MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc = NIL; MP4ITMFITEMFREE ex_MP4ItmfItemFree = NIL; MP4ITMFADDITEM ex_MP4ItmfAddItem = NIL; DynamicLoader *fdkaacdll = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadFDKAACDLL() { fdkaacdll = BoCA::Utilities::LoadCodecDLL("fdk-aac"); if (fdkaacdll == NIL) return False; ex_aacEncOpen = (AACENCOPEN) fdkaacdll->GetFunctionAddress("aacEncOpen"); ex_aacEncClose = (AACENCCLOSE) fdkaacdll->GetFunctionAddress("aacEncClose"); ex_aacEncEncode = (AACENCENCODE) fdkaacdll->GetFunctionAddress("aacEncEncode"); ex_aacEncInfo = (AACENCINFO) fdkaacdll->GetFunctionAddress("aacEncInfo"); ex_aacEncGetLibInfo = (AACENCGETLIBINFO) fdkaacdll->GetFunctionAddress("aacEncGetLibInfo"); ex_aacEncoder_GetParam = (AACENCODER_GETPARAM) fdkaacdll->GetFunctionAddress("aacEncoder_GetParam"); ex_aacEncoder_SetParam = (AACENCODER_SETPARAM) fdkaacdll->GetFunctionAddress("aacEncoder_SetParam"); if (ex_aacEncOpen == NIL || ex_aacEncClose == NIL || ex_aacEncEncode == NIL || ex_aacEncInfo == NIL || ex_aacEncGetLibInfo == NIL || ex_aacEncoder_GetParam == NIL || ex_aacEncoder_SetParam == NIL) { FreeFDKAACDLL(); return False; } return True; } Void FreeFDKAACDLL() { BoCA::Utilities::FreeCodecDLL(fdkaacdll); fdkaacdll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4CreateCallbacks = (MP4CREATECALLBACKS) mp4v2dll->GetFunctionAddress("MP4CreateCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4SetTrackESConfiguration = (MP4SETTRACKESCONFIGURATION) mp4v2dll->GetFunctionAddress("MP4SetTrackESConfiguration"); ex_MP4SetTrackIntegerProperty = (MP4SETTRACKINTEGERPROPERTY) mp4v2dll->GetFunctionAddress("MP4SetTrackIntegerProperty"); ex_MP4SetAudioProfileLevel = (MP4SETAUDIOPROFILELEVEL) mp4v2dll->GetFunctionAddress("MP4SetAudioProfileLevel"); ex_MP4AddAudioTrack = (MP4ADDAUDIOTRACK) mp4v2dll->GetFunctionAddress("MP4AddAudioTrack"); ex_MP4WriteSample = (MP4WRITESAMPLE) mp4v2dll->GetFunctionAddress("MP4WriteSample"); ex_MP4ItmfItemAlloc = (MP4ITMFITEMALLOC) mp4v2dll->GetFunctionAddress("MP4ItmfItemAlloc"); ex_MP4ItmfItemFree = (MP4ITMFITEMFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemFree"); ex_MP4ItmfAddItem = (MP4ITMFADDITEM) mp4v2dll->GetFunctionAddress("MP4ItmfAddItem"); if (ex_MP4CreateCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Optimize == NIL || ex_MP4SetTrackESConfiguration == NIL || ex_MP4SetTrackIntegerProperty == NIL || ex_MP4SetAudioProfileLevel == NIL || ex_MP4AddAudioTrack == NIL || ex_MP4WriteSample == NIL || ex_MP4ItmfItemAlloc == NIL || ex_MP4ItmfItemFree == NIL || ex_MP4ItmfAddItem == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/dllinterface.h000066400000000000000000000067071516712004000260200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *fdkaacdll; extern DynamicLoader *mp4v2dll; Bool LoadFDKAACDLL(); Void FreeFDKAACDLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef struct { UINT maxOutBufBytes; UINT maxAncBytes; UINT inBufFillLevel; UINT inputChannels; UINT frameLength; UINT encoderDelay; UCHAR confBuf[64]; UINT confSize; } AACENC_InfoStruct_Old; typedef AACENC_ERROR (*AACENCOPEN) (HANDLE_AACENCODER *, const UINT, const UINT); typedef AACENC_ERROR (*AACENCCLOSE) (HANDLE_AACENCODER *); typedef AACENC_ERROR (*AACENCENCODE) (const HANDLE_AACENCODER, const AACENC_BufDesc *, const AACENC_BufDesc *, const AACENC_InArgs *, AACENC_OutArgs *); typedef AACENC_ERROR (*AACENCINFO) (const HANDLE_AACENCODER, AACENC_InfoStruct *); typedef AACENC_ERROR (*AACENCGETLIBINFO) (LIB_INFO *); typedef UINT (*AACENCODER_GETPARAM) (const HANDLE_AACENCODER, const AACENC_PARAM); typedef AACENC_ERROR (*AACENCODER_SETPARAM) (const HANDLE_AACENCODER, const AACENC_PARAM, const UINT); extern AACENCOPEN ex_aacEncOpen; extern AACENCCLOSE ex_aacEncClose; extern AACENCENCODE ex_aacEncEncode; extern AACENCINFO ex_aacEncInfo; extern AACENCGETLIBINFO ex_aacEncGetLibInfo; extern AACENCODER_GETPARAM ex_aacEncoder_GetParam; extern AACENCODER_SETPARAM ex_aacEncoder_SetParam; typedef MP4FileHandle (*MP4CREATECALLBACKS) (const MP4IOCallbacks *, void *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef bool (*MP4SETTRACKESCONFIGURATION) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t); typedef bool (*MP4SETTRACKINTEGERPROPERTY) (MP4FileHandle, MP4TrackId, const char *, int64_t); typedef void (*MP4SETAUDIOPROFILELEVEL) (MP4FileHandle, uint8_t); typedef MP4TrackId (*MP4ADDAUDIOTRACK) (MP4FileHandle, uint32_t, MP4Duration, uint8_t); typedef bool (*MP4WRITESAMPLE) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t, MP4Duration, MP4Duration, bool); typedef MP4ItmfItem * (*MP4ITMFITEMALLOC) (const char *, uint32_t); typedef void (*MP4ITMFITEMFREE) (MP4ItmfItem *); typedef bool (*MP4ITMFADDITEM) (MP4FileHandle, const MP4ItmfItem *); extern MP4CREATECALLBACKS ex_MP4CreateCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration; extern MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty; extern MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel; extern MP4ADDAUDIOTRACK ex_MP4AddAudioTrack; extern MP4WRITESAMPLE ex_MP4WriteSample; extern MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc; extern MP4ITMFITEMFREE ex_MP4ItmfItemFree; extern MP4ITMFADDITEM ex_MP4ItmfAddItem; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/fdkaac.cpp000066400000000000000000000512011516712004000251150ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "fdkaac.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderFDKAAC::GetComponentSpecs() { static String componentSpecs; if (fdkaacdll != NIL) { LIB_INFO info[FDK_MODULE_LAST]; FDKinitLibInfo(info); ex_aacEncGetLibInfo(info); UINT sbrFlags = FDKlibInfo_getCapabilities(info, FDK_SBRENC); componentSpecs = " \ \ \ \ FDK-AAC Encoder %VERSION% \ 1.0 \ fdkaac-enc \ encoder \ faac-enc \ voaacenc-enc \ \ "; if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ MP4 Metadata \ \ \ "); } componentSpecs.Append(" \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ \ \ \ \ "); if (sbrFlags) componentSpecs.Append(""); if (sbrFlags & CAPF_SBR_PS_MPEG) componentSpecs.Append(""); componentSpecs.Append(" \ \ \ \ "); if (sbrFlags) componentSpecs.Append(""); componentSpecs.Append(" \ \ \ \ 8 \ 256 \ \ \ \ "); if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ \ "); } componentSpecs.Append(" \ \ \ \ \ "); UnsignedInt32 version = GetEncoderVersion(); componentSpecs.Replace("%VERSION%", String("v").Append(String::FromInt((version >> 24) & 0xff)).Append(".") .Append(String::FromInt((version >> 16) & 0xff)).Append(".") .Append(String::FromInt((version >> 8) & 0xff))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFDKAACDLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeFDKAACDLL(); FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_write(void *, const void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, NIL, MP4IO_write, NIL }; }; BoCA::EncoderFDKAAC::EncoderFDKAAC() { configLayer = NIL; config = NIL; mp4File = NIL; mp4Track = MP4_INVALID_TRACK_ID; frameSize = 0; granuleSize = 0; blockSize = 128; overlap = 12; totalFrames = 0; totalSamples = 0; delaySamples = 0; nextWorker = 0; } BoCA::EncoderFDKAAC::~EncoderFDKAAC() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } UnsignedInt32 BoCA::EncoderFDKAAC::GetEncoderVersion() { LIB_INFO info[FDK_MODULE_LAST]; FDKinitLibInfo(info); ex_aacEncGetLibInfo(info); for (Int i = 0; i < FDK_MODULE_LAST; i++) { if (info[i].module_id != FDK_AACENC) continue; return info[i].version; } return 0; } Bool BoCA::EncoderFDKAAC::Activate() { const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); if (mp4v2dll == NIL) config->SetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", False); Bool mp4Container = config->GetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True); Int mpegVersion = config->GetIntValue(ConfigureFDKAAC::ConfigID, "MPEGVersion", 0); Int aacType = config->GetIntValue(ConfigureFDKAAC::ConfigID, "AACType", AOT_AAC_LC); Int mode = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Mode", 0); Int bitrate = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Bitrate", 64); Int quality = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Quality", 4); /* Fall back to HE if HEv2 is selected for non-stereo input. */ if (aacType == AOT_PS && format.channels != 2) aacType = AOT_SBR; /* Create and configure FDK AAC encoder. */ HANDLE_AACENCODER handle = NIL; ex_aacEncOpen(&handle, 0x07, format.channels); Int channelMode = MODE_UNKNOWN; switch (format.channels) { case 1: channelMode = MODE_1; break; case 2: channelMode = MODE_2; break; case 3: channelMode = MODE_1_2; break; case 4: channelMode = MODE_1_2_1; break; case 5: channelMode = MODE_1_2_2; break; case 6: channelMode = MODE_1_2_2_1; break; case 8: channelMode = MODE_1_2_2_2_1; break; } ex_aacEncoder_SetParam(handle, AACENC_SAMPLERATE, format.rate); ex_aacEncoder_SetParam(handle, AACENC_CHANNELMODE, channelMode); if (mode == 0) ex_aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate * 1000 * format.channels); else ex_aacEncoder_SetParam(handle, AACENC_BITRATEMODE, quality); ex_aacEncoder_SetParam(handle, AACENC_AOT, mpegVersion + aacType); ex_aacEncoder_SetParam(handle, AACENC_TRANSMUX, mp4Container ? TT_MP4_RAW : TT_MP4_ADTS); if ( mp4Container && (aacType == AOT_SBR || aacType == AOT_PS )) ex_aacEncoder_SetParam(handle, AACENC_SIGNALING_MODE, 1); if (!mp4Container && (aacType == AOT_ER_AAC_LD || aacType == AOT_ER_AAC_ELD)) ex_aacEncoder_SetParam(handle, AACENC_TRANSMUX, TT_MP4_LOAS); AACENC_InfoStruct aacInfo; AACENC_InfoStruct_Old &aacInfoOld = *(AACENC_InfoStruct_Old *) &aacInfo; if (ex_aacEncEncode(handle, NULL, NULL, NULL, NULL) != AACENC_OK) { ex_aacEncClose(&handle); return False; } ex_aacEncInfo(handle, &aacInfo); frameSize = aacInfo.frameLength; granuleSize = ex_aacEncoder_GetParam(handle, AACENC_GRANULE_LENGTH); #if AACENCODER_LIB_VL0 >= 4 if (GetEncoderVersion() >= LIB_VERSION(4, 0, 0)) { delaySamples = aacInfo.nDelayCore; } else #endif { delaySamples = aacInfoOld.encoderDelay; /* Adjust delay for LD/ELD object types. */ if (aacType == AOT_ER_AAC_LD) delaySamples = frameSize; if (aacType == AOT_ER_AAC_ELD) delaySamples = frameSize / 4; } /* Check whether to use MP4 container. */ if (mp4Container) { /* Create MP4 file. */ uint32_t flags = (track.length >= 0xFFFF0000 || track.approxLength >= 0xFFFF0000) ? MP4_CREATE_64BIT_DATA | MP4_CREATE_64BIT_TIME : 0; mp4File = ex_MP4CreateCallbacks(&mp4Callbacks, driver, flags); mp4Track = ex_MP4AddAudioTrack(mp4File, format.rate * granuleSize / frameSize, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); ex_MP4SetAudioProfileLevel(mp4File, 0x0F); ex_MP4SetTrackIntegerProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.mp4a.channels", format.channels); if (GetEncoderVersion() >= LIB_VERSION(4, 0, 0)) ex_MP4SetTrackESConfiguration(mp4File, mp4Track, aacInfo.confBuf, aacInfo.confSize); else ex_MP4SetTrackESConfiguration(mp4File, mp4Track, aacInfoOld.confBuf, aacInfoOld.confSize); totalFrames = 0; totalSamples = 0; } ex_aacEncClose(&handle); /* Write ID3v2 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureFDKAAC::ConfigID, "AllowID3v2", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = 12; /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, format)); foreach (SuperWorker *worker, workers) worker->Start(); return True; } Bool BoCA::EncoderFDKAAC::Deactivate() { /* Output remaining samples to encoder. */ EncodeFrames(True); /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Finish MP4 writing. */ if (mp4File != NIL) { /* Write iTunes metadata with gapless information. */ Float sbrRatio = Float(frameSize) / granuleSize; Int64 delayValue = Math::Floor(delaySamples / sbrRatio); Int64 totalValue = Math::Ceil(totalSamples / sbrRatio); MP4ItmfItem *item = ex_MP4ItmfItemAlloc("----", 1); String value = String().Append(" 00000000") .Append(" ").Append(Number(delayValue).ToHexString(8).ToUpper()) .Append(" ").Append(Number(totalFrames * granuleSize - totalValue - delayValue).ToHexString(8).ToUpper()) .Append(" ").Append(Number(totalValue).ToHexString(16).ToUpper()) .Append(" 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000"); item->mean = (char *) "com.apple.iTunes"; item->name = (char *) "iTunSMPB"; item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8; item->dataList.elements[0].value = (uint8_t *) value.ConvertTo("UTF-8"); item->dataList.elements[0].valueSize = value.Length(); ex_MP4ItmfAddItem(mp4File, item); item->mean = NIL; item->name = NIL; item->dataList.elements[0].typeCode = MP4_ITMF_BT_IMPLICIT; item->dataList.elements[0].value = NIL; item->dataList.elements[0].valueSize = 0; ex_MP4ItmfItemFree(item); ex_MP4Close(mp4File, 0); /* Close output file as tagger needs to modify it. */ driver->Close(); /* Write metadata to file. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableMP4Metadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } else { /* Optimize file even when no tags are written. */ String tempFile = String(track.outputFile).Append(".temp"); ex_MP4Optimize(track.outputFile.ConvertTo("UTF-8"), tempFile.ConvertTo("UTF-8")); File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } } /* Write ID3v1 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v1", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Update ID3v2 tag with correct chapter marks. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureFDKAAC::ConfigID, "AllowID3v2", False)) { if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Int BoCA::EncoderFDKAAC::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ totalSamples += data.Size() / format.channels / (format.bits / 8); return EncodeFrames(False); } Int BoCA::EncoderFDKAAC::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int samplesPerFrame = frameSize * format.channels; if (flush) framesToProcess = Math::Floor(samplesBuffer.Size() / samplesPerFrame); while (samplesBuffer.Size() - framesProcessed * samplesPerFrame >= samplesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length()); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * samplesPerFrame, flush ? samplesBuffer.Size() : samplesPerFrame * framesToProcess, flush); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } memmove(samplesBuffer, samplesBuffer + framesProcessed * samplesPerFrame, sizeof(int16_t) * (samplesBuffer.Size() - framesProcessed * samplesPerFrame)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * samplesPerFrame); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length()); nextWorker++; } return dataLength; } Int BoCA::EncoderFDKAAC::ProcessPackets(const Buffer &packets, const Array &packetSizes, Bool first) { Int offset = 0; Int dataLength = 0; if (!first) for (Int i = 0; i < overlap; i++) offset += packetSizes.GetNth(i); for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap && !first) continue; if (packetSizes.GetNth(i) == 0) continue; if (mp4File != NIL) ex_MP4WriteSample(mp4File, mp4Track, (uint8_t *) (unsigned char *) packets + offset, packetSizes.GetNth(i), granuleSize, 0, true); else driver->WriteData(packets + offset, packetSizes.GetNth(i)); totalFrames++; offset += packetSizes.GetNth(i); dataLength += packetSizes.GetNth(i); } return dataLength; } Bool BoCA::EncoderFDKAAC::SetOutputFormat(Int n) { Config *config = Config::Get(); if (n == 0 && mp4v2dll != NIL) { config->SetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureFDKAAC::ConfigID, "MPEGVersion", 0); } else { config->SetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", False); } return True; } String BoCA::EncoderFDKAAC::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True)) { switch (config->GetIntValue(ConfigureFDKAAC::ConfigID, "MP4FileExtension", 0)) { default: case 0: return "m4a"; case 1: return "m4b"; case 2: return "m4r"; case 3: return "mp4"; } } return "aac"; } Bool BoCA::EncoderFDKAAC::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "fdkaac-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureFDKAAC::ConfigID, "MPEGVersion", 0); config->SetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureFDKAAC::ConfigID, "AACType", AOT_AAC_LC); config->SetIntValue(ConfigureFDKAAC::ConfigID, "Bitrate", 64); config->SetIntValue(ConfigureFDKAAC::ConfigID, "Afterburner", True); } /* Get command line settings. */ Bool rawAAC = config->GetIntValue(encoderID, "Create ADTS AAC files (no MP4 container)", !config->GetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True)); Bool afterburner = !config->GetIntValue(encoderID, "Disable Afterburner processing", False); Int bitrate = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Bitrate", 64); Int aacType = config->GetIntValue(ConfigureFDKAAC::ConfigID, "AACType", AOT_AAC_LC); String aacTypeString = "LC"; if (aacType == AOT_SBR) aacTypeString = "HE"; else if (aacType == AOT_PS) aacTypeString = "HEv2"; else if (aacType == AOT_ER_AAC_LD) aacTypeString = "LD"; else if (aacType == AOT_ER_AAC_ELD) aacTypeString = "ELD"; if (config->GetIntValue(encoderID, "Set Bitrate per channel", False)) bitrate = config->GetIntValue(encoderID, "Bitrate per channel", bitrate); if (config->GetIntValue(encoderID, "Set AAC encoding mode", False)) aacTypeString = config->GetStringValue(encoderID, "AAC encoding mode", aacTypeString).ToUpper(); /* Set configuration values. */ config->SetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", !rawAAC); if (aacTypeString == "LC" ) aacType = AOT_AAC_LC; else if (aacTypeString == "HE" ) aacType = AOT_SBR; else if (aacTypeString == "HEV2") aacType = AOT_PS; else if (aacTypeString == "LD" ) aacType = AOT_ER_AAC_LD; else if (aacTypeString == "ELD" ) aacType = AOT_ER_AAC_ELD; config->SetIntValue(ConfigureFDKAAC::ConfigID, "AACType", aacType); config->SetIntValue(ConfigureFDKAAC::ConfigID, "Bitrate", Math::Max(8, Math::Min(256, bitrate))); if (!afterburner) config->SetIntValue(ConfigureFDKAAC::ConfigID, "Afterburner", False); return True; } ConfigLayer *BoCA::EncoderFDKAAC::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureFDKAAC(); return configLayer; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_write(void *handle, const void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->WriteData((const UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/fdkaac.h000066400000000000000000000032661516712004000245720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" BoCA_BEGIN_COMPONENT(EncoderFDKAAC) namespace BoCA { class EncoderFDKAAC : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; Array workers; MP4FileHandle mp4File; MP4TrackId mp4Track; Int nextWorker; Int frameSize; Int granuleSize; Int blockSize; Int overlap; Int64 totalFrames; Int64 totalSamples; Int delaySamples; Buffer samplesBuffer; Int EncodeFrames(Bool); Int ProcessPackets(const Buffer &, const Array &, Bool); static UnsignedInt32 GetEncoderVersion(); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderFDKAAC(); ~EncoderFDKAAC(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderFDKAAC) BoCA_END_COMPONENT(EncoderFDKAAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/worker.cpp000066400000000000000000000137201516712004000252210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "config.h" BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat) : processSignal(1), readySignal(1) { processSignal.Wait(); flush = False; quit = False; format = iFormat; threadMain.Connect(&SuperWorker::Run, this); /* Get configuration. */ Bool mp4Container = config->GetIntValue(ConfigureFDKAAC::ConfigID, "MP4Container", True); Int mpegVersion = config->GetIntValue(ConfigureFDKAAC::ConfigID, "MPEGVersion", 0); Int aacType = config->GetIntValue(ConfigureFDKAAC::ConfigID, "AACType", AOT_AAC_LC); Int mode = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Mode", 0); Int bitrate = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Bitrate", 64); Int quality = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Quality", 4); Bool afterburner = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Afterburner", True); Int bandwidth = config->GetIntValue(ConfigureFDKAAC::ConfigID, "Bandwidth", 0); /* Fall back to HE if HEv2 is selected for non-stereo input. */ if (aacType == AOT_PS && format.channels != 2) aacType = AOT_SBR; /* Create and configure FDK AAC encoder. */ ex_aacEncOpen(&handle, 0x07, format.channels); Int channelMode = MODE_UNKNOWN; switch (format.channels) { case 1: channelMode = MODE_1; break; case 2: channelMode = MODE_2; break; case 3: channelMode = MODE_1_2; break; case 4: channelMode = MODE_1_2_1; break; case 5: channelMode = MODE_1_2_2; break; case 6: channelMode = MODE_1_2_2_1; break; case 8: channelMode = MODE_1_2_2_2_1; break; } ex_aacEncoder_SetParam(handle, AACENC_SAMPLERATE, format.rate); ex_aacEncoder_SetParam(handle, AACENC_CHANNELMODE, channelMode); ex_aacEncoder_SetParam(handle, AACENC_CHANNELORDER, 1 /* WAVE channel order */); if (mode == 0) ex_aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate * 1000 * format.channels); else ex_aacEncoder_SetParam(handle, AACENC_BITRATEMODE, quality); if (aacType == AOT_AAC_LC || aacType == AOT_ER_AAC_LD) ex_aacEncoder_SetParam(handle, AACENC_BANDWIDTH, Math::Min(bandwidth, format.rate / 2)); ex_aacEncoder_SetParam(handle, AACENC_AOT, mpegVersion + aacType); ex_aacEncoder_SetParam(handle, AACENC_AFTERBURNER, afterburner); ex_aacEncoder_SetParam(handle, AACENC_TRANSMUX, mp4Container ? TT_MP4_RAW : TT_MP4_ADTS); if ( mp4Container && (aacType == AOT_SBR || aacType == AOT_PS )) ex_aacEncoder_SetParam(handle, AACENC_SIGNALING_MODE, 1); if (!mp4Container && (aacType == AOT_ER_AAC_LD || aacType == AOT_ER_AAC_ELD)) ex_aacEncoder_SetParam(handle, AACENC_TRANSMUX, TT_MP4_LOAS); AACENC_InfoStruct aacInfo; ex_aacEncEncode(handle, NULL, NULL, NULL, NULL); ex_aacEncInfo(handle, &aacInfo); frameSize = aacInfo.frameLength; maxPacketSize = aacInfo.maxOutBufBytes; } BoCA::SuperWorker::~SuperWorker() { /* Destroy FDK encoder. */ ex_aacEncClose(&handle); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); Int samplesLeft = samplesBuffer.Size(); Int samplesPerFrame = frameSize * format.channels; Int framesProcessed = 0; while (flush || samplesLeft >= samplesPerFrame) { packetBuffer.Resize(packetBuffer.Size() + maxPacketSize); /* Prepare buffer information. */ Void *inputBuffer = (int16_t *) samplesBuffer + framesProcessed * samplesPerFrame; Int inputBufferID = IN_AUDIO_DATA; Int inputBufferSize = samplesPerFrame; Int inputElementSize = 2; Void *outputBuffer = (uint8_t *) packetBuffer + packetBuffer.Size() - maxPacketSize; Int outputBufferID = OUT_BITSTREAM_DATA; Int outputBufferSize = maxPacketSize; Int outputElementSize = 1; /* Configure buffer descriptors. */ AACENC_BufDesc input = { 0 }; AACENC_BufDesc output = { 0 }; input.numBufs = 1; input.bufs = &inputBuffer; input.bufferIdentifiers = &inputBufferID; input.bufSizes = &inputBufferSize; input.bufElSizes = &inputElementSize; output.numBufs = 1; output.bufs = &outputBuffer; output.bufferIdentifiers = &outputBufferID; output.bufSizes = &outputBufferSize; output.bufElSizes = &outputElementSize; /* Hand input data to encoder and retrieve output. */ AACENC_InArgs inputInfo = { 0 }; AACENC_OutArgs outputInfo = { 0 }; if (samplesLeft > 0) inputInfo.numInSamples = Math::Min(samplesLeft, samplesPerFrame); else inputInfo.numInSamples = -1; Int dataLength = 0; if (ex_aacEncEncode(handle, &input, &output, &inputInfo, &outputInfo) == AACENC_OK) dataLength = outputInfo.numOutBytes; packetBuffer.Resize(packetBuffer.Size() - maxPacketSize + dataLength); if (samplesLeft < 0 && dataLength == 0) break; if (dataLength > 0) packetSizes.Add(dataLength); framesProcessed++; samplesLeft -= samplesPerFrame; } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int size, Bool last) { samplesBuffer.Resize(size); memcpy(samplesBuffer, buffer + offset, size * sizeof(int16_t)); flush = last; processSignal.Release(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/fdkaac/worker.h000066400000000000000000000025721516712004000246710ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; HANDLE_AACENCODER handle; Format format; Int frameSize; Int maxPacketSize; Buffer samplesBuffer; Buffer packetBuffer; Array packetSizes; Bool flush; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &); ~SuperWorker(); Void Encode(const Buffer &, Int, Int, Bool); Void WaitUntilReady(); Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/000077500000000000000000000000001516712004000226755ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/Makefile000077500000000000000000000012231516712004000243360ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = flac TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o flac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/config.cpp000077500000000000000000000461771516712004000246700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureFLAC::ConfigID = "FLAC"; BoCA::ConfigureFLAC::ConfigureFLAC() { Point pos; Size size; const Config *config = Config::Get(); preset = config->GetIntValue(ConfigID, "Preset", 5); file_format = config->GetIntValue(ConfigID, "FileFormat", 0); streamable_subset = config->GetIntValue(ConfigID, "StreamableSubset", 1); do_mid_side_stereo = config->GetIntValue(ConfigID, "DoMidSideStereo", 1); loose_mid_side_stereo = config->GetIntValue(ConfigID, "LooseMidSideStereo", 0); blocksize = config->GetIntValue(ConfigID, "Blocksize", 4096) / 8; max_lpc_order = config->GetIntValue(ConfigID, "MaxLPCOrder", 8); qlp_coeff_precision = config->GetIntValue(ConfigID, "QLPCoeffPrecision", 0); do_qlp_coeff_prec_search = config->GetIntValue(ConfigID, "DoQLPCoeffPrecSearch", 0); do_exhaustive_model_search = config->GetIntValue(ConfigID, "DoExhaustiveModelSearch", 0); min_residual_partition_order = config->GetIntValue(ConfigID, "MinResidualPartitionOrder", 0); max_residual_partition_order = config->GetIntValue(ConfigID, "MaxResidualPartitionOrder", 5); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::FLAC"); layer_simple = new Layer(i18n->TranslateString("Basic")); layer_format = new Layer(i18n->TranslateString("Format")); layer_advanced = new Layer(i18n->TranslateString("Expert")); tabwidget = new TabWidget(Point(7, 7), Size(536, 245)); i18n->SetContext("Encoders::FLAC::Basic"); group_preset = new GroupBox(i18n->TranslateString("Presets"), Point(7, 11), Size(518, 39)); text_preset = new Text(i18n->AddColon(i18n->TranslateString("Use preset")), Point(9, 13)); combo_preset = new ComboBox(Point(17 + text_preset->GetUnscaledTextWidth(), 10), Size(491 - text_preset->GetUnscaledTextWidth(), 0)); combo_preset->AddEntry(i18n->TranslateString("Custom settings")); combo_preset->AddEntry(String("0").Append(", ").Append(i18n->TranslateString("Fastest encoding"))); combo_preset->AddEntry("1"); combo_preset->AddEntry("2"); combo_preset->AddEntry("3"); combo_preset->AddEntry("4"); combo_preset->AddEntry(String("5").Append(", ").Append(i18n->TranslateString("Default"))); combo_preset->AddEntry("6"); combo_preset->AddEntry("7"); combo_preset->AddEntry(String("8").Append(", ").Append(i18n->TranslateString("Best compression"))); combo_preset->SelectNthEntry(preset + 1); combo_preset->onSelectEntry.Connect(&ConfigureFLAC::SetPreset, this); group_preset->Add(text_preset); group_preset->Add(combo_preset); group_file_format = new GroupBox(i18n->TranslateString("File format"), Point(7, 62), Size(190, 65)); option_file_format_flac = new OptionBox("FLAC", Point(10, 13), Size(170, 0), &file_format, 0); option_file_format_ogg = new OptionBox("Ogg FLAC", Point(10, 38), Size(170, 0), &file_format, 1); if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 0) { file_format = 0; option_file_format_ogg->Deactivate(); } group_file_format->Add(option_file_format_flac); group_file_format->Add(option_file_format_ogg); group_stereo = new GroupBox(i18n->TranslateString("Stereo mode"), Point(205, 62), Size(320, 65)); check_mid_side_stereo = new CheckBox(i18n->TranslateString("Joint Stereo"), Point(10, 13), Size(300, 0), &do_mid_side_stereo); check_mid_side_stereo->onAction.Connect(&ConfigureFLAC::SetStereoMode, this); check_loose_mid_side = new CheckBox(i18n->TranslateString("Adaptive Joint Stereo"), Point(10, 38), Size(300, 0), &loose_mid_side_stereo); group_stereo->Add(check_mid_side_stereo); group_stereo->Add(check_loose_mid_side); layer_simple->Add(group_preset); layer_simple->Add(group_file_format); layer_simple->Add(group_stereo); i18n->SetContext("Encoders::FLAC::Format"); group_format = new GroupBox(i18n->TranslateString("Format"), Point(7, 11), Size(518, 66)); check_streamable_subset = new CheckBox(i18n->TranslateString("Use streamable subset"), Point(10, 13), Size(518, 0), &streamable_subset); check_streamable_subset->onAction.Connect(&ConfigureFLAC::SetStreamableSubset, this); check_streamable_subset->SetWidth(check_streamable_subset->GetUnscaledTextWidth() + 21); text_blocksize = new Text(i18n->AddColon(i18n->TranslateString("Blocksize")), Point(9, 40)); text_blocksize_samples = new Text(i18n->TranslateString("%1 samples").Replace("%1", NIL).Trim(), Point(508, 40)); text_blocksize_samples->SetX(9 + text_blocksize_samples->GetUnscaledTextWidth()); text_blocksize_samples->SetOrientation(OR_UPPERRIGHT); slider_blocksize = new Slider(Point(16 + text_blocksize->GetUnscaledTextWidth(), 38), Size(441 - text_blocksize->GetUnscaledTextWidth() - text_blocksize_samples->GetUnscaledTextWidth(), 0), OR_HORZ, &blocksize, 24, 4096); slider_blocksize->onValueChange.Connect(&ConfigureFLAC::SetBlockSize, this); edit_blocksize = new EditBox(Point(24 + text_blocksize->GetUnscaledTextWidth() + slider_blocksize->GetWidth(), 37), Size(37, 0), 5); edit_blocksize->onInput.Connect(&ConfigureFLAC::EditBlockSize, this); group_format->Add(check_streamable_subset); group_format->Add(text_blocksize); group_format->Add(slider_blocksize); group_format->Add(edit_blocksize); group_format->Add(text_blocksize_samples); layer_format->Add(group_format); i18n->SetContext("Encoders::FLAC::Expert"); group_apodization = new GroupBox(i18n->TranslateString("Signal processing"), Point(7, 11), Size(518, 56)); text_apodization = new Text(i18n->AddColon(i18n->TranslateString("Window function(s)")), Point(9, 13)); edit_apodization = new EditBox(config->GetStringValue(ConfigID, "Apodization", "tukey(0.5)"), Point(16 + text_apodization->GetUnscaledTextWidth(), 10), Size(492 - text_apodization->GetUnscaledTextWidth(), 0)); list_apodization = new ListBox(pos, size); list_apodization->AddEntry("bartlett"); list_apodization->AddEntry("bartlett_hann"); list_apodization->AddEntry("blackman"); list_apodization->AddEntry("blackman_harris_4term_92db"); list_apodization->AddEntry("connes"); list_apodization->AddEntry("flattop"); list_apodization->AddEntry("gauss(0.2)"); list_apodization->AddEntry("hamming"); list_apodization->AddEntry("hann"); list_apodization->AddEntry("kaiser_bessel"); list_apodization->AddEntry("nuttall"); list_apodization->AddEntry("rectangle"); list_apodization->AddEntry("triangle"); list_apodization->AddEntry("tukey(0.5)"); list_apodization->AddEntry("welch"); edit_apodization->SetDropDownList(list_apodization); text_apodization_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(16 + text_apodization->GetUnscaledTextWidth(), 35)); text_apodization_explain= new Text(i18n->TranslateString("You can specify multiple functions separated by semicolons."), Point(19 + text_apodization_note->GetUnscaledTextWidth() + text_apodization->GetUnscaledTextWidth(), 35)); group_apodization->SetHeight(text_apodization_explain->GetHeight() + 42); group_apodization->Add(text_apodization); group_apodization->Add(edit_apodization); group_apodization->Add(text_apodization_note); group_apodization->Add(text_apodization_explain); group_lpc = new GroupBox(i18n->TranslateString("Linear predictor"), Point(7, 23 + group_apodization->GetHeight()), Size(518, 62)); text_max_lpc_order = new Text(i18n->AddColon(i18n->TranslateString("Maximum LPC order")), Point(9, 13)); slider_max_lpc_order = new Slider(Point(16, 11), Size(250, 0), OR_HORZ, &max_lpc_order, 0, FLAC__MAX_LPC_ORDER); slider_max_lpc_order->onValueChange.Connect(&ConfigureFLAC::SetLPCOrder, this); text_max_lpc_order_value= new Text(i18n->TranslateString("disabled"), Point(273, 13)); check_exhaustive_model = new CheckBox(i18n->TranslateString("Exhaustive model search"), Point(358, 11), Size(150, 0), &do_exhaustive_model_search); text_qlp_precision = new Text(i18n->AddColon(i18n->TranslateString("Quantized LPC precision")), Point(9, 36)); slider_qlp_precision = new Slider(Point(16, 34), Size(250, 0), OR_HORZ, &qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION - 1, FLAC__MAX_QLP_COEFF_PRECISION); slider_qlp_precision->onValueChange.Connect(&ConfigureFLAC::SetQLPPrecision, this); text_qlp_precision_value= new Text(i18n->TranslateString("auto"), Point(273, 36)); check_qlp_precision_search= new CheckBox(i18n->TranslateString("Optimize LPC quantization"), Point(358, 34), Size(150, 0), &do_qlp_coeff_prec_search); check_qlp_precision_search->onAction.Connect(&ConfigureFLAC::SetQLPSearch, this); Int maxTextSize = Math::Max(check_exhaustive_model->GetUnscaledTextWidth(), check_qlp_precision_search->GetUnscaledTextWidth()); check_exhaustive_model->SetX(487 - maxTextSize); check_exhaustive_model->SetWidth(maxTextSize + 21); check_qlp_precision_search->SetX(487 - maxTextSize); check_qlp_precision_search->SetWidth(maxTextSize + 21); maxTextSize = Math::Max(text_max_lpc_order_value->GetUnscaledTextWidth(), text_qlp_precision_value->GetUnscaledTextWidth()); text_max_lpc_order_value->SetX(check_exhaustive_model->GetX() - 8 - maxTextSize); text_qlp_precision_value->SetX(check_qlp_precision_search->GetX() - 8 - maxTextSize); group_lpc->Add(text_max_lpc_order); group_lpc->Add(slider_max_lpc_order); group_lpc->Add(text_max_lpc_order_value); group_lpc->Add(check_exhaustive_model); group_lpc->Add(check_qlp_precision_search); group_lpc->Add(text_qlp_precision); group_lpc->Add(slider_qlp_precision); group_lpc->Add(text_qlp_precision_value); group_rice = new GroupBox(i18n->TranslateString("Residual coding"), Point(7, 97 + group_apodization->GetHeight()), Size(10 + text_max_lpc_order_value->GetX() + text_max_lpc_order_value->GetFont().GetUnscaledTextSizeX("00"), 62)); text_min_part_order = new Text(i18n->AddColon(i18n->TranslateString("Minimum partition order")), Point(9, 13)); slider_min_part_order = new Slider(Point(16, 11), Size(250, 0), OR_HORZ, &min_residual_partition_order, 0, FLAC__MAX_RICE_PARTITION_ORDER); slider_min_part_order->onValueChange.Connect(&ConfigureFLAC::SetRiceOrder, this); text_min_part_order_value= new Text(NIL, Point(text_max_lpc_order_value->GetX(), 13)); text_max_part_order = new Text(i18n->AddColon(i18n->TranslateString("Maximum partition order")), Point(9, 36)); slider_max_part_order = new Slider(Point(16, 34), Size(250, 0), OR_HORZ, &max_residual_partition_order, 0, FLAC__MAX_RICE_PARTITION_ORDER); slider_max_part_order->onValueChange.Connect(&ConfigureFLAC::SetRiceOrder, this); text_max_part_order_value= new Text(NIL, Point(text_max_lpc_order_value->GetX(), 36)); maxTextSize = Math::Max(Math::Max(text_min_part_order->GetUnscaledTextWidth(), text_max_part_order->GetUnscaledTextWidth()), Math::Max(text_max_lpc_order->GetUnscaledTextWidth(), text_qlp_precision->GetUnscaledTextWidth())); slider_min_part_order->SetX(16 + maxTextSize); slider_min_part_order->SetWidth(text_min_part_order_value->GetX() - maxTextSize - 24); slider_max_part_order->SetX(16 + maxTextSize); slider_max_part_order->SetWidth(text_max_part_order_value->GetX() - maxTextSize - 24); slider_max_lpc_order->SetX(16 + maxTextSize); slider_max_lpc_order->SetWidth(text_max_lpc_order_value->GetX() - maxTextSize - 24); slider_qlp_precision->SetX(16 + maxTextSize); slider_qlp_precision->SetWidth(text_qlp_precision_value->GetX() - maxTextSize - 24); group_rice->Add(text_min_part_order); group_rice->Add(text_max_part_order); group_rice->Add(slider_min_part_order); group_rice->Add(text_min_part_order_value); group_rice->Add(slider_max_part_order); group_rice->Add(text_max_part_order_value); layer_advanced->Add(group_apodization); layer_advanced->Add(group_lpc); layer_advanced->Add(group_rice); SetStereoMode(); SetStreamableSubset(); SetBlockSize(); SetRiceOrder(); SetLPCOrder(); SetQLPSearch(); SetQLPPrecision(); SetPreset(); tabwidget->SetHeight(189 + group_apodization->GetHeight()); Add(tabwidget); tabwidget->Add(layer_simple); tabwidget->Add(layer_format); tabwidget->Add(layer_advanced); SetSize(Size(550, 203 + group_apodization->GetHeight())); } BoCA::ConfigureFLAC::~ConfigureFLAC() { DeleteObject(tabwidget); DeleteObject(layer_simple); DeleteObject(layer_format); DeleteObject(layer_advanced); DeleteObject(group_preset); DeleteObject(text_preset); DeleteObject(combo_preset); DeleteObject(group_file_format); DeleteObject(option_file_format_flac); DeleteObject(option_file_format_ogg); DeleteObject(group_stereo); DeleteObject(check_mid_side_stereo); DeleteObject(check_loose_mid_side); DeleteObject(group_format); DeleteObject(check_streamable_subset); DeleteObject(text_blocksize); DeleteObject(slider_blocksize); DeleteObject(edit_blocksize); DeleteObject(text_blocksize_samples); DeleteObject(group_apodization); DeleteObject(text_apodization); DeleteObject(edit_apodization); DeleteObject(list_apodization); DeleteObject(text_apodization_note); DeleteObject(text_apodization_explain); DeleteObject(group_lpc); DeleteObject(text_max_lpc_order); DeleteObject(slider_max_lpc_order); DeleteObject(text_max_lpc_order_value); DeleteObject(check_exhaustive_model); DeleteObject(check_qlp_precision_search); DeleteObject(text_qlp_precision); DeleteObject(slider_qlp_precision); DeleteObject(text_qlp_precision_value); DeleteObject(group_rice); DeleteObject(text_min_part_order); DeleteObject(text_max_part_order); DeleteObject(slider_min_part_order); DeleteObject(text_min_part_order_value); DeleteObject(slider_max_part_order); DeleteObject(text_max_part_order_value); } Int BoCA::ConfigureFLAC::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Preset", preset); config->SetIntValue(ConfigID, "FileFormat", file_format); config->SetIntValue(ConfigID, "StreamableSubset", streamable_subset); config->SetIntValue(ConfigID, "DoMidSideStereo", do_mid_side_stereo); config->SetIntValue(ConfigID, "LooseMidSideStereo", loose_mid_side_stereo); config->SetIntValue(ConfigID, "Blocksize", (streamable_subset ? blocksize * 8 : Math::Max(0, Math::Min(32768, (Int) edit_blocksize->GetText().ToInt())))); config->SetStringValue(ConfigID, "Apodization", edit_apodization->GetText()); config->SetIntValue(ConfigID, "MaxLPCOrder", max_lpc_order); config->SetIntValue(ConfigID, "QLPCoeffPrecision", qlp_coeff_precision == 4 ? 0 : qlp_coeff_precision); config->SetIntValue(ConfigID, "DoQLPCoeffPrecSearch", do_qlp_coeff_prec_search); config->SetIntValue(ConfigID, "DoExhaustiveModelSearch", do_exhaustive_model_search); config->SetIntValue(ConfigID, "MinResidualPartitionOrder", min_residual_partition_order); config->SetIntValue(ConfigID, "MaxResidualPartitionOrder", max_residual_partition_order); return Success(); } Void BoCA::ConfigureFLAC::SetPreset() { preset = combo_preset->GetSelectedEntryNumber() - 1; if (preset == -1) { group_stereo->Activate(); group_format->Activate(); group_apodization->Activate(); group_lpc->Activate(); group_rice->Activate(); } else { group_stereo->Deactivate(); group_format->Deactivate(); group_apodization->Deactivate(); group_lpc->Deactivate(); group_rice->Deactivate(); } } Void BoCA::ConfigureFLAC::SetLPCOrder() { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::FLAC::Expert"); if (max_lpc_order == 0) text_max_lpc_order_value->SetText(i18n->TranslateString("disabled")); else text_max_lpc_order_value->SetText(String::FromInt(max_lpc_order)); if (max_lpc_order == 0) { text_qlp_precision->Deactivate(); slider_qlp_precision->Deactivate(); text_qlp_precision_value->Deactivate(); check_exhaustive_model->Deactivate(); check_qlp_precision_search->Deactivate(); } else { if (!do_qlp_coeff_prec_search) { text_qlp_precision->Activate(); slider_qlp_precision->Activate(); text_qlp_precision_value->Activate(); } check_exhaustive_model->Activate(); check_qlp_precision_search->Activate(); } } Void BoCA::ConfigureFLAC::SetQLPSearch() { if (do_qlp_coeff_prec_search) { text_qlp_precision->Deactivate(); slider_qlp_precision->Deactivate(); text_qlp_precision_value->Deactivate(); } else { text_qlp_precision->Activate(); slider_qlp_precision->Activate(); text_qlp_precision_value->Activate(); } } Void BoCA::ConfigureFLAC::SetQLPPrecision() { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::FLAC::Expert"); if (qlp_coeff_precision == 4) text_qlp_precision_value->SetText(i18n->TranslateString("auto")); else text_qlp_precision_value->SetText(String::FromInt(qlp_coeff_precision)); } Void BoCA::ConfigureFLAC::SetRiceOrder() { if (max_residual_partition_order < min_residual_partition_order) slider_max_part_order->SetValue(min_residual_partition_order); if (min_residual_partition_order > max_residual_partition_order) slider_min_part_order->SetValue(max_residual_partition_order); text_min_part_order_value->SetText(String::FromInt(min_residual_partition_order)); text_max_part_order_value->SetText(String::FromInt(max_residual_partition_order)); } Void BoCA::ConfigureFLAC::SetStereoMode() { if (do_mid_side_stereo) check_loose_mid_side->Activate(); else check_loose_mid_side->Deactivate(); } Void BoCA::ConfigureFLAC::SetStreamableSubset() { if (streamable_subset) { edit_blocksize->Deactivate(); slider_blocksize->SetRange(24, 576); slider_max_lpc_order->SetRange(0, FLAC__SUBSET_MAX_LPC_ORDER_48000HZ); slider_min_part_order->SetRange(0, FLAC__SUBSET_MAX_RICE_PARTITION_ORDER); slider_max_part_order->SetRange(0, FLAC__SUBSET_MAX_RICE_PARTITION_ORDER); } else { edit_blocksize->Activate(); slider_blocksize->SetRange(24, 4096); slider_max_lpc_order->SetRange(0, FLAC__MAX_LPC_ORDER); slider_min_part_order->SetRange(0, FLAC__MAX_RICE_PARTITION_ORDER); slider_max_part_order->SetRange(0, FLAC__MAX_RICE_PARTITION_ORDER); } SetBlockSize(); SetLPCOrder(); SetRiceOrder(); } Void BoCA::ConfigureFLAC::SetBlockSize() { if (streamable_subset) { if ( blocksize <= 28) blocksize = 24; else if (blocksize > 28 && blocksize <= 48) blocksize = 32; else if (blocksize > 48 && blocksize <= 68) blocksize = 64; else if (blocksize > 68 && blocksize <= 100) blocksize = 72; else if (blocksize > 100 && blocksize <= 136) blocksize = 128; else if (blocksize > 136 && blocksize <= 200) blocksize = 144; else if (blocksize > 200 && blocksize <= 272) blocksize = 256; else if (blocksize > 272 && blocksize <= 400) blocksize = 288; else if (blocksize > 400 && blocksize <= 544) blocksize = 512; else if (blocksize > 544 && blocksize <= 800) blocksize = 576; else if (blocksize > 800 && blocksize <= 1536) blocksize = 1024; else if (blocksize > 1536 && blocksize <= 3072) blocksize = 2048; else if (blocksize > 3072) blocksize = 4096; slider_blocksize->SetValue(blocksize); } if (!edit_blocksize->IsFocussed()) edit_blocksize->SetText(String::FromInt(blocksize * 8)); } Void BoCA::ConfigureFLAC::EditBlockSize() { slider_blocksize->SetValue(edit_blocksize->GetText().ToInt() / 8); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/config.h000077500000000000000000000055531516712004000243260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_FLACCONFIG #define H_FLACCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureFLAC : public ConfigLayer { private: TabWidget *tabwidget; Layer *layer_simple; GroupBox *group_preset; Text *text_preset; ComboBox *combo_preset; GroupBox *group_file_format; OptionBox *option_file_format_flac; OptionBox *option_file_format_ogg; GroupBox *group_stereo; CheckBox *check_mid_side_stereo; CheckBox *check_loose_mid_side; Layer *layer_format; GroupBox *group_format; CheckBox *check_streamable_subset; Text *text_blocksize; Slider *slider_blocksize; EditBox *edit_blocksize; Text *text_blocksize_samples; Layer *layer_advanced; GroupBox *group_apodization; Text *text_apodization; EditBox *edit_apodization; ListBox *list_apodization; Text *text_apodization_note; Text *text_apodization_explain; GroupBox *group_lpc; Text *text_max_lpc_order; Slider *slider_max_lpc_order; Text *text_max_lpc_order_value; CheckBox *check_exhaustive_model; Text *text_qlp_precision; Slider *slider_qlp_precision; Text *text_qlp_precision_value; CheckBox *check_qlp_precision_search; GroupBox *group_rice; Text *text_min_part_order; Slider *slider_min_part_order; Text *text_min_part_order_value; Text *text_max_part_order; Slider *slider_max_part_order; Text *text_max_part_order_value; Int preset; Int file_format; Bool streamable_subset; Bool do_mid_side_stereo; Bool loose_mid_side_stereo; Int blocksize; Int max_lpc_order; Int qlp_coeff_precision; Bool do_qlp_coeff_prec_search; Bool do_exhaustive_model_search; Int min_residual_partition_order; Int max_residual_partition_order; slots: Void SetPreset(); Void SetLPCOrder(); Void SetQLPSearch(); Void SetQLPPrecision(); Void SetRiceOrder(); Void SetStereoMode(); Void SetStreamableSubset(); Void SetBlockSize(); Void EditBlockSize(); public: static const String ConfigID; ConfigureFLAC(); ~ConfigureFLAC(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/dllinterface.cpp000077500000000000000000000334701516712004000260470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC = NIL; FLAC__STREAM_ENCODER_NEW ex_FLAC__stream_encoder_new = NIL; FLAC__STREAM_ENCODER_DELETE ex_FLAC__stream_encoder_delete = NIL; FLAC__STREAM_ENCODER_INIT_STREAM ex_FLAC__stream_encoder_init_stream = NIL; FLAC__STREAM_ENCODER_INIT_OGG_STREAM ex_FLAC__stream_encoder_init_ogg_stream = NIL; FLAC__STREAM_ENCODER_FINISH ex_FLAC__stream_encoder_finish = NIL; FLAC__STREAM_ENCODER_SET_CHANNELS ex_FLAC__stream_encoder_set_channels = NIL; FLAC__STREAM_ENCODER_SET_BITS_PER_SAMPLE ex_FLAC__stream_encoder_set_bits_per_sample = NIL; FLAC__STREAM_ENCODER_SET_SAMPLE_RATE ex_FLAC__stream_encoder_set_sample_rate = NIL; FLAC__STREAM_ENCODER_SET_STREAMABLE_SUBSET ex_FLAC__stream_encoder_set_streamable_subset = NIL; FLAC__STREAM_ENCODER_SET_DO_MID_SIDE_STEREO ex_FLAC__stream_encoder_set_do_mid_side_stereo = NIL; FLAC__STREAM_ENCODER_SET_LOOSE_MID_SIDE_STEREO ex_FLAC__stream_encoder_set_loose_mid_side_stereo = NIL; FLAC__STREAM_ENCODER_SET_BLOCKSIZE ex_FLAC__stream_encoder_set_blocksize = NIL; FLAC__STREAM_ENCODER_SET_MAX_LPC_ORDER ex_FLAC__stream_encoder_set_max_lpc_order = NIL; FLAC__STREAM_ENCODER_SET_QLP_COEFF_PRECISION ex_FLAC__stream_encoder_set_qlp_coeff_precision = NIL; FLAC__STREAM_ENCODER_SET_DO_QLP_COEFF_PREC_SEARCH ex_FLAC__stream_encoder_set_do_qlp_coeff_prec_search = NIL; FLAC__STREAM_ENCODER_SET_DO_EXHAUSTIVE_MODEL_SEARCH ex_FLAC__stream_encoder_set_do_exhaustive_model_search = NIL; FLAC__STREAM_ENCODER_SET_MIN_RESIDUAL_PARTITION_ORDER ex_FLAC__stream_encoder_set_min_residual_partition_order = NIL; FLAC__STREAM_ENCODER_SET_MAX_RESIDUAL_PARTITION_ORDER ex_FLAC__stream_encoder_set_max_residual_partition_order = NIL; FLAC__STREAM_ENCODER_SET_METADATA ex_FLAC__stream_encoder_set_metadata = NIL; FLAC__STREAM_ENCODER_SET_COMPRESSION_LEVEL ex_FLAC__stream_encoder_set_compression_level = NIL; FLAC__STREAM_ENCODER_SET_APODIZATION ex_FLAC__stream_encoder_set_apodization = NIL; FLAC__STREAM_ENCODER_SET_OGG_SERIAL_NUMBER ex_FLAC__stream_encoder_set_ogg_serial_number = NIL; FLAC__STREAM_ENCODER_SET_NUM_THREADS ex_FLAC__stream_encoder_set_num_threads = NIL; FLAC__STREAM_ENCODER_PROCESS_INTERLEAVED ex_FLAC__stream_encoder_process_interleaved = NIL; FLAC__METADATA_OBJECT_NEW ex_FLAC__metadata_object_new = NIL; FLAC__METADATA_OBJECT_DELETE ex_FLAC__metadata_object_delete = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE ex_FLAC__metadata_object_picture_set_mime_type = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION ex_FLAC__metadata_object_picture_set_description = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_DATA ex_FLAC__metadata_object_picture_set_data = NIL; FLAC__METADATA_OBJECT_CUESHEET_TRACK_NEW ex_FLAC__metadata_object_cuesheet_track_new = NIL; FLAC__METADATA_OBJECT_CUESHEET_TRACK_DELETE ex_FLAC__metadata_object_cuesheet_track_delete = NIL; FLAC__METADATA_OBJECT_CUESHEET_TRACK_RESIZE_INDICES ex_FLAC__metadata_object_cuesheet_track_resize_indices = NIL; FLAC__METADATA_OBJECT_CUESHEET_TRACK_INSERT_INDEX ex_FLAC__metadata_object_cuesheet_track_insert_index = NIL; FLAC__METADATA_OBJECT_CUESHEET_RESIZE_TRACKS ex_FLAC__metadata_object_cuesheet_resize_tracks = NIL; FLAC__METADATA_OBJECT_CUESHEET_INSERT_TRACK ex_FLAC__metadata_object_cuesheet_insert_track = NIL; FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT ex_FLAC__metadata_object_vorbiscomment_append_comment = NIL; FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_APPEND_SPACED_POINTS ex_FLAC__metadata_object_seektable_template_append_spaced_points = NIL; FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_SORT ex_FLAC__metadata_object_seektable_template_sort = NIL; FLAC__VERSION_STRING_TYPE ex_FLAC__VERSION_STRING = NIL; FLAC__VENDOR_STRING_TYPE ex_FLAC__VENDOR_STRING = NIL; DynamicLoader *flacdll = NIL; Bool LoadFLACDLL() { flacdll = BoCA::Utilities::LoadCodecDLL("FLAC"); if (flacdll == NIL) return False; ex_FLAC_API_SUPPORTS_OGG_FLAC = (FLAC_API_SUPPORTS_OGG_FLAC_TYPE) flacdll->GetFunctionAddress("FLAC_API_SUPPORTS_OGG_FLAC"); ex_FLAC__stream_encoder_new = (FLAC__STREAM_ENCODER_NEW) flacdll->GetFunctionAddress("FLAC__stream_encoder_new"); ex_FLAC__stream_encoder_delete = (FLAC__STREAM_ENCODER_DELETE) flacdll->GetFunctionAddress("FLAC__stream_encoder_delete"); ex_FLAC__stream_encoder_init_stream = (FLAC__STREAM_ENCODER_INIT_STREAM) flacdll->GetFunctionAddress("FLAC__stream_encoder_init_stream"); ex_FLAC__stream_encoder_init_ogg_stream = (FLAC__STREAM_ENCODER_INIT_OGG_STREAM) flacdll->GetFunctionAddress("FLAC__stream_encoder_init_ogg_stream"); ex_FLAC__stream_encoder_finish = (FLAC__STREAM_ENCODER_FINISH) flacdll->GetFunctionAddress("FLAC__stream_encoder_finish"); ex_FLAC__stream_encoder_set_channels = (FLAC__STREAM_ENCODER_SET_CHANNELS) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_channels"); ex_FLAC__stream_encoder_set_bits_per_sample = (FLAC__STREAM_ENCODER_SET_BITS_PER_SAMPLE) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_bits_per_sample"); ex_FLAC__stream_encoder_set_sample_rate = (FLAC__STREAM_ENCODER_SET_SAMPLE_RATE) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_sample_rate"); ex_FLAC__stream_encoder_set_streamable_subset = (FLAC__STREAM_ENCODER_SET_STREAMABLE_SUBSET) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_streamable_subset"); ex_FLAC__stream_encoder_set_do_mid_side_stereo = (FLAC__STREAM_ENCODER_SET_DO_MID_SIDE_STEREO) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_do_mid_side_stereo"); ex_FLAC__stream_encoder_set_loose_mid_side_stereo = (FLAC__STREAM_ENCODER_SET_LOOSE_MID_SIDE_STEREO) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_loose_mid_side_stereo"); ex_FLAC__stream_encoder_set_blocksize = (FLAC__STREAM_ENCODER_SET_BLOCKSIZE) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_blocksize"); ex_FLAC__stream_encoder_set_max_lpc_order = (FLAC__STREAM_ENCODER_SET_MAX_LPC_ORDER) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_max_lpc_order"); ex_FLAC__stream_encoder_set_qlp_coeff_precision = (FLAC__STREAM_ENCODER_SET_QLP_COEFF_PRECISION) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_qlp_coeff_precision"); ex_FLAC__stream_encoder_set_do_qlp_coeff_prec_search = (FLAC__STREAM_ENCODER_SET_DO_QLP_COEFF_PREC_SEARCH) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_do_qlp_coeff_prec_search"); ex_FLAC__stream_encoder_set_do_exhaustive_model_search = (FLAC__STREAM_ENCODER_SET_DO_EXHAUSTIVE_MODEL_SEARCH) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_do_exhaustive_model_search"); ex_FLAC__stream_encoder_set_min_residual_partition_order = (FLAC__STREAM_ENCODER_SET_MIN_RESIDUAL_PARTITION_ORDER) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_min_residual_partition_order"); ex_FLAC__stream_encoder_set_max_residual_partition_order = (FLAC__STREAM_ENCODER_SET_MAX_RESIDUAL_PARTITION_ORDER) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_max_residual_partition_order"); ex_FLAC__stream_encoder_set_metadata = (FLAC__STREAM_ENCODER_SET_METADATA) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_metadata"); ex_FLAC__stream_encoder_set_compression_level = (FLAC__STREAM_ENCODER_SET_COMPRESSION_LEVEL) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_compression_level"); ex_FLAC__stream_encoder_set_apodization = (FLAC__STREAM_ENCODER_SET_APODIZATION) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_apodization"); ex_FLAC__stream_encoder_set_ogg_serial_number = (FLAC__STREAM_ENCODER_SET_OGG_SERIAL_NUMBER) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_ogg_serial_number"); ex_FLAC__stream_encoder_set_num_threads = (FLAC__STREAM_ENCODER_SET_NUM_THREADS) flacdll->GetFunctionAddress("FLAC__stream_encoder_set_num_threads"); ex_FLAC__stream_encoder_process_interleaved = (FLAC__STREAM_ENCODER_PROCESS_INTERLEAVED) flacdll->GetFunctionAddress("FLAC__stream_encoder_process_interleaved"); ex_FLAC__metadata_object_new = (FLAC__METADATA_OBJECT_NEW) flacdll->GetFunctionAddress("FLAC__metadata_object_new"); ex_FLAC__metadata_object_delete = (FLAC__METADATA_OBJECT_DELETE) flacdll->GetFunctionAddress("FLAC__metadata_object_delete"); ex_FLAC__metadata_object_picture_set_mime_type = (FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_mime_type"); ex_FLAC__metadata_object_picture_set_description = (FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_description"); ex_FLAC__metadata_object_picture_set_data = (FLAC__METADATA_OBJECT_PICTURE_SET_DATA) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_data"); ex_FLAC__metadata_object_cuesheet_track_new = (FLAC__METADATA_OBJECT_CUESHEET_TRACK_NEW) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_track_new"); ex_FLAC__metadata_object_cuesheet_track_delete = (FLAC__METADATA_OBJECT_CUESHEET_TRACK_DELETE) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_track_delete"); ex_FLAC__metadata_object_cuesheet_track_resize_indices = (FLAC__METADATA_OBJECT_CUESHEET_TRACK_RESIZE_INDICES) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_track_resize_indices"); ex_FLAC__metadata_object_cuesheet_track_insert_index = (FLAC__METADATA_OBJECT_CUESHEET_TRACK_INSERT_INDEX) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_track_insert_index"); ex_FLAC__metadata_object_cuesheet_resize_tracks = (FLAC__METADATA_OBJECT_CUESHEET_RESIZE_TRACKS) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_resize_tracks"); ex_FLAC__metadata_object_cuesheet_insert_track = (FLAC__METADATA_OBJECT_CUESHEET_INSERT_TRACK) flacdll->GetFunctionAddress("FLAC__metadata_object_cuesheet_insert_track"); ex_FLAC__metadata_object_vorbiscomment_append_comment = (FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT) flacdll->GetFunctionAddress("FLAC__metadata_object_vorbiscomment_append_comment"); ex_FLAC__metadata_object_seektable_template_append_spaced_points = (FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_APPEND_SPACED_POINTS) flacdll->GetFunctionAddress("FLAC__metadata_object_seektable_template_append_spaced_points"); ex_FLAC__metadata_object_seektable_template_sort = (FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_SORT) flacdll->GetFunctionAddress("FLAC__metadata_object_seektable_template_sort"); ex_FLAC__VERSION_STRING = (FLAC__VERSION_STRING_TYPE) flacdll->GetFunctionAddress("FLAC__VERSION_STRING"); ex_FLAC__VENDOR_STRING = (FLAC__VENDOR_STRING_TYPE) flacdll->GetFunctionAddress("FLAC__VENDOR_STRING"); if (ex_FLAC_API_SUPPORTS_OGG_FLAC == NIL || ex_FLAC__stream_encoder_new == NIL || ex_FLAC__stream_encoder_delete == NIL || ex_FLAC__stream_encoder_init_stream == NIL || ex_FLAC__stream_encoder_init_ogg_stream == NIL || ex_FLAC__stream_encoder_finish == NIL || ex_FLAC__stream_encoder_set_channels == NIL || ex_FLAC__stream_encoder_set_bits_per_sample == NIL || ex_FLAC__stream_encoder_set_sample_rate == NIL || ex_FLAC__stream_encoder_set_streamable_subset == NIL || ex_FLAC__stream_encoder_set_do_mid_side_stereo == NIL || ex_FLAC__stream_encoder_set_loose_mid_side_stereo == NIL || ex_FLAC__stream_encoder_set_blocksize == NIL || ex_FLAC__stream_encoder_set_max_lpc_order == NIL || ex_FLAC__stream_encoder_set_qlp_coeff_precision == NIL || ex_FLAC__stream_encoder_set_do_qlp_coeff_prec_search == NIL || ex_FLAC__stream_encoder_set_do_exhaustive_model_search == NIL || ex_FLAC__stream_encoder_set_min_residual_partition_order == NIL || ex_FLAC__stream_encoder_set_max_residual_partition_order == NIL || ex_FLAC__stream_encoder_set_metadata == NIL || ex_FLAC__stream_encoder_set_compression_level == NIL || ex_FLAC__stream_encoder_set_apodization == NIL || ex_FLAC__stream_encoder_set_ogg_serial_number == NIL || ex_FLAC__stream_encoder_process_interleaved == NIL || ex_FLAC__metadata_object_new == NIL || ex_FLAC__metadata_object_delete == NIL || ex_FLAC__metadata_object_picture_set_mime_type == NIL || ex_FLAC__metadata_object_picture_set_description == NIL || ex_FLAC__metadata_object_picture_set_data == NIL || ex_FLAC__metadata_object_cuesheet_track_new == NIL || ex_FLAC__metadata_object_cuesheet_track_delete == NIL || ex_FLAC__metadata_object_cuesheet_track_resize_indices == NIL || ex_FLAC__metadata_object_cuesheet_track_insert_index == NIL || ex_FLAC__metadata_object_cuesheet_resize_tracks == NIL || ex_FLAC__metadata_object_cuesheet_insert_track == NIL || ex_FLAC__metadata_object_vorbiscomment_append_comment == NIL || ex_FLAC__metadata_object_seektable_template_append_spaced_points == NIL || ex_FLAC__metadata_object_seektable_template_sort == NIL || ex_FLAC__VERSION_STRING == NIL || ex_FLAC__VENDOR_STRING == NIL) { FreeFLACDLL(); return False; } return True; } Void FreeFLACDLL() { BoCA::Utilities::FreeCodecDLL(flacdll); flacdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/dllinterface.h000077500000000000000000000223011516712004000255030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *flacdll; Bool LoadFLACDLL(); Void FreeFLACDLL(); /* FLAC API functions. */ typedef int *FLAC_API_SUPPORTS_OGG_FLAC_TYPE; typedef FLAC__StreamEncoder * (*FLAC__STREAM_ENCODER_NEW) (); typedef void (*FLAC__STREAM_ENCODER_DELETE) (FLAC__StreamEncoder *); typedef FLAC__StreamEncoderInitStatus (*FLAC__STREAM_ENCODER_INIT_STREAM) (FLAC__StreamEncoder *, FLAC__StreamEncoderWriteCallback, FLAC__StreamEncoderSeekCallback, FLAC__StreamEncoderTellCallback, FLAC__StreamEncoderMetadataCallback, void *); typedef FLAC__StreamEncoderInitStatus (*FLAC__STREAM_ENCODER_INIT_OGG_STREAM) (FLAC__StreamEncoder *, FLAC__StreamEncoderReadCallback, FLAC__StreamEncoderWriteCallback, FLAC__StreamEncoderSeekCallback, FLAC__StreamEncoderTellCallback, FLAC__StreamEncoderMetadataCallback, void *); typedef FLAC__bool (*FLAC__STREAM_ENCODER_FINISH) (FLAC__StreamEncoder *); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_CHANNELS) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_BITS_PER_SAMPLE) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_SAMPLE_RATE) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_STREAMABLE_SUBSET) (FLAC__StreamEncoder *, FLAC__bool); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_DO_MID_SIDE_STEREO) (FLAC__StreamEncoder *, FLAC__bool); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_LOOSE_MID_SIDE_STEREO) (FLAC__StreamEncoder *, FLAC__bool); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_BLOCKSIZE) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_MAX_LPC_ORDER) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_QLP_COEFF_PRECISION) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_DO_QLP_COEFF_PREC_SEARCH) (FLAC__StreamEncoder *, FLAC__bool); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_DO_EXHAUSTIVE_MODEL_SEARCH) (FLAC__StreamEncoder *, FLAC__bool); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_MIN_RESIDUAL_PARTITION_ORDER) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_MAX_RESIDUAL_PARTITION_ORDER) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_METADATA) (FLAC__StreamEncoder *, FLAC__StreamMetadata **, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_COMPRESSION_LEVEL) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_APODIZATION) (FLAC__StreamEncoder *, const char *); typedef FLAC__bool (*FLAC__STREAM_ENCODER_SET_OGG_SERIAL_NUMBER) (FLAC__StreamEncoder *, long); typedef uint32_t (*FLAC__STREAM_ENCODER_SET_NUM_THREADS) (FLAC__StreamEncoder *, uint32_t); typedef FLAC__bool (*FLAC__STREAM_ENCODER_PROCESS_INTERLEAVED) (FLAC__StreamEncoder *, const FLAC__int32[], uint32_t); typedef FLAC__StreamMetadata * (*FLAC__METADATA_OBJECT_NEW) (FLAC__MetadataType); typedef void (*FLAC__METADATA_OBJECT_DELETE) (FLAC__StreamMetadata *); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE) (FLAC__StreamMetadata *, char *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION) (FLAC__StreamMetadata *, FLAC__byte *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_DATA) (FLAC__StreamMetadata *, FLAC__byte *, FLAC__uint32, FLAC__bool); typedef FLAC__StreamMetadata_CueSheet_Track * (*FLAC__METADATA_OBJECT_CUESHEET_TRACK_NEW) (); typedef void (*FLAC__METADATA_OBJECT_CUESHEET_TRACK_DELETE) (FLAC__StreamMetadata_CueSheet_Track *); typedef FLAC__bool (*FLAC__METADATA_OBJECT_CUESHEET_TRACK_RESIZE_INDICES) (FLAC__StreamMetadata *, uint32_t, uint32_t); typedef FLAC__bool (*FLAC__METADATA_OBJECT_CUESHEET_TRACK_INSERT_INDEX) (FLAC__StreamMetadata *, uint32_t, uint32_t, FLAC__StreamMetadata_CueSheet_Index); typedef FLAC__bool (*FLAC__METADATA_OBJECT_CUESHEET_RESIZE_TRACKS) (FLAC__StreamMetadata *, uint32_t); typedef FLAC__bool (*FLAC__METADATA_OBJECT_CUESHEET_INSERT_TRACK) (FLAC__StreamMetadata *, uint32_t, FLAC__StreamMetadata_CueSheet_Track *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT) (FLAC__StreamMetadata *, FLAC__StreamMetadata_VorbisComment_Entry, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_APPEND_SPACED_POINTS) (FLAC__StreamMetadata *, uint32_t, FLAC__uint64); typedef FLAC__bool (*FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_SORT) (FLAC__StreamMetadata *, FLAC__bool); typedef char * *FLAC__VERSION_STRING_TYPE; typedef char * *FLAC__VENDOR_STRING_TYPE; extern FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC; extern FLAC__STREAM_ENCODER_NEW ex_FLAC__stream_encoder_new; extern FLAC__STREAM_ENCODER_DELETE ex_FLAC__stream_encoder_delete; extern FLAC__STREAM_ENCODER_INIT_STREAM ex_FLAC__stream_encoder_init_stream; extern FLAC__STREAM_ENCODER_INIT_OGG_STREAM ex_FLAC__stream_encoder_init_ogg_stream; extern FLAC__STREAM_ENCODER_FINISH ex_FLAC__stream_encoder_finish; extern FLAC__STREAM_ENCODER_SET_CHANNELS ex_FLAC__stream_encoder_set_channels; extern FLAC__STREAM_ENCODER_SET_BITS_PER_SAMPLE ex_FLAC__stream_encoder_set_bits_per_sample; extern FLAC__STREAM_ENCODER_SET_SAMPLE_RATE ex_FLAC__stream_encoder_set_sample_rate; extern FLAC__STREAM_ENCODER_SET_STREAMABLE_SUBSET ex_FLAC__stream_encoder_set_streamable_subset; extern FLAC__STREAM_ENCODER_SET_DO_MID_SIDE_STEREO ex_FLAC__stream_encoder_set_do_mid_side_stereo; extern FLAC__STREAM_ENCODER_SET_LOOSE_MID_SIDE_STEREO ex_FLAC__stream_encoder_set_loose_mid_side_stereo; extern FLAC__STREAM_ENCODER_SET_BLOCKSIZE ex_FLAC__stream_encoder_set_blocksize; extern FLAC__STREAM_ENCODER_SET_MAX_LPC_ORDER ex_FLAC__stream_encoder_set_max_lpc_order; extern FLAC__STREAM_ENCODER_SET_QLP_COEFF_PRECISION ex_FLAC__stream_encoder_set_qlp_coeff_precision; extern FLAC__STREAM_ENCODER_SET_DO_QLP_COEFF_PREC_SEARCH ex_FLAC__stream_encoder_set_do_qlp_coeff_prec_search; extern FLAC__STREAM_ENCODER_SET_DO_EXHAUSTIVE_MODEL_SEARCH ex_FLAC__stream_encoder_set_do_exhaustive_model_search; extern FLAC__STREAM_ENCODER_SET_MIN_RESIDUAL_PARTITION_ORDER ex_FLAC__stream_encoder_set_min_residual_partition_order; extern FLAC__STREAM_ENCODER_SET_MAX_RESIDUAL_PARTITION_ORDER ex_FLAC__stream_encoder_set_max_residual_partition_order; extern FLAC__STREAM_ENCODER_SET_METADATA ex_FLAC__stream_encoder_set_metadata; extern FLAC__STREAM_ENCODER_SET_COMPRESSION_LEVEL ex_FLAC__stream_encoder_set_compression_level; extern FLAC__STREAM_ENCODER_SET_APODIZATION ex_FLAC__stream_encoder_set_apodization; extern FLAC__STREAM_ENCODER_SET_OGG_SERIAL_NUMBER ex_FLAC__stream_encoder_set_ogg_serial_number; extern FLAC__STREAM_ENCODER_SET_NUM_THREADS ex_FLAC__stream_encoder_set_num_threads; extern FLAC__STREAM_ENCODER_PROCESS_INTERLEAVED ex_FLAC__stream_encoder_process_interleaved; extern FLAC__METADATA_OBJECT_NEW ex_FLAC__metadata_object_new; extern FLAC__METADATA_OBJECT_DELETE ex_FLAC__metadata_object_delete; extern FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE ex_FLAC__metadata_object_picture_set_mime_type; extern FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION ex_FLAC__metadata_object_picture_set_description; extern FLAC__METADATA_OBJECT_PICTURE_SET_DATA ex_FLAC__metadata_object_picture_set_data; extern FLAC__METADATA_OBJECT_CUESHEET_TRACK_NEW ex_FLAC__metadata_object_cuesheet_track_new; extern FLAC__METADATA_OBJECT_CUESHEET_TRACK_DELETE ex_FLAC__metadata_object_cuesheet_track_delete; extern FLAC__METADATA_OBJECT_CUESHEET_TRACK_RESIZE_INDICES ex_FLAC__metadata_object_cuesheet_track_resize_indices; extern FLAC__METADATA_OBJECT_CUESHEET_TRACK_INSERT_INDEX ex_FLAC__metadata_object_cuesheet_track_insert_index; extern FLAC__METADATA_OBJECT_CUESHEET_RESIZE_TRACKS ex_FLAC__metadata_object_cuesheet_resize_tracks; extern FLAC__METADATA_OBJECT_CUESHEET_INSERT_TRACK ex_FLAC__metadata_object_cuesheet_insert_track; extern FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT ex_FLAC__metadata_object_vorbiscomment_append_comment; extern FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_APPEND_SPACED_POINTS ex_FLAC__metadata_object_seektable_template_append_spaced_points; extern FLAC__METADATA_OBJECT_SEEKTABLE_TEMPLATE_SORT ex_FLAC__metadata_object_seektable_template_sort; extern FLAC__VERSION_STRING_TYPE ex_FLAC__VERSION_STRING; extern FLAC__VENDOR_STRING_TYPE ex_FLAC__VENDOR_STRING; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/flac.cpp000066400000000000000000000520401516712004000243070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "flac.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderFLAC::GetComponentSpecs() { static String componentSpecs; if (flacdll != NIL) { const Array &flacVersion = String(*ex_FLAC__VERSION_STRING).Explode("."); Int maxBitDepth = 24; Int maxSampleRate = 655350; if ( flacVersion.GetNth(0).ToInt() > 1 || (flacVersion.GetNth(0).ToInt() == 1 && flacVersion.GetNth(1).ToInt() >= 4)) { maxBitDepth = 32; maxSampleRate = 1048575; } componentSpecs = " \ \ \ \ FLAC Audio Encoder %VERSION% \ 1.0 \ flac-enc \ encoder \ \ FLAC Files \ true \ flac \ FLAC Metadata \ \ \ "; if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 1) { componentSpecs.Append(" \ \ \ Ogg FLAC Files \ true \ oga \ Vorbis Comment \ \ \ "); } componentSpecs.Append(" \ \ \ \ \ "); if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 1) { componentSpecs.Append(" \ \ \ \ \ \ \ "); } componentSpecs.Append(" \ \ \ 0 \ 8 \ \ \ 192 \ 32768 \ \ \ \ \ 0 \ ").Append(String::FromInt(FLAC__MAX_LPC_ORDER)).Append(" \ \ \ \ ").Append(String::FromInt(FLAC__MIN_QLP_COEFF_PRECISION)).Append(" \ ").Append(String::FromInt(FLAC__MAX_QLP_COEFF_PRECISION)).Append(" \ \ \ 0 \ ").Append(String::FromInt(FLAC__MAX_RICE_PARTITION_ORDER)).Append(" \ \ \ \ \ "); componentSpecs.Replace("%VERSION%", String("v").Append(*ex_FLAC__VERSION_STRING)); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFLACDLL(); } Void smooth::DetachDLL() { FreeFLACDLL(); } namespace BoCA { FLAC__StreamEncoderReadStatus FLACStreamEncoderReadCallback(const FLAC__StreamEncoder *, FLAC__byte[], size_t *, void *); FLAC__StreamEncoderWriteStatus FLACStreamEncoderWriteCallback(const FLAC__StreamEncoder *, const FLAC__byte[], size_t, uint32_t, uint32_t, void *); FLAC__StreamEncoderSeekStatus FLACStreamEncoderSeekCallback(const FLAC__StreamEncoder *, FLAC__uint64, void *); FLAC__StreamEncoderTellStatus FLACStreamEncoderTellCallback(const FLAC__StreamEncoder *, FLAC__uint64 *, void *); /* Use 512kB IO buffer for writing FLAC files. */ static const Int flacStreamEncoderBufferSize = 512 * 1024; }; BoCA::EncoderFLAC::EncoderFLAC() { configLayer = NIL; config = NIL; encoder = NIL; bytesWritten = 0; } BoCA::EncoderFLAC::~EncoderFLAC() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderFLAC::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Create FLAC encoder. */ Math::RandomSeed(); encoder = ex_FLAC__stream_encoder_new(); /* Add Vorbis Comment metadata object. */ Buffer vcBuffer; if (config->GetIntValue("Tags", "EnableFLACMetadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { FLAC__StreamMetadata *vorbiscomment = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); metadata.Add(vorbiscomment); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { /* Disable writing album art to Vorbis Comment tags for FLAC files. */ Config *taggerConfig = Config::Copy(config); taggerConfig->SetIntValue("Tags", "CoverArtWriteToVorbisComment", False); taggerConfig->SetIntValue("Tags", "TrackPrependZeroVorbisComment", config->GetIntValue("Tags", "TrackPrependZeroFLACMetadata", True)); tagger->SetConfiguration(taggerConfig); tagger->SetVendorString(*ex_FLAC__VENDOR_STRING); tagger->RenderBuffer(vcBuffer, track); boca.DeleteComponent(tagger); Config::Free(taggerConfig); } /* Process output comment tag and add it to FLAC metadata. */ InStream in(STREAM_BUFFER, vcBuffer, vcBuffer.Size()); in.RelSeek(in.InputNumber(4)); Int numComments = in.InputNumber(4); for (Int i = 0; i < numComments; i++) { FLAC__StreamMetadata_VorbisComment_Entry entry; entry.length = in.InputNumber(4); entry.entry = vcBuffer + in.GetPos(); ex_FLAC__metadata_object_vorbiscomment_append_comment(vorbiscomment, entry, true); in.RelSeek(entry.length); } vorbiscomment->length = vcBuffer.Size(); } /* Add seektable metadata object. */ Int64 numSamples = track.length >= 0 ? track.length : track.approxLength; if (numSamples >= 0) { FLAC__StreamMetadata *seektable = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE); /* Set number of seek points and limit it to 230 for Ogg FLAC to fit in one Ogg page. */ Int numSeekPoints = Math::Min(1000, (Int) Math::Ceil(Float(numSamples) / format.rate / 10.0)); if (config->GetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0) == 1 && *ex_FLAC_API_SUPPORTS_OGG_FLAC == 1) numSeekPoints = Math::Min(230, numSeekPoints); ex_FLAC__metadata_object_seektable_template_append_spaced_points(seektable, numSeekPoints, numSamples); ex_FLAC__metadata_object_seektable_template_sort(seektable, true); metadata.Add(seektable); } /* Add picture metadata object. */ if (config->GetIntValue("Tags", "EnableFLACMetadata", True) && config->GetIntValue("Tags", "CoverArtWriteToTags", True) && config->GetIntValue("Tags", "CoverArtWriteToFLACMetadata", True)) { for (Int i = 0; i < track.pictures.Length(); i++) { FLAC__StreamMetadata *picture = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE); const Picture &picInfo = track.pictures.GetNth(i); metadata.Add(picture); if (picInfo.mime != NIL) ex_FLAC__metadata_object_picture_set_mime_type(picture, picInfo.mime, true); if (picInfo.description != NIL) ex_FLAC__metadata_object_picture_set_description(picture, (FLAC__byte *) picInfo.description.Trim().ConvertTo("UTF-8"), true); ex_FLAC__metadata_object_picture_set_data(picture, const_cast((const UnsignedByte *) picInfo.data), picInfo.data.Size(), true); picture->data.picture.type = (FLAC__StreamMetadata_Picture_Type) picInfo.type; } } /* Add padding metadata object. */ FLAC__StreamMetadata *padding = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING); padding->length = 8192; metadata.Add(padding); /* Put metadata in an array and hand it to the encoder. */ { FLAC__StreamMetadata **metadataArray = new FLAC__StreamMetadata * [metadata.Length()]; for (Int i = 0; i < metadata.Length(); i++) metadataArray[i] = metadata.GetNth(i); ex_FLAC__stream_encoder_set_metadata(encoder, metadataArray, metadata.Length()); delete [] metadataArray; } ex_FLAC__stream_encoder_set_channels(encoder, format.channels); ex_FLAC__stream_encoder_set_sample_rate(encoder, format.rate); ex_FLAC__stream_encoder_set_bits_per_sample(encoder, format.bits); if (config->GetIntValue(ConfigureFLAC::ConfigID, "Preset", 5) < 0) { const String &windowFunctions = config->GetStringValue(ConfigureFLAC::ConfigID, "Apodization", "tukey(0.5)"); ex_FLAC__stream_encoder_set_streamable_subset(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "StreamableSubset", 1)); ex_FLAC__stream_encoder_set_do_mid_side_stereo(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "DoMidSideStereo", 1)); ex_FLAC__stream_encoder_set_loose_mid_side_stereo(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "LooseMidSideStereo", 0)); ex_FLAC__stream_encoder_set_blocksize(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "Blocksize", 4096)); ex_FLAC__stream_encoder_set_max_lpc_order(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "MaxLPCOrder", 8)); ex_FLAC__stream_encoder_set_qlp_coeff_precision(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "QLPCoeffPrecision", 0)); ex_FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "DoQLPCoeffPrecSearch", 0)); ex_FLAC__stream_encoder_set_do_exhaustive_model_search(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "DoExhaustiveModelSearch", 0)); ex_FLAC__stream_encoder_set_min_residual_partition_order(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "MinResidualPartitionOrder", 0)); ex_FLAC__stream_encoder_set_max_residual_partition_order(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "MaxResidualPartitionOrder", 5)); if (windowFunctions != NIL) ex_FLAC__stream_encoder_set_apodization(encoder, windowFunctions); } else { ex_FLAC__stream_encoder_set_streamable_subset(encoder, true); ex_FLAC__stream_encoder_set_compression_level(encoder, config->GetIntValue(ConfigureFLAC::ConfigID, "Preset", 5)); if (config->GetIntValue(ConfigureFLAC::ConfigID, "Preset", 5) < 3) ex_FLAC__stream_encoder_set_blocksize(encoder, 1152); else ex_FLAC__stream_encoder_set_blocksize(encoder, 4096); } bytesWritten = 0; /* Set larger write buffer size. */ if (driver->IsBuffered()) driver->SetBufferSize(flacStreamEncoderBufferSize); /* Get number of threads to use. */ if (ex_FLAC__stream_encoder_set_num_threads != NIL) { Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; ex_FLAC__stream_encoder_set_num_threads(encoder, Math::Min(numberOfThreads, 128)); } /* Init encoder and check status. */ FLAC__StreamEncoderInitStatus status = FLAC__STREAM_ENCODER_INIT_STATUS_OK; if (config->GetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0) == 0 || *ex_FLAC_API_SUPPORTS_OGG_FLAC == 0) { status = ex_FLAC__stream_encoder_init_stream(encoder, &FLACStreamEncoderWriteCallback, &FLACStreamEncoderSeekCallback, &FLACStreamEncoderTellCallback, NIL, this); } else { ex_FLAC__stream_encoder_set_ogg_serial_number(encoder, Math::Random()); status = ex_FLAC__stream_encoder_init_ogg_stream(encoder, &FLACStreamEncoderReadCallback, &FLACStreamEncoderWriteCallback, &FLACStreamEncoderSeekCallback, &FLACStreamEncoderTellCallback, NIL, this); } if (status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { errorString = "Could not initialize FLAC encoder! Please check the configuration!"; errorState = True; ex_FLAC__stream_encoder_delete(encoder); return False; } return True; } Bool BoCA::EncoderFLAC::Deactivate() { /* Finish and free encoder. */ ex_FLAC__stream_encoder_finish(encoder); ex_FLAC__stream_encoder_delete(encoder); for (Int i = 0; i < metadata.Length(); i++) ex_FLAC__metadata_object_delete(metadata.GetNth(i)); /* Fix chapter marks in Vorbis Comments. */ if (config->GetIntValue("Tags", "EnableFLACMetadata", True) && track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { driver->Close(); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = NIL; if (config->GetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0) == 0 || *ex_FLAC_API_SUPPORTS_OGG_FLAC == 0) tagger = (AS::TaggerComponent *) boca.CreateComponentByID("flac-tag"); else tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->UpdateStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderFLAC::WriteData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); bytesWritten = 0; /* Convert samples to encoder input format. */ const Format &format = track.GetFormat(); buffer.Resize(data.Size() / (format.bits / 8)); for (Int i = 0; i < data.Size() / (format.bits / 8); i++) { if (format.bits == 8 ) buffer[i] = ((int8_t *) (UnsignedByte *) data)[i]; else if (format.bits == 16 ) buffer[i] = ((int16_t *) (UnsignedByte *) data)[i]; else if (format.bits == 24 && endianness == EndianLittle) buffer[i] = (data[3 * i + 2] << 24 | data[3 * i + 1] << 16 | data[3 * i ] << 8) / 256; else if (format.bits == 24 && endianness == EndianBig ) buffer[i] = (data[3 * i ] << 24 | data[3 * i + 1] << 16 | data[3 * i + 2] << 8) / 256; else if (format.bits == 32 ) buffer[i] = ((int32_t *) (UnsignedByte *) data)[i]; } ex_FLAC__stream_encoder_process_interleaved(encoder, buffer, data.Size() / (format.bits / 8) / format.channels); return bytesWritten; } Bool BoCA::EncoderFLAC::SetOutputFormat(Int n) { Config *config = Config::Get(); config->SetIntValue(ConfigureFLAC::ConfigID, "FileFormat", n); return True; } String BoCA::EncoderFLAC::GetOutputFileExtension() const { String extension = "flac"; if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 1) { Config *config = Config::Copy(GetConfiguration()); ConvertArguments(config); if (config->GetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0) == 1) extension = "oga"; Config::Free(config); } return extension; } Bool BoCA::EncoderFLAC::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "flac-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0); config->SetIntValue(ConfigureFLAC::ConfigID, "Preset", -1); config->SetIntValue(ConfigureFLAC::ConfigID, "DoMidSideStereo", False); config->SetIntValue(ConfigureFLAC::ConfigID, "DoExhaustiveModelSearch", False); config->SetIntValue(ConfigureFLAC::ConfigID, "DoQLPCoeffPrecSearch", False); config->SetIntValue(ConfigureFLAC::ConfigID, "Blocksize", 4096); config->SetIntValue(ConfigureFLAC::ConfigID, "MaxLPCOrder", 8); config->SetIntValue(ConfigureFLAC::ConfigID, "QLPCoeffPrecision", 0); config->SetIntValue(ConfigureFLAC::ConfigID, "MinResidualPartitionOrder", 0); config->SetIntValue(ConfigureFLAC::ConfigID, "MaxResidualPartitionOrder", 5); } /* Get command line settings. */ Bool midSideStereo = config->GetIntValue(encoderID, "Use mid-side stereo", config->GetIntValue(ConfigureFLAC::ConfigID, "DoMidSideStereo", False)); Bool exhaustiveSearch = config->GetIntValue(encoderID, "Do exhaustive model search", config->GetIntValue(ConfigureFLAC::ConfigID, "DoExhaustiveModelSearch", False)); Bool qlpCoeffSearch = config->GetIntValue(encoderID, "Do exhaustive QLP coefficient search", config->GetIntValue(ConfigureFLAC::ConfigID, "DoQLPCoeffPrecSearch", False)); String format = config->GetIntValue(ConfigureFLAC::ConfigID, "FileFormat", 0) == 0 ? "flac" : "ogg"; Int preset = config->GetIntValue(ConfigureFLAC::ConfigID, "Preset", -1); Int blocksize = config->GetIntValue(ConfigureFLAC::ConfigID, "Blocksize", 4096); Int lpc = config->GetIntValue(ConfigureFLAC::ConfigID, "MaxLPCOrder", 8); Int qlp = config->GetIntValue(ConfigureFLAC::ConfigID, "QLPCoeffPrecision", 0); Int rice = config->GetIntValue(ConfigureFLAC::ConfigID, "MaxResidualPartitionOrder", 5); if (config->GetIntValue(encoderID, "Set Format", False)) format = config->GetStringValue(encoderID, "Format", format).ToLower(); if (config->GetIntValue(encoderID, "Set Compression level", False)) preset = config->GetIntValue(encoderID, "Compression level", preset); if (config->GetIntValue(encoderID, "Set Block size", False)) blocksize = config->GetIntValue(encoderID, "Block size", blocksize); if (config->GetIntValue(encoderID, "Set Max LPC order", False)) lpc = config->GetIntValue(encoderID, "Max LPC order", lpc); if (config->GetIntValue(encoderID, "Set QLP coefficient precision", False)) qlp = config->GetIntValue(encoderID, "QLP coefficient precision", qlp); if (config->GetIntValue(encoderID, "Set Maximum rice partition order", False)) rice = config->GetIntValue(encoderID, "Maximum rice partition order", rice); /* Set configuration values. */ config->SetIntValue(ConfigureFLAC::ConfigID, "FileFormat", format == "ogg"); config->SetIntValue(ConfigureFLAC::ConfigID, "Preset", preset); config->SetIntValue(ConfigureFLAC::ConfigID, "DoMidSideStereo", midSideStereo); config->SetIntValue(ConfigureFLAC::ConfigID, "DoExhaustiveModelSearch", exhaustiveSearch); config->SetIntValue(ConfigureFLAC::ConfigID, "DoQLPCoeffPrecSearch", qlpCoeffSearch); config->SetIntValue(ConfigureFLAC::ConfigID, "Blocksize", Math::Max(192, Math::Min(32768, blocksize))); config->SetIntValue(ConfigureFLAC::ConfigID, "MaxLPCOrder", Math::Max(0, Math::Min(FLAC__MAX_LPC_ORDER, lpc))); config->SetIntValue(ConfigureFLAC::ConfigID, "QLPCoeffPrecision", qlp == 0 ? 0 : Math::Max(FLAC__MIN_QLP_COEFF_PRECISION, Math::Min(FLAC__MAX_QLP_COEFF_PRECISION, qlp))); config->SetIntValue(ConfigureFLAC::ConfigID, "MaxResidualPartitionOrder", Math::Max(0, Math::Min(FLAC__MAX_RICE_PARTITION_ORDER, rice))); return True; } ConfigLayer *BoCA::EncoderFLAC::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureFLAC(); return configLayer; } FLAC__StreamEncoderReadStatus BoCA::FLACStreamEncoderReadCallback(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { EncoderFLAC *filter = (EncoderFLAC *) client_data; *bytes = filter->driver->ReadData((UnsignedByte *) buffer, *bytes); return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; } FLAC__StreamEncoderWriteStatus BoCA::FLACStreamEncoderWriteCallback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data) { EncoderFLAC *filter = (EncoderFLAC *) client_data; filter->driver->WriteData((UnsignedByte *) buffer, bytes); filter->bytesWritten += bytes; return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } FLAC__StreamEncoderSeekStatus BoCA::FLACStreamEncoderSeekCallback(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) { EncoderFLAC *filter = (EncoderFLAC *) client_data; filter->driver->Seek(absolute_byte_offset); return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; } FLAC__StreamEncoderTellStatus BoCA::FLACStreamEncoderTellCallback(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { EncoderFLAC *filter = (EncoderFLAC *) client_data; *absolute_byte_offset = filter->driver->GetPos(); return FLAC__STREAM_ENCODER_TELL_STATUS_OK; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/flac/flac.h000066400000000000000000000036361516712004000237630ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderFLAC) namespace BoCA { class EncoderFLAC : public CS::EncoderComponent { friend FLAC__StreamEncoderReadStatus FLACStreamEncoderReadCallback(const FLAC__StreamEncoder *, FLAC__byte[], size_t *, void *); friend FLAC__StreamEncoderWriteStatus FLACStreamEncoderWriteCallback(const FLAC__StreamEncoder *, const FLAC__byte[], size_t, uint32_t, uint32_t, void *); friend FLAC__StreamEncoderSeekStatus FLACStreamEncoderSeekCallback(const FLAC__StreamEncoder *, FLAC__uint64, void *); friend FLAC__StreamEncoderTellStatus FLACStreamEncoderTellCallback(const FLAC__StreamEncoder *, FLAC__uint64 *, void *); private: ConfigLayer *configLayer; Config *config; FLAC__StreamEncoder *encoder; Array metadata; Buffer buffer; Int bytesWritten; static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderFLAC(); ~EncoderFLAC(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderFLAC) BoCA_END_COMPONENT(EncoderFLAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/000077500000000000000000000000001516712004000227065ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/Makefile000077500000000000000000000012621516712004000243520ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = lame TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o framecrc.o lame.o repacker.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/config.cpp000077500000000000000000001225211516712004000246650ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "lame/lame.h" const String BoCA::ConfigureLAME::ConfigID = "LAME"; BoCA::ConfigureLAME::ConfigureLAME() { const Config *config = Config::Get(); preset = config->GetIntValue(ConfigID, "Preset", 2); set_bitrate = config->GetIntValue(ConfigID, "SetBitrate", 1); bitrate = GetSliderValue(); ratio = config->GetIntValue(ConfigID, "Ratio", 1100); set_quality = config->GetIntValue(ConfigID, "SetQuality", 0); quality = 9 - config->GetIntValue(ConfigID, "Quality", 3); forcejs = config->GetIntValue(ConfigID, "ForceJS", 0); vbrmode = config->GetIntValue(ConfigID, "VBRMode", 4); vbrquality = 99 - config->GetIntValue(ConfigID, "VBRQuality", 50); abrbitrate = config->GetIntValue(ConfigID, "ABRBitrate", 192); set_min_vbr_brate = config->GetIntValue(ConfigID, "SetMinVBRBitrate", 0); min_vbr_brate = GetMinVBRSliderValue(); set_max_vbr_brate = config->GetIntValue(ConfigID, "SetMaxVBRBitrate", 0); max_vbr_brate = GetMaxVBRSliderValue(); set_original = config->GetIntValue(ConfigID, "Original", 1); set_copyright = config->GetIntValue(ConfigID, "Copyright", 0); set_private = config->GetIntValue(ConfigID, "Private", 0); set_crc = config->GetIntValue(ConfigID, "CRC", 0); set_iso = config->GetIntValue(ConfigID, "StrictISO", 0); disable_filtering = config->GetIntValue(ConfigID, "DisableFiltering", 0); set_lowpass = config->GetIntValue(ConfigID, "SetLowpass", 0); set_lowpass_width = config->GetIntValue(ConfigID, "SetLowpassWidth", 0); set_highpass = config->GetIntValue(ConfigID, "SetHighpass", 0); set_highpass_width = config->GetIntValue(ConfigID, "SetHighpassWidth", 0); enable_ath = config->GetIntValue(ConfigID, "EnableATH", 1); enable_tns = config->GetIntValue(ConfigID, "UseTNS", 1); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::LAME"); Int kbpsLabelWidth = Font().GetUnscaledTextSizeX(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", "256")); register_layer_basic = new Layer(i18n->TranslateString("Basic")); register_layer_misc = new Layer(i18n->TranslateString("Misc")); register_layer_expert = new Layer(i18n->TranslateString("Expert")); register_layer_filtering = new Layer(i18n->TranslateString("Audio processing")); i18n->SetContext("Encoders::LAME::Basic"); reg_register = new TabWidget(Point(7, 7), Size(433, 218)); basic_preset = new GroupBox(i18n->TranslateString("Presets"), Point(7, 11), Size(415, 39)); basic_text_preset = new Text(i18n->AddColon(i18n->TranslateString("Use preset")), Point(9, 13)); basic_combo_preset = new ComboBox(Point(17 + basic_text_preset->GetUnscaledTextWidth(), 10), Size(388 - basic_text_preset->GetUnscaledTextWidth(), 0)); basic_combo_preset->AddEntry(i18n->TranslateString("Custom settings")); basic_combo_preset->AddEntry(i18n->TranslateString("Medium")); basic_combo_preset->AddEntry(i18n->TranslateString("Standard")); basic_combo_preset->AddEntry(i18n->TranslateString("Extreme")); basic_combo_preset->AddEntry("ABR"); basic_combo_preset->SelectNthEntry(preset); basic_combo_preset->onSelectEntry.Connect(&ConfigureLAME::SetPreset, this); basic_preset->Add(basic_text_preset); basic_preset->Add(basic_combo_preset); basic_bitrate = new GroupBox(i18n->TranslateString("Bitrate"), Point(142, 62), Size(280, 63)); basic_option_set_bitrate = new OptionBox(i18n->AddColon(i18n->TranslateString("Set bitrate")), Point(10, 11), Size(90, 0), &set_bitrate, 1); basic_option_set_bitrate->onAction.Connect(&ConfigureLAME::SetBitrateOption, this); basic_option_set_ratio = new OptionBox(i18n->AddColon(i18n->TranslateString("Set ratio")), Point(10, 36), Size(90, 0), &set_bitrate, 0); basic_option_set_ratio->onAction.Connect(&ConfigureLAME::SetBitrateOption, this); basic_option_set_bitrate->SetWidth(Math::Max(basic_option_set_bitrate->GetUnscaledTextWidth(), basic_option_set_ratio->GetUnscaledTextWidth()) + 21); basic_option_set_ratio->SetWidth(Math::Max(basic_option_set_bitrate->GetUnscaledTextWidth(), basic_option_set_ratio->GetUnscaledTextWidth()) + 21); basic_slider_bitrate = new Slider(Point(18 + basic_option_set_bitrate->GetWidth(), 11), Size(200 - basic_option_set_bitrate->GetWidth(), 0), OR_HORZ, &bitrate, 0, 17); basic_slider_bitrate->onValueChange.Connect(&ConfigureLAME::SetBitrate, this); basic_text_bitrate = new Text(NIL, Point(kbpsLabelWidth + 10, 13)); basic_text_bitrate->SetOrientation(OR_UPPERRIGHT); SetBitrate(); basic_text_ratio = new Text(i18n->IsActiveLanguageRightToLeft() ? ": 1" : "1 :", Point(18 + basic_option_set_bitrate->GetWidth(), 38)); basic_edit_ratio = new EditBox(String::FromFloat(((double) ratio) / 100), Point(basic_text_ratio->GetX() + 16, 35), Size(19, 0), 2); basic_edit_ratio->SetFlags(EDB_NUMERIC); basic_bitrate->Add(basic_option_set_bitrate); basic_bitrate->Add(basic_option_set_ratio); basic_bitrate->Add(basic_slider_bitrate); basic_bitrate->Add(basic_text_bitrate); basic_bitrate->Add(basic_text_ratio); basic_bitrate->Add(basic_edit_ratio); basic_quality = new GroupBox(i18n->TranslateString("Quality"), Point(142, 137), Size(280, 51)); basic_check_set_quality = new CheckBox(i18n->AddColon(i18n->TranslateString("Set quality")), Point(10, 11), Size(90, 0), &set_quality); basic_check_set_quality->SetWidth(basic_check_set_quality->GetUnscaledTextWidth() + 21); basic_check_set_quality->onAction.Connect(&ConfigureLAME::SetQualityOption, this); basic_slider_quality = new Slider(Point(18 + basic_check_set_quality->GetWidth(), 11), Size(238 - basic_check_set_quality->GetWidth(), 0), OR_HORZ, &quality, 0, 9); basic_slider_quality->onValueChange.Connect(&ConfigureLAME::SetQuality, this); basic_text_quality = new Text(NIL, Point(16, 13)); basic_text_quality->SetOrientation(OR_UPPERRIGHT); SetQuality(); basic_text_quality_worse = new Text(i18n->TranslateString("worse"), Point()); basic_text_quality_worse->SetPosition(Point(basic_slider_quality->GetX() + 3 - (basic_text_quality_worse->GetUnscaledTextWidth() / 2), 30)); basic_text_quality_better = new Text(i18n->TranslateString("better"), Point()); basic_text_quality_better->SetOrientation(OR_UPPERRIGHT); basic_text_quality_better->SetPosition(Point(29 + (basic_text_quality_better->GetUnscaledTextWidth() / 2), 30)); basic_quality->Add(basic_check_set_quality); basic_quality->Add(basic_slider_quality); basic_quality->Add(basic_text_quality); basic_quality->Add(basic_text_quality_worse); basic_quality->Add(basic_text_quality_better); vbr_vbrmode = new GroupBox(i18n->TranslateString("VBR mode"), Point(7, 62), Size(127, 88)); vbr_option_vbrmtrh = new OptionBox("VBR", Point(10, 11), Size(107, 0), &vbrmode, vbr_mtrh); vbr_option_vbrmtrh->onAction.Connect(&ConfigureLAME::SetVBRMode, this); vbr_option_abr = new OptionBox("ABR", Point(10, 36), Size(107, 0), &vbrmode, vbr_abr); vbr_option_abr->onAction.Connect(&ConfigureLAME::SetVBRMode, this); vbr_option_cbr = new OptionBox(String("CBR (").Append(i18n->TranslateString("no VBR")).Append(")"), Point(10, 61), Size(107, 0), &vbrmode, vbr_off); vbr_option_cbr->onAction.Connect(&ConfigureLAME::SetVBRMode, this); vbr_vbrmode->Add(vbr_option_cbr); vbr_vbrmode->Add(vbr_option_abr); vbr_vbrmode->Add(vbr_option_vbrmtrh); vbr_quality = new GroupBox(i18n->TranslateString("VBR quality"), Point(142, 62), Size(280, 51)); vbr_text_setquality = new Text(i18n->AddColon(i18n->TranslateString("Quality")), Point(11, 13)); vbr_slider_quality = new Slider(Point(18 + vbr_text_setquality->GetUnscaledTextWidth(), 11), Size(229 - vbr_text_setquality->GetUnscaledTextWidth(), 0), OR_HORZ, &vbrquality, 0, 99); vbr_slider_quality->onValueChange.Connect(&ConfigureLAME::SetVBRQuality, this); vbr_text_quality = new Text(NIL, Point(25, 13)); vbr_text_quality->SetOrientation(OR_UPPERRIGHT); vbr_text_quality_worse = new Text(i18n->TranslateString("worse"), Point()); vbr_text_quality_worse->SetPosition(Point(vbr_slider_quality->GetX() + 3 - (vbr_text_quality_worse->GetUnscaledTextWidth() / 2), 30)); vbr_text_quality_better = new Text(i18n->TranslateString("better"), Point()); vbr_text_quality_better->SetOrientation(OR_UPPERRIGHT); vbr_text_quality_better->SetPosition(Point(38 + (vbr_text_quality_better->GetUnscaledTextWidth() / 2), 30)); SetVBRQuality(); vbr_quality->Add(vbr_text_setquality); vbr_quality->Add(vbr_slider_quality); vbr_quality->Add(vbr_text_quality); vbr_quality->Add(vbr_text_quality_worse); vbr_quality->Add(vbr_text_quality_better); vbr_abrbitrate = new GroupBox(i18n->TranslateString("ABR target bitrate"), Point(142, 62), Size(280, 39)); vbr_slider_abrbitrate = new Slider(Point(10, 11), Size(194, 0), OR_HORZ, &abrbitrate, 8, 320); vbr_slider_abrbitrate->onValueChange.Connect(&ConfigureLAME::SetABRBitrate, this); vbr_text_abrbitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 13)); vbr_text_abrbitrate_kbps->SetX(vbr_text_abrbitrate_kbps->GetUnscaledTextWidth() + 10); vbr_text_abrbitrate_kbps->SetOrientation(OR_UPPERRIGHT); vbr_edit_abrbitrate = new EditBox(Point(vbr_text_abrbitrate_kbps->GetX() + 33, 10), Size(25, 0), 3); vbr_edit_abrbitrate->SetFlags(EDB_NUMERIC); vbr_edit_abrbitrate->SetOrientation(OR_UPPERRIGHT); vbr_edit_abrbitrate->onInput.Connect(&ConfigureLAME::SetABRBitrateByEditBox, this); SetABRBitrate(); vbr_abrbitrate->Add(vbr_slider_abrbitrate); vbr_abrbitrate->Add(vbr_edit_abrbitrate); vbr_abrbitrate->Add(vbr_text_abrbitrate_kbps); i18n->SetContext("Encoders::LAME::Misc"); misc_bits = new GroupBox(i18n->TranslateString("Control bits"), Point(7, 11), Size(138, 90)); misc_check_copyright = new CheckBox(i18n->TranslateString("Set Copyright bit"), Point(10, 11), Size(118, 0), &set_copyright); misc_check_original = new CheckBox(i18n->TranslateString("Set Original bit"), Point(10, 36), Size(118, 0), &set_original); misc_check_private = new CheckBox(i18n->TranslateString("Set Private bit"), Point(10, 61), Size(118, 0), &set_private); Int maxTextSize = Math::Max(Math::Max(misc_check_copyright->GetUnscaledTextWidth(), misc_check_original->GetUnscaledTextWidth()), misc_check_private->GetUnscaledTextWidth()); misc_check_copyright->SetWidth(Math::Max(118, maxTextSize + 21)); misc_check_original->SetWidth(misc_check_copyright->GetWidth()); misc_check_private->SetWidth(misc_check_copyright->GetWidth()); misc_bits->SetWidth(misc_check_copyright->GetWidth() + 20); misc_bits->Add(misc_check_original); misc_bits->Add(misc_check_copyright); misc_bits->Add(misc_check_private); misc_crc = new GroupBox(i18n->TranslateString("CRC"), Point(misc_bits->GetWidth() + 15, 62), Size(269, 39)); misc_check_crc = new CheckBox(i18n->TranslateString("Enable CRC"), Point(10, 11), Size(249, 0), &set_crc); misc_crc->Add(misc_check_crc); misc_stereomode = new GroupBox(i18n->TranslateString("Stereo mode"), Point(misc_bits->GetWidth() + 15, 11), Size(269, 39)); misc_combo_stereomode = new ComboBox(Point(10, 10), Size(120, 0)); misc_combo_stereomode->AddEntry(i18n->TranslateString("auto")); misc_combo_stereomode->AddEntry(i18n->TranslateString("Mono")); misc_combo_stereomode->AddEntry(i18n->TranslateString("Stereo")); misc_combo_stereomode->AddEntry(i18n->TranslateString("Joint Stereo")); misc_combo_stereomode->SelectNthEntry(config->GetIntValue(ConfigID, "StereoMode", 0)); misc_combo_stereomode->onSelectEntry.Connect(&ConfigureLAME::SetStereoMode, this); misc_check_forcejs = new CheckBox(i18n->TranslateString("Force Joint Stereo"), Point(137, 11), Size(122, 0), &forcejs); misc_stereomode->Add(misc_combo_stereomode); misc_stereomode->Add(misc_check_forcejs); misc_bitrate = new GroupBox(i18n->TranslateString("VBR/ABR bitrate range"), Point(7, 113), Size(misc_bits->GetWidth() + misc_stereomode->GetWidth() + 8, 63)); misc_check_set_min_brate = new CheckBox(i18n->AddColon(i18n->TranslateString("Set minimum VBR/ABR bitrate")), Point(10, 11), Size(176, 0), &set_min_vbr_brate); misc_check_set_min_brate->onAction.Connect(&ConfigureLAME::SetMinVBRBitrateOption, this); misc_check_set_max_brate = new CheckBox(i18n->AddColon(i18n->TranslateString("Set maximum VBR/ABR bitrate")), Point(10, 36), Size(176, 0), &set_max_vbr_brate); misc_check_set_max_brate->onAction.Connect(&ConfigureLAME::SetMaxVBRBitrateOption, this); misc_check_set_min_brate->SetWidth(Math::Max(misc_check_set_min_brate->GetUnscaledTextWidth(), misc_check_set_max_brate->GetUnscaledTextWidth()) + 21); misc_check_set_max_brate->SetWidth(Math::Max(misc_check_set_min_brate->GetUnscaledTextWidth(), misc_check_set_max_brate->GetUnscaledTextWidth()) + 21); misc_slider_min_brate = new Slider(Point(18 + misc_check_set_min_brate->GetWidth(), 11), Size(misc_bitrate->GetWidth() - 83 - misc_check_set_min_brate->GetWidth(), 0), OR_HORZ, &min_vbr_brate, 0, 17); misc_slider_min_brate->onValueChange.Connect(&ConfigureLAME::SetMinVBRBitrate, this); misc_text_min_brate_kbps = new Text(NIL, Point(kbpsLabelWidth + 10, 13)); misc_text_min_brate_kbps->SetOrientation(OR_UPPERRIGHT); misc_slider_max_brate = new Slider(Point(18 + misc_check_set_min_brate->GetWidth(), 36), Size(misc_bitrate->GetWidth() - 83 - misc_check_set_min_brate->GetWidth(), 0), OR_HORZ, &max_vbr_brate, 0, 17); misc_slider_max_brate->onValueChange.Connect(&ConfigureLAME::SetMaxVBRBitrate, this); misc_text_max_brate_kbps = new Text(NIL, Point(kbpsLabelWidth + 10, 38)); misc_text_max_brate_kbps->SetOrientation(OR_UPPERRIGHT); SetMinVBRBitrate(); SetMaxVBRBitrate(); SetVBRMode(); misc_bitrate->Add(misc_check_set_min_brate); misc_bitrate->Add(misc_check_set_max_brate); misc_bitrate->Add(misc_slider_min_brate); misc_bitrate->Add(misc_slider_max_brate); misc_bitrate->Add(misc_text_min_brate_kbps); misc_bitrate->Add(misc_text_max_brate_kbps); i18n->SetContext("Encoders::LAME::Expert"); expert_ath = new GroupBox(i18n->TranslateString("ATH"), Point(7, 11), Size(415, 39)); expert_check_ath = new CheckBox(i18n->AddColon(i18n->TranslateString("Enable ATH")), Point(10, 11), Size(93, 0), &enable_ath); expert_check_ath->onAction.Connect(&ConfigureLAME::SetEnableATH, this); expert_check_ath->SetWidth(expert_check_ath->GetUnscaledTextWidth() + 19); expert_combo_athtype = new ComboBox(Point(38 + expert_check_ath->GetUnscaledTextWidth(), 10), Size(367 - expert_check_ath->GetUnscaledTextWidth(), 0)); expert_combo_athtype->AddEntry(i18n->TranslateString("Use default setting")); expert_combo_athtype->AddEntry("Gabriel Bouvigne, 9"); expert_combo_athtype->AddEntry("Frank Klemm"); expert_combo_athtype->AddEntry("Gabriel Bouvigne, 0"); expert_combo_athtype->AddEntry("Roel Van Den Berghe"); expert_combo_athtype->AddEntry("Gabriel Bouvigne VBR"); expert_combo_athtype->AddEntry("John Dahlstrom"); expert_combo_athtype->SelectNthEntry(config->GetIntValue(ConfigID, "ATHType", -1) + 1); if (!enable_ath) expert_combo_athtype->Deactivate(); expert_ath->Add(expert_check_ath); expert_ath->Add(expert_combo_athtype); expert_psycho = new GroupBox(i18n->TranslateString("Psycho acoustic model"), Point(7, 62), Size(415, 39)); expert_check_tns = new CheckBox(i18n->AddColon(i18n->TranslateString("Use Temporal Masking Effect")), Point(10, 11), Size(394, 0), &enable_tns); expert_check_tns->onAction.Connect(&ConfigureLAME::SetEnableTNS, this); expert_check_tns->SetWidth(expert_check_tns->GetUnscaledTextWidth() + 19); expert_combo_tnsmode = new ComboBox(Point(38 + expert_check_tns->GetUnscaledTextWidth(), 10), Size(367 - expert_check_tns->GetUnscaledTextWidth(), 0)); expert_combo_tnsmode->AddEntry(i18n->TranslateString("automatic")); expert_combo_tnsmode->AddEntry(i18n->TranslateString("always")); expert_combo_tnsmode->SelectNthEntry(config->GetIntValue(ConfigID, "TNSMode", -1) + 1); if (!enable_tns) expert_combo_tnsmode->Deactivate(); expert_psycho->Add(expert_check_tns); expert_psycho->Add(expert_combo_tnsmode); expert_format = new GroupBox(i18n->TranslateString("Stream format"), Point(7, 113), Size(415, 39)); expert_check_iso = new CheckBox(i18n->TranslateString("Enforce strict ISO compliance"), Point(10, 11), Size(394, 0), &set_iso); expert_format->Add(expert_check_iso); i18n->SetContext("Encoders::LAME::Audio processing"); filtering_highpass = new GroupBox(i18n->TranslateString("Highpass filter"), Point(7, 11), Size(246, 64)); filtering_set_highpass = new CheckBox(i18n->AddColon(i18n->TranslateString("Set Highpass frequency (Hz)")), Point(10, 11), Size(180, 0), &set_highpass); filtering_set_highpass->onAction.Connect(&ConfigureLAME::SetHighpass, this); filtering_edit_highpass = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "Highpass", 0)), Point(199, 10), Size(37, 0), 5); filtering_edit_highpass->SetFlags(EDB_NUMERIC); filtering_set_highpass_width = new CheckBox(i18n->AddColon(i18n->TranslateString("Set Highpass width (Hz)")), Point(10, 36), Size(180, 0), &set_highpass_width); filtering_set_highpass_width->onAction.Connect(&ConfigureLAME::SetHighpassWidth, this); filtering_edit_highpass_width = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "HighpassWidth", 0)), Point(199, 35), Size(37, 0), 5); filtering_edit_highpass_width->SetFlags(EDB_NUMERIC); filtering_highpass->Add(filtering_set_highpass); filtering_highpass->Add(filtering_edit_highpass); filtering_highpass->Add(filtering_set_highpass_width); filtering_highpass->Add(filtering_edit_highpass_width); filtering_lowpass = new GroupBox(i18n->TranslateString("Lowpass filter"), Point(7, 87), Size(246, 64)); filtering_set_lowpass = new CheckBox(i18n->AddColon(i18n->TranslateString("Set Lowpass frequency (Hz)")), Point(10, 11), Size(180, 0), &set_lowpass); filtering_set_lowpass->onAction.Connect(&ConfigureLAME::SetLowpass, this); filtering_edit_lowpass = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "Lowpass", 0)), Point(199, 10), Size(37, 0), 5); filtering_edit_lowpass->SetFlags(EDB_NUMERIC); filtering_set_lowpass_width = new CheckBox(i18n->AddColon(i18n->TranslateString("Set Lowpass width (Hz)")), Point(10, 36), Size(180, 0), &set_lowpass_width); filtering_set_lowpass_width->onAction.Connect(&ConfigureLAME::SetLowpassWidth, this); filtering_edit_lowpass_width = new EditBox(String::FromInt(config->GetIntValue(ConfigID, "LowpassWidth", 0)), Point(199, 35), Size(37, 0), 5); filtering_edit_lowpass_width->SetFlags(EDB_NUMERIC); filtering_lowpass->Add(filtering_set_lowpass); filtering_lowpass->Add(filtering_edit_lowpass); filtering_lowpass->Add(filtering_set_lowpass_width); filtering_lowpass->Add(filtering_edit_lowpass_width); filtering_misc = new GroupBox(i18n->TranslateString("Misc settings"), Point(261, 11), Size(161, 39)); filtering_check_disable_all = new CheckBox(i18n->TranslateString("Disable all filtering"), Point(10, 11), Size(140, 0), &disable_filtering); filtering_check_disable_all->onAction.Connect(&ConfigureLAME::SetDisableFiltering, this); filtering_check_disable_all->SetWidth(Math::Max(140, filtering_check_disable_all->GetUnscaledTextWidth() + 21)); filtering_misc->SetWidth(filtering_check_disable_all->GetWidth() + 20); filtering_misc->Add(filtering_check_disable_all); SetPreset(); /* Adjust element widths. */ reg_register->SetWidth(Math::Max(Math::Max(433, misc_bitrate->GetWidth() + 18), filtering_highpass->GetWidth() + filtering_misc->GetWidth() + 26)); basic_preset->SetWidth(reg_register->GetWidth() - 18); basic_combo_preset->SetWidth(basic_preset->GetWidth() - basic_combo_preset->GetX() - 10); basic_bitrate->SetWidth(reg_register->GetWidth() - vbr_vbrmode->GetWidth() - 26); basic_quality->SetWidth(basic_bitrate->GetWidth()); vbr_quality->SetWidth(basic_bitrate->GetWidth()); vbr_abrbitrate->SetWidth(basic_bitrate->GetWidth()); basic_slider_bitrate->SetWidth(basic_bitrate->GetWidth() - basic_slider_bitrate->GetX() - basic_text_bitrate->GetX() - 8); basic_slider_quality->SetWidth(basic_quality->GetWidth() - basic_slider_quality->GetX() - 24); vbr_slider_quality->SetWidth(vbr_quality->GetWidth() - vbr_slider_quality->GetX() - 33); vbr_slider_abrbitrate->SetWidth(vbr_abrbitrate->GetWidth() - vbr_edit_abrbitrate->GetX() - 18); misc_crc->SetWidth(reg_register->GetWidth() - misc_bits->GetWidth() - 26); misc_stereomode->SetWidth(misc_crc->GetWidth()); misc_check_crc->SetWidth(misc_crc->GetWidth() - 20); misc_check_forcejs->SetWidth(misc_stereomode->GetWidth() - misc_check_forcejs->GetX() - 10); misc_bitrate->SetWidth(reg_register->GetWidth() - 18); misc_slider_min_brate->SetWidth(reg_register->GetWidth() - misc_slider_min_brate->GetX() - misc_text_min_brate_kbps->GetX() - 26); misc_slider_max_brate->SetWidth(misc_slider_min_brate->GetWidth()); expert_ath->SetWidth(reg_register->GetWidth() - 18); expert_psycho->SetWidth(expert_ath->GetWidth()); expert_format->SetWidth(expert_ath->GetWidth()); expert_combo_athtype->SetWidth(expert_ath->GetWidth() - expert_combo_athtype->GetX() - 10); expert_combo_tnsmode->SetWidth(expert_ath->GetWidth() - expert_combo_tnsmode->GetX() - 10); expert_check_iso->SetWidth(expert_format->GetWidth() - 20); filtering_misc->SetWidth(reg_register->GetWidth() - filtering_highpass->GetWidth() - 26); filtering_check_disable_all->SetWidth(filtering_misc->GetWidth() - 20); /* Add groups to layers. */ Add(reg_register); reg_register->Add(register_layer_basic); reg_register->Add(register_layer_misc); reg_register->Add(register_layer_expert); reg_register->Add(register_layer_filtering); register_layer_basic->Add(basic_preset); register_layer_basic->Add(basic_bitrate); register_layer_basic->Add(basic_quality); register_layer_basic->Add(vbr_vbrmode); register_layer_basic->Add(vbr_quality); register_layer_basic->Add(vbr_abrbitrate); register_layer_misc->Add(misc_bits); register_layer_misc->Add(misc_crc); register_layer_misc->Add(misc_stereomode); register_layer_misc->Add(misc_bitrate); register_layer_expert->Add(expert_ath); register_layer_expert->Add(expert_psycho); register_layer_expert->Add(expert_format); register_layer_filtering->Add(filtering_lowpass); register_layer_filtering->Add(filtering_highpass); register_layer_filtering->Add(filtering_misc); SetSize(Size(reg_register->GetWidth() + 14, 232)); } BoCA::ConfigureLAME::~ConfigureLAME() { DeleteObject(reg_register); DeleteObject(register_layer_basic); DeleteObject(register_layer_misc); DeleteObject(register_layer_expert); DeleteObject(register_layer_filtering); DeleteObject(basic_preset); DeleteObject(basic_text_preset); DeleteObject(basic_combo_preset); DeleteObject(basic_bitrate); DeleteObject(basic_option_set_bitrate); DeleteObject(basic_option_set_ratio); DeleteObject(basic_slider_bitrate); DeleteObject(basic_text_bitrate); DeleteObject(basic_text_ratio); DeleteObject(basic_edit_ratio); DeleteObject(basic_quality); DeleteObject(basic_check_set_quality); DeleteObject(basic_slider_quality); DeleteObject(basic_text_quality); DeleteObject(basic_text_quality_worse); DeleteObject(basic_text_quality_better); DeleteObject(vbr_vbrmode); DeleteObject(vbr_option_cbr); DeleteObject(vbr_option_abr); DeleteObject(vbr_option_vbrmtrh); DeleteObject(vbr_quality); DeleteObject(vbr_text_setquality); DeleteObject(vbr_slider_quality); DeleteObject(vbr_text_quality); DeleteObject(vbr_text_quality_worse); DeleteObject(vbr_text_quality_better); DeleteObject(vbr_abrbitrate); DeleteObject(vbr_slider_abrbitrate); DeleteObject(vbr_edit_abrbitrate); DeleteObject(vbr_text_abrbitrate_kbps); DeleteObject(misc_bits); DeleteObject(misc_check_original); DeleteObject(misc_check_copyright); DeleteObject(misc_check_private); DeleteObject(misc_crc); DeleteObject(misc_check_crc); DeleteObject(misc_stereomode); DeleteObject(misc_combo_stereomode); DeleteObject(misc_check_forcejs); DeleteObject(misc_bitrate); DeleteObject(misc_check_set_min_brate); DeleteObject(misc_check_set_max_brate); DeleteObject(misc_slider_min_brate); DeleteObject(misc_slider_max_brate); DeleteObject(misc_text_min_brate_kbps); DeleteObject(misc_text_max_brate_kbps); DeleteObject(expert_ath); DeleteObject(expert_check_ath); DeleteObject(expert_combo_athtype); DeleteObject(expert_psycho); DeleteObject(expert_check_tns); DeleteObject(expert_combo_tnsmode); DeleteObject(expert_format); DeleteObject(expert_check_iso); DeleteObject(filtering_lowpass); DeleteObject(filtering_set_lowpass); DeleteObject(filtering_edit_lowpass); DeleteObject(filtering_set_lowpass_width); DeleteObject(filtering_edit_lowpass_width); DeleteObject(filtering_highpass); DeleteObject(filtering_set_highpass); DeleteObject(filtering_edit_highpass); DeleteObject(filtering_set_highpass_width); DeleteObject(filtering_edit_highpass_width); DeleteObject(filtering_misc); DeleteObject(filtering_check_disable_all); } Int BoCA::ConfigureLAME::SaveSettings() { Config *config = Config::Get(); if (abrbitrate < 8) abrbitrate = 8; if (abrbitrate > 320) abrbitrate = 320; if (set_lowpass && filtering_edit_lowpass->GetText().Length() == 0) { Utilities::ErrorMessage("Please enter a frequency for the Lowpass filter!"); return Error(); } if (set_lowpass && set_lowpass_width && filtering_edit_lowpass_width->GetText().Length() == 0) { Utilities::ErrorMessage("Please enter a frequency for the Lowpass filter width!"); return Error(); } if (set_highpass && filtering_edit_highpass->GetText().Length() == 0) { Utilities::ErrorMessage("Please enter a frequency for the Highpass filter!"); return Error(); } if (set_highpass && set_highpass_width && filtering_edit_highpass_width->GetText().Length() == 0) { Utilities::ErrorMessage("Please enter a frequency for the Highpass filter width!"); return Error(); } if (set_highpass && set_lowpass && filtering_edit_lowpass->GetText().ToInt() != 0 && filtering_edit_highpass->GetText().ToInt() != 0 && (filtering_edit_lowpass->GetText().ToInt() < filtering_edit_highpass->GetText().ToInt())) { Utilities::ErrorMessage("Lowpass frequency is lower than Highpass frequency!"); return Error(); } config->SetIntValue(ConfigID, "Preset", preset); config->SetIntValue(ConfigID, "SetBitrate", set_bitrate); config->SetIntValue(ConfigID, "Bitrate", GetBitrate()); config->SetIntValue(ConfigID, "Ratio", (int) (basic_edit_ratio->GetText().ToFloat() * 100)); config->SetIntValue(ConfigID, "SetQuality", set_quality); config->SetIntValue(ConfigID, "Quality", 9 - quality); config->SetIntValue(ConfigID, "StereoMode", misc_combo_stereomode->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "ForceJS", forcejs); config->SetIntValue(ConfigID, "VBRMode", vbrmode); config->SetIntValue(ConfigID, "VBRQuality", 99 - vbrquality); config->SetIntValue(ConfigID, "ABRBitrate", abrbitrate); config->SetIntValue(ConfigID, "SetMinVBRBitrate", set_min_vbr_brate); config->SetIntValue(ConfigID, "MinVBRBitrate", GetMinVBRBitrate()); config->SetIntValue(ConfigID, "SetMaxVBRBitrate", set_max_vbr_brate); config->SetIntValue(ConfigID, "MaxVBRBitrate", GetMaxVBRBitrate()); config->SetIntValue(ConfigID, "CRC", set_crc); config->SetIntValue(ConfigID, "Copyright", set_copyright); config->SetIntValue(ConfigID, "Original", set_original); config->SetIntValue(ConfigID, "Private", set_private); config->SetIntValue(ConfigID, "StrictISO", set_iso); config->SetIntValue(ConfigID, "DisableFiltering", disable_filtering); config->SetIntValue(ConfigID, "SetLowpass", set_lowpass); config->SetIntValue(ConfigID, "Lowpass", filtering_edit_lowpass->GetText().ToInt()); config->SetIntValue(ConfigID, "SetLowpassWidth", set_lowpass_width); config->SetIntValue(ConfigID, "LowpassWidth", filtering_edit_lowpass_width->GetText().ToInt()); config->SetIntValue(ConfigID, "SetHighpass", set_highpass); config->SetIntValue(ConfigID, "Highpass", filtering_edit_highpass->GetText().ToInt()); config->SetIntValue(ConfigID, "SetHighpassWidth", set_highpass_width); config->SetIntValue(ConfigID, "HighpassWidth", filtering_edit_highpass_width->GetText().ToInt()); config->SetIntValue(ConfigID, "EnableATH", enable_ath); config->SetIntValue(ConfigID, "ATHType", expert_combo_athtype->GetSelectedEntryNumber() - 1); config->SetIntValue(ConfigID, "UseTNS", enable_tns); config->SetIntValue(ConfigID, "TNSMode", expert_combo_tnsmode->GetSelectedEntryNumber() - 1); return Success(); } Void BoCA::ConfigureLAME::SetPreset() { preset = basic_combo_preset->GetSelectedEntryNumber(); if (preset == 0) { basic_bitrate->Activate(); basic_option_set_bitrate->Activate(); basic_option_set_ratio->Activate(); basic_quality->Activate(); basic_check_set_quality->Activate(); vbr_vbrmode->Activate(); vbr_option_cbr->Activate(); vbr_option_abr->Activate(); vbr_option_vbrmtrh->Activate(); vbr_quality->Activate(); vbr_text_setquality->Activate(); vbr_slider_quality->Activate(); vbr_text_quality->Activate(); vbr_text_quality_worse->Activate(); vbr_text_quality_better->Activate(); vbr_abrbitrate->Activate(); vbr_slider_abrbitrate->Activate(); vbr_edit_abrbitrate->Activate(); vbr_text_abrbitrate_kbps->Activate(); misc_bits->Activate(); misc_check_original->Activate(); misc_check_copyright->Activate(); misc_check_private->Activate(); misc_crc->Activate(); misc_check_crc->Activate(); misc_stereomode->Activate(); misc_combo_stereomode->Activate(); expert_ath->Activate(); expert_check_ath->Activate(); expert_psycho->Activate(); expert_check_tns->Activate(); expert_format->Activate(); expert_check_iso->Activate(); filtering_misc->Activate(); filtering_check_disable_all->Activate(); SetVBRMode(); SetQualityOption(); SetStereoMode(); SetEnableATH(); SetEnableTNS(); SetDisableFiltering(); } else { basic_bitrate->Deactivate(); basic_option_set_bitrate->Deactivate(); basic_option_set_ratio->Deactivate(); basic_slider_bitrate->Deactivate(); basic_text_bitrate->Deactivate(); basic_edit_ratio->Deactivate(); basic_quality->Deactivate(); basic_check_set_quality->Deactivate(); basic_slider_quality->Deactivate(); basic_text_quality->Deactivate(); basic_text_quality_worse->Deactivate(); basic_text_quality_better->Deactivate(); vbr_vbrmode->Deactivate(); vbr_option_cbr->Deactivate(); vbr_option_abr->Deactivate(); vbr_option_vbrmtrh->Deactivate(); vbr_quality->Deactivate(); vbr_text_setquality->Deactivate(); vbr_slider_quality->Deactivate(); vbr_text_quality->Deactivate(); vbr_text_quality_worse->Deactivate(); vbr_text_quality_better->Deactivate(); vbr_abrbitrate->Deactivate(); vbr_slider_abrbitrate->Deactivate(); vbr_edit_abrbitrate->Deactivate(); vbr_text_abrbitrate_kbps->Deactivate(); misc_bits->Deactivate(); misc_check_original->Deactivate(); misc_check_copyright->Deactivate(); misc_check_private->Deactivate(); misc_crc->Deactivate(); misc_check_crc->Deactivate(); misc_stereomode->Deactivate(); misc_combo_stereomode->Deactivate(); misc_check_forcejs->Deactivate(); misc_bitrate->Deactivate(); misc_check_set_min_brate->Deactivate(); misc_check_set_max_brate->Deactivate(); misc_slider_min_brate->Deactivate(); misc_slider_max_brate->Deactivate(); misc_text_min_brate_kbps->Deactivate(); misc_text_max_brate_kbps->Deactivate(); expert_ath->Deactivate(); expert_check_ath->Deactivate(); expert_combo_athtype->Deactivate(); expert_psycho->Deactivate(); expert_check_tns->Deactivate(); expert_combo_tnsmode->Deactivate(); expert_format->Deactivate(); expert_check_iso->Deactivate(); filtering_lowpass->Deactivate(); filtering_set_lowpass->Deactivate(); filtering_edit_lowpass->Deactivate(); filtering_set_lowpass_width->Deactivate(); filtering_edit_lowpass_width->Deactivate(); filtering_highpass->Deactivate(); filtering_set_highpass->Deactivate(); filtering_edit_highpass->Deactivate(); filtering_set_highpass_width->Deactivate(); filtering_edit_highpass_width->Deactivate(); filtering_misc->Deactivate(); filtering_check_disable_all->Deactivate(); if (preset == 4) { basic_bitrate->Hide(); basic_option_set_bitrate->Hide(); basic_option_set_ratio->Hide(); basic_slider_bitrate->Hide(); basic_text_bitrate->Hide(); basic_text_ratio->Hide(); basic_edit_ratio->Hide(); vbr_quality->Hide(); vbr_text_setquality->Hide(); vbr_slider_quality->Hide(); vbr_text_quality->Hide(); vbr_text_quality_worse->Hide(); vbr_text_quality_better->Hide(); vbr_abrbitrate->Show(); vbr_slider_abrbitrate->Show(); vbr_edit_abrbitrate->Show(); vbr_text_abrbitrate_kbps->Show(); vbr_abrbitrate->Activate(); vbr_slider_abrbitrate->Activate(); vbr_edit_abrbitrate->Activate(); vbr_text_abrbitrate_kbps->Activate(); } } } Void BoCA::ConfigureLAME::SetBitrateOption() { if (set_bitrate) { basic_slider_bitrate->Activate(); basic_text_bitrate->Activate(); basic_edit_ratio->Deactivate(); } else { basic_edit_ratio->Activate(); basic_slider_bitrate->Deactivate(); basic_text_bitrate->Deactivate(); } } Void BoCA::ConfigureLAME::SetBitrate() { I18n *i18n = I18n::Get(); basic_text_bitrate->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(GetBitrate()))); } Void BoCA::ConfigureLAME::SetQualityOption() { if (set_quality) { basic_slider_quality->Activate(); basic_text_quality->Activate(); basic_text_quality_worse->Activate(); basic_text_quality_better->Activate(); } else { basic_slider_quality->Deactivate(); basic_text_quality->Deactivate(); basic_text_quality_worse->Deactivate(); basic_text_quality_better->Deactivate(); } } Void BoCA::ConfigureLAME::SetQuality() { basic_text_quality->SetText(String::FromInt(9 - quality)); } Void BoCA::ConfigureLAME::SetStereoMode() { if (misc_combo_stereomode->GetSelectedEntryNumber() == 3) misc_check_forcejs->Activate(); else misc_check_forcejs->Deactivate(); } Void BoCA::ConfigureLAME::SetVBRQuality() { String txt = String::FromFloat(9.9 - vbrquality / 10.0); if ((vbrquality + 1) % 10 == 0) txt.Append(".0"); vbr_text_quality->SetText(txt); } Void BoCA::ConfigureLAME::SetVBRMode() { switch (vbrmode) { default: vbr_quality->Hide(); vbr_text_setquality->Hide(); vbr_slider_quality->Hide(); vbr_text_quality->Hide(); vbr_text_quality_worse->Hide(); vbr_text_quality_better->Hide(); vbr_abrbitrate->Hide(); vbr_slider_abrbitrate->Hide(); vbr_edit_abrbitrate->Hide(); vbr_text_abrbitrate_kbps->Hide(); misc_bitrate->Deactivate(); misc_check_set_min_brate->Deactivate(); misc_slider_min_brate->Deactivate(); misc_text_min_brate_kbps->Deactivate(); misc_check_set_max_brate->Deactivate(); misc_slider_max_brate->Deactivate(); misc_text_max_brate_kbps->Deactivate(); basic_bitrate->Show(); basic_option_set_bitrate->Show(); basic_option_set_ratio->Show(); basic_slider_bitrate->Show(); basic_text_bitrate->Show(); basic_text_ratio->Show(); basic_edit_ratio->Show(); SetBitrateOption(); break; case vbr_abr: basic_bitrate->Hide(); basic_option_set_bitrate->Hide(); basic_option_set_ratio->Hide(); basic_slider_bitrate->Hide(); basic_text_bitrate->Hide(); basic_text_ratio->Hide(); basic_edit_ratio->Hide(); vbr_quality->Hide(); vbr_text_setquality->Hide(); vbr_slider_quality->Hide(); vbr_text_quality->Hide(); vbr_text_quality_worse->Hide(); vbr_text_quality_better->Hide(); vbr_abrbitrate->Show(); vbr_slider_abrbitrate->Show(); vbr_edit_abrbitrate->Show(); vbr_text_abrbitrate_kbps->Show(); misc_bitrate->Activate(); misc_check_set_min_brate->Activate(); misc_check_set_max_brate->Activate(); SetMinVBRBitrateOption(); SetMaxVBRBitrateOption(); break; case vbr_mtrh: basic_bitrate->Hide(); basic_option_set_bitrate->Hide(); basic_option_set_ratio->Hide(); basic_slider_bitrate->Hide(); basic_text_bitrate->Hide(); basic_text_ratio->Hide(); basic_edit_ratio->Hide(); vbr_abrbitrate->Hide(); vbr_slider_abrbitrate->Hide(); vbr_edit_abrbitrate->Hide(); vbr_text_abrbitrate_kbps->Hide(); vbr_quality->Show(); vbr_text_setquality->Show(); vbr_slider_quality->Show(); vbr_text_quality->Show(); vbr_text_quality_worse->Show(); vbr_text_quality_better->Show(); misc_bitrate->Activate(); misc_check_set_min_brate->Activate(); misc_check_set_max_brate->Activate(); SetMinVBRBitrateOption(); SetMaxVBRBitrateOption(); break; } } Void BoCA::ConfigureLAME::SetABRBitrate() { if (!vbr_edit_abrbitrate->IsFocussed()) vbr_edit_abrbitrate->SetText(String::FromInt(abrbitrate)); } Void BoCA::ConfigureLAME::SetABRBitrateByEditBox() { vbr_slider_abrbitrate->SetValue(vbr_edit_abrbitrate->GetText().ToInt()); } Void BoCA::ConfigureLAME::SetMinVBRBitrateOption() { if (set_min_vbr_brate) { misc_slider_min_brate->Activate(); misc_text_min_brate_kbps->Activate(); } else { misc_slider_min_brate->Deactivate(); misc_text_min_brate_kbps->Deactivate(); } } Void BoCA::ConfigureLAME::SetMaxVBRBitrateOption() { if (set_max_vbr_brate) { misc_slider_max_brate->Activate(); misc_text_max_brate_kbps->Activate(); } else { misc_slider_max_brate->Deactivate(); misc_text_max_brate_kbps->Deactivate(); } } Void BoCA::ConfigureLAME::SetMinVBRBitrate() { I18n *i18n = I18n::Get(); misc_text_min_brate_kbps->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(GetMinVBRBitrate()))); if (min_vbr_brate > max_vbr_brate) { misc_slider_max_brate->SetValue(min_vbr_brate); } } Void BoCA::ConfigureLAME::SetMaxVBRBitrate() { I18n *i18n = I18n::Get(); misc_text_max_brate_kbps->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(GetMaxVBRBitrate()))); if (max_vbr_brate < min_vbr_brate) { misc_slider_min_brate->SetValue(max_vbr_brate); } } Void BoCA::ConfigureLAME::SetHighpass() { if (set_highpass) { filtering_edit_highpass->Activate(); filtering_set_highpass_width->Activate(); SetHighpassWidth(); } else { filtering_edit_highpass->Deactivate(); filtering_set_highpass_width->Deactivate(); filtering_edit_highpass_width->Deactivate(); } } Void BoCA::ConfigureLAME::SetHighpassWidth() { if (set_highpass_width) filtering_edit_highpass_width->Activate(); else filtering_edit_highpass_width->Deactivate(); } Void BoCA::ConfigureLAME::SetLowpass() { if (set_lowpass) { filtering_edit_lowpass->Activate(); filtering_set_lowpass_width->Activate(); SetLowpassWidth(); } else { filtering_edit_lowpass->Deactivate(); filtering_set_lowpass_width->Deactivate(); filtering_edit_lowpass_width->Deactivate(); } } Void BoCA::ConfigureLAME::SetLowpassWidth() { if (set_lowpass_width) filtering_edit_lowpass_width->Activate(); else filtering_edit_lowpass_width->Deactivate(); } Void BoCA::ConfigureLAME::SetEnableATH() { if (enable_ath) expert_combo_athtype->Activate(); else expert_combo_athtype->Deactivate(); } Void BoCA::ConfigureLAME::SetEnableTNS() { if (enable_tns) expert_combo_tnsmode->Activate(); else expert_combo_tnsmode->Deactivate(); } Void BoCA::ConfigureLAME::SetDisableFiltering() { if (disable_filtering) { filtering_lowpass->Deactivate(); filtering_highpass->Deactivate(); filtering_set_lowpass->Deactivate(); filtering_edit_lowpass->Deactivate(); filtering_set_lowpass_width->Deactivate(); filtering_edit_lowpass_width->Deactivate(); filtering_set_highpass->Deactivate(); filtering_edit_highpass->Deactivate(); filtering_set_highpass_width->Deactivate(); filtering_edit_highpass_width->Deactivate(); } else { filtering_lowpass->Activate(); filtering_highpass->Activate(); filtering_set_lowpass->Activate(); filtering_set_highpass->Activate(); SetLowpass(); SetHighpass(); } } Int BoCA::ConfigureLAME::GetBitrate() { return SliderValueToBitrate(bitrate); } Int BoCA::ConfigureLAME::GetSliderValue() { return BitrateToSliderValue(Config::Get()->GetIntValue(ConfigID, "Bitrate", 192)); } Int BoCA::ConfigureLAME::GetMinVBRBitrate() { return SliderValueToBitrate(min_vbr_brate); } Int BoCA::ConfigureLAME::GetMinVBRSliderValue() { return BitrateToSliderValue(Config::Get()->GetIntValue(ConfigID, "MinVBRBitrate", 128)); } Int BoCA::ConfigureLAME::GetMaxVBRBitrate() { return SliderValueToBitrate(max_vbr_brate); } Int BoCA::ConfigureLAME::GetMaxVBRSliderValue() { return BitrateToSliderValue(Config::Get()->GetIntValue(ConfigID, "MaxVBRBitrate", 256)); } Int BoCA::ConfigureLAME::SliderValueToBitrate(Int value) { switch (value) { case 0: return 8; case 1: return 16; case 2: return 24; case 3: return 32; case 4: return 40; case 5: return 48; case 6: return 56; case 7: return 64; case 8: return 80; case 9: return 96; case 10: return 112; case 11: return 128; case 12: return 144; case 13: return 160; case 14: return 192; case 15: return 224; case 16: return 256; case 17: return 320; default: return 128; } } Int BoCA::ConfigureLAME::BitrateToSliderValue(Int value) { switch (value) { case 8: return 0; case 16: return 1; case 24: return 2; case 32: return 3; case 40: return 4; case 48: return 5; case 56: return 6; case 64: return 7; case 80: return 8; case 96: return 9; case 112: return 10; case 128: return 11; case 144: return 12; case 160: return 13; case 192: return 14; case 224: return 15; case 256: return 16; case 320: return 17; default: return 11; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/config.h000077500000000000000000000114211516712004000243260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_LAMECONFIG #define H_LAMECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureLAME : public ConfigLayer { private: TabWidget *reg_register; Layer *register_layer_basic; Layer *register_layer_misc; Layer *register_layer_expert; Layer *register_layer_filtering; GroupBox *basic_preset; Text *basic_text_preset; ComboBox *basic_combo_preset; GroupBox *basic_bitrate; OptionBox *basic_option_set_bitrate; OptionBox *basic_option_set_ratio; Slider *basic_slider_bitrate; Text *basic_text_bitrate; Text *basic_text_ratio; EditBox *basic_edit_ratio; GroupBox *basic_quality; CheckBox *basic_check_set_quality; Slider *basic_slider_quality; Text *basic_text_quality; Text *basic_text_quality_better; Text *basic_text_quality_worse; GroupBox *vbr_vbrmode; OptionBox *vbr_option_cbr; OptionBox *vbr_option_abr; OptionBox *vbr_option_vbrmtrh; GroupBox *vbr_quality; Text *vbr_text_setquality; Slider *vbr_slider_quality; Text *vbr_text_quality; Text *vbr_text_quality_better; Text *vbr_text_quality_worse; GroupBox *vbr_abrbitrate; Slider *vbr_slider_abrbitrate; EditBox *vbr_edit_abrbitrate; Text *vbr_text_abrbitrate_kbps; GroupBox *misc_bits; CheckBox *misc_check_original; CheckBox *misc_check_copyright; CheckBox *misc_check_private; GroupBox *misc_crc; CheckBox *misc_check_crc; GroupBox *misc_stereomode; ComboBox *misc_combo_stereomode; CheckBox *misc_check_forcejs; GroupBox *misc_bitrate; CheckBox *misc_check_set_min_brate; CheckBox *misc_check_set_max_brate; Slider *misc_slider_min_brate; Slider *misc_slider_max_brate; Text *misc_text_min_brate_kbps; Text *misc_text_max_brate_kbps; GroupBox *expert_ath; CheckBox *expert_check_ath; ComboBox *expert_combo_athtype; GroupBox *expert_psycho; CheckBox *expert_check_tns; ComboBox *expert_combo_tnsmode; GroupBox *expert_format; CheckBox *expert_check_iso; GroupBox *filtering_lowpass; CheckBox *filtering_set_lowpass; EditBox *filtering_edit_lowpass; CheckBox *filtering_set_lowpass_width; EditBox *filtering_edit_lowpass_width; GroupBox *filtering_highpass; CheckBox *filtering_set_highpass; EditBox *filtering_edit_highpass; CheckBox *filtering_set_highpass_width; EditBox *filtering_edit_highpass_width; GroupBox *filtering_misc; CheckBox *filtering_check_disable_all; Int preset; Int set_bitrate; Int bitrate; Int ratio; Bool set_quality; Int quality; Bool forcejs; Int vbrmode; Int vbrquality; Int abrbitrate; Bool set_min_vbr_brate; Bool set_max_vbr_brate; Int min_vbr_brate; Int max_vbr_brate; Bool set_original; Bool set_private; Bool set_copyright; Bool set_crc; Bool set_iso; Bool enable_ath; Bool enable_tns; Bool disable_filtering; Bool set_lowpass; Bool set_lowpass_width; Bool set_highpass; Bool set_highpass_width; slots: Void SetPreset(); Void SetBitrateOption(); Void SetBitrate(); Void SetQualityOption(); Void SetQuality(); Void SetStereoMode(); Void SetVBRMode(); Void SetVBRQuality(); Void SetABRBitrate(); Void SetABRBitrateByEditBox(); Void SetMinVBRBitrateOption(); Void SetMaxVBRBitrateOption(); Void SetMinVBRBitrate(); Void SetMaxVBRBitrate(); Void SetEnableATH(); Void SetEnableTNS(); Void SetDisableFiltering(); Void SetLowpass(); Void SetLowpassWidth(); Void SetHighpass(); Void SetHighpassWidth(); Int GetBitrate(); Int GetSliderValue(); Int GetMinVBRBitrate(); Int GetMinVBRSliderValue(); Int GetMaxVBRBitrate(); Int GetMaxVBRSliderValue(); Int SliderValueToBitrate(Int); Int BitrateToSliderValue(Int); public: static const String ConfigID; ConfigureLAME(); ~ConfigureLAME(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/dllinterface.cpp000077500000000000000000000222041516712004000260510ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; LAME_INIT ex_lame_init = NIL; LAME_SET_PRESET ex_lame_set_preset = NIL; LAME_SET_IN_SAMPLERATE ex_lame_set_in_samplerate = NIL; LAME_SET_NUM_CHANNELS ex_lame_set_num_channels = NIL; LAME_SET_COPYRIGHT ex_lame_set_copyright = NIL; LAME_SET_ORIGINAL ex_lame_set_original = NIL; LAME_SET_EXTENSION ex_lame_set_extension = NIL; LAME_SET_ERROR_PROTECTION ex_lame_set_error_protection = NIL; LAME_SET_STRICT_ISO ex_lame_set_strict_ISO = NIL; LAME_SET_BRATE ex_lame_set_brate = NIL; LAME_SET_COMPRESSION_RATIO ex_lame_set_compression_ratio = NIL; LAME_SET_QUALITY ex_lame_set_quality = NIL; LAME_SET_LOWPASSFREQ ex_lame_set_lowpassfreq = NIL; LAME_SET_HIGHPASSFREQ ex_lame_set_highpassfreq = NIL; LAME_SET_LOWPASSWIDTH ex_lame_set_lowpasswidth = NIL; LAME_SET_HIGHPASSWIDTH ex_lame_set_highpasswidth = NIL; LAME_SET_MODE ex_lame_set_mode = NIL; LAME_SET_FORCE_MS ex_lame_set_force_ms = NIL; LAME_CLOSE ex_lame_close = NIL; LAME_SET_VBR ex_lame_set_VBR = NIL; LAME_SET_VBR_QUALITY ex_lame_set_VBR_quality = NIL; LAME_SET_VBR_MEAN_BITRATE_KBPS ex_lame_set_VBR_mean_bitrate_kbps = NIL; LAME_SET_VBR_MIN_BITRATE_KBPS ex_lame_set_VBR_min_bitrate_kbps = NIL; LAME_SET_VBR_MAX_BITRATE_KBPS ex_lame_set_VBR_max_bitrate_kbps = NIL; LAME_SET_NOATH ex_lame_set_noATH = NIL; LAME_SET_ATHTYPE ex_lame_set_ATHtype = NIL; LAME_SET_USETEMPORAL ex_lame_set_useTemporal = NIL; LAME_INIT_PARAMS ex_lame_init_params = NIL; LAME_GET_OUT_SAMPLERATE ex_lame_get_out_samplerate = NIL; LAME_GET_FRAMESIZE ex_lame_get_framesize = NIL; LAME_ENCODE_BUFFER ex_lame_encode_buffer = NIL; LAME_ENCODE_BUFFER_INTERLEAVED ex_lame_encode_buffer_interleaved = NIL; LAME_ENCODE_BUFFER_IEEE_FLOAT ex_lame_encode_buffer_ieee_float = NIL; LAME_ENCODE_BUFFER_INTERLEAVED_IEEE_FLOAT ex_lame_encode_buffer_interleaved_ieee_float = NIL; LAME_ENCODE_FLUSH ex_lame_encode_flush = NIL; LAME_ENCODE_FLUSH_NOGAP ex_lame_encode_flush_nogap = NIL; GET_LAME_SHORT_VERSION ex_get_lame_short_version = NIL; GET_LAME_VERSION_NUMERICAL ex_get_lame_version_numerical = NIL; LAME_GET_LAMETAG_FRAME ex_lame_get_lametag_frame = NIL; LAME_SET_BWRITEVBRTAG ex_lame_set_bWriteVbrTag = NIL; DynamicLoader *lamedll = NIL; Bool LoadLAMEDLL() { #ifdef __WIN32__ lamedll = BoCA::Utilities::LoadCodecDLL("LAME"); #else lamedll = BoCA::Utilities::LoadCodecDLL("mp3lame"); #endif if (lamedll == NIL) return False; ex_lame_init = (LAME_INIT) lamedll->GetFunctionAddress("lame_init"); ex_lame_set_preset = (LAME_SET_PRESET) lamedll->GetFunctionAddress("lame_set_preset"); ex_lame_set_in_samplerate = (LAME_SET_IN_SAMPLERATE) lamedll->GetFunctionAddress("lame_set_in_samplerate"); ex_lame_set_num_channels = (LAME_SET_NUM_CHANNELS) lamedll->GetFunctionAddress("lame_set_num_channels"); ex_lame_set_copyright = (LAME_SET_COPYRIGHT) lamedll->GetFunctionAddress("lame_set_copyright"); ex_lame_set_original = (LAME_SET_ORIGINAL) lamedll->GetFunctionAddress("lame_set_original"); ex_lame_set_extension = (LAME_SET_EXTENSION) lamedll->GetFunctionAddress("lame_set_extension"); ex_lame_set_error_protection = (LAME_SET_ERROR_PROTECTION) lamedll->GetFunctionAddress("lame_set_error_protection"); ex_lame_set_strict_ISO = (LAME_SET_STRICT_ISO) lamedll->GetFunctionAddress("lame_set_strict_ISO"); ex_lame_set_brate = (LAME_SET_BRATE) lamedll->GetFunctionAddress("lame_set_brate"); ex_lame_set_compression_ratio = (LAME_SET_COMPRESSION_RATIO) lamedll->GetFunctionAddress("lame_set_compression_ratio"); ex_lame_set_quality = (LAME_SET_QUALITY) lamedll->GetFunctionAddress("lame_set_quality"); ex_lame_set_lowpassfreq = (LAME_SET_LOWPASSFREQ) lamedll->GetFunctionAddress("lame_set_lowpassfreq"); ex_lame_set_highpassfreq = (LAME_SET_HIGHPASSFREQ) lamedll->GetFunctionAddress("lame_set_highpassfreq"); ex_lame_set_lowpasswidth = (LAME_SET_LOWPASSWIDTH) lamedll->GetFunctionAddress("lame_set_lowpasswidth"); ex_lame_set_highpasswidth = (LAME_SET_HIGHPASSWIDTH) lamedll->GetFunctionAddress("lame_set_highpasswidth"); ex_lame_set_mode = (LAME_SET_MODE) lamedll->GetFunctionAddress("lame_set_mode"); ex_lame_set_force_ms = (LAME_SET_FORCE_MS) lamedll->GetFunctionAddress("lame_set_force_ms"); ex_lame_close = (LAME_CLOSE) lamedll->GetFunctionAddress("lame_close"); ex_lame_set_VBR = (LAME_SET_VBR) lamedll->GetFunctionAddress("lame_set_VBR"); ex_lame_set_VBR_quality = (LAME_SET_VBR_QUALITY) lamedll->GetFunctionAddress("lame_set_VBR_quality"); ex_lame_set_VBR_mean_bitrate_kbps = (LAME_SET_VBR_MEAN_BITRATE_KBPS) lamedll->GetFunctionAddress("lame_set_VBR_mean_bitrate_kbps"); ex_lame_set_VBR_min_bitrate_kbps = (LAME_SET_VBR_MIN_BITRATE_KBPS) lamedll->GetFunctionAddress("lame_set_VBR_min_bitrate_kbps"); ex_lame_set_VBR_max_bitrate_kbps = (LAME_SET_VBR_MAX_BITRATE_KBPS) lamedll->GetFunctionAddress("lame_set_VBR_max_bitrate_kbps"); ex_lame_set_noATH = (LAME_SET_NOATH) lamedll->GetFunctionAddress("lame_set_noATH"); ex_lame_set_ATHtype = (LAME_SET_ATHTYPE) lamedll->GetFunctionAddress("lame_set_ATHtype"); ex_lame_set_useTemporal = (LAME_SET_USETEMPORAL) lamedll->GetFunctionAddress("lame_set_useTemporal"); ex_lame_init_params = (LAME_INIT_PARAMS) lamedll->GetFunctionAddress("lame_init_params"); ex_lame_get_out_samplerate = (LAME_GET_OUT_SAMPLERATE) lamedll->GetFunctionAddress("lame_get_out_samplerate"); ex_lame_get_framesize = (LAME_GET_FRAMESIZE) lamedll->GetFunctionAddress("lame_get_framesize"); ex_lame_encode_buffer = (LAME_ENCODE_BUFFER) lamedll->GetFunctionAddress("lame_encode_buffer"); ex_lame_encode_buffer_interleaved = (LAME_ENCODE_BUFFER_INTERLEAVED) lamedll->GetFunctionAddress("lame_encode_buffer_interleaved"); ex_lame_encode_buffer_ieee_float = (LAME_ENCODE_BUFFER_IEEE_FLOAT) lamedll->GetFunctionAddress("lame_encode_buffer_ieee_float"); ex_lame_encode_buffer_interleaved_ieee_float = (LAME_ENCODE_BUFFER_INTERLEAVED_IEEE_FLOAT) lamedll->GetFunctionAddress("lame_encode_buffer_interleaved_ieee_float"); ex_lame_encode_flush = (LAME_ENCODE_FLUSH) lamedll->GetFunctionAddress("lame_encode_flush"); ex_lame_encode_flush_nogap = (LAME_ENCODE_FLUSH_NOGAP) lamedll->GetFunctionAddress("lame_encode_flush_nogap"); ex_get_lame_short_version = (GET_LAME_SHORT_VERSION) lamedll->GetFunctionAddress("get_lame_short_version"); ex_get_lame_version_numerical = (GET_LAME_VERSION_NUMERICAL) lamedll->GetFunctionAddress("get_lame_version_numerical"); ex_lame_get_lametag_frame = (LAME_GET_LAMETAG_FRAME) lamedll->GetFunctionAddress("lame_get_lametag_frame"); ex_lame_set_bWriteVbrTag = (LAME_SET_BWRITEVBRTAG) lamedll->GetFunctionAddress("lame_set_bWriteVbrTag"); if (ex_lame_init == NIL || ex_lame_set_preset == NIL || ex_lame_set_in_samplerate == NIL || ex_lame_set_num_channels == NIL || ex_lame_set_copyright == NIL || ex_lame_set_original == NIL || ex_lame_set_extension == NIL || ex_lame_set_error_protection == NIL || ex_lame_set_strict_ISO == NIL || ex_lame_set_brate == NIL || ex_lame_set_compression_ratio == NIL || ex_lame_set_quality == NIL || ex_lame_set_lowpassfreq == NIL || ex_lame_set_highpassfreq == NIL || ex_lame_set_lowpasswidth == NIL || ex_lame_set_highpasswidth == NIL || ex_lame_set_mode == NIL || ex_lame_set_force_ms == NIL || ex_lame_close == NIL || ex_lame_set_VBR == NIL || ex_lame_set_VBR_quality == NIL || ex_lame_set_VBR_mean_bitrate_kbps == NIL || ex_lame_set_VBR_min_bitrate_kbps == NIL || ex_lame_set_VBR_max_bitrate_kbps == NIL || ex_lame_set_noATH == NIL || ex_lame_set_ATHtype == NIL || ex_lame_set_useTemporal == NIL || ex_lame_init_params == NIL || ex_lame_get_out_samplerate == NIL || ex_lame_get_framesize == NIL || ex_lame_encode_buffer == NIL || ex_lame_encode_buffer_interleaved == NIL || ex_lame_encode_buffer_ieee_float == NIL || ex_lame_encode_buffer_interleaved_ieee_float == NIL || ex_lame_encode_flush == NIL || ex_lame_encode_flush_nogap == NIL || ex_get_lame_short_version == NIL || ex_get_lame_version_numerical == NIL || ex_lame_get_lametag_frame == NIL || ex_lame_set_bWriteVbrTag == NIL) { FreeLAMEDLL(); return False; } return True; } Void FreeLAMEDLL() { BoCA::Utilities::FreeCodecDLL(lamedll); lamedll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/dllinterface.h000077500000000000000000000132331516712004000255200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *lamedll; Bool LoadLAMEDLL(); Void FreeLAMEDLL(); typedef lame_t (CDECL *LAME_INIT) (); typedef int (CDECL *LAME_SET_PRESET) (lame_t, int); typedef int (CDECL *LAME_SET_IN_SAMPLERATE) (lame_t, int); typedef int (CDECL *LAME_SET_NUM_CHANNELS) (lame_t, int); typedef int (CDECL *LAME_SET_COPYRIGHT) (lame_t, int); typedef int (CDECL *LAME_SET_ORIGINAL) (lame_t, int); typedef int (CDECL *LAME_SET_EXTENSION) (lame_t, int); typedef int (CDECL *LAME_SET_ERROR_PROTECTION) (lame_t, int); typedef int (CDECL *LAME_SET_STRICT_ISO) (lame_t, int); typedef int (CDECL *LAME_SET_BRATE) (lame_t, int); typedef int (CDECL *LAME_SET_COMPRESSION_RATIO) (lame_t, float); typedef int (CDECL *LAME_SET_QUALITY) (lame_t, int); typedef int (CDECL *LAME_SET_LOWPASSFREQ) (lame_t, int); typedef int (CDECL *LAME_SET_HIGHPASSFREQ) (lame_t, int); typedef int (CDECL *LAME_SET_LOWPASSWIDTH) (lame_t, int); typedef int (CDECL *LAME_SET_HIGHPASSWIDTH) (lame_t, int); typedef int (CDECL *LAME_SET_MODE) (lame_t, MPEG_mode); typedef int (CDECL *LAME_SET_FORCE_MS) (lame_t, int); typedef int (CDECL *LAME_CLOSE) (lame_t); typedef int (CDECL *LAME_SET_VBR) (lame_t, vbr_mode); typedef int (CDECL *LAME_SET_VBR_QUALITY) (lame_t, float); typedef int (CDECL *LAME_SET_VBR_MEAN_BITRATE_KBPS) (lame_t, int); typedef int (CDECL *LAME_SET_VBR_MIN_BITRATE_KBPS) (lame_t, int); typedef int (CDECL *LAME_SET_VBR_MAX_BITRATE_KBPS) (lame_t, int); typedef int (CDECL *LAME_SET_NOATH) (lame_t, int); typedef int (CDECL *LAME_SET_ATHTYPE) (lame_t, int); typedef int (CDECL *LAME_SET_USETEMPORAL) (lame_t, int); typedef int (CDECL *LAME_INIT_PARAMS) (lame_t); typedef int (CDECL *LAME_GET_OUT_SAMPLERATE) (const lame_t); typedef int (CDECL *LAME_GET_FRAMESIZE) (const lame_t); typedef int (CDECL *LAME_ENCODE_BUFFER) (lame_t, const short int [], const short int [], const int, unsigned char *, const int); typedef int (CDECL *LAME_ENCODE_BUFFER_INTERLEAVED) (lame_t, short int [], int, unsigned char *, int); typedef int (CDECL *LAME_ENCODE_BUFFER_IEEE_FLOAT) (lame_t, const float [], const float [], const int, unsigned char *, const int); typedef int (CDECL *LAME_ENCODE_BUFFER_INTERLEAVED_IEEE_FLOAT) (lame_t, const float [], const int, unsigned char *, const int); typedef int (CDECL *LAME_ENCODE_FLUSH) (lame_t, unsigned char *, int); typedef int (CDECL *LAME_ENCODE_FLUSH_NOGAP) (lame_t, unsigned char *, int); typedef char * (CDECL *GET_LAME_SHORT_VERSION) (); typedef void (CDECL *GET_LAME_VERSION_NUMERICAL) (lame_version_t * const); typedef size_t (CDECL *LAME_GET_LAMETAG_FRAME) (const lame_t, unsigned char *, size_t); typedef int (CDECL *LAME_SET_BWRITEVBRTAG) (lame_t, int); extern LAME_INIT ex_lame_init; extern LAME_SET_PRESET ex_lame_set_preset; extern LAME_SET_IN_SAMPLERATE ex_lame_set_in_samplerate; extern LAME_SET_NUM_CHANNELS ex_lame_set_num_channels; extern LAME_SET_COPYRIGHT ex_lame_set_copyright; extern LAME_SET_ORIGINAL ex_lame_set_original; extern LAME_SET_EXTENSION ex_lame_set_extension; extern LAME_SET_ERROR_PROTECTION ex_lame_set_error_protection; extern LAME_SET_STRICT_ISO ex_lame_set_strict_ISO; extern LAME_SET_BRATE ex_lame_set_brate; extern LAME_SET_COMPRESSION_RATIO ex_lame_set_compression_ratio; extern LAME_SET_QUALITY ex_lame_set_quality; extern LAME_SET_LOWPASSFREQ ex_lame_set_lowpassfreq; extern LAME_SET_HIGHPASSFREQ ex_lame_set_highpassfreq; extern LAME_SET_LOWPASSWIDTH ex_lame_set_lowpasswidth; extern LAME_SET_HIGHPASSWIDTH ex_lame_set_highpasswidth; extern LAME_SET_MODE ex_lame_set_mode; extern LAME_SET_FORCE_MS ex_lame_set_force_ms; extern LAME_CLOSE ex_lame_close; extern LAME_SET_VBR ex_lame_set_VBR; extern LAME_SET_VBR_QUALITY ex_lame_set_VBR_quality; extern LAME_SET_VBR_MEAN_BITRATE_KBPS ex_lame_set_VBR_mean_bitrate_kbps; extern LAME_SET_VBR_MIN_BITRATE_KBPS ex_lame_set_VBR_min_bitrate_kbps; extern LAME_SET_VBR_MAX_BITRATE_KBPS ex_lame_set_VBR_max_bitrate_kbps; extern LAME_SET_NOATH ex_lame_set_noATH; extern LAME_SET_ATHTYPE ex_lame_set_ATHtype; extern LAME_SET_USETEMPORAL ex_lame_set_useTemporal; extern LAME_INIT_PARAMS ex_lame_init_params; extern LAME_GET_OUT_SAMPLERATE ex_lame_get_out_samplerate; extern LAME_GET_FRAMESIZE ex_lame_get_framesize; extern LAME_ENCODE_BUFFER ex_lame_encode_buffer; extern LAME_ENCODE_BUFFER_INTERLEAVED ex_lame_encode_buffer_interleaved; extern LAME_ENCODE_BUFFER_IEEE_FLOAT ex_lame_encode_buffer_ieee_float; extern LAME_ENCODE_BUFFER_INTERLEAVED_IEEE_FLOAT ex_lame_encode_buffer_interleaved_ieee_float; extern LAME_ENCODE_FLUSH ex_lame_encode_flush; extern LAME_ENCODE_FLUSH_NOGAP ex_lame_encode_flush_nogap; extern GET_LAME_SHORT_VERSION ex_get_lame_short_version; extern GET_LAME_VERSION_NUMERICAL ex_get_lame_version_numerical; extern LAME_GET_LAMETAG_FRAME ex_lame_get_lametag_frame; extern LAME_SET_BWRITEVBRTAG ex_lame_set_bWriteVbrTag; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/framecrc.cpp000066400000000000000000000027641516712004000252050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "framecrc.h" UnsignedInt16 BoCA::FrameCRC::table[256]; Bool BoCA::FrameCRC::initialized = InitTable(); BoCA::FrameCRC::FrameCRC() : crc(0xFFFF) { } BoCA::FrameCRC::~FrameCRC() { } Bool BoCA::FrameCRC::InitTable() { UnsignedInt16 polynomial = 0x8005; for (Int i = 0; i <= 0xFF; i++) { UnsignedInt16 value = i << 8; for (Int n = 0; n < 8; n++) value = (value << 1) ^ (value & (1 << 15) ? polynomial : 0); table[i] = value; } return True; } Bool BoCA::FrameCRC::Feed(const UnsignedByte *data, Int size) { while (size--) crc = (crc << 8) ^ table[(crc >> 8) ^ *data++]; return True; } Bool BoCA::FrameCRC::Update(UnsignedByte *frame) { FrameCRC crc; Int sil = ((frame[1] >> 3) & 0x03) == 0x03 ? ((frame[3] >> 6) == 0x03 ? 17 : 32) : ((frame[3] >> 6) == 0x03 ? 9 : 17); crc.Feed(frame + 2, 2); crc.Feed(frame + 6, sil); frame[4] = crc.crc >> 8; frame[5] = crc.crc & 0xFF; return True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/framecrc.h000066400000000000000000000017321516712004000246440ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_FRAMECRC #define H_FRAMECRC #include using namespace smooth; namespace BoCA { class FrameCRC { private: static UnsignedInt16 table[256]; static Bool initialized; UnsignedInt16 crc; static Bool InitTable(); Bool Feed(const UnsignedByte *, Int); FrameCRC(); ~FrameCRC(); public: static Bool Update(UnsignedByte *); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/lame.cpp000066400000000000000000000377651516712004000243520ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "lame.h" #include "config.h" const String &BoCA::EncoderLAME::GetComponentSpecs() { static String componentSpecs; if (lamedll != NIL) { componentSpecs = " \ \ \ \ LAME MP3 Encoder %VERSION% \ 1.0 \ lame-enc \ encoder \ \ MPEG 1 Audio Layer 3 \ mp3 \ ID3v1 \ ID3v2 \ \ \ \ \ \ \ \ \ \ \ 8 \ 320 \ \ \ 0 \ 9 \ \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(ex_get_lame_short_version())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadLAMEDLL(); } Void smooth::DetachDLL() { FreeLAMEDLL(); } BoCA::EncoderLAME::EncoderLAME() { configLayer = NIL; config = NIL; dataOffset = 0; frameSize = 0; blockSize = 128; overlap = 4; nextWorker = 0; totalSamples = 0; repacker = NIL; } BoCA::EncoderLAME::~EncoderLAME() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderLAME::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); Int preset = config->GetIntValue(ConfigureLAME::ConfigID, "Preset", 2); Int vbrMode = config->GetIntValue(ConfigureLAME::ConfigID, "VBRMode", 4); Bool setBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetBitrate", 1); Int bitrate = config->GetIntValue(ConfigureLAME::ConfigID, "Bitrate", 192); Int ratio = config->GetIntValue(ConfigureLAME::ConfigID, "Ratio", 1100); Int abrBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "ABRBitrate", 192); Int vbrQuality = config->GetIntValue(ConfigureLAME::ConfigID, "VBRQuality", 50); Bool setMinVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetMinVBRBitrate", 0); Bool setMaxVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetMaxVBRBitrate", 0); Int minVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "MinVBRBitrate", 128); Int maxVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "MaxVBRBitrate", 256); Bool strictISO = config->GetIntValue(ConfigureLAME::ConfigID, "StrictISO", 0); Int stereoMode = config->GetIntValue(ConfigureLAME::ConfigID, "StereoMode", 0); Bool disableFiltering = config->GetIntValue(ConfigureLAME::ConfigID, "DisableFiltering", 0); /* Create and configure LAME encoder. */ lame_t context = ex_lame_init(); ex_lame_set_in_samplerate(context, format.rate); ex_lame_set_num_channels(context, format.channels); switch (preset) { case 0: /* Enforce strict ISO compliance. */ if (strictISO) ex_lame_set_strict_ISO(context, strictISO); /* Set bitrate. */ if (vbrMode == vbr_off) { if (setBitrate) ex_lame_set_brate(context, bitrate); else ex_lame_set_compression_ratio(context, ratio / 100.0); } /* Set audio filtering. */ if (disableFiltering) { ex_lame_set_lowpassfreq(context, -1); ex_lame_set_highpassfreq(context, -1); } /* Set Stereo mode. */ if (stereoMode == 1) ex_lame_set_mode(context, MONO); else if (stereoMode == 2) ex_lame_set_mode(context, STEREO); else if (stereoMode == 3) ex_lame_set_mode(context, JOINT_STEREO); else ex_lame_set_mode(context, NOT_SET); /* Set VBR mode. */ switch (vbrMode) { default: case vbr_off: break; case vbr_abr: ex_lame_set_VBR(context, vbr_abr); ex_lame_set_VBR_mean_bitrate_kbps(context, abrBitrate); break; case vbr_rh: ex_lame_set_VBR(context, vbr_rh); ex_lame_set_VBR_quality(context, vbrQuality / 10.0); break; case vbr_mtrh: ex_lame_set_VBR(context, vbr_mtrh); ex_lame_set_VBR_quality(context, vbrQuality / 10.0); break; } if (vbrMode != vbr_off && setMinVBRBitrate) ex_lame_set_VBR_min_bitrate_kbps(context, minVBRBitrate); if (vbrMode != vbr_off && setMaxVBRBitrate) ex_lame_set_VBR_max_bitrate_kbps(context, maxVBRBitrate); break; case 1: ex_lame_set_preset(context, MEDIUM); break; case 2: ex_lame_set_preset(context, STANDARD); break; case 3: ex_lame_set_preset(context, EXTREME); break; case 4: ex_lame_set_preset(context, abrBitrate); break; } if (ex_lame_init_params(context) < 0) { errorString = "Bad LAME encoder settings!\n\nPlease check your encoder settings in the\nconfiguration dialog."; errorState = True; return False; } Int outSamplerate = ex_lame_get_out_samplerate(context); frameSize = ex_lame_get_framesize(context); ex_lame_close(context); dataOffset = 0; /* Write ID3v2 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v2", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); dataOffset = id3Buffer.Size(); } } /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True) && format.rate == outSamplerate; Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = 4 * 1152 / frameSize; /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, format, overlap)); foreach (SuperWorker *worker, workers) worker->Start(); /* Create repacker instance. */ repacker = new SuperRepacker(driver); repacker->EnableRateControl(setMinVBRBitrate ? minVBRBitrate * 1000 : 8000, setMaxVBRBitrate ? maxVBRBitrate * 1000 : 320000); return True; } Bool BoCA::EncoderLAME::Deactivate() { const Info &info = track.GetInfo(); /* Output remaining samples to encoder. */ EncodeFrames(True); /* Write Xing or Info header. */ Buffer buffer; workers.GetFirst()->GetInfoTag(buffer); if (workers.Length() > 1) repacker->UpdateInfoTag(buffer, totalSamples); driver->Seek(dataOffset); driver->WriteData(buffer, buffer.Size()); /* Delete repacker instance. */ delete repacker; /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Write ID3v1 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v1", False) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(driver->GetSize()); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } /* Update ID3v2 tag with correct chapter marks. */ if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True) && config->GetIntValue("Tags", "EnableID3v2", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderLAME::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Copy data to samples buffer. */ Int size = data.Size(); samplesBuffer.Resize(samplesBuffer.Size() + size); memcpy(samplesBuffer + samplesBuffer.Size() - size, data, size); /* Output samples to encoder. */ totalSamples += size / format.channels / (format.bits / 8); return EncodeFrames(False); } Int BoCA::EncoderLAME::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int samplesPerFrame = frameSize * format.channels; Int samplesInBuffer = samplesBuffer.Size() / (format.bits / 8); if (flush) framesToProcess = Math::Floor(samplesInBuffer / samplesPerFrame); while (samplesInBuffer - framesProcessed * samplesPerFrame >= samplesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessResults(workerToUse, nextWorker == workers.Length()); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * samplesPerFrame, flush ? samplesInBuffer : samplesPerFrame * framesToProcess, flush); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } Int bytesProcessed = framesProcessed * samplesPerFrame * (format.bits / 8); memmove((UnsignedByte *) samplesBuffer, (UnsignedByte *) samplesBuffer + bytesProcessed, samplesBuffer.Size() - bytesProcessed); samplesBuffer.Resize(samplesBuffer.Size() - bytesProcessed); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessResults(workerToUse, nextWorker == workers.Length()); nextWorker++; } /* Flush repacker. */ repacker->Flush(); return dataLength; } Int BoCA::EncoderLAME::ProcessResults(SuperWorker *worker, Bool first) { Int processed = 0; Bool complete = False; if (workers.Length() == 1) return ProcessPackets(worker->GetPackets(), worker->GetPacketSizes(), first, processed, complete); Int dataLength = 0; for (Int round = 0; !complete; round++) { dataLength += ProcessPackets(worker->GetPackets(), worker->GetPacketSizes(), first, processed, complete); /* Reduce overlap if not finished after 16 rounds. */ if (round & 16 && overlap > 0) { round = 0; overlap--; processed++; } /* Re-encode remaining frames if a frame didn't fit. */ if (first) { first = False; overlap = Math::Min(processed, overlap); processed -= overlap; } if (!complete) worker->ReEncode(processed, round); } overlap = 4 * 1152 / frameSize; return dataLength; } Int BoCA::EncoderLAME::ProcessPackets(const Buffer &data, const Array &chunkSizes, Bool first, Int &processed, Bool &complete) { if (workers.Length() == 1) return driver->WriteData(data, data.Size()); Buffer packets; Array packetSizes; repacker->UnpackFrames(data, packets, packetSizes); Int offset = 0; Int dataLength = 0; if (!first) for (Int i = 0; i < overlap; i++) offset += packetSizes.GetNth(i); processed = 0; complete = False; for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap && !first) continue; if (packetSizes.GetNth(i) == 0) continue; if (!repacker->WriteFrame(packets + offset, packetSizes.GetNth(i))) return dataLength; processed++; offset += packetSizes.GetNth(i); dataLength += packetSizes.GetNth(i); } complete = True; return dataLength; } Bool BoCA::EncoderLAME::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "lame-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureLAME::ConfigID, "Preset", 0); config->SetIntValue(ConfigureLAME::ConfigID, "SetBitrate", True); config->SetIntValue(ConfigureLAME::ConfigID, "Bitrate", 192); config->SetIntValue(ConfigureLAME::ConfigID, "ABRBitrate", 192); config->SetIntValue(ConfigureLAME::ConfigID, "VBRQuality", 50); config->SetIntValue(ConfigureLAME::ConfigID, "VBRMode", vbr_default); } /* Get command line settings. */ Int mode = config->GetIntValue(ConfigureLAME::ConfigID, "VBRMode", vbr_default); String modeString = "VBR"; if (mode == vbr_abr) modeString = "ABR"; else if (mode == vbr_off) modeString = "CBR"; Int bitrate = config->GetIntValue(ConfigureLAME::ConfigID, mode == vbr_off ? "Bitrate" : "ABRBitrate", 192); Int quality = config->GetIntValue(ConfigureLAME::ConfigID, "VBRQuality", 50) / 10; if (config->GetIntValue(encoderID, "Set CBR/ABR bitrate", False)) bitrate = config->GetIntValue(encoderID, "CBR/ABR bitrate", bitrate); if (config->GetIntValue(encoderID, "Set VBR quality", False)) quality = config->GetIntValue(encoderID, "VBR quality", quality); if (config->GetIntValue(encoderID, "Set Mode", False)) modeString = config->GetStringValue(encoderID, "Mode", modeString).ToUpper(); /* Set configuration values. */ config->SetIntValue(ConfigureLAME::ConfigID, "Bitrate", Math::Max(0, Math::Min(320, bitrate))); config->SetIntValue(ConfigureLAME::ConfigID, "ABRBitrate", Math::Max(0, Math::Min(320, bitrate))); config->SetIntValue(ConfigureLAME::ConfigID, "VBRQuality", Math::Max(0, Math::Min(9, quality)) * 10); if (modeString == "VBR") mode = vbr_mtrh; else if (modeString == "ABR") mode = vbr_abr; else if (modeString == "CBR") mode = vbr_off; config->SetIntValue(ConfigureLAME::ConfigID, "VBRMode", mode); return True; } ConfigLayer *BoCA::EncoderLAME::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureLAME(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/lame.h000066400000000000000000000030711516712004000237760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "repacker.h" #include "worker.h" BoCA_BEGIN_COMPONENT(EncoderLAME) namespace BoCA { class EncoderLAME : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; Array workers; Int nextWorker; Int dataOffset; Int frameSize; Int blockSize; Int overlap; Int64 totalSamples; SuperRepacker *repacker; Buffer samplesBuffer; Int EncodeFrames(Bool); Int ProcessResults(SuperWorker *, Bool); Int ProcessPackets(const Buffer &, const Array &, Bool, Int &, Bool &); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderLAME(); ~EncoderLAME(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderLAME) BoCA_END_COMPONENT(EncoderLAME) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/repacker.cpp000066400000000000000000000405631516712004000252160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "repacker.h" #include "framecrc.h" namespace BoCA { static const Int maxFrameSize = 1441; static const Int bitrates[4][16] = { { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0 }, // MPEG 2.5 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // reserved { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0 }, // MPEG 2 { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0 } }; // MPEG 1 static const Int samplerates[4][4] = { { 11025, 12000, 8000, 0 }, // MPEG 2.5 { 0, 0, 0, 0 }, // reserved { 22050, 24000, 16000, 0 }, // MPEG 2 { 44100, 48000, 32000, 0 } }; // MPEG 1 static Int GetMode(const UnsignedByte *frame) { return (frame[1] >> 3) & 0x03; } static Int GetLayer(const UnsignedByte *frame) { return (frame[1] >> 1) & 0x03; } static Int GetBitrateIndex(const UnsignedByte *frame) { return frame[2] >> 4; } static Void SetBitrateIndex(UnsignedByte *frame, Int brindex) { frame[2] = (brindex << 4) | (frame[2] & 0x0F); } static Int GetSampleRateIndex(const UnsignedByte *frame) { return (frame[2] >> 2) & 0x03; } static Bool GetPadding(const UnsignedByte *frame) { return (frame[2] >> 1) & 0x01; } static Void SetPadding(UnsignedByte *frame, Bool padding) { frame[2] = (padding ? 0x02 : 0x00) | (frame[2] & 0xFD); } static Int GetFrameSize(const UnsignedByte *frame) { Int mode = GetMode(frame); Int brindex = GetBitrateIndex(frame); Int srindex = GetSampleRateIndex(frame); Int bitrate = bitrates[mode][brindex]; Int srate = samplerates[mode][srindex]; Int padding = GetPadding(frame); return (mode == 3 ? 144 : 72) * bitrate / srate + padding; } static Int GetHeaderLength(const UnsignedByte *frame) { if (frame[1] & 0x01) return 4; return 6; } static Int GetSideInfoLength(const UnsignedByte *frame) { return GetMode(frame) == 3 ? ((frame[3] >> 6) == 0x03 ? 17 : 32) : ((frame[3] >> 6) == 0x03 ? 9 : 17); } static Int GetMainDataOffset(const UnsignedByte *frame) { Int hl = GetHeaderLength(frame); return GetMode(frame) == 3 ? (frame[hl] << 1) | (frame[hl + 1] >> 7) : frame[hl]; } static Void SetMainDataOffset(UnsignedByte*frame, Int offset) { Int hl = GetHeaderLength(frame); if (GetMode(frame) == 3) { frame[hl ] = offset >> 1; frame[hl + 1] = ((offset & 1) << 7) | (frame[hl + 1] & 0x7F); } else { frame[hl ] = offset; } } static Int GetMainDataLength(const UnsignedByte *frame) { Int hl = GetHeaderLength(frame); Int bits = 0; if (GetMode(frame) != 3) { if (GetSideInfoLength(frame) == 9) { bits += ((frame[hl + 1] & 0x7F) << 5) | (frame[hl + 2] >> 3); } else { bits += ((frame[hl + 1] & 0x3F) << 6) | (frame[hl + 2] >> 2); bits += ((frame[hl + 9] & 0x7F) << 5) | (frame[hl + 10] >> 3); } } else { if (GetSideInfoLength(frame) == 17) { bits += ((frame[hl + 2] & 0x3F) << 6) | (frame[hl + 3] >> 2) ; bits += ((frame[hl + 9] & 0x07) << 9) | (frame[hl + 10] << 1) | (frame[hl + 11] >> 7); } else { bits += ((frame[hl + 2] & 0x0F) << 8) | (frame[hl + 3] ) ; bits += ((frame[hl + 9] & 0x01) << 11) | (frame[hl + 10] << 3) | (frame[hl + 11] >> 5); bits += ((frame[hl + 17] & 0x3F) << 6) | (frame[hl + 18] >> 2) ; bits += ((frame[hl + 24] & 0x07) << 9) | (frame[hl + 25] << 1) | (frame[hl + 26] >> 7); } } return Math::Ceil(Float(bits) / 8); } static Bool IsValidFrame(const UnsignedByte *frame, const UnsignedByte *reference = NIL) { if (((frame[0] << 3) | (frame[1] >> 5)) != 0x07FF) return False; Int mode = GetMode(frame); Int layer = GetLayer(frame); Int brindex = GetBitrateIndex(frame); Int srindex = GetSampleRateIndex(frame); if (mode == 1 || layer != 1 || brindex == 0 || brindex == 15 || srindex == 3) return False; Int frameb = GetFrameSize(frame); if (frameb < 24) return False; /* Verify that frame parameters are constant. */ if (reference != NIL) { if (GetMode(frame) != GetMode(reference) || GetHeaderLength(frame) != GetHeaderLength(reference) || GetSampleRateIndex(frame) != GetSampleRateIndex(reference)) return False; } return True; } }; BoCA::SuperRepacker::SuperRepacker(IO::Driver *iDriver) { driver = iDriver; offset = driver->GetPos(); frameCount = 0; reservoir = 0; cbrIndex = -1; minIndex = 1; maxIndex = 14; } BoCA::SuperRepacker::~SuperRepacker() { } Bool BoCA::SuperRepacker::EnableRateControl(Int minRate, Int maxRate) { if (maxRate < minRate) return False; minIndex = -minRate; maxIndex = -maxRate; return True; } Bool BoCA::SuperRepacker::UpdateInfoTag(Buffer &frame, Int64 totalSamples) const { if (frame.Size() < 169) return False; UnsignedByte *tag = frame + 4 + GetSideInfoLength(frame); /* Set frame count (minus this info frame). */ UnsignedInt32 frames = frameCount - 1; tag[0x08] = frames >> 24; tag[0x09] = (frames >> 16) & 0xFF; tag[0x0A] = (frames >> 8) & 0xFF; tag[0x0B] = frames & 0xFF; /* Set byte count. */ UnsignedInt32 bytes = driver->GetSize() - offset; tag[0x0C] = bytes >> 24; tag[0x0D] = (bytes >> 16) & 0xFF; tag[0x0E] = (bytes >> 8) & 0xFF; tag[0x0F] = bytes & 0xFF; /* Write TOC. */ for (Int i = 0; i < 100; i++) { UnsignedInt32 offset = frameOffsets.GetNth(frameOffsets.Length() * i / 100); tag[0x10 + i] = Math::Min(255, Math::Floor(256.0 * offset / bytes)); } /* Set pad samples. */ Int delaySamples = (tag[0x8D] << 4) | ((tag[0x8E] & 0xF0) >> 4); Int padSamples = frames * (GetMode(frame) == 3 ? 1152 : 576) - totalSamples - delaySamples; tag[0x8E] |= padSamples >> 8; tag[0x8F] = padSamples & 0xFF; /* Set byte count. */ tag[0x94] = bytes >> 24; tag[0x95] = (bytes >> 16) & 0xFF; tag[0x96] = (bytes >> 8) & 0xFF; tag[0x97] = bytes & 0xFF; /* Calculate music CRC. */ Hash::CRC16 hash; driver->Seek(offset + GetFrameSize(frame)); Buffer buffer(256 * 1024); Int64 bytesLeft = driver->GetSize() - driver->GetPos(); while (bytesLeft) { Int bytes = driver->ReadData(buffer, Math::Min(bytesLeft, Int64(256 * 1024))); hash.Feed(buffer, bytes); bytesLeft -= bytes; } /* Set music CRC. */ UnsignedInt16 musicCRC = hash.Finish(); tag[0x98] = musicCRC >> 8; tag[0x99] = musicCRC & 0xFF; /* Set info CRC. */ UnsignedInt16 tagCRC = Hash::CRC16::Compute(frame, 4 + GetSideInfoLength(frame) + 0x9A); tag[0x9A] = tagCRC >> 8; tag[0x9B] = tagCRC & 0xFF; return True; } Bool BoCA::SuperRepacker::UnpackFrames(const Buffer &data, Buffer &packets, Array &packetSizes) { Buffer main; for (Int n = 0; n < data.Size(); n++) { if (!IsValidFrame(data + n)) continue; UnsignedByte *frame = data + n; Int frameb = GetFrameSize(frame); Int info = GetHeaderLength(frame) + GetSideInfoLength(frame); Int bytes = GetMainDataLength(frame); Int pre = GetMainDataOffset(frame); /* Set CBR bitrate index. */ if (cbrIndex == -1) cbrIndex = GetBitrateIndex(frame); else if (cbrIndex != 0 && cbrIndex != GetBitrateIndex(frame)) cbrIndex = 0; /* Set minimum/maximum VBR bitrate index. */ Int mode = GetMode(frame); if (minIndex < 0) for (Int i = 1; i <= 14; i++) if (bitrates[mode][i] >= -minIndex || i == 14) { minIndex = i; break; } if (maxIndex < 0) for (Int i = 14; i >= 1; i--) if (bitrates[mode][i] <= -maxIndex || i == 1) { maxIndex = i; break; } /* Buffer main data. */ main.Resize(main.Size() + frameb - info); memcpy(main + main.Size() - (frameb - info), frame + info, frameb - info); /* Write packet. */ Int offset = packets.Size(); Int size = Math::Max(info + bytes, frameb); packets.Resize(packets.Size() + size); memcpy(packets + offset, frame, info); memcpy(packets + offset + info, main + main.Size() - (frameb - info) - pre, bytes); SetBitrateIndex(packets + offset, cbrIndex); SetMainDataOffset(packets + offset, 0); packetSizes.Add(size); n += frameb - 1; } return True; } Bool BoCA::SuperRepacker::WriteFrame(UnsignedByte *iFrame, Int size) { UnsignedByte frame[maxFrameSize + 511] = { 0 }; // Frame can exceed maxFrameSize when using reservoir. if (frameCount++ == 0 && memcmp(iFrame + GetHeaderLength(iFrame), frame, GetSideInfoLength(iFrame)) == 0) { driver->WriteData(iFrame, size); return True; } memcpy(frame, iFrame, size); Int info = GetHeaderLength(frame) + GetSideInfoLength(frame); Int bytes = GetMainDataLength(frame); /* Fill superfluous reservoir with zero bytes. */ Int maxR = GetMode(frame) == 3 ? 511 : 255; FillReservoir(maxR); /* Process frame data. */ while (True) { /* Write main data to reservoir. */ driver->WriteData(frame + info, Math::Min(reservoir, bytes)); SetMainDataOffset(frame, GetMainDataOffset(frame) + reservoir); /* Write next frame header and remaining bytes. */ if (bytes >= reservoir && frameBuffer.Size() >= info) { /* Update frame. */ memmove(frame + info, frame + info + reservoir, bytes - reservoir); bytes -= reservoir; reservoir = GetFrameSize(frameBuffer) - info; /* Write buffered frame header. */ frameOffsets.Add(driver->GetPos() - offset); driver->WriteData(frameBuffer, info); memmove(frameBuffer, frameBuffer + info, frameBuffer.Size() - info); frameBuffer.Resize(frameBuffer.Size() - info); continue; } /* Update main data offset and compute total reservoir size. */ Int total = reservoir; for (Int i = 0; i < frameBuffer.Size(); i += info) { SetMainDataOffset(frame, GetMainDataOffset(frame) + GetFrameSize(frameBuffer + i) - info); total += GetFrameSize(frameBuffer + i) - info; } /* Adjust bitrate to stay under maximum reservoir size. */ if (!cbrIndex) { SetBitrateIndex(frame, maxIndex); while (GetFrameSize(frame) - info + total - bytes > maxR) { if (GetBitrateIndex(frame) == minIndex) break; SetBitrateIndex(frame, GetBitrateIndex(frame) - 1); } } /* Increase reservoir if not enough bytes left. */ Int required = bytes - reservoir - (GetFrameSize(frame) - info); if (required > 0) { Int prevRes = reservoir; IncreaseReservoir(required, frame); SetMainDataOffset(frame, GetMainDataOffset(frame) + reservoir - prevRes); driver->WriteData(frame + info + prevRes, reservoir - prevRes); } /* Revert changes if new data does not fit into frame. */ if (bytes - reservoir - (GetFrameSize(frame) - info) > 0) { driver->Seek(driver->GetPos() - reservoir); frameCount--; return False; } /* Compute frame CRC. */ if (GetHeaderLength(frame) == 6) FrameCRC::Update(frame); /* Process frame depending on reservoir size. */ if (bytes >= reservoir) { /* Write frame. */ frameOffsets.Add(driver->GetPos() - offset); driver->WriteData(frame, info); driver->WriteData(frame + info + reservoir, bytes - reservoir); reservoir += GetFrameSize(frame) - info - bytes; } else { /* Write header to back buffer. */ frameBuffer.Resize(frameBuffer.Size() + info); memcpy(frameBuffer + frameBuffer.Size() - info, frame, info); reservoir -= bytes; } break; } return True; } Bool BoCA::SuperRepacker::Flush() { return FillReservoir(); } Bool BoCA::SuperRepacker::FillReservoir(Int threshold) { /* Get total reservoir size including buffered frames. */ Int total = reservoir; if (frameBuffer.Size() > 0) { Int info = GetHeaderLength(frameBuffer) + GetSideInfoLength(frameBuffer); for (Int i = 0; i < frameBuffer.Size(); i += info) total += GetFrameSize(frameBuffer + i) - info; } /* Fill superfluous reservoir with zero bytes. */ UnsignedByte zero[maxFrameSize] = { 0 }; while (total > threshold) { driver->WriteData(zero, Math::Min(total - threshold, reservoir)); if (total - threshold <= reservoir) { reservoir -= total - threshold; total -= total - threshold; } else { Int info = GetHeaderLength(frameBuffer) + GetSideInfoLength(frameBuffer); total -= reservoir; reservoir = GetFrameSize(frameBuffer) - info; /* Write buffered frame header. */ driver->WriteData(frameBuffer, info); memmove(frameBuffer, frameBuffer + info, frameBuffer.Size() - info); frameBuffer.Resize(frameBuffer.Size() - info); } } return True; } Bool BoCA::SuperRepacker::IncreaseReservoir(Int bytes, UnsignedByte *reference, Int depth) { /* Limit recursion depth to avoid stack overflow. */ if (depth == 256) return False; /* Find last written frame. */ UnsignedByte data[2 * maxFrameSize]; Int dataSize = Math::Min(driver->GetPos() - offset, sizeof(data)); driver->Seek(driver->GetPos() - dataSize); driver->ReadData(data, dataSize); for (Int n = dataSize - 13; n >= 0; n--) { if (!IsValidFrame(data + n, reference)) continue; UnsignedByte *frame = data + n; Int frameb = GetFrameSize(frame); Int nframeb = GetFrameSize(frame); /* Verify that frame size looks correct. */ if (frameb != dataSize - n) continue; /* Verify that there is a frame preceding this one at the correct position. */ if (!CheckPrecedingFrame(data, n, reference)) continue; /* Check that reservoir plus requested bytes does not exceed maximum reservoir size. */ Int offset = driver->GetPos() - frameb; Int info = GetHeaderLength(frame) + GetSideInfoLength(frame); Int pre = GetMainDataOffset(frame); Int maxR = GetMode(frame) == 3 ? 511 : 255; if (reservoir + bytes >= maxR) return False; Int prevRes = reservoir; /* Check if frame can be enlarged. */ Int brindex = GetBitrateIndex(frame); while ((brindex < maxIndex && !cbrIndex) || !GetPadding(frame)) { if ((brindex == maxIndex || cbrIndex) || (nframeb - frameb == bytes - 1 && !GetPadding(frame))) SetPadding(frame, True); else SetBitrateIndex(frame, ++brindex); nframeb = GetFrameSize(frame); if (nframeb - frameb >= bytes) { /* Compute frame CRC. */ if (GetHeaderLength(frame) == 6) FrameCRC::Update(frame); /* Write updated frame and update reservoir size. */ driver->Seek(offset); driver->WriteData(frame, Math::Max(info, frameb - prevRes)); reservoir += nframeb - frameb; /* Fill superfluous reservoir with zero bytes. */ FillReservoir(maxR); driver->WriteData(frame + Math::Max(info, frameb - prevRes), Math::Min(prevRes, frameb - info)); return True; } } /* Recursively try enlarging previous frames. */ driver->Seek(offset); reservoir = pre; Bool result = IncreaseReservoir(bytes - (nframeb - frameb), reference, depth + 1); SetMainDataOffset(frame, reservoir); /* Compute frame CRC. */ if (GetHeaderLength(frame) == 6) FrameCRC::Update(frame); /* Write modified frame. */ Int frameRes = Math::Min(frameb - info - (reservoir - pre), prevRes); driver->WriteData(frame + info, reservoir - pre); driver->WriteData(frame, info); driver->WriteData(frame + info + reservoir - pre, frameb - info - (reservoir - pre) - frameRes); reservoir += prevRes - pre + nframeb - frameb; /* Fill superfluous reservoir with zero bytes. */ FillReservoir(maxR); driver->WriteData(frame + frameb - frameRes, frameRes); return result; } return False; } Bool BoCA::SuperRepacker::CheckPrecedingFrame(UnsignedByte *data, Int offset, UnsignedByte *reference) { for (Int n = offset - 13; n >= 0; n--) { if (!IsValidFrame(data + n, reference)) continue; /* Verify that frame size looks correct. */ if (GetFrameSize(data + n) != offset - n) continue; return True; } return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/repacker.h000066400000000000000000000025531516712004000246600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include namespace BoCA { class SuperRepacker { private: IO::Driver *driver; Int offset; Int frameCount; Int reservoir; Int cbrIndex; Int minIndex; Int maxIndex; Buffer frameBuffer; Array frameOffsets; Bool FillReservoir(Int = 0); Bool IncreaseReservoir(Int, UnsignedByte *, Int = 0); Bool CheckPrecedingFrame(UnsignedByte *, Int, UnsignedByte *); public: SuperRepacker(IO::Driver *); ~SuperRepacker(); Bool EnableRateControl(Int, Int); Bool UnpackFrames(const Buffer &, Buffer &, Array &); Bool WriteFrame(UnsignedByte *, Int); Bool Flush(); Bool UpdateInfoTag(Buffer &, Int64) const; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/worker.cpp000066400000000000000000000271071516712004000247320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "config.h" BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat, Int iOverlap) : processSignal(1), readySignal(1) { processSignal.Wait(); flush = False; quit = False; format = iFormat; overlap = iOverlap; threadMain.Connect(&SuperWorker::Run, this); /* Get configuration. */ Int preset = config->GetIntValue(ConfigureLAME::ConfigID, "Preset", 2); Int vbrMode = config->GetIntValue(ConfigureLAME::ConfigID, "VBRMode", 4); Bool setBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetBitrate", 1); Int bitrate = config->GetIntValue(ConfigureLAME::ConfigID, "Bitrate", 192); Int ratio = config->GetIntValue(ConfigureLAME::ConfigID, "Ratio", 1100); Bool setQuality = config->GetIntValue(ConfigureLAME::ConfigID, "SetQuality", 0); Int quality = config->GetIntValue(ConfigureLAME::ConfigID, "Quality", 3); Int abrBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "ABRBitrate", 192); Int vbrQuality = config->GetIntValue(ConfigureLAME::ConfigID, "VBRQuality", 50); Bool setMinVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetMinVBRBitrate", 0); Bool setMaxVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "SetMaxVBRBitrate", 0); Int minVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "MinVBRBitrate", 128); Int maxVBRBitrate = config->GetIntValue(ConfigureLAME::ConfigID, "MaxVBRBitrate", 256); Bool copyrightBit = config->GetIntValue(ConfigureLAME::ConfigID, "Copyright", 0); Bool originalBit = config->GetIntValue(ConfigureLAME::ConfigID, "Original", 1); Bool privateBit = config->GetIntValue(ConfigureLAME::ConfigID, "Private", 0); Bool crc = config->GetIntValue(ConfigureLAME::ConfigID, "CRC", 0); Bool strictISO = config->GetIntValue(ConfigureLAME::ConfigID, "StrictISO", 0); Int stereoMode = config->GetIntValue(ConfigureLAME::ConfigID, "StereoMode", 0); Bool forceJS = config->GetIntValue(ConfigureLAME::ConfigID, "ForceJS", 0); Bool enableATH = config->GetIntValue(ConfigureLAME::ConfigID, "EnableATH", 1); Int athType = config->GetIntValue(ConfigureLAME::ConfigID, "ATHType", -1); Bool useTNS = config->GetIntValue(ConfigureLAME::ConfigID, "UseTNS", 1); Int tnsMode = config->GetIntValue(ConfigureLAME::ConfigID, "TNSMode", -1); Bool disableFiltering = config->GetIntValue(ConfigureLAME::ConfigID, "DisableFiltering", 0); Bool setLowpass = config->GetIntValue(ConfigureLAME::ConfigID, "SetLowpass", 0); Int lowpass = config->GetIntValue(ConfigureLAME::ConfigID, "Lowpass", 0); Bool setHighpass = config->GetIntValue(ConfigureLAME::ConfigID, "SetHighpass", 0); Int highpass = config->GetIntValue(ConfigureLAME::ConfigID, "Highpass", 0); Bool setLowpassWidth = config->GetIntValue(ConfigureLAME::ConfigID, "SetLowpassWidth", 0); Int lowpassWidth = config->GetIntValue(ConfigureLAME::ConfigID, "LowpassWidth", 0); Bool setHighpassWidth = config->GetIntValue(ConfigureLAME::ConfigID, "SetHighpassWidth", 0); Int highpassWidth = config->GetIntValue(ConfigureLAME::ConfigID, "HighpassWidth", 0); /* Create and configure LAME encoder. */ context = ex_lame_init(); ex_lame_set_in_samplerate(context, format.rate); ex_lame_set_num_channels(context, format.channels); switch (preset) { case 0: ex_lame_set_copyright(context, copyrightBit); ex_lame_set_original(context, originalBit); ex_lame_set_extension(context, privateBit); ex_lame_set_error_protection(context, crc); /* Enforce strict ISO compliance. */ if (strictISO) ex_lame_set_strict_ISO(context, strictISO); /* Set bitrate. */ if (vbrMode == vbr_off) { if (setBitrate) ex_lame_set_brate(context, bitrate); else ex_lame_set_compression_ratio(context, ratio / 100.0); } /* Set quality. */ if (setQuality) { /* For LAME 3.99 through LAME 3.101 beta 3, limit quality value * to 4-9 in CBR/ABR mode as there is an encoder issue at 0-3. * * See https://sourceforge.net/p/lame/bugs/516/ for reference. */ if (vbrMode == vbr_off || vbrMode == vbr_abr) { lame_version_t version = { 0 }; ex_get_lame_version_numerical(&version); if ((version.major == 3 && version.minor >= 99 && version.minor <= 100) || (version.major == 3 && version.minor == 101 && (version.alpha || (version.beta && version.beta <= 3)))) quality = Math::Max(quality, 4); } ex_lame_set_quality(context, quality); } /* Set audio filtering. */ if (disableFiltering) { ex_lame_set_lowpassfreq(context, -1); ex_lame_set_highpassfreq(context, -1); } else { if (setLowpass) ex_lame_set_lowpassfreq(context, lowpass); if (setHighpass) ex_lame_set_highpassfreq(context, highpass); if (setLowpass && setLowpassWidth) ex_lame_set_lowpasswidth(context, lowpassWidth); if (setHighpass && setHighpassWidth) ex_lame_set_highpasswidth(context, highpassWidth); } /* Set Stereo mode. */ if (stereoMode == 1) ex_lame_set_mode(context, MONO); else if (stereoMode == 2) ex_lame_set_mode(context, STEREO); else if (stereoMode == 3) ex_lame_set_mode(context, JOINT_STEREO); else ex_lame_set_mode(context, NOT_SET); if (stereoMode == 3) { if (forceJS) ex_lame_set_force_ms(context, 1); else ex_lame_set_force_ms(context, 0); } /* Set VBR mode. */ switch (vbrMode) { default: case vbr_off: break; case vbr_abr: ex_lame_set_VBR(context, vbr_abr); ex_lame_set_VBR_mean_bitrate_kbps(context, abrBitrate); break; case vbr_rh: ex_lame_set_VBR(context, vbr_rh); ex_lame_set_VBR_quality(context, vbrQuality / 10.0); break; case vbr_mtrh: ex_lame_set_VBR(context, vbr_mtrh); ex_lame_set_VBR_quality(context, vbrQuality / 10.0); break; } if (vbrMode != vbr_off && setMinVBRBitrate) ex_lame_set_VBR_min_bitrate_kbps(context, minVBRBitrate); if (vbrMode != vbr_off && setMaxVBRBitrate) ex_lame_set_VBR_max_bitrate_kbps(context, maxVBRBitrate); /* Set ATH. */ if (!enableATH) ex_lame_set_noATH(context, 1); else if (athType != -1) ex_lame_set_ATHtype(context, athType); /* Set TNS. */ if (!useTNS) ex_lame_set_useTemporal(context, 0); else if (tnsMode != -1) ex_lame_set_useTemporal(context, 1); break; case 1: ex_lame_set_preset(context, MEDIUM); break; case 2: ex_lame_set_preset(context, STANDARD); break; case 3: ex_lame_set_preset(context, EXTREME); break; case 4: ex_lame_set_preset(context, abrBitrate); break; } ex_lame_init_params(context); frameSize = ex_lame_get_framesize(context); maxPacketSize = frameSize * 1.25 + 7200; bytesPerSample = format.bits / 8; } BoCA::SuperWorker::~SuperWorker() { /* Destroy LAME encoder. */ ex_lame_close(context); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); Int samplesLeft = samplesBuffer.Size() / bytesPerSample; Int samplesPerFrame = frameSize * format.channels; Int framesProcessed = 0; while (flush || samplesLeft >= samplesPerFrame) { packetBuffer.Resize(packetBuffer.Size() + maxPacketSize); Int dataLength = 0; if (samplesLeft > 0) { if (format.bits == 16) { if (format.channels == 2) dataLength = ex_lame_encode_buffer_interleaved(context, ((short int *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, Math::Min(samplesLeft / 2, frameSize), packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); else dataLength = ex_lame_encode_buffer( context, ((short int *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, ((short int *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, Math::Min(samplesLeft, frameSize), packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); } else { if (format.channels == 2) dataLength = ex_lame_encode_buffer_interleaved_ieee_float(context, ((float *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, Math::Min(samplesLeft / 2, frameSize), packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); else dataLength = ex_lame_encode_buffer_ieee_float( context, ((float *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, ((float *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, Math::Min(samplesLeft, frameSize), packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); } } else { dataLength = ex_lame_encode_flush(context, packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); } packetBuffer.Resize(packetBuffer.Size() - maxPacketSize + dataLength); if (samplesLeft < 0 && dataLength == 0) break; packetSizes.Add(dataLength); framesProcessed++; samplesLeft -= samplesPerFrame; } /* Flush at the end of each block in parallel mode. */ if (overlap > 0) { packetBuffer.Resize(packetBuffer.Size() + maxPacketSize); Int dataLength = ex_lame_encode_flush_nogap(context, packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); packetBuffer.Resize(packetBuffer.Size() - maxPacketSize + dataLength); if (dataLength > 0) packetSizes.Add(dataLength); } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int samples, Bool last) { samplesBuffer.Resize(samples * bytesPerSample); memcpy(samplesBuffer, buffer + offset * bytesPerSample, samples * bytesPerSample); flush = last; processSignal.Release(); } Void BoCA::SuperWorker::ReEncode(Int skipFrames, Int dummyFrames) { Int skipSamples = skipFrames * frameSize * format.channels; Int dummySamples = dummyFrames * frameSize * format.channels; /* Backup samples buffer. */ Buffer backupBuffer(samplesBuffer.Size() - skipSamples * bytesPerSample); memcpy(backupBuffer, samplesBuffer + skipSamples * bytesPerSample, backupBuffer.Size()); /* Create buffer with dummy data. */ Buffer dummyBuffer(dummySamples * bytesPerSample); for (Int i = 0; i < dummySamples; i++) { if (format.bits == 16) ((short int *) (UnsignedByte *) dummyBuffer)[i] = i * 147; else ((float *) (UnsignedByte *) dummyBuffer)[i] = float(i) * 0.0045f; } /* Encode dummy frames to pressure reservoir. */ Encode(dummyBuffer, 0, dummyBuffer.Size() / bytesPerSample, flush); WaitUntilReady(); /* Re-encode previous samples. */ Encode(backupBuffer, 0, backupBuffer.Size() / bytesPerSample, flush); WaitUntilReady(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Void BoCA::SuperWorker::GetInfoTag(Buffer &buffer) const { buffer.Resize(2880); // Maximum frame size Int size = ex_lame_get_lametag_frame(context, buffer, buffer.Size()); buffer.Resize(size); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/lame/worker.h000066400000000000000000000030071516712004000243700ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; lame_t context; Format format; Int frameSize; Int maxPacketSize; Buffer samplesBuffer; Int bytesPerSample; Buffer packetBuffer; Array packetSizes; Int overlap; Bool flush; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &, Int); ~SuperWorker(); Void Encode(const Buffer &, Int, Int, Bool); Void ReEncode(Int, Int); Void WaitUntilReady(); Void GetInfoTag(Buffer &) const; Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/000077500000000000000000000000001516712004000225305ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/Makefile000077500000000000000000000015171516712004000241770ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mac TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = config.o dllinterface.o mac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support ifeq ($(BUILD_WIN32),True) DEFINE += -DPLATFORM_WINDOWS -DWINVER=0x0500 else DEFINE += -DPLATFORM_LINUX endif # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/config.cpp000077500000000000000000000037771516712004000245220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureMAC::ConfigID = "MAC"; BoCA::ConfigureMAC::ConfigureMAC() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::Monkey's Audio"); group_compression = new GroupBox(i18n->TranslateString("Compression"), Point(7, 11), Size(216, 39)); text_compression = new Text(i18n->AddColon(i18n->TranslateString("Compression mode")), Point(9, 13)); combo_compression = new ComboBox(Point(text_compression->GetUnscaledTextWidth() + 17, 10), Size(189 - text_compression->GetUnscaledTextWidth(), 0)); combo_compression->AddEntry(i18n->TranslateString("Fast")); combo_compression->AddEntry(i18n->TranslateString("Normal")); combo_compression->AddEntry(i18n->TranslateString("High")); combo_compression->AddEntry(i18n->TranslateString("Extra high")); combo_compression->AddEntry(i18n->TranslateString("Insane")); combo_compression->SelectNthEntry(config->GetIntValue(ConfigID, "CompressionMode", 2)); group_compression->Add(text_compression); group_compression->Add(combo_compression); Add(group_compression); SetSize(Size(230, 57)); } BoCA::ConfigureMAC::~ConfigureMAC() { DeleteObject(group_compression); DeleteObject(text_compression); DeleteObject(combo_compression); } Int BoCA::ConfigureMAC::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "CompressionMode", combo_compression->GetSelectedEntryNumber()); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/config.h000077500000000000000000000020161516712004000241500ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_MACCONFIG #define H_MACCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureMAC : public ConfigLayer { private: GroupBox *group_compression; Text *text_compression; ComboBox *combo_compression; public: static const String ConfigID; ConfigureMAC(); ~ConfigureMAC(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/dllinterface.cpp000077500000000000000000000052771516712004000257060ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" APECOMPRESS_CREATE ex_APECompress_Create = NIL; APECOMPRESS_DESTROY ex_APECompress_Destroy = NIL; APECOMPRESS_STARTW ex_APECompress_StartW = NIL; APECOMPRESS_ADDDATA ex_APECompress_AddData = NIL; APECOMPRESS_FINISH ex_APECompress_Finish = NIL; APECOMPRESS_SETNUMBEROFTHREADS ex_APECompress_SetNumberOfThreads = NIL; GETLIBRARYVERSIONSTRING ex_GetLibraryVersionString = NIL; GETLIBRARYINTERFACEVERSION ex_GetLibraryInterfaceVersion = NIL; DynamicLoader *macdll = NIL; Bool LoadMACDLL() { #ifdef __WIN32__ macdll = BoCA::Utilities::LoadCodecDLL("MACDll"); #else macdll = BoCA::Utilities::LoadCodecDLL("MAC"); #endif if (macdll == NIL) return False; ex_APECompress_Create = (APECOMPRESS_CREATE) macdll->GetFunctionAddress("c_APECompress_Create"); ex_APECompress_Destroy = (APECOMPRESS_DESTROY) macdll->GetFunctionAddress("c_APECompress_Destroy"); ex_APECompress_StartW = (APECOMPRESS_STARTW) macdll->GetFunctionAddress("c_APECompress_StartW"); ex_APECompress_AddData = (APECOMPRESS_ADDDATA) macdll->GetFunctionAddress("c_APECompress_AddData"); ex_APECompress_Finish = (APECOMPRESS_FINISH) macdll->GetFunctionAddress("c_APECompress_Finish"); ex_APECompress_SetNumberOfThreads = (APECOMPRESS_SETNUMBEROFTHREADS) macdll->GetFunctionAddress("c_APECompress_SetNumberOfThreads"); ex_GetLibraryVersionString = (GETLIBRARYVERSIONSTRING) macdll->GetFunctionAddress("GetLibraryVersionString"); ex_GetLibraryInterfaceVersion = (GETLIBRARYINTERFACEVERSION) macdll->GetFunctionAddress("GetLibraryInterfaceVersion"); if (ex_APECompress_Create == NIL || ex_APECompress_Destroy == NIL || ex_APECompress_StartW == NIL || ex_APECompress_AddData == NIL || ex_APECompress_Finish == NIL || ex_GetLibraryVersionString == NIL || ex_GetLibraryInterfaceVersion == NIL) { FreeMACDLL(); return False; } /* Check library interface version. */ unsigned int interfaceVersion = ex_GetLibraryInterfaceVersion(); if (interfaceVersion > 15) { FreeMACDLL(); return False; } return True; } Void FreeMACDLL() { Object::DeleteObject(macdll); macdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/dllinterface.h000077500000000000000000000037041516712004000253440ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace APE; using namespace smooth; using namespace smooth::System; extern DynamicLoader *macdll; Bool LoadMACDLL(); Void FreeMACDLL(); typedef APE_COMPRESS_HANDLE (__stdcall *APECOMPRESS_CREATE) (int *); typedef void (__stdcall *APECOMPRESS_DESTROY) (APE_COMPRESS_HANDLE); typedef int (__stdcall *APECOMPRESS_STARTW) (APE_COMPRESS_HANDLE, const APE::str_utfn *, const APE::WAVEFORMATEX *, APE::int64, int, const void *, APE::int64); typedef APE::int64 (__stdcall *APECOMPRESS_ADDDATA) (APE_COMPRESS_HANDLE, unsigned char *, int); typedef int (__stdcall *APECOMPRESS_FINISH) (APE_COMPRESS_HANDLE, unsigned char *, APE::int64, APE::int64); typedef int (__stdcall *APECOMPRESS_SETNUMBEROFTHREADS) (APE_COMPRESS_HANDLE, int); typedef const char * (__stdcall *GETLIBRARYVERSIONSTRING) (); typedef unsigned int (__stdcall *GETLIBRARYINTERFACEVERSION) (); extern APECOMPRESS_CREATE ex_APECompress_Create; extern APECOMPRESS_DESTROY ex_APECompress_Destroy; extern APECOMPRESS_STARTW ex_APECompress_StartW; extern APECOMPRESS_ADDDATA ex_APECompress_AddData; extern APECOMPRESS_FINISH ex_APECompress_Finish; extern APECOMPRESS_SETNUMBEROFTHREADS ex_APECompress_SetNumberOfThreads; extern GETLIBRARYVERSIONSTRING ex_GetLibraryVersionString; extern GETLIBRARYINTERFACEVERSION ex_GetLibraryInterfaceVersion; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/mac.cpp000066400000000000000000000160201516712004000237730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2025 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "mac.h" #include "config.h" #ifndef WAVE_FORMAT_PCM # define WAVE_FORMAT_PCM 0x0001 # define WAVE_FORMAT_IEEE_FLOAT 0x0003 #endif using namespace smooth::IO; const String &BoCA::EncoderMAC::GetComponentSpecs() { static String componentSpecs; if (macdll != NIL) { componentSpecs = " \ \ \ \ Monkey's Audio Encoder %VERSION% \ 1.0 \ mac-enc \ encoder \ \ Monkey's Audio \ true \ ape \ mac \ APEv2 \ \ \ \ \ "; if (ex_GetLibraryInterfaceVersion() >= 10) { componentSpecs.Append(" \ \ \ \ "); } componentSpecs.Append(" \ \ \ \ \ \ \ \ \ \ \ \ \ "); componentSpecs.Replace("%VERSION%", String("v").Append(ex_GetLibraryVersionString())); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMACDLL(); } Void smooth::DetachDLL() { FreeMACDLL(); } BoCA::EncoderMAC::EncoderMAC() { configLayer = NIL; config = NIL; hAPECompress = NIL; } BoCA::EncoderMAC::~EncoderMAC() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderMAC::Activate() { const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Close output file as it will be written directly by APE. */ driver->Close(); /* Create encoder and retrieve handle. */ int nRetVal = 0; hAPECompress = ex_APECompress_Create(&nRetVal); /* Get number of threads to use. */ if (ex_APECompress_SetNumberOfThreads != NIL) { Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; ex_APECompress_SetNumberOfThreads(hAPECompress, 2);//numberOfThreads); } /* Init encoder using output file name and format info. */ APE::WAVEFORMATEX waveFormat; waveFormat.wFormatTag = format.fp ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM; waveFormat.nChannels = format.channels; waveFormat.nSamplesPerSec = format.rate; waveFormat.nAvgBytesPerSec = format.rate * format.channels * (format.bits / 8); waveFormat.nBlockAlign = format.channels * (format.bits / 8); waveFormat.wBitsPerSample = format.bits; waveFormat.cbSize = 0; int64 maxAudioBytes = MAX_AUDIO_BYTES_UNKNOWN; if (track.length >= 0) maxAudioBytes = track.length * format.channels * (format.bits / 8); ex_APECompress_StartW(hAPECompress, track.outputFile, &waveFormat, maxAudioBytes, (config->GetIntValue(ConfigureMAC::ConfigID, "CompressionMode", 2) + 1) * 1000, NIL, CREATE_WAV_HEADER_ON_DECOMPRESSION); return True; } Bool BoCA::EncoderMAC::Deactivate() { /* Finish encoding and destroy the encoder. */ ex_APECompress_Finish(hAPECompress, NIL, 0, 0); ex_APECompress_Destroy(hAPECompress); /* Write APEv2 tag if requested. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableAPEv2", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("apev2-tag"); if (tagger != NIL) { OutStream out(STREAM_FILE, track.outputFile, OS_APPEND); Buffer tagBuffer; tagger->SetConfiguration(config); tagger->RenderBuffer(tagBuffer, track); out.OutputData(tagBuffer, tagBuffer.Size()); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderMAC::WriteData(Buffer &data) { /* Hand data over to the encoder. */ ex_APECompress_AddData(hAPECompress, data, data.Size()); return data.Size(); } Bool BoCA::EncoderMAC::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "mac-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureMAC::ConfigID, "CompressionMode", 2); } /* Get command line settings. */ Int compressionMode = config->GetIntValue(ConfigureMAC::ConfigID, "CompressionMode", 2); String compressionModeName = "fast"; if (compressionMode == 1) compressionModeName = "normal"; else if (compressionMode == 2) compressionModeName = "high"; else if (compressionMode == 3) compressionModeName = "extra"; else if (compressionMode == 4) compressionModeName = "insane"; if (config->GetIntValue(encoderID, "Set Compression mode", False)) compressionModeName = config->GetStringValue(encoderID, "Compression mode", compressionModeName).ToLower(); /* Set configuration values. */ if (compressionModeName == "fast" ) compressionMode = 0; else if (compressionModeName == "normal") compressionMode = 1; else if (compressionModeName == "high" ) compressionMode = 2; else if (compressionModeName == "extra" ) compressionMode = 3; else if (compressionModeName == "insane") compressionMode = 4; config->SetIntValue(ConfigureMAC::ConfigID, "CompressionMode", compressionMode); return True; } ConfigLayer *BoCA::EncoderMAC::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureMAC(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/mac/mac.h000066400000000000000000000022511516712004000234410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderMAC) namespace BoCA { class EncoderMAC : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; APE_COMPRESS_HANDLE hAPECompress; static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderMAC(); ~EncoderMAC(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderMAC) BoCA_END_COMPONENT(EncoderMAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/000077500000000000000000000000001516712004000225415ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/Makefile000066400000000000000000000011501516712004000241760ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = meh TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o config_encoder.o meh.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/config.cpp000066400000000000000000000156361516712004000245250ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "config_encoder.h" const String BoCA::ConfigureMultiEncoderHub::ConfigID = "meh!"; BoCA::ConfigureMultiEncoderHub::ConfigureMultiEncoderHub() { const Config *config = Config::Get(); separateFolders = config->GetIntValue(ConfigID, "SeparateFolders", False); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::meh!"); group_encoders = new GroupBox(i18n->TranslateString("Encoders"), Point(7, 11), Size(552, 185)); text_available = new Text(i18n->AddColon(i18n->TranslateString("Available")), Point(10, 10)); list_available = new ListBox(Point(10, 29), Size(245, 116)); list_available->onSelectEntry.Connect(&ConfigureMultiEncoderHub::OnSelectAvailable, this); btn_add = new Button(i18n->IsActiveLanguageRightToLeft() ? "<-" : "->", Point(263, 60), Size(26, 0)); btn_add->onAction.Connect(&ConfigureMultiEncoderHub::OnAddEncoder, this); btn_add->Deactivate(); btn_remove = new Button(i18n->IsActiveLanguageRightToLeft() ? "->" : "<-", Point(263, 90), Size(26, 0)); btn_remove->onAction.Connect(&ConfigureMultiEncoderHub::OnRemoveEncoder, this); btn_remove->Deactivate(); text_selected = new Text(i18n->AddColon(i18n->TranslateString("Selected")), Point(297, 10)); list_selected = new ListBox(Point(297, 29), Size(245, 116)); list_selected->onSelectEntry.Connect(&ConfigureMultiEncoderHub::OnSelectEncoder, this); btn_configure = new Button(i18n->TranslateString("Configure encoder"), Point(382, 153), Size(160, 0)); btn_configure->onAction.Connect(&ConfigureMultiEncoderHub::OnConfigureEncoder, this); btn_configure->Deactivate(); btn_configure->SetWidth(Math::Max(80, btn_configure->GetUnscaledTextWidth() + 14)); btn_configure->SetX(542 - btn_configure->GetWidth()); group_encoders->Add(text_available); group_encoders->Add(list_available); group_encoders->Add(btn_add); group_encoders->Add(btn_remove); group_encoders->Add(text_selected); group_encoders->Add(list_selected); group_encoders->Add(btn_configure); group_options = new GroupBox(i18n->TranslateString("Options"), Point(7, 207), Size(552, 40)); check_folders = new CheckBox(i18n->TranslateString("Create a separate folder for each output format"), Point(10, 13), Size(532, 0), &separateFolders); group_options->Add(check_folders); Add(group_encoders); Add(group_options); AddEncoders(); SetSize(Size(566, 254)); } BoCA::ConfigureMultiEncoderHub::~ConfigureMultiEncoderHub() { DeleteObject(group_encoders); DeleteObject(text_available); DeleteObject(list_available); DeleteObject(btn_add); DeleteObject(btn_remove); DeleteObject(text_selected); DeleteObject(list_selected); DeleteObject(btn_configure); DeleteObject(group_options); DeleteObject(check_folders); } Void BoCA::ConfigureMultiEncoderHub::AddEncoders() { const Config *config = Config::Get(); AS::Registry &boca = AS::Registry::Get(); const Array &encoderIDs = config->GetStringValue(ConfigID, "Encoders", "flac-enc,lame-enc").Explode(","); for (Int i = 0; i < boca.GetNumberOfComponents(); i++) { if (boca.GetComponentType(i) != COMPONENT_TYPE_ENCODER || boca.GetComponentID(i) == "meh-enc") continue; list_available->AddEntry(boca.GetComponentName(i)); } foreach (const String &encoderID, encoderIDs) { if (!boca.ComponentExists(encoderID)) continue; Int entryNumber = -1; for (Int i = 0; i < boca.GetNumberOfComponents(); i++) { if (boca.GetComponentType(i) != COMPONENT_TYPE_ENCODER || boca.GetComponentID(i) == "meh-enc") continue; entryNumber++; if (boca.GetComponentID(i) != encoderID) continue; list_available->GetNthEntry(entryNumber)->SetHeight(0); list_selected->AddEntry(boca.GetComponentName(i)); break; } } } Void BoCA::ConfigureMultiEncoderHub::OnSelectAvailable() { btn_add->Activate(); } Void BoCA::ConfigureMultiEncoderHub::OnSelectEncoder() { btn_remove->Activate(); btn_configure->Activate(); } Void BoCA::ConfigureMultiEncoderHub::OnAddEncoder() { Surface *surface = GetDrawSurface(); ListEntry *entry = list_available->GetSelectedEntry(); surface->StartPaint(Rect(list_available->GetRealPosition(), list_available->GetRealSize())); entry->Deselect(); entry->SetHeight(0); list_available->Paint(SP_PAINT); surface->EndPaint(); list_selected->AddEntry(entry->GetText()); btn_add->Deactivate(); } Void BoCA::ConfigureMultiEncoderHub::OnRemoveEncoder() { Surface *surface = GetDrawSurface(); ListEntry *entry = list_selected->GetSelectedEntry(); surface->StartPaint(Rect(list_available->GetRealPosition(), list_available->GetRealSize())); for (Int i = 0; i < list_available->Length(); i++) { ListEntry *nthEntry = list_available->GetNthEntry(i); if (nthEntry->GetHeight() != 0) continue; if (nthEntry->GetText() != entry->GetText()) continue; nthEntry->SetHeight(16); list_available->Paint(SP_PAINT); } surface->EndPaint(); list_selected->Remove(entry); btn_remove->Deactivate(); btn_configure->Deactivate(); } Void BoCA::ConfigureMultiEncoderHub::OnConfigureEncoder() { AS::Registry &boca = AS::Registry::Get(); String encoderID; for (Int i = 0; i < boca.GetNumberOfComponents(); i++) { if (boca.GetComponentType(i) != COMPONENT_TYPE_ENCODER || boca.GetComponentID(i) == "meh-enc") continue; if (list_selected->GetSelectedEntry()->GetText() == boca.GetComponentName(i)) { encoderID = boca.GetComponentID(i); break; } } AS::Component *component = boca.CreateComponentByID(encoderID); if (component != NIL) { Point position = GetContainerWindow()->GetPosition() + Point(60, 60); if (ConfigureEncoder(component, position).ShowDialog() == Error()) Utilities::ErrorMessage("No configuration dialog available for:\n\n%1", component->GetName()); boca.DeleteComponent(component); } } Int BoCA::ConfigureMultiEncoderHub::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "SeparateFolders", separateFolders); AS::Registry &boca = AS::Registry::Get(); Int entryNumber = 0; String encoders; for (Int i = 0; i < boca.GetNumberOfComponents(); i++) { if (boca.GetComponentType(i) != COMPONENT_TYPE_ENCODER || boca.GetComponentID(i) == "meh-enc") continue; if (list_available->GetNthEntry(entryNumber++)->GetHeight() != 0) continue; encoders.Append(encoders.Length() > 0 ? "," : NIL).Append(boca.GetComponentID(i)); } config->SetStringValue(ConfigID, "Encoders", encoders); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/config.h000066400000000000000000000027351516712004000241660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_MULTIENCODERHUBCONFIG #define H_MULTIENCODERHUBCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureMultiEncoderHub : public ConfigLayer { private: GroupBox *group_encoders; Text *text_available; ListBox *list_available; Text *text_selected; ListBox *list_selected; Button *btn_add; Button *btn_remove; Button *btn_configure; GroupBox *group_options; CheckBox *check_folders; Bool separateFolders; Void AddEncoders(); public: static const String ConfigID; ConfigureMultiEncoderHub(); ~ConfigureMultiEncoderHub(); Int SaveSettings(); slots: Void OnSelectAvailable(); Void OnSelectEncoder(); Void OnAddEncoder(); Void OnRemoveEncoder(); Void OnConfigureEncoder(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/config_encoder.cpp000066400000000000000000000054341516712004000262170ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config_encoder.h" BoCA::ConfigureEncoder::ConfigureEncoder(AS::Component *component, const Point &pos) { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::meh!"); componentID = component->GetID(); layer = component->GetConfigurationLayer(); if (layer != NIL) { mainWnd = new Window(component->GetName(), pos, layer->GetSize() + Size(8, 73)); mainWnd->SetRightToLeft(i18n->IsActiveLanguageRightToLeft()); mainWnd_titlebar = new Titlebar(TB_CLOSEBUTTON); divbar = new Divider(39, OR_HORZ | OR_BOTTOM); btn_cancel = new Button(i18n->TranslateString("Cancel"), Point(175, 29), Size()); btn_cancel->onAction.Connect(&ConfigureEncoder::Cancel, this); btn_cancel->SetOrientation(OR_LOWERRIGHT); btn_ok = new Button(i18n->TranslateString("OK"), btn_cancel->GetPosition() - Point(88, 0), Size()); btn_ok->onAction.Connect(&ConfigureEncoder::OK, this); btn_ok->SetOrientation(OR_LOWERRIGHT); Add(mainWnd); mainWnd->Add(mainWnd_titlebar); mainWnd->Add(divbar); mainWnd->Add(btn_ok); mainWnd->Add(btn_cancel); mainWnd->GetMainLayer()->Add(layer); String resourcesPath = Application::GetApplicationDirectory(); #ifndef __WIN32__ if (Directory(S::System::System::GetResourcesDirectory().Append("freac")).Exists()) resourcesPath = S::System::System::GetResourcesDirectory().Append("freac").Append(Directory::GetDirectoryDelimiter()); #endif mainWnd->SetFlags(mainWnd->GetFlags() | WF_NOTASKBUTTON | WF_MODAL); mainWnd->SetIcon(ImageLoader::Load(String(resourcesPath).Append("icons/freac.png"))); } else { mainWnd = NIL; mainWnd_titlebar = NIL; btn_cancel = NIL; btn_ok = NIL; divbar = NIL; } } BoCA::ConfigureEncoder::~ConfigureEncoder() { if (layer == NIL) return; DeleteObject(mainWnd_titlebar); DeleteObject(mainWnd); DeleteObject(btn_ok); DeleteObject(btn_cancel); DeleteObject(divbar); } const Error &BoCA::ConfigureEncoder::ShowDialog() { if (layer != NIL) mainWnd->WaitUntilClosed(); else error = Error(); return error; } Void BoCA::ConfigureEncoder::OK() { if (layer->SaveSettings() == Error()) return; mainWnd->Close(); Settings::onChangeComponentSettings.Emit(componentID); } Void BoCA::ConfigureEncoder::Cancel() { mainWnd->Close(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/config_encoder.h000066400000000000000000000022311516712004000256540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_ENCODERCONFIG #define H_ENCODERCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureEncoder : public Dialogs::Dialog { private: String componentID; ConfigLayer *layer; Window *mainWnd; Titlebar *mainWnd_titlebar; Button *btn_cancel; Button *btn_ok; Divider *divbar; slots: Void OK(); Void Cancel(); public: ConfigureEncoder(AS::Component *, const Point &); ~ConfigureEncoder(); const Error &ShowDialog(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/meh.cpp000066400000000000000000000607271516712004000240320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "meh.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderMultiEncoderHub::GetComponentSpecs() { I18n *i18n = I18n::Get(); i18n->SetContext("Components::Encoders"); static String componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("meh! - multi encoder hub")).Append(" \ 1.0 \ meh-enc \ encoder \ \ multi encoder hub Output \ \ \ \ "); return componentSpecs; } Void smooth::AttachDLL(Void *instance) { /* Register conversion event handlers. */ Engine *engine = Engine::Get(); engine->onStartConversion.Connect(&EncoderMultiEncoderHub::OnStartConversion); engine->onFinishConversion.Connect(&EncoderMultiEncoderHub::OnFinishConversion); engine->onCancelConversion.Connect(&EncoderMultiEncoderHub::OnCancelConversion); } Void smooth::DetachDLL() { /* Unregister conversion event handlers. */ Engine *engine = Engine::Get(); engine->onStartConversion.Disconnect(&EncoderMultiEncoderHub::OnStartConversion); engine->onFinishConversion.Disconnect(&EncoderMultiEncoderHub::OnFinishConversion); engine->onCancelConversion.Disconnect(&EncoderMultiEncoderHub::OnCancelConversion); } Array BoCA::EncoderMultiEncoderHub::conversionData; BoCA::EncoderMultiEncoderHub::EncoderMultiEncoderHub() { conversionData.EnableLocking(); conversionID = -1; finished = False; cancelled = False; trackLength = 0; totalLength = 0; configLayer = NIL; Engine *engine = Engine::Get(); engine->onFinishTrackConversion.Connect(&EncoderMultiEncoderHub::OnFinishTrackConversion, this); engine->onCancelTrackConversion.Connect(&EncoderMultiEncoderHub::OnCancelTrackConversion, this); } BoCA::EncoderMultiEncoderHub::~EncoderMultiEncoderHub() { if (configLayer != NIL) Object::DeleteObject(configLayer); Engine *engine = Engine::Get(); engine->onFinishTrackConversion.Disconnect(&EncoderMultiEncoderHub::OnFinishTrackConversion, this); engine->onCancelTrackConversion.Disconnect(&EncoderMultiEncoderHub::OnCancelTrackConversion, this); /* Delete output file if it still exists. */ if (track.outputFile != NIL) { File(track.outputFile).Delete(); if (track.outputFile.Contains(Directory::GetDirectoryDelimiter())) track.outputFile[track.outputFile.FindLast(Directory::GetDirectoryDelimiter())] = 0; } /* Delete empty folders if was used in path. */ while (track.outputFile.Contains("[FILETYPE]")) { Directory(track.outputFile).Delete(); if (track.outputFile.Contains(Directory::GetDirectoryDelimiter())) track.outputFile[track.outputFile.FindLast(Directory::GetDirectoryDelimiter())] = 0; else break; } } Bool BoCA::EncoderMultiEncoderHub::IsThreadSafe() const { const Config *config = GetConfiguration(); /* Check if at least one downstream encoder is not thread safe. */ AS::Registry &boca = AS::Registry::Get(); const Array &encoderIDs = config->GetStringValue(ConfigureMultiEncoderHub::ConfigID, "Encoders", "flac-enc,lame-enc").Explode(","); Bool threadSafe = True; foreach (const String &encoderID, encoderIDs) { AS::EncoderComponent *encoder = (AS::EncoderComponent *) boca.CreateComponentByID(encoderID); if (encoder != NIL) { encoder->SetConfiguration(config); if (!encoder->IsThreadSafe()) threadSafe = False; boca.DeleteComponent(encoder); } } return threadSafe; } Bool BoCA::EncoderMultiEncoderHub::IsLossless() const { const Config *config = GetConfiguration(); /* Check if at least one downstream encoder is lossless. */ AS::Registry &boca = AS::Registry::Get(); const Array &encoderIDs = config->GetStringValue(ConfigureMultiEncoderHub::ConfigID, "Encoders", "flac-enc,lame-enc").Explode(","); Bool lossless = False; foreach (const String &encoderID, encoderIDs) { AS::EncoderComponent *encoder = (AS::EncoderComponent *) boca.CreateComponentByID(encoderID); if (encoder != NIL) { encoder->SetConfiguration(config); if (encoder->IsLossless()) lossless = True; boca.DeleteComponent(encoder); } } return lossless; } Bool BoCA::EncoderMultiEncoderHub::Activate() { const Config *config = GetConfiguration(); const Format &format = track.GetFormat(); finished = False; cancelled = False; trackLength = 0; totalLength = 0; /* Instantiate encoders. */ AS::Registry &boca = AS::Registry::Get(); const Array &encoderIDs = config->GetStringValue(ConfigureMultiEncoderHub::ConfigID, "Encoders", "flac-enc,lame-enc").Explode(","); String fileNamePattern = GetFileNamePattern(config, track); foreach (const String &encoderID, encoderIDs) { AS::EncoderComponent *encoder = (AS::EncoderComponent *) boca.CreateComponentByID(encoderID); if (encoder != NIL) { /* Set up encoder and stream. */ encoder->SetConfiguration(config); Track encoderTrack = track; String fileName = String(fileNamePattern).Replace("[FILETYPE]", encoder->GetOutputFileExtension().ToUpper()).Append(".").Append(encoder->GetOutputFileExtension()); encoderTrack.outputFile = fileName; encoder->SetAudioTrackInfo(encoderTrack); OutStream *stream = new OutStream(STREAM_FILE, Utilities::CreateDirectoryForFile(fileName), OS_REPLACE); stream->SetPackageSize(32768 * format.channels * (format.bits / 8)); stream->SetFilter(encoder); encoders.Add(encoder); streams.Add(stream); /* Set up mutexes, buffers and threads. */ if ((config->GetIntValue("Settings", "EncodeToSingleFile", False) || !IsThreadSafe()) && CPU().GetNumLogicalCPUs() > 1) { mutexes.Add(new Threads::Mutex()); buffers.Add(new Buffer); threads.Add(NonBlocking1(&EncoderMultiEncoderHub::EncodeThread, this).Call(threads.Length())); } } } return True; } Bool BoCA::EncoderMultiEncoderHub::Deactivate() { const Config *config = GetConfiguration(); /* Signal encoder threads that we are done. */ finished = True; /* Free encoders. */ AS::Registry &boca = AS::Registry::Get(); String fileNamePattern = GetFileNamePattern(config, track); for (Int i = encoders.Length() - 1; i >= 0; i--) { /* Delete mutexes, buffers and threads. */ if (threads.Length() > 0) { threads.GetNth(i)->Wait(); delete buffers.GetNth(i); delete mutexes.GetNth(i); } /* Finish and delete encoder and stream. */ AS::EncoderComponent *encoder = encoders.GetNth(i); OutStream *stream = streams.GetNth(i); Track encoderTrack = track; String fileName = String(fileNamePattern).Replace("[FILETYPE]", encoder->GetOutputFileExtension().ToUpper()).Append(".").Append(encoder->GetOutputFileExtension()); encoderTrack.outputFile = fileName; encoder->SetAudioTrackInfo(encoderTrack); stream->RemoveFilter(); if (encoder->GetErrorState()) { errorState = True; errorString = encoder->GetErrorString(); } delete stream; boca.DeleteComponent(encoder); if (cancelled) { File(encoderTrack.outputFile).Delete(); if (config->GetIntValue(ConfigureMultiEncoderHub::ConfigID, "SeparateFolders", False) && !config->GetIntValue("Settings", "EncodeToSingleFile", False)) { encoderTrack.outputFile[encoderTrack.outputFile.FindLast(Directory::GetDirectoryDelimiter())] = 0; Directory(encoderTrack.outputFile).Delete(); } } } encoders.RemoveAll(); streams.RemoveAll(); mutexes.RemoveAll(); buffers.RemoveAll(); threads.RemoveAll(); if (config->GetIntValue("Settings", "EncodeToSingleFile", False)) { ConversionData *data = conversionData.Get(conversionID); data->playlistTrack = track; data->playlistTrack.length = totalLength; } return True; } Int BoCA::EncoderMultiEncoderHub::WriteData(Buffer &data) { /* Hand data to encoders. */ if (threads.Length() == 0) { foreach (OutStream *stream, streams) stream->OutputData(data, data.Size()); } else { for (Int i = 0; i < threads.Length(); i++) { Threads::Mutex *mutex = mutexes.GetNth(i); Buffer *buffer = buffers.GetNth(i); Bool done = False; while (!done) { mutex->Lock(); if (buffer->Size() == 0) { buffer->Resize(data.Size()); memcpy(*buffer, data, data.Size()); done = True; } mutex->Release(); } } } const Format &format = track.GetFormat(); trackLength += data.Size() / format.channels / (format.bits / 8); totalLength += data.Size() / format.channels / (format.bits / 8); return data.Size(); } String BoCA::EncoderMultiEncoderHub::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (!config->GetIntValue("Settings", "EncodeToSingleFile", False)) return "[FILETYPE]"; return NIL; } String BoCA::EncoderMultiEncoderHub::GetFileNamePattern(const Config *configuration, const Track &track) { String fileNamePattern = track.outputFile; if (fileNamePattern.EndsWith(".[FILETYPE]")) fileNamePattern[fileNamePattern.Length() - 11] = 0; if (configuration->GetIntValue(ConfigureMultiEncoderHub::ConfigID, "SeparateFolders", False) && !configuration->GetIntValue("Settings", "EncodeToSingleFile", False)) { String pre; String post = fileNamePattern; if (fileNamePattern.Contains(Directory::GetDirectoryDelimiter())) { pre = fileNamePattern.Head(fileNamePattern.FindLast(Directory::GetDirectoryDelimiter()) + 1); post = fileNamePattern.Tail(fileNamePattern.Length() - fileNamePattern.FindLast(Directory::GetDirectoryDelimiter()) - 1); } fileNamePattern = String(pre).Append("[FILETYPE]").Append(Directory::GetDirectoryDelimiter()).Append(post); } return fileNamePattern; } String BoCA::EncoderMultiEncoderHub::GetPlaylistFileName(const Config *configuration, const Track &track, const Array &originalTracks) { I18n *i18n = I18n::Get(); const Info &info = track.GetInfo(); /* Find playlist output folder. */ const Track &originalTrack = originalTracks.Get(track.GetTrackID()); String outputDir = configuration->GetStringValue("Settings", "EncoderOutDir", NIL); String inputDir = originalTrack.fileName.Head(Math::Max(originalTrack.fileName.FindLast("\\"), originalTrack.fileName.FindLast("/")) + 1); if (configuration->GetIntValue("Settings", "WriteToInputDirectory", False) && !originalTrack.isCDTrack && Utilities::IsFolderWritable(inputDir)) outputDir = inputDir; /* Generate playlist file name. */ Bool useUnicode = configuration->GetIntValue("Settings", "UseUnicodeFilenames", True); Bool replaceSpaces = configuration->GetIntValue("Settings", "FilenamesReplaceSpaces", False); String playlistOutputDir = Utilities::GetAbsolutePathName(configuration->GetIntValue("Playlist", "UseEncoderOutputDir", True) ? outputDir : configuration->GetStringValue("Playlist", "OutputDir", outputDir)); String playlistFileName = playlistOutputDir; if (info.artist != NIL || info.album != NIL) { String shortOutFileName = configuration->GetStringValue("Playlist", "FilenamePattern", String(" - ").Append(Directory::GetDirectoryDelimiter()).Append(" - ")); DateTime currentDateTime = DateTime::Current(); String currentDate = String().FillN('0', 3 - Math::Floor(Math::Log10( currentDateTime.GetYear() ))) .Append(String::FromInt(currentDateTime.GetYear())) .Append(String().FillN('0', 1 - Math::Floor(Math::Log10( currentDateTime.GetMonth() )))).Append(String::FromInt(currentDateTime.GetMonth())) .Append(String().FillN('0', 1 - Math::Floor(Math::Log10( currentDateTime.GetDay() )))).Append(String::FromInt(currentDateTime.GetDay())); String currentTime = String().FillN('0', 1 - Math::Floor(Math::Log10(currentDateTime.GetHour() > 0 ? currentDateTime.GetHour() : 1))) .Append(String::FromInt(currentDateTime.GetHour())) .Append(String().FillN('0', 1 - Math::Floor(Math::Log10(currentDateTime.GetMinute() > 0 ? currentDateTime.GetMinute() : 1)))).Append(String::FromInt(currentDateTime.GetMinute())); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(info.artist.Length() > 0 ? info.artist : i18n->TranslateString("unknown artist"))); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(info.album.Length() > 0 ? info.album : i18n->TranslateString("unknown album"))); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(info.genre.Length() > 0 ? info.genre : i18n->TranslateString("unknown genre"))); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(info.year > 0 ? String::FromInt(info.year) : i18n->TranslateString("unknown year"))); shortOutFileName.Replace("", currentDate); shortOutFileName.Replace("", currentTime); /* Replace pattern. */ shortOutFileName.Replace("", String::FromInt(info.disc < 0 ? 0 : info.disc)); for (Int i = 1; i <= 4; i++) { String pattern = String(""); shortOutFileName.Replace(pattern, String().FillN('0', i - ((Int) Math::Log10(info.disc > 0 ? info.disc : 1) + 1)).Append(String::FromInt(info.disc < 0 ? 0 : info.disc))); } /* Replace other text fields. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(value)); else if (key == INFO_CONDUCTOR) shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(value)); else if (key == INFO_COMPOSER) shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(value)); } if (info.artist.Length() > 0) shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(info.artist)); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(i18n->TranslateString("unknown album artist"))); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(i18n->TranslateString("unknown conductor"))); shortOutFileName.Replace("", Utilities::ReplaceIncompatibleCharacters(i18n->TranslateString("unknown composer"))); playlistFileName.Append(Utilities::ReplaceIncompatibleCharacters(shortOutFileName, useUnicode, False, replaceSpaces)); } else if (track.isCDTrack) { playlistFileName.Append("cd").Append(String::FromInt(track.drive)); } else { playlistFileName.Append(Utilities::ReplaceIncompatibleCharacters(i18n->TranslateString("unknown playlist"), useUnicode, True, replaceSpaces)); } if (configuration->GetIntValue("Playlist", "UseEncoderOutputDir", True)) { Track playlistTrack; playlistTrack.outputFile = playlistFileName; playlistFileName = GetFileNamePattern(configuration, playlistTrack); } return Utilities::NormalizeFileName(playlistFileName); } Void BoCA::EncoderMultiEncoderHub::EncodeThread(Int n) { Threads::Mutex *mutex = mutexes.GetNth(n); Buffer *buffer = buffers.GetNth(n); OutStream *stream = streams.GetNth(n); while (!finished) { mutex->Lock(); if (buffer->Size() > 0) { stream->OutputData(*buffer, buffer->Size()); buffer->Resize(0); } mutex->Release(); } } Void BoCA::EncoderMultiEncoderHub::OnStartConversion(Int conversionID, const Array &tracks) { ConversionData *data = new ConversionData(); data->configuration = Config::Copy(); conversionData.Add(data, conversionID); if (data->configuration->GetStringValue("Settings", "Encoder", "lame-enc") != "meh-enc") return; /* Set tracks to convert. */ data->tracksToConvert = tracks; /* Enable locking on playlist track arrays. */ data->tracksToConvert.EnableLocking(); data->convertedTracks.EnableLocking(); } Void BoCA::EncoderMultiEncoderHub::OnFinishConversion(Int conversionID) { AS::Registry &boca = AS::Registry::Get(); /* Get config values. */ ConversionData *data = conversionData.Get(conversionID); Bool encodeToSingleFile = data->configuration->GetIntValue("Settings", "EncodeToSingleFile", False); Bool separateFolders = data->configuration->GetIntValue(ConfigureMultiEncoderHub::ConfigID, "SeparateFolders", False); Bool createPlaylist = data->configuration->GetIntValue("Playlist", "CreatePlaylist", False); Bool createCueSheet = data->configuration->GetIntValue("Playlist", "CreateCueSheet", False); Bool useEncoderOutputDir = data->configuration->GetIntValue("Playlist", "UseEncoderOutputDir", True); Bool singlePlaylistFile = data->configuration->GetIntValue("Playlist", "SinglePlaylistFile", False); /* Compute playlist/cuesheet track list. */ Array playlistTracks; Array cuesheetTracks; foreach (const Track &trackToConvert, data->tracksToConvert) { Track track = data->convertedTracks.Get(trackToConvert.GetTrackID()); if (track == NIL) continue; if (!encodeToSingleFile) { Track playlistTrack = track; playlistTrack.isCDTrack = False; playlistTrack.fileName = track.outputFile; playlistTracks.Add(playlistTrack); cuesheetTracks.Add(playlistTrack); } else { Track cuesheetTrack = trackToConvert; cuesheetTrack.isCDTrack = False; cuesheetTrack.sampleOffset = track.sampleOffset; cuesheetTrack.length = track.length; cuesheetTrack.fileName = track.outputFile; cuesheetTracks.Add(cuesheetTrack); } } if (data->tracksToConvert.Length() > 0 && encodeToSingleFile) playlistTracks.Add(data->playlistTrack); /* Write playlists and cue sheets. */ if ((createPlaylist && playlistTracks.Length() > 0) || (createCueSheet && cuesheetTracks.Length() > 0)) { String playlistID = data->configuration->GetStringValue("Playlist", "PlaylistFormat", "m3u-playlist-m3u8"); String playlistExtension = playlistID.Tail(playlistID.Length() - playlistID.FindLast("-") - 1); /* Split playlist tracks to individual playlists. */ Array playlistFileNames; Array *> playlistTrackLists; Array *> cuesheetTrackLists; if (encodeToSingleFile || singlePlaylistFile) { /* Set playlist filename so it is written to the same place as a single output file. */ if (encodeToSingleFile) playlistFileNames.Add(data->playlistTrack.outputFile); else playlistFileNames.Add(GetPlaylistFileName(data->configuration, playlistTracks.GetFirst(), data->tracksToConvert)); playlistTrackLists.Add(new Array(playlistTracks)); cuesheetTrackLists.Add(new Array(cuesheetTracks)); } else { foreach (const Track &track, playlistTracks) { /* Check if we already have a list for this playlist. */ String playlistFileName = GetPlaylistFileName(data->configuration, track, data->tracksToConvert); UnsignedInt32 playlistFileCRC = playlistFileName.ComputeCRC32(); if (playlistFileNames.Add(playlistFileName, playlistFileCRC)) { playlistTrackLists.Add(new Array(), playlistFileCRC); cuesheetTrackLists.Add(new Array(), playlistFileCRC); } /* Find current lists and add track. */ playlistTrackLists.Get(playlistFileCRC)->Add(track); cuesheetTrackLists.Get(playlistFileCRC)->Add(track); } } /* Save playlists per encoder. */ const Array &encoderIDs = data->configuration->GetStringValue(ConfigureMultiEncoderHub::ConfigID, "Encoders", "flac-enc,lame-enc").Explode(","); foreach (const String &encoderID, encoderIDs) { /* Get encoder file extension. */ String formatExtension; AS::EncoderComponent *encoder = (AS::EncoderComponent *) boca.CreateComponentByID(encoderID); if (encoder != NIL) { encoder->SetConfiguration(data->configuration); formatExtension = encoder->GetOutputFileExtension(); boca.DeleteComponent(encoder); } /* Write playlists and cue sheets. */ for (Int i = 0; i < playlistFileNames.Length(); i++) { /* Update playlist tracks. */ String actualPlaylistFileName = String(playlistFileNames.GetNth(i)).Replace("[FILETYPE]", formatExtension.ToUpper()); if (!separateFolders || !useEncoderOutputDir || encodeToSingleFile) actualPlaylistFileName.Append(".").Append(formatExtension); Array actualPlaylistTracks = *playlistTrackLists.GetNth(i); Array actualCuesheetTracks = *cuesheetTrackLists.GetNth(i); foreach (Track &playlistTrack, actualPlaylistTracks) playlistTrack.fileName = String(playlistTrack.fileName).Replace("[FILETYPE]", formatExtension.ToUpper()).Append(".").Append(formatExtension); foreach (Track &cuesheetTrack, actualCuesheetTracks) cuesheetTrack.fileName = String(cuesheetTrack.fileName).Replace("[FILETYPE]", formatExtension.ToUpper()).Append(".").Append(formatExtension); /* Write playlist. */ AS::PlaylistComponent *playlist = createPlaylist ? (AS::PlaylistComponent *) boca.CreateComponentByID(playlistID.Head(playlistID.FindLast("-"))) : NIL; if (playlist != NIL) { playlist->SetTrackList(actualPlaylistTracks); playlist->WritePlaylist(String(actualPlaylistFileName).Append(".").Append(playlistExtension)); boca.DeleteComponent(playlist); } /* Write cue sheet. */ AS::PlaylistComponent *cuesheet = createCueSheet ? (AS::PlaylistComponent *) boca.CreateComponentByID("cuesheet-playlist") : NIL; if (cuesheet != NIL) { cuesheet->SetTrackList(actualCuesheetTracks); cuesheet->WritePlaylist(String(actualPlaylistFileName).Append(".cue")); boca.DeleteComponent(cuesheet); } } } /* Clean up playlist and cuesheet track lists. */ foreach (Array *trackList, playlistTrackLists) delete trackList; foreach (Array *trackList, cuesheetTrackLists) delete trackList; } /* Free conversion data for this conversion. */ Config::Free(data->configuration); delete data; conversionData.Remove(conversionID); } Void BoCA::EncoderMultiEncoderHub::OnCancelConversion(Int conversionID) { /* Free conversion data for this conversion. */ ConversionData *data = conversionData.Get(conversionID); Config::Free(data->configuration); delete data; conversionData.Remove(conversionID); } Void BoCA::EncoderMultiEncoderHub::OnFinishTrackConversion(Int conversionID, const Track &finishedTrack) { const Config *config = GetConfiguration(); /* Get config values. */ Bool encodeToSingleFile = config->GetIntValue("Settings", "EncodeToSingleFile", False); /* Update conversion ID. */ this->conversionID = conversionID; /* Check if this conversion is the one being finished. */ if ((encodeToSingleFile && finishedTrack.outputFile == track.outputFile) || finishedTrack.GetTrackID() == track.GetTrackID()) { Track convertedTrack = finishedTrack; convertedTrack.SetFormat(track.GetFormat()); convertedTrack.outputFile = GetFileNamePattern(config, track); convertedTrack.length = trackLength; if (encodeToSingleFile) { convertedTrack.sampleOffset = Math::Round((Float) (totalLength - trackLength) / convertedTrack.GetFormat().rate * 75); trackLength = 0; } /* Add track to converted tracks. */ ConversionData *data = conversionData.Get(conversionID); data->convertedTracks.Add(convertedTrack, convertedTrack.GetTrackID()); } } Void BoCA::EncoderMultiEncoderHub::OnCancelTrackConversion(Int conversionID, const Track &cancelledTrack) { const Config *config = GetConfiguration(); /* Get config values. */ Bool encodeToSingleFile = config->GetIntValue("Settings", "EncodeToSingleFile", False); /* Update conversion ID. */ this->conversionID = conversionID; /* Check if this conversion is the one being cancelled. */ if ((encodeToSingleFile && cancelledTrack.outputFile == track.outputFile) || cancelledTrack.GetTrackID() == track.GetTrackID()) cancelled = True; } ConfigLayer *BoCA::EncoderMultiEncoderHub::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureMultiEncoderHub(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/meh/meh.h000066400000000000000000000044221516712004000234650ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(EncoderMultiEncoderHub) namespace BoCA { struct ConversionData { Config *configuration; Array tracksToConvert; Array convertedTracks; Track playlistTrack; }; class EncoderMultiEncoderHub : public CS::EncoderComponent { private: ConfigLayer *configLayer; static Array conversionData; Int conversionID; Array streams; Array encoders; Array mutexes; Array *, Void *> buffers; Array threads; Int64 trackLength; Int64 totalLength; Bool finished; Bool cancelled; static String GetFileNamePattern(const Config *, const Track &); static String GetPlaylistFileName(const Config *, const Track &, const Array &); Void EncodeThread(Int); public: static const String &GetComponentSpecs(); EncoderMultiEncoderHub(); ~EncoderMultiEncoderHub(); Bool IsThreadSafe() const; Bool IsLossless() const; Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); slots: static Void OnStartConversion(Int, const Array &); static Void OnFinishConversion(Int); static Void OnCancelConversion(Int); Void OnFinishTrackConversion(Int, const Track &); Void OnCancelTrackConversion(Int, const Track &); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderMultiEncoderHub) BoCA_END_COMPONENT(EncoderMultiEncoderHub) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/000077500000000000000000000000001516712004000227565ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/Makefile000066400000000000000000000012341516712004000244160ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = opus TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o opus.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/config.cpp000066400000000000000000000257531516712004000247430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureOpus::ConfigID = "Opus"; BoCA::ConfigureOpus::ConfigureOpus() { const Config *config = Config::Get(); fileExtension = config->GetIntValue(ConfigID, "FileExtension", 0); bitrate = config->GetIntValue(ConfigID, "Bitrate", 128) / 2; complexity = config->GetIntValue(ConfigID, "Complexity", 10); framesize = config->GetIntValue(ConfigID, "FrameSize", 20000); framesize = Math::Round(framesize <= 10000 ? Math::Log2(framesize / 2500) : framesize / 20000 + 2); packet_loss = config->GetIntValue(ConfigID, "PacketLoss", 0); enableVBR = config->GetIntValue(ConfigID, "EnableVBR", True); enableCVBR = config->GetIntValue(ConfigID, "EnableConstrainedVBR", False); enableDTX = config->GetIntValue(ConfigID, "EnableDTX", False); disablePI = config->GetIntValue(ConfigID, "DisablePhaseInversion", False); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::Opus"); group_basic = new GroupBox(i18n->TranslateString("Basic settings"), Point(7, 11), Size(228, 66)); text_mode = new Text(i18n->AddColon(i18n->TranslateString("Encoding mode")), Point(7, 13)); combo_mode = new ComboBox(Point(120, 10), Size(214, 0)); combo_mode->AddEntry(i18n->TranslateString("auto")); combo_mode->AddEntry(i18n->TranslateString("Voice")); combo_mode->AddEntry(i18n->TranslateString("Music")); combo_mode->SelectNthEntry(config->GetIntValue(ConfigID, "Mode", 0)); combo_mode->onSelectEntry.Connect(&ConfigureOpus::SetMode, this); text_bandwidth = new Text(i18n->AddColon(i18n->TranslateString("Bandwidth")), Point(7, 40)); combo_bandwidth = new ComboBox(Point(120, 37), Size(214, 0)); combo_bandwidth->AddEntry(i18n->TranslateString("auto")); combo_bandwidth->AddEntry(i18n->TranslateString("Narrowband")); combo_bandwidth->AddEntry(i18n->TranslateString("Mediumband")); combo_bandwidth->AddEntry(i18n->TranslateString("Wideband")); combo_bandwidth->AddEntry(i18n->TranslateString("Superwideband")); combo_bandwidth->AddEntry(i18n->TranslateString("Fullband")); combo_bandwidth->SelectNthEntry(config->GetIntValue(ConfigID, "Bandwidth", 0)); Int maxTextSize = Math::Max(text_mode->GetUnscaledTextWidth(), text_bandwidth->GetUnscaledTextWidth()); combo_mode->SetMetrics(Point(14 + maxTextSize, combo_mode->GetY()), Size(202 - maxTextSize, combo_mode->GetHeight())); combo_bandwidth->SetMetrics(Point(14 + maxTextSize, combo_bandwidth->GetY()), Size(202 - maxTextSize, combo_bandwidth->GetHeight())); group_basic->Add(text_mode); group_basic->Add(combo_mode); group_basic->Add(text_bandwidth); group_basic->Add(combo_bandwidth); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(243, 11), Size(108, 66)); option_extension_opus = new OptionBox(".opus", Point(10, 13), Size(88, 0), &fileExtension, 0); option_extension_oga = new OptionBox(".oga", Point(10, 38), Size(88, 0), &fileExtension, 1); group_extension->Add(option_extension_opus); group_extension->Add(option_extension_oga); group_vbr = new GroupBox(i18n->TranslateString("Variable bitrate"), Point(7, 89), Size(344, 63)); check_vbr = new CheckBox(i18n->TranslateString("Enable variable bitrate encoding"), Point(10, 13), Size(324, 0), &enableVBR); check_vbr->onAction.Connect(&ConfigureOpus::SetVBR, this); check_cvbr = new CheckBox(i18n->TranslateString("Constrain bitrate to target value"), Point(27, 36), Size(307, 0), &enableCVBR); group_vbr->Add(check_vbr); group_vbr->Add(check_cvbr); group_quality = new GroupBox(i18n->TranslateString("Quality"), Point(7, 164), Size(344, 90)); text_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Bitrate")), Point(10, 13)); slider_bitrate = new Slider(Point(70, 11), Size(201, 0), OR_HORZ, &bitrate, 3, 255); slider_bitrate->onValueChange.Connect(&ConfigureOpus::SetBitrate, this); edit_bitrate = new EditBox("000", Point(279, 10), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetWidth(edit_bitrate->GetUnscaledTextWidth() + 6); edit_bitrate->onInput.Connect(&ConfigureOpus::SetBitrateByEditBox, this); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(310, 13)); text_bitrate_kbps->SetX(335 - text_bitrate_kbps->GetUnscaledTextWidth()); edit_bitrate->SetX(329 - text_bitrate_kbps->GetUnscaledTextWidth() - edit_bitrate->GetWidth()); text_complexity = new Text(i18n->AddColon(i18n->TranslateString("Complexity")), Point(10, 40)); slider_complexity = new Slider(Point(70, 38), Size(201, 0), OR_HORZ, &complexity, 0, 10); slider_complexity->onValueChange.Connect(&ConfigureOpus::SetComplexity, this); text_complexity_value = new Text(NIL, Point(edit_bitrate->GetX(), 40)); maxTextSize = Math::Max(text_bitrate->GetUnscaledTextWidth(), text_complexity->GetUnscaledTextWidth()); slider_bitrate->SetMetrics(Point(17 + maxTextSize, slider_bitrate->GetY()), Size(edit_bitrate->GetX() - 25 - maxTextSize, slider_bitrate->GetHeight())); slider_complexity->SetMetrics(Point(17 + maxTextSize, slider_complexity->GetY()), Size(edit_bitrate->GetX()- 25 - maxTextSize, slider_complexity->GetHeight())); check_disable_pi = new CheckBox(i18n->TranslateString("Disable intensity stereo phase inversion"), Point(10, 63), Size(324, 0), &disablePI); group_quality->Add(text_bitrate); group_quality->Add(slider_bitrate); group_quality->Add(edit_bitrate); group_quality->Add(text_bitrate_kbps); group_quality->Add(text_complexity); group_quality->Add(slider_complexity); group_quality->Add(text_complexity_value); group_quality->Add(check_disable_pi); group_stream = new GroupBox(i18n->TranslateString("Stream"), Point(7, 266), Size(344, 40)); text_framesize = new Text(i18n->AddColon(i18n->TranslateString("Frame length")), Point(10, 13)); slider_framesize = new Slider(Point(17 + text_framesize->GetUnscaledTextWidth(), 11), Size(edit_bitrate->GetX() - 25 - text_framesize->GetUnscaledTextWidth(), 0), OR_HORZ, &framesize, 0, 8); slider_framesize->onValueChange.Connect(&ConfigureOpus::SetFrameSize, this); text_framesize_value = new Text(NIL, Point(edit_bitrate->GetX(), 13)); group_stream->Add(text_framesize); group_stream->Add(slider_framesize); group_stream->Add(text_framesize_value); group_options = new GroupBox(i18n->TranslateString("Options"), Point(7, 318), Size(344, 66)); check_dtx = new CheckBox(i18n->TranslateString("Enable discontinuous transmission"), Point(10, 13), Size(324, 0), &enableDTX); text_packet_loss = new Text(i18n->AddColon(i18n->TranslateString("Expected packet loss")), Point(10, 40)); slider_packet_loss = new Slider(Point(17 + text_packet_loss->GetUnscaledTextWidth(), 38), Size(edit_bitrate->GetX() - 25 - text_packet_loss->GetUnscaledTextWidth(), 0), OR_HORZ, &packet_loss, 0, 100); slider_packet_loss->onValueChange.Connect(&ConfigureOpus::SetPacketLoss, this); text_packet_loss_value = new Text(NIL, Point(edit_bitrate->GetX(), 40)); group_options->Add(check_dtx); group_options->Add(text_packet_loss); group_options->Add(slider_packet_loss); group_options->Add(text_packet_loss_value); SetMode(); SetVBR(); SetBitrate(); SetComplexity(); SetFrameSize(); SetPacketLoss(); Add(group_basic); Add(group_extension); Add(group_vbr); Add(group_quality); Add(group_stream); Add(group_options); SetSize(Size(358, 391)); } BoCA::ConfigureOpus::~ConfigureOpus() { DeleteObject(group_basic); DeleteObject(text_mode); DeleteObject(combo_mode); DeleteObject(text_bandwidth); DeleteObject(combo_bandwidth); DeleteObject(group_extension); DeleteObject(option_extension_opus); DeleteObject(option_extension_oga); DeleteObject(group_vbr); DeleteObject(check_vbr); DeleteObject(check_cvbr); DeleteObject(group_quality); DeleteObject(text_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); DeleteObject(text_complexity); DeleteObject(slider_complexity); DeleteObject(text_complexity_value); DeleteObject(check_disable_pi); DeleteObject(group_stream); DeleteObject(text_framesize); DeleteObject(slider_framesize); DeleteObject(text_framesize_value); DeleteObject(group_options); DeleteObject(check_dtx); DeleteObject(text_packet_loss); DeleteObject(slider_packet_loss); DeleteObject(text_packet_loss_value); } Int BoCA::ConfigureOpus::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Mode", combo_mode->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "Bandwidth", combo_bandwidth->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "FileExtension", fileExtension); config->SetIntValue(ConfigID, "Bitrate", bitrate * 2); config->SetIntValue(ConfigID, "Complexity", complexity); config->SetIntValue(ConfigID, "FrameSize", Math::Min(framesize <= 2 ? (Int) (2500 * Math::Pow(2, framesize)) : 20000 * (framesize - 2), 120000)); config->SetIntValue(ConfigID, "PacketLoss", packet_loss); config->SetIntValue(ConfigID, "EnableVBR", enableVBR); config->SetIntValue(ConfigID, "EnableConstrainedVBR", enableCVBR); config->SetIntValue(ConfigID, "EnableDTX", enableDTX); config->SetIntValue(ConfigID, "DisablePhaseInversion", disablePI); return Success(); } Void BoCA::ConfigureOpus::SetMode() { switch (combo_mode->GetSelectedEntryNumber()) { case 0: case 1: check_dtx->Activate(); text_packet_loss->Activate(); slider_packet_loss->Activate(); text_packet_loss_value->Activate(); break; case 2: check_dtx->Deactivate(); text_packet_loss->Deactivate(); slider_packet_loss->Deactivate(); text_packet_loss_value->Deactivate(); break; } SetVBR(); } Void BoCA::ConfigureOpus::SetVBR() { if (enableVBR && combo_mode->GetSelectedEntryNumber() != 1) { check_cvbr->Activate(); } else { enableCVBR = False; check_cvbr->Deactivate(); } } Void BoCA::ConfigureOpus::SetBitrate() { if (!edit_bitrate->IsFocussed()) edit_bitrate->SetText(String::FromInt(bitrate * 2)); } Void BoCA::ConfigureOpus::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt() / 2); } Void BoCA::ConfigureOpus::SetComplexity() { text_complexity_value->SetText(String::FromInt(complexity)); } Void BoCA::ConfigureOpus::SetFrameSize() { I18n *i18n = I18n::Get(); text_framesize_value->SetText(i18n->TranslateString("%1 ms", "Technical").Replace("%1", String::FromFloat(Math::Min(framesize <= 2 ? 2.5 * Math::Pow(2, framesize) : 20.0 * (framesize - 2), 120.0)))); } Void BoCA::ConfigureOpus::SetPacketLoss() { I18n *i18n = I18n::Get(); text_packet_loss_value->SetText(i18n->TranslateString("%1%", "Technical").Replace("%1", String::FromInt(packet_loss))); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/config.h000066400000000000000000000042351516712004000244000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_OPUSCONFIG #define H_OPUSCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureOpus : public ConfigLayer { private: GroupBox *group_basic; Text *text_mode; ComboBox *combo_mode; Text *text_bandwidth; ComboBox *combo_bandwidth; GroupBox *group_extension; OptionBox *option_extension_opus; OptionBox *option_extension_oga; GroupBox *group_vbr; CheckBox *check_vbr; CheckBox *check_cvbr; GroupBox *group_quality; Text *text_bitrate; Slider *slider_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; Text *text_complexity; Slider *slider_complexity; Text *text_complexity_value; CheckBox *check_disable_pi; GroupBox *group_stream; Text *text_framesize; Slider *slider_framesize; Text *text_framesize_value; GroupBox *group_options; CheckBox *check_dtx; Text *text_packet_loss; Slider *slider_packet_loss; Text *text_packet_loss_value; Int bitrate; Int fileExtension; Int complexity; Int framesize; Int packet_loss; Bool enableVBR; Bool enableCVBR; Bool enableDTX; Bool disablePI; slots: Void SetMode(); Void SetVBR(); Void SetBitrate(); Void SetBitrateByEditBox(); Void SetComplexity(); Void SetFrameSize(); Void SetPacketLoss(); public: static const String ConfigID; ConfigureOpus(); ~ConfigureOpus(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/dllinterface.cpp000066400000000000000000000072041516712004000261210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETIN ex_ogg_stream_packetin = NIL; OGGSTREAMFLUSH ex_ogg_stream_flush = NIL; OGGSTREAMPAGEOUT ex_ogg_stream_pageout = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OPUSMULTISTREAMSURROUNDENCODERCREATE ex_opus_multistream_surround_encoder_create = NIL; OPUSMULTISTREAMENCODE ex_opus_multistream_encode = NIL; OPUSMULTISTREAMENCODEFLOAT ex_opus_multistream_encode_float = NIL; OPUSMULTISTREAMENCODERCTL ex_opus_multistream_encoder_ctl = NIL; OPUSMULTISTREAMENCODERDESTROY ex_opus_multistream_encoder_destroy = NIL; OPUSGETVERSIONSTRING ex_opus_get_version_string = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *opusdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetin = (OGGSTREAMPACKETIN) oggdll->GetFunctionAddress("ogg_stream_packetin"); ex_ogg_stream_flush = (OGGSTREAMFLUSH) oggdll->GetFunctionAddress("ogg_stream_flush"); ex_ogg_stream_pageout = (OGGSTREAMPAGEOUT) oggdll->GetFunctionAddress("ogg_stream_pageout"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetin == NIL || ex_ogg_stream_flush == NIL || ex_ogg_stream_pageout == NIL || ex_ogg_page_eos == NIL || ex_ogg_stream_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadOpusDLL() { opusdll = BoCA::Utilities::LoadCodecDLL("opus"); if (opusdll == NIL) return False; ex_opus_multistream_surround_encoder_create = (OPUSMULTISTREAMSURROUNDENCODERCREATE) opusdll->GetFunctionAddress("opus_multistream_surround_encoder_create"); ex_opus_multistream_encode = (OPUSMULTISTREAMENCODE) opusdll->GetFunctionAddress("opus_multistream_encode"); ex_opus_multistream_encode_float = (OPUSMULTISTREAMENCODEFLOAT) opusdll->GetFunctionAddress("opus_multistream_encode_float"); ex_opus_multistream_encoder_ctl = (OPUSMULTISTREAMENCODERCTL) opusdll->GetFunctionAddress("opus_multistream_encoder_ctl"); ex_opus_multistream_encoder_destroy = (OPUSMULTISTREAMENCODERDESTROY) opusdll->GetFunctionAddress("opus_multistream_encoder_destroy"); ex_opus_get_version_string = (OPUSGETVERSIONSTRING) opusdll->GetFunctionAddress("opus_get_version_string"); if (ex_opus_multistream_surround_encoder_create == NIL || ex_opus_multistream_encode == NIL || ex_opus_multistream_encode_float == NIL || ex_opus_multistream_encoder_ctl == NIL || ex_opus_multistream_encoder_destroy == NIL || ex_opus_get_version_string == NIL) { FreeOpusDLL(); return False; } return True; } Void FreeOpusDLL() { BoCA::Utilities::FreeCodecDLL(opusdll); opusdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/dllinterface.h000066400000000000000000000050341516712004000255650ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *opusdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadOpusDLL(); Void FreeOpusDLL(); /* Ogg API functions. */ typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETIN) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMFLUSH) (ogg_stream_state *, ogg_page *); typedef int (*OGGSTREAMPAGEOUT) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETIN ex_ogg_stream_packetin; extern OGGSTREAMFLUSH ex_ogg_stream_flush; extern OGGSTREAMPAGEOUT ex_ogg_stream_pageout; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGSTREAMCLEAR ex_ogg_stream_clear; /* Opus API functions. */ typedef OpusMSEncoder * (*OPUSMULTISTREAMSURROUNDENCODERCREATE) (opus_int32, int, int, int *, int *, unsigned char *, int, int *); typedef int (*OPUSMULTISTREAMENCODE) (OpusMSEncoder *, const opus_int16 *, int, unsigned char *, opus_int32); typedef int (*OPUSMULTISTREAMENCODEFLOAT) (OpusMSEncoder *, const float *, int, unsigned char *, opus_int32); typedef int (*OPUSMULTISTREAMENCODERCTL) (OpusMSEncoder *, int, ...); typedef void (*OPUSMULTISTREAMENCODERDESTROY) (OpusMSEncoder *); typedef const char * (*OPUSGETVERSIONSTRING) (); extern OPUSMULTISTREAMSURROUNDENCODERCREATE ex_opus_multistream_surround_encoder_create; extern OPUSMULTISTREAMENCODE ex_opus_multistream_encode; extern OPUSMULTISTREAMENCODEFLOAT ex_opus_multistream_encode_float; extern OPUSMULTISTREAMENCODERCTL ex_opus_multistream_encoder_ctl; extern OPUSMULTISTREAMENCODERDESTROY ex_opus_multistream_encoder_destroy; extern OPUSGETVERSIONSTRING ex_opus_get_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/opus.cpp000066400000000000000000000434421516712004000244570ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "opus.h" #include "config.h" const String &BoCA::EncoderOpus::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && opusdll != NIL) { componentSpecs = " \ \ \ \ Opus Audio Encoder %VERSION% \ 1.0 \ opus-enc \ encoder \ \ Opus Audio \ opus \ oga \ Vorbis Comment \ \ \ \ \ \ 6 \ 510 \ \ \ 0 \ 10 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "; componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_opus_get_version_string()).Replace("libopus ", NIL))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadOpusDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeOpusDLL(); } namespace BoCA { /* Opus header definition. */ struct OpusHeader { char codec_id[8]; /**< MUST be "OpusHead" */ uint8_t version_id; /**< Version number */ uint8_t nb_channels; /**< Number of channels */ uint16_t preskip; /**< Pre-skip */ uint32_t sample_rate; /**< Input sample rate; informational only */ int16_t output_gain; /**< Output gain to apply when decoding */ uint8_t channel_mapping; /**< Channel mapping family */ uint8_t nb_streams; /**< Stream count */ uint8_t nb_coupled; /**< Two-channel stream count */ uint8_t stream_map[255]; /**< Channel mapping */ }; }; BoCA::EncoderOpus::EncoderOpus() { configLayer = NIL; config = NIL; converter = NIL; frameSize = 0; preSkip = 0; blockSize = 256; overlap = 24; totalSamples = 0; nextWorker = 0; memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); } BoCA::EncoderOpus::~EncoderOpus() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderOpus::Activate() { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); Info info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Get target format. */ targetFormat = format; if (format.rate <= 8000) targetFormat.rate = 8000; else if (format.rate <= 12000) targetFormat.rate = 12000; else if (format.rate <= 16000) targetFormat.rate = 16000; else if (format.rate <= 24000) targetFormat.rate = 24000; else targetFormat.rate = 48000; if (targetFormat.rate != format.rate) { targetFormat.bits = 32; targetFormat.fp = True; } /* Create and init format converter component. */ converter = new FormatConverter(format, targetFormat); if (converter->GetErrorState() == True) { errorState = True; errorString = converter->GetErrorString(); delete converter; return False; } /* Init Ogg stream. */ Math::RandomSeed(); ex_ogg_stream_init(&os, Math::Random()); /* Create Opus header. */ OpusHeader setup; memcpy(setup.codec_id, "OpusHead", 8); setup.version_id = 1; setup.nb_channels = format.channels; setup.sample_rate = format.rate; setup.output_gain = 0; if (format.channels <= 2) setup.channel_mapping = 0; else setup.channel_mapping = 1; /* Init Opus encoder. */ int error = 0; int streams = 0; int coupled = 0; OpusMSEncoder *encoder = ex_opus_multistream_surround_encoder_create(targetFormat.rate, setup.nb_channels, setup.channel_mapping, &streams, &coupled, setup.stream_map, OPUS_APPLICATION_AUDIO, &error); setup.nb_streams = streams; setup.nb_coupled = coupled; /* Get number of pre-skip samples. */ ex_opus_multistream_encoder_ctl(encoder, OPUS_GET_LOOKAHEAD(&preSkip)); setup.preskip = preSkip * (48000 / targetFormat.rate); frameSize = Math::Round(Float(targetFormat.rate) / (1000000.0 / config->GetIntValue(ConfigureOpus::ConfigID, "FrameSize", 20000))); totalSamples = 0; ex_opus_multistream_encoder_destroy(encoder); /* Adjust endianness of header fields. */ if (endianness != EndianLittle) { BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.preskip, sizeof(setup.preskip)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.sample_rate, sizeof(setup.sample_rate)); BoCA::Utilities::SwitchByteOrder((UnsignedByte *) &setup.output_gain, sizeof(setup.output_gain)); } /* Write header packet. */ ogg_packet header = { (unsigned char *) &setup, 19 + (setup.channel_mapping == 0 ? 0 : 2 + setup.nb_channels), 1, 0, 0, 0 }; ex_ogg_stream_packetin(&os, &header); /* Write Vorbis Comment header */ { Buffer vcBuffer; /* Remove ReplayGain information as per Opus comment spec. */ info.track_gain = NIL; info.track_peak = NIL; info.album_gain = NIL; info.album_peak = NIL; /* Render actual Vorbis Comment tag. * * An empty tag containing only the vendor string * is rendered if Vorbis Comment tags are disabled. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { const char *opusVersion = ex_opus_get_version_string(); tagger->SetConfiguration(config); tagger->SetVendorString(opusVersion); if (config->GetIntValue("Tags", "EnableVorbisComment", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) tagger->RenderBuffer(vcBuffer, track); else tagger->RenderBuffer(vcBuffer, Track()); boca.DeleteComponent(tagger); } vcBuffer.Resize(vcBuffer.Size() + 8); memmove(vcBuffer + 8, vcBuffer, vcBuffer.Size() - 8); memcpy(vcBuffer, "OpusTags", 8); ogg_packet header_comm = { vcBuffer, vcBuffer.Size(), 0, 0, 0, 0 }; ex_ogg_stream_packetin(&os, &header_comm); } WriteOggPackets(True); /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = Math::Max(24, (Int) Math::Ceil(24.0 * 960 / frameSize)); /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, targetFormat)); foreach (SuperWorker *worker, workers) worker->Start(); return True; } Bool BoCA::EncoderOpus::Deactivate() { /* Flush and clean up format converter. */ Buffer buffer; converter->Finish(buffer); delete converter; /* Append remaining samples to samples buffer. */ Int size = buffer.Size(); samplesBuffer.Resize(samplesBuffer.Size() + size); memcpy(samplesBuffer + samplesBuffer.Size() - size, buffer, size); /* Output remaining samples to encoder. */ EncodeFrames(True); /* Write any remaining Ogg packets. */ WriteOggPackets(True); ex_ogg_stream_clear(&os); /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Fix chapter marks in Vorbis Comments. */ if (config->GetIntValue("Tags", "EnableVorbisComment", True) && track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { driver->Close(); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->UpdateStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderOpus::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Change to Vorbis channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Default_3_0, Channel::Vorbis_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::Vorbis_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::Vorbis_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Default_6_1, Channel::Vorbis_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Default_7_1, Channel::Vorbis_7_1); /* Perform sample rate conversion. */ converter->Transform(data); /* Copy data to samples buffer. */ Int size = data.Size(); samplesBuffer.Resize(samplesBuffer.Size() + size); memcpy(samplesBuffer + samplesBuffer.Size() - size, data, size); /* Output samples to encoder. */ return EncodeFrames(False); } Int BoCA::EncoderOpus::EncodeFrames(Bool flush) { /* Pad end of stream with empty samples. */ Int nullSamples = 0; Int bytesPerSample = targetFormat.bits / 8; if (flush) { nullSamples = preSkip; if ((samplesBuffer.Size() / bytesPerSample / targetFormat.channels + preSkip) % frameSize > 0) nullSamples += frameSize - (samplesBuffer.Size() / bytesPerSample / targetFormat.channels + preSkip) % frameSize; samplesBuffer.Resize(samplesBuffer.Size() + nullSamples * targetFormat.channels * bytesPerSample); memset(((UnsignedByte *) samplesBuffer) + samplesBuffer.Size() - nullSamples * targetFormat.channels * bytesPerSample, 0, nullSamples * targetFormat.channels * bytesPerSample); } /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int samplesPerFrame = frameSize * targetFormat.channels; Int samplesInBuffer = samplesBuffer.Size() / bytesPerSample; if (flush) framesToProcess = Math::Floor(samplesInBuffer / samplesPerFrame); while (samplesInBuffer - framesProcessed * samplesPerFrame >= samplesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length(), False, 0); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * samplesPerFrame, samplesPerFrame * framesToProcess); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } Int bytesProcessed = framesProcessed * samplesPerFrame * bytesPerSample; memmove((UnsignedByte *) samplesBuffer, (UnsignedByte *) samplesBuffer + bytesProcessed, samplesBuffer.Size() - bytesProcessed); samplesBuffer.Resize(samplesBuffer.Size() - bytesProcessed); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length(), i == workers.Length() - 1, i == workers.Length() - 1 ? nullSamples : 0); nextWorker++; } return dataLength; } Int BoCA::EncoderOpus::ProcessPackets(const Buffer &packets, const Array &packetSizes, Bool first, Bool flush, Int nullSamples) { Int offset = 0; if (!first) for (Int i = 0; i < overlap; i++) offset += packetSizes.GetNth(i); for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap && !first) continue; if (packetSizes.GetNth(i) == 0) continue; totalSamples += frameSize; op.packet = packets + offset; op.bytes = packetSizes.GetNth(i); op.b_o_s = first && i == 0; op.e_o_s = flush && i == packetSizes.Length() - 1; op.granulepos = (op.e_o_s ? totalSamples + preSkip - nullSamples : totalSamples) * (48000 / targetFormat.rate); op.packetno = 0; ex_ogg_stream_packetin(&os, &op); offset += packetSizes.GetNth(i); } return WriteOggPackets(flush); } Int BoCA::EncoderOpus::WriteOggPackets(Bool flush) { Int bytes = 0; do { int result = 0; if (flush) result = ex_ogg_stream_flush(&os, &og); else result = ex_ogg_stream_pageout(&os, &og); if (result == 0) break; bytes += driver->WriteData(og.header, og.header_len); bytes += driver->WriteData(og.body, og.body_len); } while (true); return bytes; } String BoCA::EncoderOpus::GetOutputFileExtension() const { const Config *config = GetConfiguration(); switch (config->GetIntValue(ConfigureOpus::ConfigID, "FileExtension", 0)) { default: case 0: return "opus"; case 1: return "oga"; } } Bool BoCA::EncoderOpus::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "opus-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureOpus::ConfigID, "Mode", 0); config->SetIntValue(ConfigureOpus::ConfigID, "Bandwidth", 0); config->SetIntValue(ConfigureOpus::ConfigID, "PacketLoss", 0); config->SetIntValue(ConfigureOpus::ConfigID, "EnableDTX", False); config->SetIntValue(ConfigureOpus::ConfigID, "EnableVBR", True); config->SetIntValue(ConfigureOpus::ConfigID, "EnableConstrainedVBR", False); config->SetIntValue(ConfigureOpus::ConfigID, "Bitrate", 128); config->SetIntValue(ConfigureOpus::ConfigID, "Complexity", 10); config->SetIntValue(ConfigureOpus::ConfigID, "FrameSize", 20000); config->SetIntValue(ConfigureOpus::ConfigID, "DisablePhaseInversion", False); } /* Get command line settings. */ Bool hardCBR = config->GetIntValue(encoderID, "Use hard CBR encoding", !config->GetIntValue(ConfigureOpus::ConfigID, "EnableVBR", True)); Bool constrainedVBR = config->GetIntValue(encoderID, "Use constrained VBR encoding", config->GetIntValue(ConfigureOpus::ConfigID, "EnableConstrainedVBR", False)); Int bitrate = config->GetIntValue(ConfigureOpus::ConfigID, "Bitrate", 128); Int complexity = config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10); Int framesize = config->GetIntValue(ConfigureOpus::ConfigID, "FrameSize", 20000) / 1000; if (config->GetIntValue(encoderID, "Set Bitrate", False)) bitrate = config->GetIntValue(encoderID, "Bitrate", bitrate); if (config->GetIntValue(encoderID, "Set Encoding complexity", False)) complexity = config->GetIntValue(encoderID, "Encoding complexity", complexity); if (config->GetIntValue(encoderID, "Set Frame size", False)) framesize = config->GetIntValue(encoderID, "Frame size", framesize); Bool disablePhaseInv = config->GetIntValue(encoderID, "Disable intensity stereo phase inversion", config->GetIntValue(ConfigureOpus::ConfigID, "DisablePhaseInversion", False)); /* Set configuration values. */ config->SetIntValue(ConfigureOpus::ConfigID, "EnableVBR", !hardCBR); config->SetIntValue(ConfigureOpus::ConfigID, "EnableConstrainedVBR", constrainedVBR); config->SetIntValue(ConfigureOpus::ConfigID, "Bitrate", Math::Max(6, Math::Min(510, bitrate))); config->SetIntValue(ConfigureOpus::ConfigID, "Complexity", Math::Max(0, Math::Min(10, complexity))); config->SetIntValue(ConfigureOpus::ConfigID, "FrameSize", Math::Max(5, Math::Min(120, framesize)) * 1000); config->SetIntValue(ConfigureOpus::ConfigID, "DisablePhaseInversion", disablePhaseInv); return True; } ConfigLayer *BoCA::EncoderOpus::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureOpus(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/opus.h000066400000000000000000000032651516712004000241230ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderOpus) namespace BoCA { class EncoderOpus : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; FormatConverter *converter; Format targetFormat; Array workers; ogg_stream_state os; ogg_page og; ogg_packet op; Int nextWorker; Int frameSize; Int preSkip; Int blockSize; Int overlap; Int64 totalSamples; Buffer samplesBuffer; Int EncodeFrames(Bool); Int ProcessPackets(const Buffer &, const Array &, Bool, Bool, Int); Int WriteOggPackets(Bool); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderOpus(); ~EncoderOpus(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderOpus) BoCA_END_COMPONENT(EncoderOpus) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/worker.cpp000066400000000000000000000113731516712004000250000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "worker.h" #include "config.h" BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat) : processSignal(1), readySignal(1) { processSignal.Wait(); quit = False; format = iFormat; threadMain.Connect(&SuperWorker::Run, this); /* Get best sample rate. */ Int sampleRate = 48000; if (format.rate <= 8000) sampleRate = 8000; else if (format.rate <= 12000) sampleRate = 12000; else if (format.rate <= 16000) sampleRate = 16000; else if (format.rate <= 24000) sampleRate = 24000; /* Create Opus encoder. */ int error = 0; int streams = 0; int coupled = 0; uint8_t stream_map[255]; encoder = ex_opus_multistream_surround_encoder_create(sampleRate, format.channels, format.channels <= 2 ? 0 : 1, &streams, &coupled, stream_map, OPUS_APPLICATION_AUDIO, &error); /* Set encoder parameters. */ if (config->GetIntValue(ConfigureOpus::ConfigID, "Mode", 0) != 0) ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE + config->GetIntValue("Opus", "Mode", 0) - 1)); if (config->GetIntValue(ConfigureOpus::ConfigID, "Bandwidth", 0) != 0) ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND + config->GetIntValue("Opus", "Bandwidth", 0) - 1)); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_BITRATE( config->GetIntValue(ConfigureOpus::ConfigID, "Bitrate", 128) * 1000)); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_VBR(config->GetIntValue(ConfigureOpus::ConfigID, "EnableVBR", True))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_VBR_CONSTRAINT(config->GetIntValue(ConfigureOpus::ConfigID, "EnableConstrainedVBR", False))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_PHASE_INVERSION_DISABLED(config->GetIntValue(ConfigureOpus::ConfigID, "DisablePhaseInversion", False))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_PACKET_LOSS_PERC(config->GetIntValue(ConfigureOpus::ConfigID, "PacketLoss", 0))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_DTX(config->GetIntValue(ConfigureOpus::ConfigID, "EnableDTX", False))); ex_opus_multistream_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(0)); /* Get frame size. */ frameSize = Math::Round(Float(sampleRate) / (1000000.0 / config->GetIntValue(ConfigureOpus::ConfigID, "FrameSize", 20000))); maxPacketSize = 4000 * Math::Ceil(format.channels / 2.0); bytesPerSample = format.bits / 8; } BoCA::SuperWorker::~SuperWorker() { /* Destroy Opus encoder. */ ex_opus_multistream_encoder_destroy(encoder); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); Int samplesLeft = samplesBuffer.Size() / bytesPerSample; Int samplesPerFrame = frameSize * format.channels; Int framesProcessed = 0; while (samplesLeft >= samplesPerFrame) { packetBuffer.Resize(packetBuffer.Size() + maxPacketSize); Int dataLength = 0; if (format.bits == 16) dataLength = ex_opus_multistream_encode(encoder, ((opus_int16 *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, frameSize, packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); else dataLength = ex_opus_multistream_encode_float(encoder, ((float *) (UnsignedByte *) samplesBuffer) + framesProcessed * samplesPerFrame, frameSize, packetBuffer + packetBuffer.Size() - maxPacketSize, maxPacketSize); packetBuffer.Resize(packetBuffer.Size() - maxPacketSize + dataLength); packetSizes.Add(dataLength); framesProcessed++; samplesLeft -= samplesPerFrame; } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int samples) { samplesBuffer.Resize(samples * bytesPerSample); memcpy(samplesBuffer, buffer + offset * bytesPerSample, samples * bytesPerSample); processSignal.Release(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/opus/worker.h000066400000000000000000000026021516712004000244400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; OpusMSEncoder *encoder; Format format; Int frameSize; Int maxPacketSize; Buffer samplesBuffer; Int bytesPerSample; Buffer packetBuffer; Array packetSizes; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &); ~SuperWorker(); Void Encode(const Buffer &, Int, Int); Void WaitUntilReady(); Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/000077500000000000000000000000001516712004000234145ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/Makefile000066400000000000000000000023331516712004000250550ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: ifeq ($(wrapper),) TARGET = sndfile else TARGET = sndfile_$(wrapper) endif TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: ifeq ($(wrapper),) OBJECTS = config.o dllinterface.o sndfile.o else OBJECTS = config-$(wrapper).o dllinterface.o sndfile-$(wrapper).o endif # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ifeq ($(wrapper),) ALLCMD1 = $(MAKE) -f "$(SRCDIR)"/Makefile config=$(config) wrapper=wave ALLCMD2 = CLEANCMD1 = $(MAKE) -f "$(SRCDIR)"/Makefile config=$(config) wrapper=wave clean CLEANCMD2 = INSTCMD1 = $(MAKE) -f "$(SRCDIR)"/Makefile config=$(config) wrapper=wave install INSTCMD2 = UINSTCMD1 = $(MAKE) -f "$(SRCDIR)"/Makefile config=$(config) wrapper=wave uninstall UINSTCMD2 = else ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = endif ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/config-wave.cpp000066400000000000000000000057471516712004000263420ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureSndFile::ConfigID = "SndFileWave"; BoCA::ConfigureSndFile::ConfigureSndFile() { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::SndFile"); group_format = new GroupBox(i18n->TranslateString("Output format"), Point(7, 11), Size(328, 39)); text_format = NIL; combo_format = NIL; text_subformat = new Text(i18n->AddColon(i18n->TranslateString("Audio format")), Point(10, 13)); combo_subformat = new ComboBox(Point(text_subformat->GetUnscaledTextWidth() + 17, 10), Size(301 - text_subformat->GetUnscaledTextWidth(), 0)); group_format->Add(text_subformat); group_format->Add(combo_subformat); Add(group_format); SelectFormat(); SetSize(Size(342, 57)); } BoCA::ConfigureSndFile::~ConfigureSndFile() { DeleteObject(group_format); DeleteObject(text_subformat); DeleteObject(combo_subformat); } Int BoCA::ConfigureSndFile::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "SubFormat", subformats.Get(combo_subformat->GetSelectedEntry()->GetHandle())); return Success(); } Void BoCA::ConfigureSndFile::SelectFormat() { combo_subformat->RemoveAllEntries(); subformats.RemoveAll(); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::SndFile"); const Config *config = Config::Get(); ListEntry *entry = combo_subformat->AddEntry(i18n->TranslateString("auto select")); subformats.Add(0, entry->GetHandle()); if (config->GetIntValue(ConfigID, "SubFormat", 0) == 0) combo_subformat->SelectEntry(entry); int format = SF_FORMAT_WAV; int count = 0; ex_sf_command(NIL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof(int)); for (Int i = 0; i < count; i++) { SF_FORMAT_INFO format_info; format_info.format = i; ex_sf_command(NIL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof(format_info)); SF_INFO info; info.samplerate = 44100; info.channels = 1; info.format = format | format_info.format; if (!ex_sf_format_check(&info)) continue; ListEntry *entry = NIL; info.channels = 2; if (!ex_sf_format_check(&info)) entry = combo_subformat->AddEntry(i18n->AddBrackets(format_info.name, i18n->TranslateString("mono"))); else entry = combo_subformat->AddEntry(format_info.name); subformats.Add(format_info.format, entry->GetHandle()); if (config->GetIntValue(ConfigID, "SubFormat", 0) == format_info.format) combo_subformat->SelectEntry(entry); } combo_subformat->Paint(SP_PAINT); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/config.cpp000066400000000000000000000117151516712004000253720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureSndFile::ConfigID = "SndFile"; BoCA::ConfigureSndFile::ConfigureSndFile() { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::SndFile"); group_format = new GroupBox(i18n->TranslateString("Output format"), Point(7, 11), Size(328, 65)); text_format = new Text(i18n->AddColon(i18n->TranslateString("File format")), Point(10, 13)); combo_format = new ComboBox(Point(88, 10), Size(230, 0)); combo_format->onSelectEntry.Connect(&ConfigureSndFile::SelectFormat, this); text_subformat = new Text(i18n->AddColon(i18n->TranslateString("Audio format")), Point(10, 39)); combo_subformat = new ComboBox(Point(88, 36), Size(230, 0)); Int maxTextSize = Math::Max(text_format->GetUnscaledTextWidth(), text_subformat->GetUnscaledTextWidth()); combo_format->SetX(maxTextSize + 17); combo_format->SetWidth(301 - maxTextSize); combo_subformat->SetX(maxTextSize + 17); combo_subformat->SetWidth(301 - maxTextSize); group_format->Add(text_format); group_format->Add(combo_format); group_format->Add(text_subformat); group_format->Add(combo_subformat); Add(group_format); FillFormats(); SetSize(Size(342, 83)); } BoCA::ConfigureSndFile::~ConfigureSndFile() { DeleteObject(group_format); DeleteObject(text_format); DeleteObject(combo_format); DeleteObject(text_subformat); DeleteObject(combo_subformat); } Int BoCA::ConfigureSndFile::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Format", formats.Get(combo_format->GetSelectedEntry()->GetHandle())); config->SetIntValue(ConfigID, "SubFormat", subformats.Get(combo_subformat->GetSelectedEntry()->GetHandle())); return Success(); } Void BoCA::ConfigureSndFile::FillFormats() { const Config *config = Config::Get(); int count = 0; ex_sf_command(NIL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)); for (Int i = 0; i < count; i++) { SF_FORMAT_INFO format_info; format_info.format = i; ex_sf_command(NIL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof(format_info)); if (format_info.format != SF_FORMAT_WAV && format_info.format != SF_FORMAT_AIFF && format_info.format != SF_FORMAT_AU && format_info.format != SF_FORMAT_PAF && format_info.format != SF_FORMAT_SVX && format_info.format != SF_FORMAT_IRCAM && format_info.format != SF_FORMAT_VOC && format_info.format != SF_FORMAT_W64 && format_info.format != SF_FORMAT_PVF && format_info.format != SF_FORMAT_HTK && format_info.format != SF_FORMAT_CAF && format_info.format != SF_FORMAT_AVR && format_info.format != SF_FORMAT_WVE && format_info.format != SF_FORMAT_RF64) continue; ListEntry *entry = combo_format->AddEntry(format_info.name); formats.Add(format_info.format, entry->GetHandle()); #ifdef __APPLE__ if (config->GetIntValue(ConfigID, "Format", SF_FORMAT_AIFF) == format_info.format) combo_format->SelectEntry(entry); #else if (config->GetIntValue(ConfigID, "Format", SF_FORMAT_WAV) == format_info.format) combo_format->SelectEntry(entry); #endif } SelectFormat(); } Void BoCA::ConfigureSndFile::SelectFormat() { combo_subformat->RemoveAllEntries(); subformats.RemoveAll(); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::SndFile"); const Config *config = Config::Get(); ListEntry *entry = combo_subformat->AddEntry(i18n->TranslateString("auto select")); subformats.Add(0, entry->GetHandle()); if (config->GetIntValue(ConfigID, "SubFormat", 0) == 0) combo_subformat->SelectEntry(entry); int format = formats.Get(combo_format->GetSelectedEntry()->GetHandle()); int count = 0; ex_sf_command(NIL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof(int)); for (Int i = 0; i < count; i++) { SF_FORMAT_INFO format_info; format_info.format = i; ex_sf_command(NIL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof(format_info)); SF_INFO info; info.samplerate = 44100; info.channels = 1; info.format = format | format_info.format; if (!ex_sf_format_check(&info)) continue; ListEntry *entry = NIL; info.channels = 2; if (!ex_sf_format_check(&info)) entry = combo_subformat->AddEntry(i18n->AddBrackets(format_info.name, i18n->TranslateString("mono"))); else entry = combo_subformat->AddEntry(format_info.name); subformats.Add(format_info.format, entry->GetHandle()); if (config->GetIntValue(ConfigID, "SubFormat", 0) == format_info.format) combo_subformat->SelectEntry(entry); } combo_subformat->Paint(SP_PAINT); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/config.h000066400000000000000000000023021516712004000250270ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_SNDFILECONFIG #define H_SNDFILECONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureSndFile : public ConfigLayer { private: GroupBox *group_format; Text *text_format; ComboBox *combo_format; Text *text_subformat; ComboBox *combo_subformat; Array formats; Array subformats; Void FillFormats(); slots: Void SelectFormat(); public: static const String ConfigID; ConfigureSndFile(); ~ConfigureSndFile(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/dllinterface.cpp000066400000000000000000000047101516712004000265560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" SF_FORMAT_CHECK ex_sf_format_check = NIL; SF_OPEN_VIRTUAL ex_sf_open_virtual = NIL; SF_CLOSE ex_sf_close = NIL; SF_WRITE_SHORT ex_sf_write_short = NIL; SF_WRITE_INT ex_sf_write_int = NIL; SF_WRITE_FLOAT ex_sf_write_float = NIL; SF_SET_STRING ex_sf_set_string = NIL; SF_COMMAND ex_sf_command = NIL; SF_STRERROR ex_sf_strerror = NIL; SF_VERSION_STRING ex_sf_version_string = NIL; DynamicLoader *sndfiledll = NIL; Bool LoadSndFileDLL() { sndfiledll = BoCA::Utilities::LoadCodecDLL("sndfile"); if (sndfiledll == NIL) return False; ex_sf_format_check = (SF_FORMAT_CHECK) sndfiledll->GetFunctionAddress("sf_format_check"); ex_sf_open_virtual = (SF_OPEN_VIRTUAL) sndfiledll->GetFunctionAddress("sf_open_virtual"); ex_sf_close = (SF_CLOSE) sndfiledll->GetFunctionAddress("sf_close"); ex_sf_write_short = (SF_WRITE_SHORT) sndfiledll->GetFunctionAddress("sf_write_short"); ex_sf_write_int = (SF_WRITE_INT) sndfiledll->GetFunctionAddress("sf_write_int"); ex_sf_write_float = (SF_WRITE_FLOAT) sndfiledll->GetFunctionAddress("sf_write_float"); ex_sf_set_string = (SF_SET_STRING) sndfiledll->GetFunctionAddress("sf_set_string"); ex_sf_command = (SF_COMMAND) sndfiledll->GetFunctionAddress("sf_command"); ex_sf_strerror = (SF_STRERROR) sndfiledll->GetFunctionAddress("sf_strerror"); ex_sf_version_string = (SF_VERSION_STRING) sndfiledll->GetFunctionAddress("sf_version_string"); if (ex_sf_format_check == NIL || ex_sf_open_virtual == NIL || ex_sf_close == NIL || ex_sf_write_short == NIL || ex_sf_write_int == NIL || ex_sf_write_float == NIL || ex_sf_set_string == NIL || ex_sf_command == NIL || ex_sf_strerror == NIL || ex_sf_version_string == NIL) { FreeSndFileDLL(); return False; } return True; } Void FreeSndFileDLL() { BoCA::Utilities::FreeCodecDLL(sndfiledll); sndfiledll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/dllinterface.h000066400000000000000000000033701516712004000262240ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *sndfiledll; Bool LoadSndFileDLL(); Void FreeSndFileDLL(); typedef int (*SF_FORMAT_CHECK) (const SF_INFO *); typedef SNDFILE * (*SF_OPEN_VIRTUAL) (SF_VIRTUAL_IO *, int, SF_INFO *, void *); typedef int (*SF_CLOSE) (SNDFILE *); typedef sf_count_t (*SF_WRITE_SHORT) (SNDFILE *, short *, sf_count_t); typedef sf_count_t (*SF_WRITE_INT) (SNDFILE *, int *, sf_count_t); typedef sf_count_t (*SF_WRITE_FLOAT) (SNDFILE *, float *, sf_count_t); typedef int (*SF_SET_STRING) (SNDFILE *, int, const char *); typedef int (*SF_COMMAND) (SNDFILE *, int, void *, int); typedef const char * (*SF_STRERROR) (SNDFILE *); typedef const char * (*SF_VERSION_STRING) (); extern SF_FORMAT_CHECK ex_sf_format_check; extern SF_OPEN_VIRTUAL ex_sf_open_virtual; extern SF_CLOSE ex_sf_close; extern SF_WRITE_SHORT ex_sf_write_short; extern SF_WRITE_INT ex_sf_write_int; extern SF_WRITE_FLOAT ex_sf_write_float; extern SF_SET_STRING ex_sf_set_string; extern SF_COMMAND ex_sf_command; extern SF_STRERROR ex_sf_strerror; extern SF_VERSION_STRING ex_sf_version_string; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/sndfile-wave.cpp000066400000000000000000000071421516712004000265100ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "sndfile.h" #include "config.h" const String &BoCA::EncoderSndFile::GetComponentSpecs() { static String componentSpecs; if (sndfiledll != NIL) { I18n *i18n = I18n::Get(); i18n->SetContext("Components::Encoders"); componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("Windows Wave File Output")).Append(" \ 1.0 \ sndfile-wave-enc \ encoder \ sndfile-enc \ wave-enc \ \ Microsoft Wave Files \ wav \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadSndFileDLL(); } Void smooth::DetachDLL() { FreeSndFileDLL(); } BoCA::EncoderSndFile::EncoderSndFile() { configLayer = NIL; config = NIL; encoder = NIL; fileFormat = 0; sndf = NIL; } BoCA::EncoderSndFile::~EncoderSndFile() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderSndFile::Activate() { /* Get configuration. */ config = Config::Copy(GetConfiguration()); /* Create downstream encoder. */ AS::Registry &boca = AS::Registry::Get(); encoder = (AS::EncoderComponent *) boca.CreateComponentByID("sndfile-enc"); if (encoder == NIL) return False; config->SetIntValue("SndFile", "Format", SF_FORMAT_WAV); config->SetIntValue("SndFile", "SubFormat", config->GetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0)); encoder->SetConfiguration(config); encoder->SetAudioTrackInfo(track); encoder->SetDriver(driver); if(!encoder->Activate()) { errorState = True; errorString = encoder->GetErrorString(); boca.DeleteComponent(encoder); return False; } return True; } Bool BoCA::EncoderSndFile::Deactivate() { /* Forward deactivate call. */ Bool result = encoder->Deactivate(); /* Free downstream encoder. */ AS::Registry &boca = AS::Registry::Get(); boca.DeleteComponent(encoder); return result; } Int BoCA::EncoderSndFile::WriteData(Buffer &data) { /* Forward write call. */ return encoder->WriteData(data); } Bool BoCA::EncoderSndFile::SetOutputFormat(Int n) { return EncoderComponent::SetOutputFormat(n); } String BoCA::EncoderSndFile::GetOutputFileExtension() const { return EncoderComponent::GetOutputFileExtension(); } ConfigLayer *BoCA::EncoderSndFile::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureSndFile(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/sndfile.cpp000066400000000000000000000557241516712004000255610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "sndfile.h" #include "config.h" const String &BoCA::EncoderSndFile::GetComponentSpecs() { static String componentSpecs; if (sndfiledll != NIL) { I18n *i18n = I18n::Get(); i18n->SetContext("Components::Encoders"); componentSpecs = String(" \ \ \ \ ").Append(i18n->TranslateString("SndFile Output Component")).Append(" %VERSION% \ 1.0 \ sndfile-enc \ encoder \ wave-enc \ \ Microsoft Wave Files \ wav \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ Apple Audio Files \ aif \ aiff \ aifc \ ID3v2 \ \ \ Apple Core Audio Files \ caf \ \ \ Sony Media Wave64 Files \ w64 \ RIFF INFO Tag \ \ \ RIFF 64 Audio Files \ rf64 \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ Sun Audio Files \ au \ snd \ \ \ Creative Voice Files \ voc \ \ \ Amiga Audio Files \ iff \ svx \ \ \ IRCAM Sound Files \ sf \ \ \ Paris Audio Files \ paf \ \ \ Portable Voice Format \ pvf \ \ \ Psion WVE Files \ wve \ \ \ HMM Toolkit Format \ htk \ \ \ Audio Visual Research Format \ avr \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "); #ifdef __APPLE__ componentSpecs.Replace("default=\"wav\"", "default=\"aiff\""); #endif componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_sf_version_string()).Replace("libsndfile-", NIL))); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadSndFileDLL(); } Void smooth::DetachDLL() { FreeSndFileDLL(); } namespace BoCA { sf_count_t sf_vio_get_filelen_callback(void *); sf_count_t sf_vio_seek_callback(sf_count_t, int, void *); sf_count_t sf_vio_read_callback(void *, sf_count_t, void *); sf_count_t sf_vio_write_callback(const void *, sf_count_t, void *); sf_count_t sf_vio_tell_callback(void *); }; BoCA::EncoderSndFile::EncoderSndFile() { configLayer = NIL; config = NIL; encoder = NIL; fileFormat = 0; sndf = NIL; } BoCA::EncoderSndFile::~EncoderSndFile() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderSndFile::Activate() { const Format &format = track.GetFormat(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Get selected file format. */ #ifdef __APPLE__ fileFormat = config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_AIFF); #else fileFormat = config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_WAV); #endif /* Fill format info structure. */ SF_INFO sinfo; memset(&sinfo, 0, sizeof(SF_INFO)); sinfo.format = fileFormat | config->GetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0); sinfo.samplerate = format.rate; sinfo.channels = format.channels; if (config->GetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0) == 0) sinfo.format |= SelectBestSubFormat(format, fileFormat); /* Check if selected format is supported. */ if (!ex_sf_format_check(&sinfo)) { I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::SndFile::Errors"); if (config->GetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0) == 0) errorString = i18n->TranslateString("Could not find suitable audio format."); else errorString = i18n->TranslateString("Unable to use selected audio format."); errorState = True; return False; } /* Open sndfile handle. */ SF_VIRTUAL_IO vio; vio.get_filelen = sf_vio_get_filelen_callback; vio.seek = sf_vio_seek_callback; vio.read = sf_vio_read_callback; vio.write = sf_vio_write_callback; vio.tell = sf_vio_tell_callback; sndf = ex_sf_open_virtual(&vio, SFM_WRITE, &sinfo, this); if (sndf == NIL) return False; ex_sf_command(sndf, SFC_SET_SCALE_INT_FLOAT_WRITE, NIL, SF_TRUE); ex_sf_command(sndf, SFC_SET_CLIPPING, NIL, SF_TRUE); /* Set metadata. */ if (fileFormat != SF_FORMAT_WAV && fileFormat != SF_FORMAT_RF64 && fileFormat != SF_FORMAT_W64) { Info info = track.GetInfo(); if (info.HasBasicInfo()) { if (info.artist != NIL) ex_sf_set_string(sndf, SF_STR_ARTIST, info.artist); if (info.title != NIL) ex_sf_set_string(sndf, SF_STR_TITLE, info.title); if (info.album != NIL) ex_sf_set_string(sndf, SF_STR_ALBUM, info.album); if (info.track > 0) ex_sf_set_string(sndf, SF_STR_TRACKNUMBER, String::FromInt(info.track)); if (info.year > 0) ex_sf_set_string(sndf, SF_STR_DATE, String::FromInt(info.year)); if (info.genre != NIL) ex_sf_set_string(sndf, SF_STR_GENRE, info.genre); if (info.comment != NIL && !config->GetIntValue("Tags", "ReplaceExistingComments", False)) ex_sf_set_string(sndf, SF_STR_COMMENT, info.comment); else if (config->GetStringValue("Tags", "DefaultComment", NIL) != NIL) ex_sf_set_string(sndf, SF_STR_COMMENT, config->GetStringValue("Tags", "DefaultComment", NIL)); } } return True; } Bool BoCA::EncoderSndFile::Deactivate() { static Endianness endianness = CPU().GetEndianness(); /* Close sndfile handle. */ ex_sf_close(sndf); /* Write metadata. */ const Info &info = track.GetInfo(); /* Write RIFF and CART tags to Wave and RF64 files. */ if (fileFormat == SF_FORMAT_WAV || fileFormat == SF_FORMAT_RF64) { /* Write RIFF tag if requested. */ if (config->GetIntValue("Tags", "EnableRIFFINFOTag", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("riff-tag"); if (tagger != NIL) { Buffer tagBuffer; tagger->SetConfiguration(config); tagger->RenderBuffer(tagBuffer, track); driver->WriteData(tagBuffer, tagBuffer.Size()); boca.DeleteComponent(tagger); } } /* Write CART tag if requested. */ if (config->GetIntValue("Tags", "EnableRIFFCartTag", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("cart-tag"); if (tagger != NIL) { Buffer tagBuffer; tagger->SetConfiguration(config); tagger->RenderBuffer(tagBuffer, track); driver->WriteData(tagBuffer, tagBuffer.Size()); boca.DeleteComponent(tagger); } } /* Write file size to header. */ Int64 fileSize = driver->GetSize() - 8; if (fileFormat == SF_FORMAT_WAV) { if (fileSize >= (Int64(1) << 32)) fileSize = -1; driver->Seek(4); if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 7; i >= 4; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); } else { driver->Seek(20); if (endianness == EndianLittle) for (Int i = 0; i <= 7; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 7; i >= 0; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); } driver->Seek(driver->GetSize()); } /* Write RIFF tags to Wave64 files. */ if (fileFormat == SF_FORMAT_W64) { /* Write RIFF tag if requested. */ if (config->GetIntValue("Tags", "EnableRIFFINFOTag", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("riff-tag"); if (tagger != NIL) { Int64 size = driver->GetPos(); if (size % 8 > 0) for (Int i = 0; i < 8 - (size % 8); i++) driver->WriteData((unsigned char *) "", 1); Buffer tagBuffer; tagger->SetConfiguration(config); tagger->RenderBuffer(tagBuffer, track); unsigned char guid[16] = { 'l', 'i', 's', 't', 0x2F, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; size = tagBuffer.Size() + 16; driver->WriteData(guid, 16); if (endianness == EndianLittle) for (Int i = 0; i <= 7; i++) driver->WriteData(((unsigned char *) &size) + i, 1); else for (Int i = 7; i >= 0; i--) driver->WriteData(((unsigned char *) &size) + i, 1); driver->WriteData(tagBuffer + 8, tagBuffer.Size() - 8); if (size % 8 > 0) for (Int i = 0; i < 8 - (size % 8); i++) driver->WriteData((unsigned char *) "", 1); boca.DeleteComponent(tagger); } } /* Write file size to header. */ Int64 fileSize = driver->GetSize(); driver->Seek(16); if (endianness == EndianLittle) for (Int i = 0; i <= 7; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 7; i >= 0; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); driver->Seek(driver->GetSize()); } /* Write ID3v2 tags to Wave, RF64 and AIFF files. */ if (fileFormat == SF_FORMAT_WAV || fileFormat == SF_FORMAT_RF64 || fileFormat == SF_FORMAT_AIFF) { /* Write ID3v2 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v2", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); if (fileFormat != SF_FORMAT_AIFF) driver->WriteData((unsigned char *) "id3 ", 4); else driver->WriteData((unsigned char *) "ID3 ", 4); Int size = id3Buffer.Size(); if ((fileFormat != SF_FORMAT_AIFF && endianness == EndianLittle) || (fileFormat == SF_FORMAT_AIFF && endianness == EndianBig)) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &size) + i, 1); else for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &size) + i, 1); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } /* Write file size to header. */ Int64 fileSize = driver->GetSize() - 8; if (fileSize >= (Int64(1) << 32)) fileSize = -1; driver->Seek(4); if (fileFormat != SF_FORMAT_AIFF) { if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 7; i >= 4; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); } else { if (endianness == EndianLittle) for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 4; i <= 7; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); } driver->Seek(driver->GetSize()); } return True; } Int BoCA::EncoderSndFile::WriteData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); /* Reorder channels. */ if (fileFormat == SF_FORMAT_AIFF || fileFormat == SF_FORMAT_CAF) { if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::AIFF_5_1); } /* Hand data to libsndfile. */ int bytes = 0; if (format.bits == 8) { Buffer buffer(data.Size()); for (Int i = 0; i < data.Size(); i++) buffer[i] = ((signed char *) (UnsignedByte *) data)[i] << 8; bytes = ex_sf_write_short(sndf, buffer, data.Size()); } else if (format.bits == 16) { bytes = ex_sf_write_short(sndf, (short *) (UnsignedByte *) data, data.Size() / 2) * 2; } else if (format.bits == 24) { Buffer buffer(data.Size() / 3); for (Int i = 0; i < data.Size() / 3; i++) { if (endianness == EndianLittle) { buffer[i] = (int) (data[3 * i + 2] << 24 | data[3 * i + 1] << 16 | data[3 * i ] << 8); } else { buffer[i] = (int) (data[3 * i ] << 24 | data[3 * i + 1] << 16 | data[3 * i + 2] << 8); } } bytes = ex_sf_write_int(sndf, buffer, data.Size() / 3) * 3; } else if (format.bits == 32 && !format.fp) { bytes = ex_sf_write_int(sndf, (int *) (UnsignedByte *) data, data.Size() / 4) * 4; } else if (format.bits == 32 && format.fp) { bytes = ex_sf_write_float(sndf, (float *) (UnsignedByte *) data, data.Size() / 4) * 4; } return bytes; } Int BoCA::EncoderSndFile::SelectBestSubFormat(const Format &format, Int fileFormat) { static Int formats8Bit[] = { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32, SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_ULAW, SF_FORMAT_ALAW, NIL }; static Int formats16Bit[] = { SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32, SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_PCM_S8, SF_FORMAT_PCM_U8, SF_FORMAT_ULAW, SF_FORMAT_ALAW, NIL }; static Int formats24Bit[] = { SF_FORMAT_PCM_24, SF_FORMAT_PCM_32, SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_PCM_16, SF_FORMAT_PCM_S8, SF_FORMAT_PCM_U8, SF_FORMAT_ULAW, SF_FORMAT_ALAW, NIL }; static Int formats32Bit[] = { SF_FORMAT_PCM_32, SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_PCM_24, SF_FORMAT_PCM_16, SF_FORMAT_PCM_S8, SF_FORMAT_PCM_U8, SF_FORMAT_ULAW, SF_FORMAT_ALAW, NIL }; static Int formatsFloat[] = { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_PCM_32, SF_FORMAT_PCM_24, SF_FORMAT_PCM_16, SF_FORMAT_PCM_S8, SF_FORMAT_PCM_U8, SF_FORMAT_ULAW, SF_FORMAT_ALAW, NIL }; Int *formats = NIL; if ( format.bits <= 8) formats = formats8Bit; else if ( format.bits <= 16) formats = formats16Bit; else if ( format.bits <= 24) formats = formats24Bit; else if (!format.fp ) formats = formats32Bit; else formats = formatsFloat; for (Int i = 0; formats[i] != NIL; i++) { SF_INFO info; info.samplerate = format.rate; info.channels = format.channels; info.format = fileFormat | formats[i]; if (ex_sf_format_check(&info)) return formats[i]; } return 0; } Bool BoCA::EncoderSndFile::SetOutputFormat(Int n) { Config *config = Config::Get(); SF_FORMAT_INFO format_info; switch (n) { case 0: format_info.format = SF_FORMAT_WAV; break; case 1: format_info.format = SF_FORMAT_AIFF; break; case 2: format_info.format = SF_FORMAT_CAF; break; case 3: format_info.format = SF_FORMAT_W64; break; case 4: format_info.format = SF_FORMAT_RF64; break; case 5: format_info.format = SF_FORMAT_AU; break; case 6: format_info.format = SF_FORMAT_VOC; break; case 7: format_info.format = SF_FORMAT_SVX; break; case 8: format_info.format = SF_FORMAT_IRCAM; break; case 9: format_info.format = SF_FORMAT_PAF; break; case 10: format_info.format = SF_FORMAT_PVF; break; case 11: format_info.format = SF_FORMAT_WVE; break; case 12: format_info.format = SF_FORMAT_HTK; break; case 13: format_info.format = SF_FORMAT_AVR; break; default: return False; } /* Check if output format is already set. */ #ifdef __APPLE__ if (config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_AIFF) == format_info.format) return True; #else if (config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_WAV) == format_info.format) return True; #endif /* Set new output format. */ config->SetIntValue(ConfigureSndFile::ConfigID, "Format", format_info.format); config->SetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0); return True; } String BoCA::EncoderSndFile::GetOutputFileExtension() const { const Config *config = GetConfiguration(); SF_FORMAT_INFO format_info; #ifdef __APPLE__ format_info.format = config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_AIFF); #else format_info.format = config->GetIntValue(ConfigureSndFile::ConfigID, "Format", SF_FORMAT_WAV); #endif ex_sf_command(NIL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info)); return format_info.extension; } Bool BoCA::EncoderSndFile::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "sndfile-enc"; /* Set default values. */ #ifdef __APPLE__ Int defaultFormat = SF_FORMAT_AIFF; #else Int defaultFormat = SF_FORMAT_WAV; #endif if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureSndFile::ConfigID, "Format", defaultFormat); config->SetIntValue(ConfigureSndFile::ConfigID, "SubFormat", 0); } /* Get command line settings. */ Int format = config->GetIntValue(ConfigureSndFile::ConfigID, "Format", defaultFormat); String formatName = "wav"; if (format == SF_FORMAT_AIFF) formatName = "aiff"; else if (format == SF_FORMAT_CAF) formatName = "caf"; else if (format == SF_FORMAT_W64) formatName = "w64"; else if (format == SF_FORMAT_RF64) formatName = "rf64"; else if (format == SF_FORMAT_AU) formatName = "au"; else if (format == SF_FORMAT_VOC) formatName = "voc"; else if (format == SF_FORMAT_SVX) formatName = "iff"; else if (format == SF_FORMAT_IRCAM) formatName = "sf"; else if (format == SF_FORMAT_PAF) formatName = "paf"; else if (format == SF_FORMAT_PVF) formatName = "pvf"; else if (format == SF_FORMAT_WVE) formatName = "wve"; else if (format == SF_FORMAT_HTK) formatName = "htk"; else if (format == SF_FORMAT_AVR) formatName = "avr"; if (config->GetIntValue(encoderID, "Set Output format", False)) formatName = config->GetStringValue(encoderID, "Output format", formatName).ToLower(); /* Set configuration values. */ if (formatName == "wav" ) format = SF_FORMAT_WAV; else if (formatName == "aiff") format = SF_FORMAT_AIFF; else if (formatName == "caf" ) format = SF_FORMAT_CAF; else if (formatName == "w64" ) format = SF_FORMAT_W64; else if (formatName == "rf64") format = SF_FORMAT_RF64; else if (formatName == "au" ) format = SF_FORMAT_AU; else if (formatName == "voc" ) format = SF_FORMAT_VOC; else if (formatName == "iff" ) format = SF_FORMAT_SVX; else if (formatName == "sf" ) format = SF_FORMAT_IRCAM; else if (formatName == "paf" ) format = SF_FORMAT_PAF; else if (formatName == "pvf" ) format = SF_FORMAT_PVF; else if (formatName == "wve" ) format = SF_FORMAT_WVE; else if (formatName == "htk" ) format = SF_FORMAT_HTK; else if (formatName == "avr" ) format = SF_FORMAT_AVR; config->SetIntValue(ConfigureSndFile::ConfigID, "Format", format); return True; } ConfigLayer *BoCA::EncoderSndFile::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureSndFile(); return configLayer; } sf_count_t BoCA::sf_vio_get_filelen_callback(void *user_data) { EncoderSndFile *filter = (EncoderSndFile *) user_data; return filter->driver->GetSize(); } sf_count_t BoCA::sf_vio_seek_callback(sf_count_t offset, int whence, void *user_data) { EncoderSndFile *filter = (EncoderSndFile *) user_data; if (whence == SEEK_CUR) filter->driver->Seek(filter->driver->GetPos() + offset); else if (whence == SEEK_SET) filter->driver->Seek( offset); else if (whence == SEEK_END) filter->driver->Seek(filter->driver->GetSize() + offset); return filter->driver->GetPos(); } sf_count_t BoCA::sf_vio_read_callback(void *ptr, sf_count_t count, void *user_data) { EncoderSndFile *filter = (EncoderSndFile *) user_data; return filter->driver->ReadData((UnsignedByte *) ptr, count); } sf_count_t BoCA::sf_vio_write_callback(const void * ptr, sf_count_t count, void *user_data) { EncoderSndFile *filter = (EncoderSndFile *) user_data; return filter->driver->WriteData((UnsignedByte *) ptr, count); } sf_count_t BoCA::sf_vio_tell_callback(void *user_data) { EncoderSndFile *filter = (EncoderSndFile *) user_data; return filter->driver->GetPos(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/sndfile/sndfile.h000066400000000000000000000032721516712004000252150ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderSndFile) namespace BoCA { class EncoderSndFile : public CS::EncoderComponent { friend sf_count_t sf_vio_get_filelen_callback(void *); friend sf_count_t sf_vio_seek_callback(sf_count_t, int, void *); friend sf_count_t sf_vio_read_callback(void *, sf_count_t, void *); friend sf_count_t sf_vio_write_callback(const void *, sf_count_t, void *); friend sf_count_t sf_vio_tell_callback(void *); private: ConfigLayer *configLayer; Config *config; AS::EncoderComponent *encoder; Int fileFormat; SNDFILE *sndf; static Int SelectBestSubFormat(const Format &, Int); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderSndFile(); ~EncoderSndFile(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderSndFile) BoCA_END_COMPONENT(EncoderSndFile) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/000077500000000000000000000000001516712004000231145ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/Makefile000077500000000000000000000012361516712004000245610ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = speex TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o speex.o worker.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/config.cpp000077500000000000000000000306761516712004000251040ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" const String BoCA::ConfigureSpeex::ConfigID = "Speex"; BoCA::ConfigureSpeex::ConfigureSpeex() { const Config *config = Config::Get(); quality = config->GetIntValue(ConfigID, "Quality", 8); bitrate = config->GetIntValue(ConfigID, "Bitrate", -16); if (quality > 0) cbrmode = 0; else cbrmode = 1; quality = Math::Abs(quality); bitrate = Math::Abs(bitrate); vbrmode = config->GetIntValue(ConfigID, "VBR", 0); vbrq = config->GetIntValue(ConfigID, "VBRQuality", 80); vbrmax = config->GetIntValue(ConfigID, "VBRMaxBitrate", -48); if (vbrmax > 0) use_vbrmax = True; else use_vbrmax = False; vbrmax = Math::Abs(vbrmax); abr = config->GetIntValue(ConfigID, "ABR", -16); if (abr > 0) vbrmode = 2; abr = Math::Abs(abr); complexity = config->GetIntValue(ConfigID, "Complexity", 3); use_vad = config->GetIntValue(ConfigID, "VAD", 0); use_dtx = config->GetIntValue(ConfigID, "DTX", 0); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::Speex"); Int kbpsLabelWidth = Font().GetUnscaledTextSizeX(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", "64")); group_profile = new GroupBox(i18n->TranslateString("Profile"), Point(7, 11), Size(406, 43)); text_profile = new Text(i18n->AddColon(i18n->TranslateString("Select encoding profile")), Point(10, 16)); combo_profile = new ComboBox(Point(18 + text_profile->GetUnscaledTextWidth(), 13), Size(378 - text_profile->GetUnscaledTextWidth(), 0)); combo_profile->AddEntry(i18n->TranslateString("auto")); combo_profile->AddEntry(i18n->TranslateString("Narrowband (8 kHz)")); combo_profile->AddEntry(i18n->TranslateString("Wideband (16 kHz)")); combo_profile->AddEntry(i18n->TranslateString("Ultra-Wideband (32 kHz)")); combo_profile->SelectNthEntry(config->GetIntValue(ConfigID, "Mode", -1) + 1); group_profile->Add(text_profile); group_profile->Add(combo_profile); group_vbr_mode = new GroupBox(i18n->TranslateString("VBR mode"), Point(7, 66), Size(128, 91)); option_cbr = new OptionBox(i18n->TranslateString("CBR (no VBR)"), Point(10, 14), Size(108, 0), &vbrmode, 0); option_cbr->onAction.Connect(&ConfigureSpeex::SetVBRMode, this); option_vbr = new OptionBox(i18n->TranslateString("VBR"), Point(10, 39), Size(108, 0), &vbrmode, 1); option_vbr->onAction.Connect(&ConfigureSpeex::SetVBRMode, this); option_abr = new OptionBox(i18n->TranslateString("ABR"), Point(10, 64), Size(108, 0), &vbrmode, 2); option_abr->onAction.Connect(&ConfigureSpeex::SetVBRMode, this); group_vbr_mode->Add(option_cbr); group_vbr_mode->Add(option_vbr); group_vbr_mode->Add(option_abr); group_cbr_quality = new GroupBox(i18n->TranslateString("CBR quality"), Point(143, 66), Size(270, 66)); option_cbr_quality = new OptionBox(i18n->AddColon(i18n->TranslateString("Quality")), Point(10, 14), Size(55, 0), &cbrmode, 0); option_cbr_quality->onAction.Connect(&ConfigureSpeex::SetCBRMode, this); option_cbr_bitrate = new OptionBox(i18n->AddColon(i18n->TranslateString("Bitrate")), Point(10, 39), Size(55, 0), &cbrmode, 1); option_cbr_bitrate->onAction.Connect(&ConfigureSpeex::SetCBRMode, this); Int maxTextSize = Math::Max(option_cbr_quality->GetUnscaledTextWidth(), option_cbr_bitrate->GetUnscaledTextWidth()); option_cbr_quality->SetWidth(maxTextSize + 21); option_cbr_bitrate->SetWidth(maxTextSize + 21); slider_cbr_quality = new Slider(Point(maxTextSize + 39, 14), Size(214 - maxTextSize - kbpsLabelWidth, 0), OR_HORZ, &quality, 0, 10); slider_cbr_quality->onValueChange.Connect(&ConfigureSpeex::SetQuality, this); text_cbr_quality_value = new Text(NIL, Point(kbpsLabelWidth + 10, 16)); text_cbr_quality_value->SetOrientation(OR_UPPERRIGHT); slider_cbr_bitrate = new Slider(Point(maxTextSize + 39, 39), Size(214 - maxTextSize - kbpsLabelWidth, 0), OR_HORZ, &bitrate, 4, 64); slider_cbr_bitrate->onValueChange.Connect(&ConfigureSpeex::SetBitrate, this); text_cbr_bitrate_value = new Text(NIL, Point(kbpsLabelWidth + 10, 41)); text_cbr_bitrate_value->SetOrientation(OR_UPPERRIGHT); group_cbr_quality->Add(option_cbr_quality); group_cbr_quality->Add(slider_cbr_quality); group_cbr_quality->Add(text_cbr_quality_value); group_cbr_quality->Add(option_cbr_bitrate); group_cbr_quality->Add(slider_cbr_bitrate); group_cbr_quality->Add(text_cbr_bitrate_value); group_vbr_quality = new GroupBox(i18n->TranslateString("VBR quality"), Point(143, 66), Size(270, 66)); text_vbr_quality = new Text(i18n->AddColon(i18n->TranslateString("Quality")), Point(10, 16)); check_vbr_bitrate = new CheckBox(i18n->AddColon(i18n->TranslateString("Max. bitrate")), Point(10, 39), Size(80, 0), &use_vbrmax); check_vbr_bitrate->onAction.Connect(&ConfigureSpeex::ToggleVBRBitrate, this); check_vbr_bitrate->SetWidth(check_vbr_bitrate->GetUnscaledTextWidth() + 21); maxTextSize = Math::Max(text_vbr_quality->GetUnscaledTextWidth() - 21, check_vbr_bitrate->GetUnscaledTextWidth()); slider_vbr_quality = new Slider(Point(maxTextSize + 39, 14), Size(214 - maxTextSize - kbpsLabelWidth, 0), OR_HORZ, &vbrq, 0, 100); slider_vbr_quality->onValueChange.Connect(&ConfigureSpeex::SetVBRQuality, this); text_vbr_quality_value = new Text(NIL, Point(kbpsLabelWidth + 10, 16)); text_vbr_quality_value->SetOrientation(OR_UPPERRIGHT); slider_vbr_bitrate = new Slider(Point(maxTextSize + 39, 39), Size(214 - maxTextSize - kbpsLabelWidth, 0), OR_HORZ, &vbrmax, 4, 64); slider_vbr_bitrate->onValueChange.Connect(&ConfigureSpeex::SetVBRBitrate, this); text_vbr_bitrate_value = new Text(NIL, Point(kbpsLabelWidth + 10, 41)); text_vbr_bitrate_value->SetOrientation(OR_UPPERRIGHT); group_vbr_quality->Add(text_vbr_quality); group_vbr_quality->Add(slider_vbr_quality); group_vbr_quality->Add(text_vbr_quality_value); group_vbr_quality->Add(check_vbr_bitrate); group_vbr_quality->Add(slider_vbr_bitrate); group_vbr_quality->Add(text_vbr_bitrate_value); group_abr_bitrate = new GroupBox(i18n->TranslateString("ABR target bitrate"), Point(143, 66), Size(270, 41)); text_abr_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Bitrate")), Point(10, 16)); slider_abr_bitrate = new Slider(Point(text_abr_bitrate->GetUnscaledTextWidth() + 18, 14), Size(235 - text_abr_bitrate->GetUnscaledTextWidth() - kbpsLabelWidth, 0), OR_HORZ, &abr, 4, 64); slider_abr_bitrate->onValueChange.Connect(&ConfigureSpeex::SetABRBitrate, this); text_abr_bitrate_value = new Text(NIL, Point(kbpsLabelWidth + 10, 16)); text_abr_bitrate_value->SetOrientation(OR_UPPERRIGHT); group_abr_bitrate->Add(text_abr_bitrate); group_abr_bitrate->Add(slider_abr_bitrate); group_abr_bitrate->Add(text_abr_bitrate_value); group_options = new GroupBox(i18n->TranslateString("Options"), Point(7, 169), Size(197, 66)); check_vad = new CheckBox(i18n->TranslateString("Voice Activity Detection"), Point(10, 14), Size(177, 0), &use_vad); check_vad->onAction.Connect(&ConfigureSpeex::SetVAD, this); check_dtx = new CheckBox(i18n->TranslateString("Discontinuous Transmission"), Point(10, 39), Size(177, 0), &use_dtx); group_options->Add(check_vad); group_options->Add(check_dtx); group_complexity = new GroupBox(i18n->TranslateString("Algorithm complexity"), Point(212, 169), Size(201, 42)); text_complexity = new Text(i18n->AddColon(i18n->TranslateString("Complexity")), Point(10, 16)); slider_complexity = new Slider(Point(text_complexity->GetUnscaledTextWidth() + 18, 14), Size(154 - text_complexity->GetUnscaledTextWidth(), 0), OR_HORZ, &complexity, 1, 10); slider_complexity->onValueChange.Connect(&ConfigureSpeex::SetComplexity, this); text_complexity_value = new Text(NIL, Point(179, 16)); group_complexity->Add(text_complexity); group_complexity->Add(slider_complexity); group_complexity->Add(text_complexity_value); SetVBRMode(); SetVBRQuality(); ToggleVBRBitrate(); SetVBRBitrate(); SetCBRMode(); SetQuality(); SetBitrate(); SetABRBitrate(); SetComplexity(); Add(group_profile); Add(group_vbr_mode); Add(group_cbr_quality); Add(group_vbr_quality); Add(group_abr_bitrate); Add(group_options); Add(group_complexity); SetSize(Size(420, 242)); } BoCA::ConfigureSpeex::~ConfigureSpeex() { DeleteObject(group_profile); DeleteObject(text_profile); DeleteObject(combo_profile); DeleteObject(group_vbr_mode); DeleteObject(option_cbr); DeleteObject(option_vbr); DeleteObject(option_abr); DeleteObject(group_cbr_quality); DeleteObject(option_cbr_quality); DeleteObject(slider_cbr_quality); DeleteObject(text_cbr_quality_value); DeleteObject(option_cbr_bitrate); DeleteObject(slider_cbr_bitrate); DeleteObject(text_cbr_bitrate_value); DeleteObject(group_vbr_quality); DeleteObject(text_vbr_quality); DeleteObject(slider_vbr_quality); DeleteObject(text_vbr_quality_value); DeleteObject(check_vbr_bitrate); DeleteObject(slider_vbr_bitrate); DeleteObject(text_vbr_bitrate_value); DeleteObject(group_abr_bitrate); DeleteObject(text_abr_bitrate); DeleteObject(slider_abr_bitrate); DeleteObject(text_abr_bitrate_value); DeleteObject(group_options); DeleteObject(check_vad); DeleteObject(check_dtx); DeleteObject(group_complexity); DeleteObject(text_complexity); DeleteObject(slider_complexity); DeleteObject(text_complexity_value); } Int BoCA::ConfigureSpeex::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Mode", combo_profile->GetSelectedEntryNumber() - 1); config->SetIntValue(ConfigID, "VBR", vbrmode == 1); config->SetIntValue(ConfigID, "VBRQuality", vbrq); config->SetIntValue(ConfigID, "VBRMaxBitrate", use_vbrmax ? vbrmax : -vbrmax); config->SetIntValue(ConfigID, "ABR", vbrmode == 2 ? abr : -abr); config->SetIntValue(ConfigID, "Quality", cbrmode == 0 ? quality : -quality); config->SetIntValue(ConfigID, "Bitrate", cbrmode == 1 ? bitrate : -bitrate); config->SetIntValue(ConfigID, "Complexity", complexity); config->SetIntValue(ConfigID, "VAD", use_vad); config->SetIntValue(ConfigID, "DTX", use_dtx); return Success(); } Void BoCA::ConfigureSpeex::SetVBRMode() { group_cbr_quality->Hide(); group_vbr_quality->Hide(); group_abr_bitrate->Hide(); switch (vbrmode) { case 0: group_cbr_quality->Show(); check_vad->Activate(); SetVAD(); break; case 1: group_vbr_quality->Show(); check_vad->Deactivate(); check_dtx->Activate(); break; case 2: group_abr_bitrate->Show(); check_vad->Deactivate(); check_dtx->Activate(); break; } } Void BoCA::ConfigureSpeex::SetVBRQuality() { String txt = String::FromFloat(double(vbrq) / 10); if (vbrq % 10 == 0) txt.Append(".0"); text_vbr_quality_value->SetText(txt); } Void BoCA::ConfigureSpeex::ToggleVBRBitrate() { if (use_vbrmax) { slider_vbr_bitrate->Activate(); text_vbr_bitrate_value->Activate(); } else { slider_vbr_bitrate->Deactivate(); text_vbr_bitrate_value->Deactivate(); } } Void BoCA::ConfigureSpeex::SetVBRBitrate() { I18n *i18n = I18n::Get(); text_vbr_bitrate_value->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(vbrmax))); } Void BoCA::ConfigureSpeex::SetCBRMode() { switch (cbrmode) { case 0: slider_cbr_quality->Activate(); text_cbr_quality_value->Activate(); slider_cbr_bitrate->Deactivate(); text_cbr_bitrate_value->Deactivate(); break; case 1: slider_cbr_bitrate->Activate(); text_cbr_bitrate_value->Activate(); slider_cbr_quality->Deactivate(); text_cbr_quality_value->Deactivate(); break; } } Void BoCA::ConfigureSpeex::SetQuality() { text_cbr_quality_value->SetText(String::FromInt(quality)); } Void BoCA::ConfigureSpeex::SetBitrate() { I18n *i18n = I18n::Get(); text_cbr_bitrate_value->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(bitrate))); } Void BoCA::ConfigureSpeex::SetABRBitrate() { I18n *i18n = I18n::Get(); text_abr_bitrate_value->SetText(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", String::FromInt(abr))); } Void BoCA::ConfigureSpeex::SetComplexity() { text_complexity_value->SetText(String::FromInt(complexity)); } Void BoCA::ConfigureSpeex::SetVAD() { if (use_vad) check_dtx->Activate(); else check_dtx->Deactivate(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/config.h000077500000000000000000000046241516712004000245430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_SPEEXCONFIG #define H_SPEEXCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureSpeex : public ConfigLayer { private: GroupBox *group_profile; Text *text_profile; ComboBox *combo_profile; GroupBox *group_vbr_mode; OptionBox *option_cbr; OptionBox *option_vbr; OptionBox *option_abr; GroupBox *group_cbr_quality; OptionBox *option_cbr_quality; Slider *slider_cbr_quality; Text *text_cbr_quality_value; OptionBox *option_cbr_bitrate; Slider *slider_cbr_bitrate; Text *text_cbr_bitrate_value; GroupBox *group_vbr_quality; Text *text_vbr_quality; Slider *slider_vbr_quality; Text *text_vbr_quality_value; CheckBox *check_vbr_bitrate; Slider *slider_vbr_bitrate; Text *text_vbr_bitrate_value; GroupBox *group_abr_bitrate; Text *text_abr_bitrate; Slider *slider_abr_bitrate; Text *text_abr_bitrate_value; GroupBox *group_options; CheckBox *check_vad; CheckBox *check_dtx; GroupBox *group_complexity; Text *text_complexity; Slider *slider_complexity; Text *text_complexity_value; Int cbrmode; Int quality; Int bitrate; Int complexity; Int vbrmode; Int vbrq; Int vbrmax; Bool use_vbrmax; Int abr; Bool use_vad; Bool use_dtx; slots: Void SetVBRMode(); Void SetVBRQuality(); Void ToggleVBRBitrate(); Void SetVBRBitrate(); Void SetCBRMode(); Void SetQuality(); Void SetBitrate(); Void SetABRBitrate(); Void SetComplexity(); Void SetVAD(); public: static const String ConfigID; ConfigureSpeex(); ~ConfigureSpeex(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/dllinterface.cpp000077500000000000000000000120771516712004000262660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETIN ex_ogg_stream_packetin = NIL; OGGSTREAMFLUSH ex_ogg_stream_flush = NIL; OGGSTREAMPAGEOUT ex_ogg_stream_pageout = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; SPEEXBITSINIT ex_speex_bits_init = NIL; SPEEXBITSDESTROY ex_speex_bits_destroy = NIL; SPEEXBITSRESET ex_speex_bits_reset = NIL; SPEEXBITSNBYTES ex_speex_bits_nbytes = NIL; SPEEXBITSINSERTTERMINATOR ex_speex_bits_insert_terminator = NIL; SPEEXBITSWRITE ex_speex_bits_write = NIL; SPEEXENCODERINIT ex_speex_encoder_init = NIL; SPEEXENCODERDESTROY ex_speex_encoder_destroy = NIL; SPEEXENCODERCTL ex_speex_encoder_ctl = NIL; SPEEXENCODEINT ex_speex_encode_int = NIL; SPEEXENCODESTEREOINT ex_speex_encode_stereo_int = NIL; SPEEXINITHEADER ex_speex_init_header = NIL; SPEEXHEADERTOPACKET ex_speex_header_to_packet = NIL; SPEEXHEADERFREE ex_speex_header_free = NIL; SPEEXLIBCTL ex_speex_lib_ctl = NIL; SPEEXLIBGETMODE ex_speex_lib_get_mode = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *speexdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetin = (OGGSTREAMPACKETIN) oggdll->GetFunctionAddress("ogg_stream_packetin"); ex_ogg_stream_flush = (OGGSTREAMFLUSH) oggdll->GetFunctionAddress("ogg_stream_flush"); ex_ogg_stream_pageout = (OGGSTREAMPAGEOUT) oggdll->GetFunctionAddress("ogg_stream_pageout"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetin == NIL || ex_ogg_stream_flush == NIL || ex_ogg_stream_pageout == NIL || ex_ogg_page_eos == NIL || ex_ogg_stream_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadSpeexDLL() { speexdll = BoCA::Utilities::LoadCodecDLL("speex"); if (speexdll == NIL) return False; ex_speex_bits_init = (SPEEXBITSINIT) speexdll->GetFunctionAddress("speex_bits_init"); ex_speex_bits_destroy = (SPEEXBITSDESTROY) speexdll->GetFunctionAddress("speex_bits_destroy"); ex_speex_bits_reset = (SPEEXBITSRESET) speexdll->GetFunctionAddress("speex_bits_reset"); ex_speex_bits_nbytes = (SPEEXBITSNBYTES) speexdll->GetFunctionAddress("speex_bits_nbytes"); ex_speex_bits_insert_terminator = (SPEEXBITSINSERTTERMINATOR) speexdll->GetFunctionAddress("speex_bits_insert_terminator"); ex_speex_bits_write = (SPEEXBITSWRITE) speexdll->GetFunctionAddress("speex_bits_write"); ex_speex_encoder_init = (SPEEXENCODERINIT) speexdll->GetFunctionAddress("speex_encoder_init"); ex_speex_encoder_destroy = (SPEEXENCODERDESTROY) speexdll->GetFunctionAddress("speex_encoder_destroy"); ex_speex_encoder_ctl = (SPEEXENCODERCTL) speexdll->GetFunctionAddress("speex_encoder_ctl"); ex_speex_encode_int = (SPEEXENCODEINT) speexdll->GetFunctionAddress("speex_encode_int"); ex_speex_encode_stereo_int = (SPEEXENCODESTEREOINT) speexdll->GetFunctionAddress("speex_encode_stereo_int"); ex_speex_init_header = (SPEEXINITHEADER) speexdll->GetFunctionAddress("speex_init_header"); ex_speex_header_to_packet = (SPEEXHEADERTOPACKET) speexdll->GetFunctionAddress("speex_header_to_packet"); ex_speex_header_free = (SPEEXHEADERFREE) speexdll->GetFunctionAddress("speex_header_free"); ex_speex_lib_ctl = (SPEEXLIBCTL) speexdll->GetFunctionAddress("speex_lib_ctl"); ex_speex_lib_get_mode = (SPEEXLIBGETMODE) speexdll->GetFunctionAddress("speex_lib_get_mode"); if (ex_speex_bits_init == NIL || ex_speex_bits_destroy == NIL || ex_speex_bits_reset == NIL || ex_speex_bits_nbytes == NIL || ex_speex_bits_insert_terminator == NIL || ex_speex_bits_write == NIL || ex_speex_encoder_init == NIL || ex_speex_encoder_destroy == NIL || ex_speex_encoder_ctl == NIL || ex_speex_encode_int == NIL || ex_speex_encode_stereo_int == NIL || ex_speex_init_header == NIL || ex_speex_header_to_packet == NIL || ex_speex_header_free == NIL || ex_speex_lib_ctl == NIL || ex_speex_lib_get_mode == NIL) { FreeSpeexDLL(); return False; } return True; } Void FreeSpeexDLL() { BoCA::Utilities::FreeCodecDLL(speexdll); speexdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/dllinterface.h000077500000000000000000000063371516712004000257350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *speexdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadSpeexDLL(); Void FreeSpeexDLL(); /* Ogg API functions. */ typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETIN) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMFLUSH) (ogg_stream_state *, ogg_page *); typedef int (*OGGSTREAMPAGEOUT) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETIN ex_ogg_stream_packetin; extern OGGSTREAMFLUSH ex_ogg_stream_flush; extern OGGSTREAMPAGEOUT ex_ogg_stream_pageout; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGSTREAMCLEAR ex_ogg_stream_clear; /* Speex API functions. */ typedef void (*SPEEXBITSINIT) (SpeexBits *); typedef void (*SPEEXBITSDESTROY) (SpeexBits *); typedef void (*SPEEXBITSRESET) (SpeexBits *); typedef int (*SPEEXBITSNBYTES) (SpeexBits *); typedef void (*SPEEXBITSINSERTTERMINATOR) (SpeexBits *); typedef int (*SPEEXBITSWRITE) (SpeexBits *, char *, int); typedef void * (*SPEEXENCODERINIT) (const SpeexMode *); typedef void (*SPEEXENCODERDESTROY) (void *); typedef int (*SPEEXENCODERCTL) (void *, int, void *); typedef int (*SPEEXENCODEINT) (void *, spx_int16_t *, SpeexBits *); typedef void (*SPEEXENCODESTEREOINT) (spx_int16_t *, int, SpeexBits *); typedef void (*SPEEXINITHEADER) (SpeexHeader *, int, int, const struct SpeexMode *); typedef char * (*SPEEXHEADERTOPACKET) (SpeexHeader *, int *); typedef void (*SPEEXHEADERFREE) (void *); typedef int (*SPEEXLIBCTL) (int, void *); typedef const SpeexMode * (*SPEEXLIBGETMODE) (int); extern SPEEXBITSINIT ex_speex_bits_init; extern SPEEXBITSDESTROY ex_speex_bits_destroy; extern SPEEXBITSRESET ex_speex_bits_reset; extern SPEEXBITSNBYTES ex_speex_bits_nbytes; extern SPEEXBITSINSERTTERMINATOR ex_speex_bits_insert_terminator; extern SPEEXBITSWRITE ex_speex_bits_write; extern SPEEXENCODERINIT ex_speex_encoder_init; extern SPEEXENCODERDESTROY ex_speex_encoder_destroy; extern SPEEXENCODERCTL ex_speex_encoder_ctl; extern SPEEXENCODEINT ex_speex_encode_int; extern SPEEXENCODESTEREOINT ex_speex_encode_stereo_int; extern SPEEXINITHEADER ex_speex_init_header; extern SPEEXHEADERTOPACKET ex_speex_header_to_packet; extern SPEEXHEADERFREE ex_speex_header_free; extern SPEEXLIBCTL ex_speex_lib_ctl; extern SPEEXLIBGETMODE ex_speex_lib_get_mode; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/speex.cpp000066400000000000000000000336551516712004000247600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "speex.h" #include "config.h" const String &BoCA::EncoderSpeex::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && speexdll != NIL) { componentSpecs = " \ \ \ \ Speex Speech Encoder %VERSION% \ 1.0 \ speex-enc \ encoder \ \ Speex Files \ spx \ Vorbis Comment \ \ \ \ \ 4 \ 64 \ \ \ 0 \ 10 \ \ \ 0 \ 10 \ \ \ \ 4 \ 64 \ \ \ \ \ "; const char *speexVersion = NIL; ex_speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &speexVersion); componentSpecs.Replace("%VERSION%", String("v").Append(speexVersion)); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadSpeexDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeSpeexDLL(); } BoCA::EncoderSpeex::EncoderSpeex() { configLayer = NIL; config = NIL; frameSize = 0; lookAhead = 0; blockSize = 256; overlap = 16; totalSamples = 0; nextWorker = 0; memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); } BoCA::EncoderSpeex::~EncoderSpeex() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderSpeex::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Init Ogg stream. */ Math::RandomSeed(); ex_ogg_stream_init(&os, Math::Random()); /* Get Speex mode ID. */ Int modeID = config->GetIntValue(ConfigureSpeex::ConfigID, "Mode", -1); if (modeID == -1) { /* Automatically select Speex mode * depending on sampling rate. */ if (format.rate <= 12500) modeID = SPEEX_MODEID_NB; else if (format.rate <= 25000) modeID = SPEEX_MODEID_WB; else modeID = SPEEX_MODEID_UWB; } /* Get frame size and look-ahead. */ void *encoder = ex_speex_encoder_init(ex_speex_lib_get_mode(modeID)); ex_speex_encoder_ctl(encoder, SPEEX_GET_FRAME_SIZE, &frameSize); ex_speex_encoder_ctl(encoder, SPEEX_GET_LOOKAHEAD, &lookAhead); ex_speex_encoder_destroy(encoder); totalSamples = 0; /* Create Speex header. */ SpeexHeader speex_header; ex_speex_init_header(&speex_header, format.rate, format.channels, ex_speex_lib_get_mode(modeID)); speex_header.frames_per_packet = 1; speex_header.vbr = config->GetIntValue(ConfigureSpeex::ConfigID, "VBR", 0); /* Write Speex header. */ int bytes; unsigned char *buffer = (unsigned char *) ex_speex_header_to_packet(&speex_header, &bytes); ogg_packet header = { buffer, bytes, 1, 0, 0, 0 }; ex_ogg_stream_packetin(&os, &header); ex_speex_header_free(buffer); /* Write Vorbis Comment header. */ { char *speexVersion = NIL; ex_speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &speexVersion); Buffer vcBuffer; /* Render actual Vorbis Comment tag. * * An empty tag containing only the vendor string * is rendered if Vorbis Comment tags are disabled. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->SetVendorString(String("Encoded with Speex ").Append(speexVersion)); if (config->GetIntValue("Tags", "EnableVorbisComment", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) tagger->RenderBuffer(vcBuffer, track); else tagger->RenderBuffer(vcBuffer, Track()); boca.DeleteComponent(tagger); } ogg_packet header_comm = { vcBuffer, vcBuffer.Size(), 0, 0, 0, 0 }; ex_ogg_stream_packetin(&os, &header_comm); } WriteOggPackets(True); /* Get number of threads to use. */ Bool enableParallel = config->GetIntValue("Resources", "EnableParallelConversions", True); Bool enableSuperFast = config->GetIntValue("Resources", "EnableSuperFastMode", True); Int numberOfThreads = enableParallel && enableSuperFast ? config->GetIntValue("Resources", "NumberOfConversionThreads", 0) : 1; if (enableParallel && enableSuperFast && numberOfThreads <= 1) numberOfThreads = CPU().GetNumCores() + (CPU().GetNumLogicalCPUs() - CPU().GetNumCores()) / 2; /* Disable overlap if we use only one thread. */ if (numberOfThreads == 1) overlap = 0; else overlap = 16; /* Start up worker threads. */ for (Int i = 0; i < numberOfThreads; i++) workers.Add(new SuperWorker(config, format)); foreach (SuperWorker *worker, workers) worker->Start(); return True; } Bool BoCA::EncoderSpeex::Deactivate() { /* Output remaining samples to encoder. */ EncodeFrames(True); /* Write any remaining Ogg packets. */ WriteOggPackets(True); ex_ogg_stream_clear(&os); /* Tear down worker threads. */ foreach (SuperWorker *worker, workers) worker->Quit(); foreach (SuperWorker *worker, workers) worker->Wait(); foreach (SuperWorker *worker, workers) delete worker; workers.RemoveAll(); /* Fix chapter marks in Vorbis Comments. */ if (config->GetIntValue("Tags", "EnableVorbisComment", True) && track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { driver->Close(); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->UpdateStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderSpeex::WriteData(Buffer &data) { /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ return EncodeFrames(False); } Int BoCA::EncoderSpeex::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pad end of stream with empty samples. */ Int nullSamples = 0; if (flush) { nullSamples = frameSize; if ((samplesBuffer.Size() / format.channels) % frameSize > 0) nullSamples += frameSize - (samplesBuffer.Size() / format.channels) % frameSize; samplesBuffer.Resize(samplesBuffer.Size() + nullSamples * format.channels); memset(((signed short *) samplesBuffer) + samplesBuffer.Size() - nullSamples * format.channels, 0, sizeof(short) * nullSamples * format.channels); } /* Pass samples to workers. */ Int framesToProcess = blockSize; Int framesProcessed = 0; Int dataLength = 0; Int samplesPerFrame = frameSize * format.channels; if (flush) framesToProcess = Math::Floor(samplesBuffer.Size() / samplesPerFrame); while (samplesBuffer.Size() - framesProcessed * samplesPerFrame >= samplesPerFrame * framesToProcess) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length(), False, 0); /* Pass new frames to worker. */ workerToUse->Encode(samplesBuffer, framesProcessed * samplesPerFrame, samplesPerFrame * framesToProcess); framesProcessed += framesToProcess - (flush ? 0 : overlap); nextWorker++; if (flush) break; } memmove((signed short *) samplesBuffer, ((signed short *) samplesBuffer) + framesProcessed * samplesPerFrame, sizeof(short) * (samplesBuffer.Size() - framesProcessed * samplesPerFrame)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * samplesPerFrame); if (!flush) return dataLength; /* Wait for workers to finish and process packets. */ for (Int i = 0; i < workers.Length(); i++) { SuperWorker *workerToUse = workers.GetNth(nextWorker % workers.Length()); workerToUse->WaitUntilReady(); /* See if the worker has some packets for us. */ if (workerToUse->GetPacketSizes().Length() != 0) dataLength += ProcessPackets(workerToUse->GetPackets(), workerToUse->GetPacketSizes(), nextWorker == workers.Length(), i == workers.Length() - 1, i == workers.Length() - 1 ? nullSamples : 0); nextWorker++; } return dataLength; } Int BoCA::EncoderSpeex::ProcessPackets(const Buffer &packets, const Array &packetSizes, Bool first, Bool flush, Int nullSamples) { Int offset = 0; if (!first) for (Int i = 0; i < overlap; i++) offset += packetSizes.GetNth(i); for (Int i = 0; i < packetSizes.Length(); i++) { if (i < overlap && !first) continue; if (packetSizes.GetNth(i) == 0) continue; totalSamples += frameSize; op.packet = packets + offset; op.bytes = packetSizes.GetNth(i); op.b_o_s = first && i == 0; op.e_o_s = flush && i == packetSizes.Length() - 1; op.granulepos = (flush && i == packetSizes.Length() - 1) ? totalSamples - nullSamples : ((flush && i == packetSizes.Length() - 2) ? totalSamples + frameSize - nullSamples - lookAhead : totalSamples - lookAhead); op.packetno = 0; ex_ogg_stream_packetin(&os, &op); offset += packetSizes.GetNth(i); } return WriteOggPackets(flush); } Int BoCA::EncoderSpeex::WriteOggPackets(Bool flush) { Int bytes = 0; do { int result = 0; if (flush) result = ex_ogg_stream_flush(&os, &og); else result = ex_ogg_stream_pageout(&os, &og); if (result == 0) break; bytes += driver->WriteData(og.header, og.header_len); bytes += driver->WriteData(og.body, og.body_len); } while (true); return bytes; } Bool BoCA::EncoderSpeex::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "speex-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureSpeex::ConfigID, "Mode", -1); config->SetIntValue(ConfigureSpeex::ConfigID, "VAD", False); config->SetIntValue(ConfigureSpeex::ConfigID, "DTX", False); config->SetIntValue(ConfigureSpeex::ConfigID, "VBR", False); config->SetIntValue(ConfigureSpeex::ConfigID, "Bitrate", -16); config->SetIntValue(ConfigureSpeex::ConfigID, "Quality", 8); config->SetIntValue(ConfigureSpeex::ConfigID, "VBRQuality", 80); config->SetIntValue(ConfigureSpeex::ConfigID, "VBRMaxBitrate", -48); config->SetIntValue(ConfigureSpeex::ConfigID, "Complexity", 3); config->SetIntValue(ConfigureSpeex::ConfigID, "ABR", -16); } /* Get command line settings. */ Bool useVBR = config->GetIntValue(encoderID, "Use VBR encoding", config->GetIntValue(ConfigureSpeex::ConfigID, "VBR", False)); Int bitrate = config->GetIntValue(ConfigureSpeex::ConfigID, "Bitrate", -16); Int quality = config->GetIntValue(ConfigureSpeex::ConfigID, "Quality", 8); Int complexity = config->GetIntValue(ConfigureSpeex::ConfigID, "Complexity", 3); Int abrrate = config->GetIntValue(ConfigureSpeex::ConfigID, "ABR", -16); if (config->GetIntValue(encoderID, "Set Bitrate", False)) bitrate = config->GetIntValue(encoderID, "Bitrate", bitrate); if (config->GetIntValue(encoderID, "Set Quality", False)) quality = config->GetIntValue(encoderID, "Quality", quality); if (config->GetIntValue(encoderID, "Set Encoding complexity", False)) complexity = config->GetIntValue(encoderID, "Encoding complexity", complexity); if (config->GetIntValue(encoderID, "Set Use ABR encoding", False)) abrrate = config->GetIntValue(encoderID, "Use ABR encoding", abrrate); /* Set configuration values. */ config->SetIntValue(ConfigureSpeex::ConfigID, "VBR", useVBR); config->SetIntValue(ConfigureSpeex::ConfigID, "Bitrate", bitrate >= 0 ? Math::Max(4, Math::Min(64, bitrate)) : bitrate); config->SetIntValue(ConfigureSpeex::ConfigID, "Quality", Math::Max(0, Math::Min(10, quality))); config->SetIntValue(ConfigureSpeex::ConfigID, "VBRQuality", Math::Max(0, Math::Min(10, quality)) * 10); config->SetIntValue(ConfigureSpeex::ConfigID, "Complexity", Math::Max(0, Math::Min(10, complexity))); config->SetIntValue(ConfigureSpeex::ConfigID, "ABR", abrrate >= 0 ? Math::Max(4, Math::Min(64, abrrate)) : abrrate); return True; } ConfigLayer *BoCA::EncoderSpeex::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureSpeex(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/speex.h000066400000000000000000000031401516712004000244070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderSpeex) namespace BoCA { class EncoderSpeex : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; Array workers; ogg_stream_state os; ogg_page og; ogg_packet op; Int nextWorker; spx_int32_t frameSize; spx_int32_t lookAhead; Int blockSize; Int overlap; Int64 totalSamples; Buffer samplesBuffer; Int EncodeFrames(Bool); Int ProcessPackets(const Buffer &, const Array &, Bool, Bool, Int); Int WriteOggPackets(Bool); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderSpeex(); ~EncoderSpeex(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderSpeex) BoCA_END_COMPONENT(EncoderSpeex) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/worker.cpp000066400000000000000000000111151516712004000251300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "worker.h" #include "config.h" BoCA::SuperWorker::SuperWorker(const Config *config, const Format &iFormat) : processSignal(1), readySignal(1) { processSignal.Wait(); quit = False; format = iFormat; threadMain.Connect(&SuperWorker::Run, this); /* Get Speex mode ID. */ Int modeID = config->GetIntValue(ConfigureSpeex::ConfigID, "Mode", -1); if (modeID == -1) { /* Automatically select Speex mode * depending on sampling rate. */ if (format.rate <= 12500) modeID = SPEEX_MODEID_NB; else if (format.rate <= 25000) modeID = SPEEX_MODEID_WB; else modeID = SPEEX_MODEID_UWB; } /* Create Speex encoder. */ encoder = ex_speex_encoder_init(ex_speex_lib_get_mode(modeID)); /* Set encoder options. */ spx_int32_t vbr = config->GetIntValue(ConfigureSpeex::ConfigID, "VBR", 0); spx_int32_t abr = config->GetIntValue(ConfigureSpeex::ConfigID, "ABR", -16) * 1000; spx_int32_t complexity = config->GetIntValue(ConfigureSpeex::ConfigID, "Complexity", 3); ex_speex_encoder_ctl(encoder, SPEEX_SET_VBR, &vbr); ex_speex_encoder_ctl(encoder, SPEEX_SET_COMPLEXITY, &complexity); if (abr > 0) ex_speex_encoder_ctl(encoder, SPEEX_SET_ABR, &abr); if (vbr) { float vbrq = config->GetIntValue(ConfigureSpeex::ConfigID, "VBRQuality", 80) / 10.0; spx_int32_t vbrmax = config->GetIntValue(ConfigureSpeex::ConfigID, "VBRMaxBitrate", -48) * 1000; ex_speex_encoder_ctl(encoder, SPEEX_SET_VBR_QUALITY, &vbrq); if (vbrmax > 0) ex_speex_encoder_ctl(encoder, SPEEX_SET_VBR_MAX_BITRATE, &vbrmax); } else { spx_int32_t quality = config->GetIntValue(ConfigureSpeex::ConfigID, "Quality", 8); spx_int32_t bitrate = config->GetIntValue(ConfigureSpeex::ConfigID, "Bitrate", -16) * 1000; spx_int32_t vad = config->GetIntValue(ConfigureSpeex::ConfigID, "VAD", 0); if (quality > 0) ex_speex_encoder_ctl(encoder, SPEEX_SET_QUALITY, &quality); if (bitrate > 0) ex_speex_encoder_ctl(encoder, SPEEX_SET_BITRATE, &bitrate); ex_speex_encoder_ctl(encoder, SPEEX_SET_VAD, &vad); } if (vbr || abr > 0 || config->GetIntValue(ConfigureSpeex::ConfigID, "VAD", 0)) { spx_int32_t dtx = config->GetIntValue(ConfigureSpeex::ConfigID, "DTX", 0); ex_speex_encoder_ctl(encoder, SPEEX_SET_DTX, &dtx); } /* Get frame size and look-ahead. */ spx_int32_t rate = format.rate; ex_speex_encoder_ctl(encoder, SPEEX_SET_SAMPLING_RATE, &rate); ex_speex_encoder_ctl(encoder, SPEEX_GET_FRAME_SIZE, &frameSize); ex_speex_bits_init(&bits); } BoCA::SuperWorker::~SuperWorker() { /* Destroy Speex encoder. */ ex_speex_bits_destroy(&bits); ex_speex_encoder_destroy(encoder); } Int BoCA::SuperWorker::Run() { while (!Threads::Access::Value(quit)) { processSignal.Wait(); if (Threads::Access::Value(quit)) break; packetBuffer.Resize(0); packetSizes.RemoveAll(); Int samplesLeft = samplesBuffer.Size(); Int samplesPerFrame = frameSize * format.channels; Int framesProcessed = 0; while (samplesLeft >= samplesPerFrame) { if (format.channels == 2) ex_speex_encode_stereo_int(samplesBuffer + framesProcessed * samplesPerFrame, frameSize, &bits); ex_speex_encode_int(encoder, samplesBuffer + framesProcessed * samplesPerFrame, &bits); ex_speex_bits_insert_terminator(&bits); Int dataLength = ex_speex_bits_nbytes(&bits); packetBuffer.Resize(packetBuffer.Size() + dataLength); dataLength = ex_speex_bits_write(&bits, (char *) (unsigned char *) packetBuffer + packetBuffer.Size() - dataLength, dataLength); ex_speex_bits_reset(&bits); packetSizes.Add(dataLength); framesProcessed++; samplesLeft -= samplesPerFrame; } readySignal.Release(); } return Success(); } Void BoCA::SuperWorker::Encode(const Buffer &buffer, Int offset, Int size) { samplesBuffer.Resize(size); memcpy(samplesBuffer, buffer + offset, size * sizeof(spx_int16_t)); processSignal.Release(); } Void BoCA::SuperWorker::WaitUntilReady() { readySignal.Wait(); } Int BoCA::SuperWorker::Quit() { Threads::Access::Set(quit, True); processSignal.Release(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/speex/worker.h000066400000000000000000000025401516712004000245770ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" namespace BoCA { class SuperWorker : public Threads::Thread { private: Threads::Semaphore processSignal; Threads::Semaphore readySignal; void *encoder; SpeexBits bits; Format format; spx_int32_t frameSize; Buffer samplesBuffer; Buffer packetBuffer; Array packetSizes; Bool quit; Int Run(); public: SuperWorker(const Config *, const Format &); ~SuperWorker(); Void Encode(const Buffer &, Int, Int); Void WaitUntilReady(); Int Quit(); const Buffer &GetPackets() const { return packetBuffer; }; const Array &GetPacketSizes() const { return packetSizes; }; }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/000077500000000000000000000000001516712004000235475ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/Makefile000066400000000000000000000012331516712004000252060ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = voaacenc TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o voaacenc.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/config.cpp000066400000000000000000000145331516712004000255260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureVOAAC::ConfigID = "VOAACEnc"; BoCA::ConfigureVOAAC::ConfigureVOAAC() { const Config *config = Config::Get(); bitrate = config->GetIntValue(ConfigID, "Bitrate", 96); allowID3 = config->GetIntValue(ConfigID, "AllowID3v2", False); fileFormat = config->GetIntValue(ConfigID, "MP4Container", True); fileExtension = config->GetIntValue(ConfigID, "MP4FileExtension", 0); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::AAC::Format"); group_id3v2 = new GroupBox(i18n->TranslateString("Tags"), Point(7, 143), Size(281, 90)); check_id3v2 = new CheckBox(i18n->TranslateString("Allow ID3v2 tags in AAC files"), Point(10, 13), Size(200, 0), &allowID3); check_id3v2->SetWidth(check_id3v2->GetUnscaledTextWidth() + 20); text_note = new Text(i18n->AddColon(i18n->TranslateString("Note")), Point(10, 38)); text_id3v2 = new Text(i18n->TranslateString("Some players may have problems playing AAC\nfiles with ID3 tags attached. Please use this option only\nif you are sure that your player can handle these tags."), Point(text_note->GetUnscaledTextWidth() + 12, 38)); group_id3v2->SetSize(Size(Math::Max(240, text_note->GetUnscaledTextWidth() + text_id3v2->GetUnscaledTextWidth() + 22), Math::Max(text_note->GetUnscaledTextHeight(), text_id3v2->GetUnscaledTextHeight()) + 48)); group_id3v2->Add(check_id3v2); group_id3v2->Add(text_note); group_id3v2->Add(text_id3v2); i18n->SetContext("Encoders::AAC::Quality"); group_bitrate = new GroupBox(i18n->TranslateString("Bitrate"), Point(7, 11), Size(group_id3v2->GetWidth(), 43)); text_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Bitrate per channel")), Point(10, 15)); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 15)); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); edit_bitrate = new EditBox(Point(text_bitrate_kbps->GetX() + 32, 12), Size(25, 0), 3); edit_bitrate->SetFlags(EDB_NUMERIC); edit_bitrate->SetOrientation(OR_UPPERRIGHT); edit_bitrate->onInput.Connect(&ConfigureVOAAC::SetBitrateByEditBox, this); slider_bitrate = new Slider(Point(text_bitrate->GetUnscaledTextSize().cx + 17, 13), Size(group_bitrate->GetWidth() - edit_bitrate->GetX() - 25 - text_bitrate->GetUnscaledTextSize().cx, 0), OR_HORZ, &bitrate, 8, 128); slider_bitrate->onValueChange.Connect(&ConfigureVOAAC::SetBitrate, this); group_bitrate->Add(text_bitrate); group_bitrate->Add(slider_bitrate); group_bitrate->Add(edit_bitrate); group_bitrate->Add(text_bitrate_kbps); i18n->SetContext("Encoders::AAC::Format"); group_mp4 = new GroupBox(i18n->TranslateString("File format"), Point(7, 66), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_mp4 = new OptionBox("MP4", Point(10, 13), Size(group_mp4->GetWidth() - 21, 0), &fileFormat, 1); option_mp4->onAction.Connect(&ConfigureVOAAC::SetFileFormat, this); if (mp4v2dll == NIL) { option_mp4->Deactivate(); fileFormat = 0; } option_aac = new OptionBox("AAC", Point(10, 38), Size(group_mp4->GetWidth() - 21, 0), &fileFormat, 0); option_aac->onAction.Connect(&ConfigureVOAAC::SetFileFormat, this); group_mp4->Add(option_mp4); group_mp4->Add(option_aac); group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(group_mp4->GetWidth() + 15 + (group_id3v2->GetWidth() % 2), 66), Size(group_id3v2->GetWidth() / 2 - 4, 65)); option_extension_m4a = new OptionBox(".m4a", Point(10, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 0); option_extension_m4b = new OptionBox(".m4b", Point(10, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 1); option_extension_m4r = new OptionBox(".m4r", Point(group_extension->GetWidth() / 2 + 4, 13), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 2); option_extension_mp4 = new OptionBox(".mp4", Point(group_extension->GetWidth() / 2 + 4, 38), Size(group_extension->GetWidth() / 2 - 14, 0), &fileExtension, 3); group_extension->Add(option_extension_m4a); group_extension->Add(option_extension_m4b); group_extension->Add(option_extension_m4r); group_extension->Add(option_extension_mp4); SetBitrate(); SetFileFormat(); Add(group_bitrate); Add(group_mp4); Add(group_extension); Add(group_id3v2); SetSize(group_id3v2->GetSize() + Size(14, 150)); } BoCA::ConfigureVOAAC::~ConfigureVOAAC() { DeleteObject(group_bitrate); DeleteObject(text_bitrate); DeleteObject(slider_bitrate); DeleteObject(edit_bitrate); DeleteObject(text_bitrate_kbps); DeleteObject(group_mp4); DeleteObject(option_mp4); DeleteObject(option_aac); DeleteObject(group_extension); DeleteObject(option_extension_m4a); DeleteObject(option_extension_m4b); DeleteObject(option_extension_m4r); DeleteObject(option_extension_mp4); DeleteObject(group_id3v2); DeleteObject(check_id3v2); DeleteObject(text_note); DeleteObject(text_id3v2); } Int BoCA::ConfigureVOAAC::SaveSettings() { Config *config = Config::Get(); if (bitrate < 8) bitrate = 8; if (bitrate > 128) bitrate = 128; config->SetIntValue(ConfigID, "Bitrate", bitrate); config->SetIntValue(ConfigID, "AllowID3v2", allowID3); config->SetIntValue(ConfigID, "MP4Container", fileFormat); config->SetIntValue(ConfigID, "MP4FileExtension", fileExtension); return Success(); } Void BoCA::ConfigureVOAAC::SetBitrate() { if (!edit_bitrate->IsFocussed()) edit_bitrate->SetText(String::FromInt(bitrate)); } Void BoCA::ConfigureVOAAC::SetBitrateByEditBox() { slider_bitrate->SetValue(edit_bitrate->GetText().ToInt()); } Void BoCA::ConfigureVOAAC::SetFileFormat() { if (fileFormat == 1) // MP4 container { group_id3v2->Deactivate(); group_extension->Activate(); } else // raw AAC file format { group_id3v2->Activate(); group_extension->Deactivate(); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/config.h000066400000000000000000000031461516712004000251710ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_VOAACCONFIG #define H_VOAACCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureVOAAC : public ConfigLayer { private: GroupBox *group_bitrate; Text *text_bitrate; Slider *slider_bitrate; EditBox *edit_bitrate; Text *text_bitrate_kbps; GroupBox *group_id3v2; CheckBox *check_id3v2; Text *text_note; Text *text_id3v2; GroupBox *group_mp4; OptionBox *option_mp4; OptionBox *option_aac; GroupBox *group_extension; OptionBox *option_extension_m4a; OptionBox *option_extension_m4b; OptionBox *option_extension_m4r; OptionBox *option_extension_mp4; Int bitrate; Bool allowID3; Int fileFormat; Int fileExtension; slots: Void SetBitrate(); Void SetBitrateByEditBox(); Void SetFileFormat(); public: static const String ConfigID; ConfigureVOAAC(); ~ConfigureVOAAC(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/dllinterface.cpp000066400000000000000000000105441516712004000267130ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; VOGETAACENCAPI ex_voGetAACEncAPI = NIL; CMNMEMALLOC ex_cmnMemAlloc = NIL; CMNMEMFREE ex_cmnMemFree = NIL; CMNMEMSET ex_cmnMemSet = NIL; CMNMEMCOPY ex_cmnMemCopy = NIL; CMNMEMCHECK ex_cmnMemCheck = NIL; CMNMEMCOMPARE ex_cmnMemCompare = NIL; CMNMEMMOVE ex_cmnMemMove = NIL; MP4CREATECALLBACKS ex_MP4CreateCallbacks = NIL; MP4CLOSE ex_MP4Close = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration = NIL; MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty = NIL; MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel = NIL; MP4ADDAUDIOTRACK ex_MP4AddAudioTrack = NIL; MP4WRITESAMPLE ex_MP4WriteSample = NIL; MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc = NIL; MP4ITMFITEMFREE ex_MP4ItmfItemFree = NIL; MP4ITMFADDITEM ex_MP4ItmfAddItem = NIL; DynamicLoader *voaacencdll = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadVOAACEncDLL() { voaacencdll = BoCA::Utilities::LoadCodecDLL("vo-aacenc"); if (voaacencdll == NIL) return False; ex_voGetAACEncAPI = (VOGETAACENCAPI) voaacencdll->GetFunctionAddress("voGetAACEncAPI"); ex_cmnMemAlloc = (CMNMEMALLOC) voaacencdll->GetFunctionAddress("cmnMemAlloc"); ex_cmnMemFree = (CMNMEMFREE) voaacencdll->GetFunctionAddress("cmnMemFree"); ex_cmnMemSet = (CMNMEMSET) voaacencdll->GetFunctionAddress("cmnMemSet"); ex_cmnMemCopy = (CMNMEMCOPY) voaacencdll->GetFunctionAddress("cmnMemCopy"); ex_cmnMemCheck = (CMNMEMCHECK) voaacencdll->GetFunctionAddress("cmnMemCheck"); ex_cmnMemCompare = (CMNMEMCOMPARE) voaacencdll->GetFunctionAddress("cmnMemCompare"); ex_cmnMemMove = (CMNMEMMOVE) voaacencdll->GetFunctionAddress("cmnMemMove"); if (ex_voGetAACEncAPI == NIL || ex_cmnMemAlloc == NIL || ex_cmnMemFree == NIL || ex_cmnMemSet == NIL || ex_cmnMemCopy == NIL || ex_cmnMemCheck == NIL || ex_cmnMemCompare == NIL || ex_cmnMemMove == NIL) { FreeVOAACEncDLL(); return False; } return True; } Void FreeVOAACEncDLL() { BoCA::Utilities::FreeCodecDLL(voaacencdll); voaacencdll = NIL; } Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4CreateCallbacks = (MP4CREATECALLBACKS) mp4v2dll->GetFunctionAddress("MP4CreateCallbacks"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4SetTrackESConfiguration = (MP4SETTRACKESCONFIGURATION) mp4v2dll->GetFunctionAddress("MP4SetTrackESConfiguration"); ex_MP4SetTrackIntegerProperty = (MP4SETTRACKINTEGERPROPERTY) mp4v2dll->GetFunctionAddress("MP4SetTrackIntegerProperty"); ex_MP4SetAudioProfileLevel = (MP4SETAUDIOPROFILELEVEL) mp4v2dll->GetFunctionAddress("MP4SetAudioProfileLevel"); ex_MP4AddAudioTrack = (MP4ADDAUDIOTRACK) mp4v2dll->GetFunctionAddress("MP4AddAudioTrack"); ex_MP4WriteSample = (MP4WRITESAMPLE) mp4v2dll->GetFunctionAddress("MP4WriteSample"); ex_MP4ItmfItemAlloc = (MP4ITMFITEMALLOC) mp4v2dll->GetFunctionAddress("MP4ItmfItemAlloc"); ex_MP4ItmfItemFree = (MP4ITMFITEMFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemFree"); ex_MP4ItmfAddItem = (MP4ITMFADDITEM) mp4v2dll->GetFunctionAddress("MP4ItmfAddItem"); if (ex_MP4CreateCallbacks == NIL || ex_MP4Close == NIL || ex_MP4Optimize == NIL || ex_MP4SetTrackESConfiguration == NIL || ex_MP4SetTrackIntegerProperty == NIL || ex_MP4SetAudioProfileLevel == NIL || ex_MP4AddAudioTrack == NIL || ex_MP4WriteSample == NIL || ex_MP4ItmfItemAlloc == NIL || ex_MP4ItmfItemFree == NIL || ex_MP4ItmfAddItem == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/dllinterface.h000066400000000000000000000061651516712004000263640ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *voaacencdll; extern DynamicLoader *mp4v2dll; Bool LoadVOAACEncDLL(); Void FreeVOAACEncDLL(); Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef VO_S32 (VO_API *VOGETAACENCAPI) (VO_AUDIO_CODECAPI *); typedef VO_U32 (*CMNMEMALLOC) (VO_S32, VO_MEM_INFO *); typedef VO_U32 (*CMNMEMFREE) (VO_S32, VO_PTR); typedef VO_U32 (*CMNMEMSET) (VO_S32, VO_PTR, VO_U8, VO_U32); typedef VO_U32 (*CMNMEMCOPY) (VO_S32, VO_PTR, VO_PTR, VO_U32); typedef VO_U32 (*CMNMEMCHECK) (VO_S32, VO_PTR, VO_U32); typedef VO_S32 (*CMNMEMCOMPARE) (VO_S32, VO_PTR, VO_PTR, VO_U32); typedef VO_U32 (*CMNMEMMOVE) (VO_S32, VO_PTR, VO_PTR, VO_U32); extern VOGETAACENCAPI ex_voGetAACEncAPI; extern CMNMEMALLOC ex_cmnMemAlloc; extern CMNMEMFREE ex_cmnMemFree; extern CMNMEMSET ex_cmnMemSet; extern CMNMEMCOPY ex_cmnMemCopy; extern CMNMEMCHECK ex_cmnMemCheck; extern CMNMEMCOMPARE ex_cmnMemCompare; extern CMNMEMMOVE ex_cmnMemMove; typedef MP4FileHandle (*MP4CREATECALLBACKS) (const MP4IOCallbacks *, void *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef bool (*MP4SETTRACKESCONFIGURATION) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t); typedef bool (*MP4SETTRACKINTEGERPROPERTY) (MP4FileHandle, MP4TrackId, const char *, int64_t); typedef void (*MP4SETAUDIOPROFILELEVEL) (MP4FileHandle, uint8_t); typedef MP4TrackId (*MP4ADDAUDIOTRACK) (MP4FileHandle, uint32_t, MP4Duration, uint8_t); typedef bool (*MP4WRITESAMPLE) (MP4FileHandle, MP4TrackId, const uint8_t *, uint32_t, MP4Duration, MP4Duration, bool); typedef MP4ItmfItem * (*MP4ITMFITEMALLOC) (const char *, uint32_t); typedef void (*MP4ITMFITEMFREE) (MP4ItmfItem *); typedef bool (*MP4ITMFADDITEM) (MP4FileHandle, const MP4ItmfItem *); extern MP4CREATECALLBACKS ex_MP4CreateCallbacks; extern MP4CLOSE ex_MP4Close; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4SETTRACKESCONFIGURATION ex_MP4SetTrackESConfiguration; extern MP4SETTRACKINTEGERPROPERTY ex_MP4SetTrackIntegerProperty; extern MP4SETAUDIOPROFILELEVEL ex_MP4SetAudioProfileLevel; extern MP4ADDAUDIOTRACK ex_MP4AddAudioTrack; extern MP4WRITESAMPLE ex_MP4WriteSample; extern MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc; extern MP4ITMFITEMFREE ex_MP4ItmfItemFree; extern MP4ITMFADDITEM ex_MP4ItmfAddItem; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/voaacenc.cpp000066400000000000000000000351401516712004000260350ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "voaacenc.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderVOAAC::GetComponentSpecs() { static String componentSpecs; if (voaacencdll != NIL) { componentSpecs = " \ \ \ \ VisualOn AAC Encoder \ 1.0 \ voaacenc-enc \ encoder \ \ "; if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ MPEG-4 AAC Files \ m4a \ m4b \ m4r \ mp4 \ MP4 Metadata \ \ \ "); } componentSpecs.Append(" \ \ \ Raw AAC Files \ aac \ ID3v2 \ \ \ \ \ 8 \ 128 \ \ \ "); if (mp4v2dll != NIL) { componentSpecs.Append(" \ \ \ \ "); } componentSpecs.Append(" \ \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadVOAACEncDLL(); LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeVOAACEncDLL(); FreeMP4v2DLL(); } namespace BoCA { int64_t MP4IO_size(void *); int MP4IO_seek(void *, int64_t); int MP4IO_write(void *, const void *, int64_t, int64_t *); static MP4IOCallbacks mp4Callbacks = { MP4IO_size, MP4IO_seek, NIL, MP4IO_write, NIL }; }; BoCA::EncoderVOAAC::EncoderVOAAC() { configLayer = NIL; config = NIL; mp4File = NIL; mp4Track = MP4_INVALID_TRACK_ID; handle = NIL; frameSize = 0; totalSamples = 0; delaySamples = 0; memset(&memOperator, 0, sizeof(memOperator)); memset(&userData, 0, sizeof(userData)); ex_voGetAACEncAPI(&api); } BoCA::EncoderVOAAC::~EncoderVOAAC() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderVOAAC::Activate() { const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); if (mp4v2dll == NIL) config->SetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", False); Bool mp4Container = config->GetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", True); Int bitrate = config->GetIntValue(ConfigureVOAAC::ConfigID, "Bitrate", 96); if (mp4v2dll == NIL) mp4Container = False; /* Create VO AAC encoder. */ unsigned long samplesSize = 1024 * format.channels; unsigned long bufferSize = samplesSize * 4; outBuffer.Resize(bufferSize); memOperator.Alloc = ex_cmnMemAlloc; memOperator.Copy = ex_cmnMemCopy; memOperator.Free = ex_cmnMemFree; memOperator.Set = ex_cmnMemSet; memOperator.Check = ex_cmnMemCheck; userData.memflag = VO_IMF_USERMEMOPERATOR; userData.memData = &memOperator; api.Init(&handle, VO_AUDIO_CodingAAC, &userData); /* Set encoder parameters. */ AACENC_PARAM params; params.sampleRate = format.rate; params.nChannels = format.channels; params.bitRate = bitrate * 1000 * format.channels; params.adtsUsed = !mp4Container; api.SetParam(handle, VO_PID_AAC_ENCPARAM, ¶ms); frameSize = samplesSize / format.channels; delaySamples = frameSize + 576; /* Check whether to use MP4 container. */ if (mp4Container) { /* Create MP4 file. */ uint32_t flags = (track.length >= 0xFFFF0000 || track.approxLength >= 0xFFFF0000) ? MP4_CREATE_64BIT_DATA | MP4_CREATE_64BIT_TIME : 0; mp4File = ex_MP4CreateCallbacks(&mp4Callbacks, driver, flags); mp4Track = ex_MP4AddAudioTrack(mp4File, format.rate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); ex_MP4SetAudioProfileLevel(mp4File, 0x0F); ex_MP4SetTrackIntegerProperty(mp4File, mp4Track, "mdia.minf.stbl.stsd.mp4a.channels", format.channels); int sampleRateIndex = GetSampleRateIndex(format.rate); uint8_t esConfig[2] = { uint8_t( 2 << 3 | sampleRateIndex >> 1), uint8_t((sampleRateIndex & 1) << 7 | format.channels << 3) }; ex_MP4SetTrackESConfiguration(mp4File, mp4Track, esConfig, 2); totalSamples = 0; } /* Write ID3v2 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureVOAAC::ConfigID, "AllowID3v2", False)) { if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Bool BoCA::EncoderVOAAC::Deactivate() { /* Output remaining samples to encoder. */ EncodeFrames(True); api.Uninit(handle); /* Finish MP4 writing. */ if (mp4File != NIL) { /* Write iTunes metadata with gapless information. */ MP4ItmfItem *item = ex_MP4ItmfItemAlloc("----", 1); String value = String().Append(" 00000000") .Append(" ").Append(Number((Int64) delaySamples).ToHexString(8).ToUpper()) .Append(" ").Append(Number((Int64) frameSize - (delaySamples + totalSamples) % frameSize).ToHexString(8).ToUpper()) .Append(" ").Append(Number((Int64) totalSamples).ToHexString(16).ToUpper()) .Append(" 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000"); item->mean = (char *) "com.apple.iTunes"; item->name = (char *) "iTunSMPB"; item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8; item->dataList.elements[0].value = (uint8_t *) value.ConvertTo("UTF-8"); item->dataList.elements[0].valueSize = value.Length(); ex_MP4ItmfAddItem(mp4File, item); item->mean = NIL; item->name = NIL; item->dataList.elements[0].typeCode = MP4_ITMF_BT_IMPLICIT; item->dataList.elements[0].value = NIL; item->dataList.elements[0].valueSize = 0; ex_MP4ItmfItemFree(item); ex_MP4Close(mp4File, 0); /* Close output file as tagger needs to modify it. */ driver->Close(); /* Write metadata to file. */ const Info &info = track.GetInfo(); if (config->GetIntValue("Tags", "EnableMP4Metadata", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("mp4-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } else { /* Optimize file even when no tags are written. */ String tempFile = String(track.outputFile).Append(".temp"); ex_MP4Optimize(track.outputFile.ConvertTo("UTF-8"), tempFile.ConvertTo("UTF-8")); File(track.outputFile).Delete(); File(tempFile).Move(track.outputFile); } } /* Write ID3v1 tag if requested. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v1", False)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v1-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } /* Update ID3v2 tag with correct chapter marks. */ if (mp4File == NIL && config->GetIntValue("Tags", "EnableID3v2", True) && config->GetIntValue(ConfigureVOAAC::ConfigID, "AllowID3v2", False)) { if (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->Seek(0); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } } return True; } Int BoCA::EncoderVOAAC::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Copy data to samples buffer. */ Int samples = data.Size() / 2; samplesBuffer.Resize(samplesBuffer.Size() + samples); memcpy(samplesBuffer + samplesBuffer.Size() - samples, data, data.Size()); /* Output samples to encoder. */ totalSamples += data.Size() / format.channels / (format.bits / 8); return EncodeFrames(False); } Int BoCA::EncoderVOAAC::EncodeFrames(Bool flush) { const Format &format = track.GetFormat(); /* Pad end of stream with empty samples. */ if (flush) { Int nullSamples = delaySamples; if ((samplesBuffer.Size() / format.channels + delaySamples) % frameSize > 0) nullSamples += frameSize - (samplesBuffer.Size() / format.channels + delaySamples) % frameSize; samplesBuffer.Resize(samplesBuffer.Size() + nullSamples * format.channels); memset(samplesBuffer + samplesBuffer.Size() - nullSamples * format.channels, 0, sizeof(int16_t) * nullSamples * format.channels); } /* Encode samples. */ Int dataLength = 0; Int framesProcessed = 0; Int samplesPerFrame = frameSize * format.channels; while (samplesBuffer.Size() - framesProcessed * samplesPerFrame >= samplesPerFrame) { /* Prepare buffer information. */ VO_CODECBUFFER input = { 0 }; VO_CODECBUFFER output = { 0 }; VO_AUDIO_OUTPUTINFO outputInfo = { 0 }; input.Buffer = (uint8_t *) ((int16_t *) samplesBuffer + framesProcessed * samplesPerFrame); input.Length = samplesPerFrame * sizeof(int16_t); /* Hand input data to encoder and retrieve output. */ api.SetInputData(handle, &input); output.Buffer = outBuffer; output.Length = outBuffer.Size(); if (api.GetOutputData(handle, &output, &outputInfo) == VO_ERR_NONE) { dataLength += output.Length; if (mp4File != NIL) ex_MP4WriteSample(mp4File, mp4Track, (uint8_t *) (unsigned char *) outBuffer, output.Length, frameSize, 0, true); else driver->WriteData(outBuffer, output.Length); } framesProcessed++; } memmove(samplesBuffer, samplesBuffer + framesProcessed * samplesPerFrame, sizeof(int16_t) * (samplesBuffer.Size() - framesProcessed * samplesPerFrame)); samplesBuffer.Resize(samplesBuffer.Size() - framesProcessed * samplesPerFrame); return dataLength; } Int BoCA::EncoderVOAAC::GetSampleRateIndex(Int sampleRate) const { Int sampleRates[12] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 }; for (Int i = 0; i < 12; i++) { if (sampleRate == sampleRates[i]) return i; } return -1; } Bool BoCA::EncoderVOAAC::SetOutputFormat(Int n) { Config *config = Config::Get(); if (n == 0 && mp4v2dll != NIL) config->SetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", True); else config->SetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", False); return True; } String BoCA::EncoderVOAAC::GetOutputFileExtension() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", True)) { switch (config->GetIntValue(ConfigureVOAAC::ConfigID, "MP4FileExtension", 0)) { default: case 0: return "m4a"; case 1: return "m4b"; case 2: return "m4r"; case 3: return "mp4"; } } return "aac"; } Bool BoCA::EncoderVOAAC::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "voaacenc-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", True); config->SetIntValue(ConfigureVOAAC::ConfigID, "Bitrate", 96); } /* Get command line settings. */ Bool rawAAC = config->GetIntValue(encoderID, "Create ADTS AAC files (no MP4 container)", !config->GetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", True)); Int bitrate = config->GetIntValue(ConfigureVOAAC::ConfigID, "Bitrate", 96); if (config->GetIntValue(encoderID, "Set Bitrate per channel", False)) bitrate = config->GetIntValue(encoderID, "Bitrate per channel", bitrate); /* Set configuration values. */ config->SetIntValue(ConfigureVOAAC::ConfigID, "MP4Container", !rawAAC); config->SetIntValue(ConfigureVOAAC::ConfigID, "Bitrate", Math::Max(8, Math::Min(128, bitrate))); return True; } ConfigLayer *BoCA::EncoderVOAAC::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureVOAAC(); return configLayer; } int64_t BoCA::MP4IO_size(void *handle) { Driver *driver = (Driver *) handle; return driver->GetSize(); } int BoCA::MP4IO_seek(void *handle, int64_t pos) { Driver *driver = (Driver *) handle; if (driver->Seek(pos) == -1) return 1; return 0; } int BoCA::MP4IO_write(void *handle, const void *buffer, int64_t size, int64_t *nout) { Driver *driver = (Driver *) handle; *nout = driver->WriteData((const UnsignedByte *) buffer, size); if (*nout == 0) return 1; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/voaacenc/voaacenc.h000066400000000000000000000031541516712004000255020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderVOAAC) namespace BoCA { class EncoderVOAAC : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; MP4FileHandle mp4File; MP4TrackId mp4Track; VO_HANDLE handle; VO_AUDIO_CODECAPI api; VO_MEM_OPERATOR memOperator; VO_CODEC_INIT_USERDATA userData; Int frameSize; Int64 totalSamples; Int delaySamples; Buffer outBuffer; Buffer samplesBuffer; Int EncodeFrames(Bool); Int GetSampleRateIndex(Int) const; static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderVOAAC(); ~EncoderVOAAC(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool SetOutputFormat(Int); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderVOAAC) BoCA_END_COMPONENT(EncoderVOAAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/000077500000000000000000000000001516712004000232745ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/Makefile000077500000000000000000000012271516712004000247410ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = vorbis TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o vorbis.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/config.cpp000077500000000000000000000244231516712004000252550ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureVorbis::ConfigID = "Vorbis"; BoCA::ConfigureVorbis::ConfigureVorbis() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::Vorbis"); /* Get configuration. */ mode = config->GetIntValue(ConfigID, "Mode", 0); fileExtension = config->GetIntValue(ConfigID, "FileExtension", 0); quality = config->GetIntValue(ConfigID, "Quality", 60); setABRMin = config->GetIntValue(ConfigID, "SetMinBitrate", False); abrMin = config->GetIntValue(ConfigID, "MinBitrate", 32); setABRNom = config->GetIntValue(ConfigID, "SetBitrate", True); abrNom = config->GetIntValue(ConfigID, "Bitrate", 192); setABRMax = config->GetIntValue(ConfigID, "SetMaxBitrate", False); abrMax = config->GetIntValue(ConfigID, "MaxBitrate", 320); /* Encoding mode group. */ group_mode = new GroupBox(i18n->TranslateString("Encoding Mode"), Point(7, 11), Size(168, 65)); option_mode_vbr = new OptionBox(i18n->AddBrackets("VBR", i18n->TranslateString("Variable Bitrate")), Point(10, 13), Size(148, 0), &mode, 0); option_mode_vbr->onAction.Connect(&ConfigureVorbis::SetMode, this); option_mode_abr = new OptionBox(i18n->AddBrackets("ABR", i18n->TranslateString("Average Bitrate")), Point(10, 38), Size(148, 0), &mode, 1); option_mode_abr->onAction.Connect(&ConfigureVorbis::SetMode, this); group_mode->Add(option_mode_vbr); group_mode->Add(option_mode_abr); Int maxTextSize = Math::Max(option_mode_vbr->GetUnscaledTextWidth(), option_mode_abr->GetUnscaledTextWidth()); group_mode->SetWidth(Math::Max(168, maxTextSize + 41)); option_mode_vbr->SetWidth(group_mode->GetWidth() - 20); option_mode_abr->SetWidth(group_mode->GetWidth() - 20); /* File extension group. */ group_extension = new GroupBox(i18n->TranslateString("File extension"), Point(group_mode->GetWidth() + 15, 11), Size(336 - group_mode->GetWidth(), 65)); option_extension_ogg = new OptionBox(".ogg", Point(10, 13), Size(group_extension->GetWidth() - 20, 0), &fileExtension, 0); option_extension_oga = new OptionBox(".oga", Point(10, 38), Size(group_extension->GetWidth() - 20, 0), &fileExtension, 1); group_extension->Add(option_extension_ogg); group_extension->Add(option_extension_oga); /* Quality group. */ group_quality = new GroupBox(i18n->TranslateString("Quality"), Point(7, 88), Size(344, 42)); text_quality = new Text(i18n->AddColon(i18n->TranslateString("Quality")), Point(10, 16)); slider_quality = new Slider(Point(text_quality->GetUnscaledTextWidth() + 18, 14), Size(289 - text_quality->GetUnscaledTextWidth(), 0), OR_HORZ, &quality, -20, 100); slider_quality->onValueChange.Connect(&ConfigureVorbis::SetQuality, this); if (ex_vorbis_version_string == NIL || !String(ex_vorbis_version_string()).Contains("aoTuV")) slider_quality->SetRange(-10, 100); text_quality_value = new Text(NIL, Point(313, 16)); group_quality->Add(text_quality); group_quality->Add(slider_quality); group_quality->Add(text_quality_value); /* Bitrate group. */ group_bitrate = new GroupBox(i18n->TranslateString("Bitrate"), Point(7, 88), Size(344, 96)); check_abrmin = new CheckBox(i18n->AddColon(i18n->TranslateString("Minimum bitrate")), Point(10, 14), Size(), &setABRMin); check_abrmin->onAction.Connect(&ConfigureVorbis::ToggleABRMin, this); slider_abrmin = new Slider(Point(38, 14), Size(228, 0), OR_HORZ, &abrMin, 32, 320); slider_abrmin->onValueChange.Connect(&ConfigureVorbis::SetABRMin, this); text_abrmin_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 16)); text_abrmin_kbps->SetOrientation(OR_UPPERRIGHT); text_abrmin_kbps->SetX(text_abrmin_kbps->GetUnscaledTextWidth() + 10); edit_abrmin = new EditBox(Point(text_abrmin_kbps->GetX() + 32, 13), Size(25, 0), 3); edit_abrmin->SetFlags(EDB_NUMERIC); edit_abrmin->SetOrientation(OR_UPPERRIGHT); edit_abrmin->onInput.Connect(&ConfigureVorbis::SetABRMinByEditBox, this); check_abrnom = new CheckBox(i18n->AddColon(i18n->TranslateString("Average bitrate")), Point(10, 41), Size(), &setABRNom); check_abrnom->onAction.Connect(&ConfigureVorbis::ToggleABRNom, this); slider_abrnom = new Slider(Point(38, 41), Size(228, 0), OR_HORZ, &abrNom, 32, 320); slider_abrnom->onValueChange.Connect(&ConfigureVorbis::SetABRNom, this); text_abrnom_kbps = new Text(text_abrmin_kbps->GetText(), Point(text_abrmin_kbps->GetX(), 43)); text_abrnom_kbps->SetOrientation(OR_UPPERRIGHT); edit_abrnom = new EditBox(Point(text_abrnom_kbps->GetX() + 32, 40), Size(25, 0), 3); edit_abrnom->SetFlags(EDB_NUMERIC); edit_abrnom->SetOrientation(OR_UPPERRIGHT); edit_abrnom->onInput.Connect(&ConfigureVorbis::SetABRNomByEditBox, this); check_abrmax = new CheckBox(i18n->AddColon(i18n->TranslateString("Maximum bitrate")), Point(10, 68), Size(), &setABRMax); check_abrmax->onAction.Connect(&ConfigureVorbis::ToggleABRMax, this); slider_abrmax = new Slider(Point(38, 68), Size(228, 0), OR_HORZ, &abrMax, 32, 320); slider_abrmax->onValueChange.Connect(&ConfigureVorbis::SetABRMax, this); text_abrmax_kbps = new Text(text_abrnom_kbps->GetText(), Point(text_abrnom_kbps->GetX(), 70)); text_abrmax_kbps->SetOrientation(OR_UPPERRIGHT); edit_abrmax = new EditBox(Point(text_abrmax_kbps->GetX() + 32, 67), Size(25, 0), 3); edit_abrmax->SetFlags(EDB_NUMERIC); edit_abrmax->SetOrientation(OR_UPPERRIGHT); edit_abrmax->onInput.Connect(&ConfigureVorbis::SetABRMaxByEditBox, this); maxTextSize = Math::Max(Math::Max(check_abrmin->GetUnscaledTextWidth(), check_abrnom->GetUnscaledTextWidth()), check_abrmax->GetUnscaledTextWidth()); check_abrmin->SetWidth(maxTextSize + 20); check_abrnom->SetWidth(maxTextSize + 20); check_abrmax->SetWidth(maxTextSize + 20); slider_abrmin->SetX(maxTextSize + 38); slider_abrnom->SetX(maxTextSize + 38); slider_abrmax->SetX(maxTextSize + 38); slider_abrmin->SetWidth(266 - maxTextSize - text_abrmin_kbps->GetX()); slider_abrnom->SetWidth(266 - maxTextSize - text_abrnom_kbps->GetX()); slider_abrmax->SetWidth(266 - maxTextSize - text_abrmax_kbps->GetX()); group_bitrate->Add(check_abrmin); group_bitrate->Add(slider_abrmin); group_bitrate->Add(edit_abrmin); group_bitrate->Add(text_abrmin_kbps); group_bitrate->Add(check_abrnom); group_bitrate->Add(slider_abrnom); group_bitrate->Add(edit_abrnom); group_bitrate->Add(text_abrnom_kbps); group_bitrate->Add(check_abrmax); group_bitrate->Add(slider_abrmax); group_bitrate->Add(edit_abrmax); group_bitrate->Add(text_abrmax_kbps); SetQuality(); ToggleABRMin(); ToggleABRNom(); ToggleABRMax(); SetABRMin(); SetABRNom(); SetABRMax(); Add(group_mode); Add(group_extension); Add(group_quality); Add(group_bitrate); switch (mode) { case 0: group_bitrate->Hide(); break; case 1: group_quality->Hide(); break; } SetSize(Size(358, 191)); } BoCA::ConfigureVorbis::~ConfigureVorbis() { DeleteObject(group_mode); DeleteObject(option_mode_abr); DeleteObject(option_mode_vbr); DeleteObject(group_extension); DeleteObject(option_extension_ogg); DeleteObject(option_extension_oga); DeleteObject(group_quality); DeleteObject(slider_quality); DeleteObject(text_quality); DeleteObject(text_quality_value); DeleteObject(group_bitrate); DeleteObject(check_abrmin); DeleteObject(slider_abrmin); DeleteObject(edit_abrmin); DeleteObject(text_abrmin_kbps); DeleteObject(check_abrnom); DeleteObject(slider_abrnom); DeleteObject(edit_abrnom); DeleteObject(text_abrnom_kbps); DeleteObject(check_abrmax); DeleteObject(slider_abrmax); DeleteObject(edit_abrmax); DeleteObject(text_abrmax_kbps); } Int BoCA::ConfigureVorbis::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Mode", mode); config->SetIntValue(ConfigID, "FileExtension", fileExtension); config->SetIntValue(ConfigID, "Quality", quality); config->SetIntValue(ConfigID, "SetMinBitrate", setABRMin); config->SetIntValue(ConfigID, "MinBitrate", abrMin); config->SetIntValue(ConfigID, "SetBitrate", setABRNom); config->SetIntValue(ConfigID, "Bitrate", abrNom); config->SetIntValue(ConfigID, "SetMaxBitrate", setABRMax); config->SetIntValue(ConfigID, "MaxBitrate", abrMax); return Success(); } Void BoCA::ConfigureVorbis::SetMode() { switch (mode) { case 0: group_bitrate->Hide(); group_quality->Show(); break; case 1: group_quality->Hide(); group_bitrate->Show(); break; } } Void BoCA::ConfigureVorbis::SetQuality() { String txt = String::FromFloat(((double) quality) / 10); if (quality % 10 == 0) txt.Append(".0"); text_quality_value->SetText(txt); } Void BoCA::ConfigureVorbis::ToggleABRMin() { if (!setABRMin) { edit_abrmin->Deactivate(); slider_abrmin->Deactivate(); } else { edit_abrmin->Activate(); slider_abrmin->Activate(); } } Void BoCA::ConfigureVorbis::SetABRMin() { if (!edit_abrmin->IsFocussed()) edit_abrmin->SetText(String::FromInt(abrMin)); } Void BoCA::ConfigureVorbis::SetABRMinByEditBox() { slider_abrmin->SetValue(edit_abrmin->GetText().ToInt()); } Void BoCA::ConfigureVorbis::ToggleABRNom() { if (!setABRNom) { edit_abrnom->Deactivate(); slider_abrnom->Deactivate(); } else { edit_abrnom->Activate(); slider_abrnom->Activate(); } } Void BoCA::ConfigureVorbis::SetABRNom() { if (!edit_abrnom->IsFocussed()) edit_abrnom->SetText(String::FromInt(abrNom)); } Void BoCA::ConfigureVorbis::SetABRNomByEditBox() { slider_abrnom->SetValue(edit_abrnom->GetText().ToInt()); } Void BoCA::ConfigureVorbis::ToggleABRMax() { if (!setABRMax) { edit_abrmax->Deactivate(); slider_abrmax->Deactivate(); } else { edit_abrmax->Activate(); slider_abrmax->Activate(); } } Void BoCA::ConfigureVorbis::SetABRMax() { if (!edit_abrmax->IsFocussed()) edit_abrmax->SetText(String::FromInt(abrMax)); } Void BoCA::ConfigureVorbis::SetABRMaxByEditBox() { slider_abrmax->SetValue(edit_abrmax->GetText().ToInt()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/config.h000077500000000000000000000041201516712004000247120ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_VORBISCONFIG #define H_VORBISCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureVorbis : public ConfigLayer { private: GroupBox *group_mode; OptionBox *option_mode_vbr; OptionBox *option_mode_abr; GroupBox *group_extension; OptionBox *option_extension_ogg; OptionBox *option_extension_oga; GroupBox *group_quality; Slider *slider_quality; Text *text_quality; Text *text_quality_value; GroupBox *group_bitrate; CheckBox *check_abrmin; Slider *slider_abrmin; EditBox *edit_abrmin; Text *text_abrmin_kbps; CheckBox *check_abrnom; Slider *slider_abrnom; EditBox *edit_abrnom; Text *text_abrnom_kbps; CheckBox *check_abrmax; Slider *slider_abrmax; EditBox *edit_abrmax; Text *text_abrmax_kbps; Int mode; Int fileExtension; Int quality; Int abrMin; Int abrNom; Int abrMax; Bool setABRMin; Bool setABRNom; Bool setABRMax; slots: Void SetMode(); Void SetQuality(); Void ToggleABRMin(); Void SetABRMin(); Void SetABRMinByEditBox(); Void ToggleABRNom(); Void SetABRNom(); Void SetABRNomByEditBox(); Void ToggleABRMax(); Void SetABRMax(); Void SetABRMaxByEditBox(); public: static const String ConfigID; ConfigureVorbis(); ~ConfigureVorbis(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/dllinterface.cpp000077500000000000000000000140111516712004000264340ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETIN ex_ogg_stream_packetin = NIL; OGGSTREAMFLUSH ex_ogg_stream_flush = NIL; OGGSTREAMPAGEOUT ex_ogg_stream_pageout = NIL; OGGPAGEEOS ex_ogg_page_eos = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; VORBISVERSIONSTRING ex_vorbis_version_string = NIL; VORBISINFOINIT ex_vorbis_info_init = NIL; VORBISCOMMENTINIT ex_vorbis_comment_init = NIL; VORBISCOMMENTADDTAG ex_vorbis_comment_add_tag = NIL; VORBISANALYSISINIT ex_vorbis_analysis_init = NIL; VORBISBLOCKINIT ex_vorbis_block_init = NIL; VORBISANALYSISHEADEROUT ex_vorbis_analysis_headerout = NIL; VORBISANALYSISBUFFER ex_vorbis_analysis_buffer = NIL; VORBISANALYSISWROTE ex_vorbis_analysis_wrote = NIL; VORBISANALYSISBLOCKOUT ex_vorbis_analysis_blockout = NIL; VORBISANALYSIS ex_vorbis_analysis = NIL; VORBISBITRATEADDBLOCK ex_vorbis_bitrate_addblock = NIL; VORBISBITRATEFLUSHPACKET ex_vorbis_bitrate_flushpacket = NIL; VORBISBLOCKCLEAR ex_vorbis_block_clear = NIL; VORBISDSPCLEAR ex_vorbis_dsp_clear = NIL; VORBISCOMMENTCLEAR ex_vorbis_comment_clear = NIL; VORBISINFOCLEAR ex_vorbis_info_clear = NIL; VORBISENCODEINIT ex_vorbis_encode_init = NIL; VORBISENCODEINITVBR ex_vorbis_encode_init_vbr = NIL; DynamicLoader *oggdll = NIL; DynamicLoader *vorbisdll = NIL; DynamicLoader *vorbisencdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetin = (OGGSTREAMPACKETIN) oggdll->GetFunctionAddress("ogg_stream_packetin"); ex_ogg_stream_flush = (OGGSTREAMFLUSH) oggdll->GetFunctionAddress("ogg_stream_flush"); ex_ogg_stream_pageout = (OGGSTREAMPAGEOUT) oggdll->GetFunctionAddress("ogg_stream_pageout"); ex_ogg_page_eos = (OGGPAGEEOS) oggdll->GetFunctionAddress("ogg_page_eos"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetin == NIL || ex_ogg_stream_flush == NIL || ex_ogg_stream_pageout == NIL || ex_ogg_page_eos == NIL || ex_ogg_stream_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } Bool LoadVorbisDLL() { vorbisdll = BoCA::Utilities::LoadCodecDLL("vorbis"); vorbisencdll = BoCA::Utilities::LoadCodecDLL("vorbisenc"); if (vorbisdll == NIL || vorbisencdll == NIL) return False; ex_vorbis_version_string = (VORBISVERSIONSTRING) vorbisdll->GetFunctionAddress("vorbis_version_string"); ex_vorbis_info_init = (VORBISINFOINIT) vorbisdll->GetFunctionAddress("vorbis_info_init"); ex_vorbis_comment_init = (VORBISCOMMENTINIT) vorbisdll->GetFunctionAddress("vorbis_comment_init"); ex_vorbis_comment_add_tag = (VORBISCOMMENTADDTAG) vorbisdll->GetFunctionAddress("vorbis_comment_add_tag"); ex_vorbis_analysis_init = (VORBISANALYSISINIT) vorbisdll->GetFunctionAddress("vorbis_analysis_init"); ex_vorbis_block_init = (VORBISBLOCKINIT) vorbisdll->GetFunctionAddress("vorbis_block_init"); ex_vorbis_analysis_headerout = (VORBISANALYSISHEADEROUT) vorbisdll->GetFunctionAddress("vorbis_analysis_headerout"); ex_vorbis_analysis_buffer = (VORBISANALYSISBUFFER) vorbisdll->GetFunctionAddress("vorbis_analysis_buffer"); ex_vorbis_analysis_wrote = (VORBISANALYSISWROTE) vorbisdll->GetFunctionAddress("vorbis_analysis_wrote"); ex_vorbis_analysis_blockout = (VORBISANALYSISBLOCKOUT) vorbisdll->GetFunctionAddress("vorbis_analysis_blockout"); ex_vorbis_analysis = (VORBISANALYSIS) vorbisdll->GetFunctionAddress("vorbis_analysis"); ex_vorbis_bitrate_addblock = (VORBISBITRATEADDBLOCK) vorbisdll->GetFunctionAddress("vorbis_bitrate_addblock"); ex_vorbis_bitrate_flushpacket = (VORBISBITRATEFLUSHPACKET) vorbisdll->GetFunctionAddress("vorbis_bitrate_flushpacket"); ex_vorbis_block_clear = (VORBISBLOCKCLEAR) vorbisdll->GetFunctionAddress("vorbis_block_clear"); ex_vorbis_dsp_clear = (VORBISDSPCLEAR) vorbisdll->GetFunctionAddress("vorbis_dsp_clear"); ex_vorbis_comment_clear = (VORBISCOMMENTCLEAR) vorbisdll->GetFunctionAddress("vorbis_comment_clear"); ex_vorbis_info_clear = (VORBISINFOCLEAR) vorbisdll->GetFunctionAddress("vorbis_info_clear"); ex_vorbis_encode_init = (VORBISENCODEINIT) vorbisencdll->GetFunctionAddress("vorbis_encode_init"); ex_vorbis_encode_init_vbr = (VORBISENCODEINITVBR) vorbisencdll->GetFunctionAddress("vorbis_encode_init_vbr"); if (ex_vorbis_info_init == NIL || ex_vorbis_comment_init == NIL || ex_vorbis_comment_add_tag == NIL || ex_vorbis_analysis_init == NIL || ex_vorbis_block_init == NIL || ex_vorbis_analysis_headerout == NIL || ex_vorbis_analysis_buffer == NIL || ex_vorbis_analysis_wrote == NIL || ex_vorbis_analysis_blockout == NIL || ex_vorbis_analysis == NIL || ex_vorbis_bitrate_addblock == NIL || ex_vorbis_bitrate_flushpacket == NIL || ex_vorbis_block_clear == NIL || ex_vorbis_dsp_clear == NIL || ex_vorbis_comment_clear == NIL || ex_vorbis_info_clear == NIL || ex_vorbis_encode_init == NIL || ex_vorbis_encode_init_vbr == NIL) { FreeVorbisDLL(); return False; } return True; } Void FreeVorbisDLL() { BoCA::Utilities::FreeCodecDLL(vorbisdll); BoCA::Utilities::FreeCodecDLL(vorbisencdll); vorbisdll = NIL; vorbisencdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/dllinterface.h000077500000000000000000000074371516712004000261170ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; extern DynamicLoader *vorbisdll; extern DynamicLoader *vorbisencdll; Bool LoadOggDLL(); Void FreeOggDLL(); Bool LoadVorbisDLL(); Void FreeVorbisDLL(); /* Ogg API functions. */ typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETIN) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMFLUSH) (ogg_stream_state *, ogg_page *); typedef int (*OGGSTREAMPAGEOUT) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGEEOS) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETIN ex_ogg_stream_packetin; extern OGGSTREAMFLUSH ex_ogg_stream_flush; extern OGGSTREAMPAGEOUT ex_ogg_stream_pageout; extern OGGPAGEEOS ex_ogg_page_eos; extern OGGSTREAMCLEAR ex_ogg_stream_clear; /* Vorbis API functions. */ typedef const char * (*VORBISVERSIONSTRING) (); typedef void (*VORBISINFOINIT) (vorbis_info *); typedef void (*VORBISCOMMENTINIT) (vorbis_comment *); typedef void (*VORBISCOMMENTADDTAG) (vorbis_comment *, char *, char *); typedef int (*VORBISANALYSISINIT) (vorbis_dsp_state *, vorbis_info *); typedef int (*VORBISBLOCKINIT) (vorbis_dsp_state *, vorbis_block *); typedef int (*VORBISANALYSISHEADEROUT) (vorbis_dsp_state *, vorbis_comment *, ogg_packet *, ogg_packet *, ogg_packet *); typedef float ** (*VORBISANALYSISBUFFER) (vorbis_dsp_state *, int); typedef int (*VORBISANALYSISWROTE) (vorbis_dsp_state *, int); typedef int (*VORBISANALYSISBLOCKOUT) (vorbis_dsp_state *, vorbis_block *); typedef int (*VORBISANALYSIS) (vorbis_block *, ogg_packet *); typedef int (*VORBISBITRATEADDBLOCK) (vorbis_block *); typedef int (*VORBISBITRATEFLUSHPACKET) (vorbis_dsp_state *, ogg_packet *); typedef int (*VORBISBLOCKCLEAR) (vorbis_block *); typedef void (*VORBISDSPCLEAR) (vorbis_dsp_state *); typedef void (*VORBISCOMMENTCLEAR) (vorbis_comment *); typedef void (*VORBISINFOCLEAR) (vorbis_info *); typedef int (*VORBISENCODEINIT) (vorbis_info *, long, long, long, long, long); typedef int (*VORBISENCODEINITVBR) (vorbis_info *, long, long, float); extern VORBISVERSIONSTRING ex_vorbis_version_string; extern VORBISINFOINIT ex_vorbis_info_init; extern VORBISCOMMENTINIT ex_vorbis_comment_init; extern VORBISCOMMENTADDTAG ex_vorbis_comment_add_tag; extern VORBISANALYSISINIT ex_vorbis_analysis_init; extern VORBISBLOCKINIT ex_vorbis_block_init; extern VORBISANALYSISHEADEROUT ex_vorbis_analysis_headerout; extern VORBISANALYSISBUFFER ex_vorbis_analysis_buffer; extern VORBISANALYSISWROTE ex_vorbis_analysis_wrote; extern VORBISANALYSISBLOCKOUT ex_vorbis_analysis_blockout; extern VORBISANALYSIS ex_vorbis_analysis; extern VORBISBITRATEADDBLOCK ex_vorbis_bitrate_addblock; extern VORBISBITRATEFLUSHPACKET ex_vorbis_bitrate_flushpacket; extern VORBISBLOCKCLEAR ex_vorbis_block_clear; extern VORBISDSPCLEAR ex_vorbis_dsp_clear; extern VORBISCOMMENTCLEAR ex_vorbis_comment_clear; extern VORBISINFOCLEAR ex_vorbis_info_clear; extern VORBISENCODEINIT ex_vorbis_encode_init; extern VORBISENCODEINITVBR ex_vorbis_encode_init_vbr; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/vorbis.cpp000066400000000000000000000251511516712004000253100ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "vorbis.h" #include "config.h" using namespace smooth::IO; const String &BoCA::EncoderVorbis::GetComponentSpecs() { static String componentSpecs; if (oggdll != NIL && vorbisdll != NIL && vorbisencdll != NIL) { componentSpecs = " \ \ \ \ Ogg Vorbis Encoder \ 1.0 \ vorbis-enc \ encoder \ \ Ogg Vorbis Audio \ ogg \ oga \ Vorbis Comment \ \ \ \ \ 0 \ 100 \ \ \ 45 \ 500 \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); LoadVorbisDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); FreeVorbisDLL(); } BoCA::EncoderVorbis::EncoderVorbis() { configLayer = NIL; config = NIL; memset(&os, 0, sizeof(os)); memset(&og, 0, sizeof(og)); memset(&op, 0, sizeof(op)); memset(&vi, 0, sizeof(vi)); memset(&vc, 0, sizeof(vc)); memset(&vd, 0, sizeof(vd)); memset(&vb, 0, sizeof(vb)); } BoCA::EncoderVorbis::~EncoderVorbis() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::EncoderVorbis::Activate() { /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); Int mode = config->GetIntValue(ConfigureVorbis::ConfigID, "Mode", 0); Int quality = config->GetIntValue(ConfigureVorbis::ConfigID, "Quality", 60); if (ex_vorbis_version_string != NIL && String(ex_vorbis_version_string()).Contains("aoTuV")) quality = Math::Max(-20, Math::Min(quality, 100)); else quality = Math::Max(-10, Math::Min(quality, 100)); Bool setBitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "SetBitrate", True); Bool setMinBitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "SetMinBitrate", False); Bool setMaxBitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "SetMaxBitrate", False); Int bitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "Bitrate", 192); Int minBitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "MinBitrate", 32); Int maxBitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "MaxBitrate", 320); /* Init Ogg stream. */ Math::RandomSeed(); ex_ogg_stream_init(&os, Math::Random()); /* Create and configure Vorbis encoder. */ const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); int error = -1; ex_vorbis_info_init(&vi); switch (mode) { case 0: error = ex_vorbis_encode_init_vbr(&vi, format.channels, format.rate, ((double) quality) / 100); break; case 1: error = ex_vorbis_encode_init(&vi, format.channels, format.rate, setMaxBitrate ? maxBitrate * 1000 : -1, setBitrate ? bitrate * 1000 : -1, setMinBitrate ? minBitrate * 1000 : -1); break; } if (error != 0) { errorString = "Could not initialize Vorbis encoder! Please check the configuration!"; errorState = True; ex_vorbis_info_clear(&vi); return False; } ex_vorbis_comment_init(&vc); ex_vorbis_analysis_init(&vd, &vi); ex_vorbis_block_init(&vd, &vb); ogg_packet header; ogg_packet header_comm; ogg_packet header_code; ex_vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code); ex_ogg_stream_packetin(&os, &header); /* automatically placed in its own page */ /* Write Vorbis Comment header */ { /* Read vendor string. */ InStream in(STREAM_BUFFER, header_comm.packet + 7, header_comm.bytes - 7); String vendor = in.InputString(in.InputNumber(4)); Buffer vcBuffer; /* Render actual Vorbis Comment tag. * * An empty tag containing only the vendor string * is rendered if Vorbis Comment tags are disabled. */ AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->SetVendorString(vendor); if (config->GetIntValue("Tags", "EnableVorbisComment", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) tagger->RenderBuffer(vcBuffer, track); else tagger->RenderBuffer(vcBuffer, Track()); boca.DeleteComponent(tagger); } vcBuffer.Resize(vcBuffer.Size() + 8); memmove(vcBuffer + 7, vcBuffer, vcBuffer.Size() - 8); memcpy(vcBuffer + 1, "vorbis", 6); vcBuffer[0] = 3; vcBuffer[vcBuffer.Size() - 1] = 1; ogg_packet header_comm2 = { vcBuffer, vcBuffer.Size(), 0, 0, 0, 1 }; ex_ogg_stream_packetin(&os, &header_comm2); } ex_ogg_stream_packetin(&os, &header_code); WriteOggPackets(True); return True; } Bool BoCA::EncoderVorbis::Deactivate() { /* Finish conversion and write any remaining Ogg packets. */ ex_vorbis_analysis_wrote(&vd, 0); while (ex_vorbis_analysis_blockout(&vd, &vb) == 1) { ex_vorbis_analysis(&vb, NULL); ex_vorbis_bitrate_addblock(&vb); while (ex_vorbis_bitrate_flushpacket(&vd, &op)) { ex_ogg_stream_packetin(&os, &op); WriteOggPackets(False); } } ex_vorbis_block_clear(&vb); ex_vorbis_dsp_clear(&vd); ex_vorbis_comment_clear(&vc); ex_vorbis_info_clear(&vi); ex_ogg_stream_clear(&os); /* Fix chapter marks in Vorbis Comments. */ if (config->GetIntValue("Tags", "EnableVorbisComment", True) && track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)) { driver->Close(); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { tagger->UpdateStreamInfo(track.outputFile, track); boca.DeleteComponent(tagger); } } return True; } Int BoCA::EncoderVorbis::WriteData(Buffer &data) { const Format &format = track.GetFormat(); /* Change to Vorbis channel order. */ if (format.channels == 3) Utilities::ChangeChannelOrder(data, format, Channel::Default_3_0, Channel::Vorbis_3_0); else if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::Vorbis_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::Vorbis_5_1); else if (format.channels == 7) Utilities::ChangeChannelOrder(data, format, Channel::Default_6_1, Channel::Vorbis_6_1); else if (format.channels == 8) Utilities::ChangeChannelOrder(data, format, Channel::Default_7_1, Channel::Vorbis_7_1); /* Write samples to analysis buffer. */ Int numSamples = data.Size() / sizeof(float) / format.channels; float *samples = (float *) (UnsignedByte *) data; float **buffer = ex_vorbis_analysis_buffer(&vd, numSamples); for (Int c = 0; c < format.channels; c++) { for (Int i = 0; i < numSamples; i++) buffer[c][i] = samples[i * format.channels + c]; } ex_vorbis_analysis_wrote(&vd, numSamples); /* Output samples to encoder. */ Int dataLength = 0; while (ex_vorbis_analysis_blockout(&vd, &vb) == 1) { ex_vorbis_analysis(&vb, NULL); ex_vorbis_bitrate_addblock(&vb); while (ex_vorbis_bitrate_flushpacket(&vd, &op)) { ex_ogg_stream_packetin(&os, &op); dataLength += WriteOggPackets(False); } } return dataLength; } Int BoCA::EncoderVorbis::WriteOggPackets(Bool flush) { Int bytes = 0; do { int result = 0; if (flush) result = ex_ogg_stream_flush(&os, &og); else result = ex_ogg_stream_pageout(&os, &og); if (result == 0) break; bytes += driver->WriteData(og.header, og.header_len); bytes += driver->WriteData(og.body, og.body_len); } while (true); return bytes; } String BoCA::EncoderVorbis::GetOutputFileExtension() const { const Config *config = GetConfiguration(); switch (config->GetIntValue(ConfigureVorbis::ConfigID, "FileExtension", 0)) { default: case 0: return "ogg"; case 1: return "oga"; } } Bool BoCA::EncoderVorbis::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "vorbis-enc"; /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureVorbis::ConfigID, "Mode", 0); config->SetIntValue(ConfigureVorbis::ConfigID, "Quality", 60); config->SetIntValue(ConfigureVorbis::ConfigID, "Bitrate", 192); } /* Get command line settings. */ Bool useABR = config->GetIntValue(encoderID, "Set ABR target bitrate", config->GetIntValue(ConfigureVorbis::ConfigID, "Mode", 0) == 1); Int quality = config->GetIntValue(ConfigureVorbis::ConfigID, "Quality", 60); Int bitrate = config->GetIntValue(ConfigureVorbis::ConfigID, "Bitrate", 192); if (config->GetIntValue(encoderID, "Set VBR quality", False)) quality = config->GetIntValue(encoderID, "VBR quality", quality); if (config->GetIntValue(encoderID, "Set ABR target bitrate", False)) bitrate = config->GetIntValue(encoderID, "ABR target bitrate", bitrate); /* Set configuration values. */ config->SetIntValue(ConfigureVorbis::ConfigID, "Mode", useABR ? 1 : 0); config->SetIntValue(ConfigureVorbis::ConfigID, "Quality", Math::Max(0, Math::Min(100, quality))); config->SetIntValue(ConfigureVorbis::ConfigID, "Bitrate", Math::Max(45, Math::Min(500, bitrate))); return True; } ConfigLayer *BoCA::EncoderVorbis::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureVorbis(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/vorbis/vorbis.h000066400000000000000000000026011516712004000247500ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderVorbis) namespace BoCA { class EncoderVorbis : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; ogg_stream_state os; ogg_page og; ogg_packet op; vorbis_info vi; vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; Int WriteOggPackets(Bool); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); EncoderVorbis(); ~EncoderVorbis(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); String GetOutputFileExtension() const; ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderVorbis) BoCA_END_COMPONENT(EncoderVorbis) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wave/000077500000000000000000000000001516712004000227325ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wave/Makefile000077500000000000000000000011201516712004000243670ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wave TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = wave.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wave/wave.cpp000066400000000000000000000126721516712004000244100ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef __WIN32__ # include # include #else # define WAVE_FORMAT_PCM 0x0001 # define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif #include "wave.h" using namespace smooth::IO; const String &BoCA::EncoderWave::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Windows Wave File Output \ 1.0 \ wave-enc \ encoder \ \ Microsoft Wave Files \ wav \ RIFF INFO Tag \ RIFF Cart Tag \ ID3v2 \ \ \ \ \ \ "; return componentSpecs; } BoCA::EncoderWave::EncoderWave() { } BoCA::EncoderWave::~EncoderWave() { } Bool BoCA::EncoderWave::Activate() { Buffer buffer(44); OutStream *out = new OutStream(STREAM_BUFFER, buffer, 44); const Format &format = track.GetFormat(); out->OutputString("RIFF"); out->OutputNumber(track.length * format.channels * (format.bits / 8) + 36, 4); out->OutputString("WAVE"); out->OutputString("fmt "); out->OutputNumber(16, 4); out->OutputNumber(WAVE_FORMAT_PCM, 2); out->OutputNumber(format.channels, 2); out->OutputNumber(format.rate, 4); out->OutputNumber(format.rate * format.channels * (format.bits / 8), 4); out->OutputNumber(format.channels * (format.bits / 8), 2); out->OutputNumber(format.bits, 2); out->OutputString("data"); out->OutputNumber(track.length * format.channels * (format.bits / 8), 4); delete out; driver->WriteData(buffer, 44); return True; } Bool BoCA::EncoderWave::Deactivate() { static Endianness endianness = CPU().GetEndianness(); const Config *config = GetConfiguration(); const Info &info = track.GetInfo(); /* Write data size to header. */ UnsignedInt dataSize = driver->GetSize() - 44; driver->Seek(40); if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &dataSize) + i, 1); else for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &dataSize) + i, 1); driver->Seek(driver->GetSize()); /* Write RIFF tag if requested. */ if (config->GetIntValue("Tags", "EnableRIFFINFOTag", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("riff-tag"); if (tagger != NIL) { Buffer tagBuffer; tagger->SetConfiguration(GetConfiguration()); tagger->RenderBuffer(tagBuffer, track); driver->WriteData(tagBuffer, tagBuffer.Size()); boca.DeleteComponent(tagger); } } /* Write CART tag if requested. */ if (config->GetIntValue("Tags", "EnableRIFFCartTag", True) && info.HasBasicInfo()) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("cart-tag"); if (tagger != NIL) { Buffer tagBuffer; tagger->SetConfiguration(GetConfiguration()); tagger->RenderBuffer(tagBuffer, track); driver->WriteData(tagBuffer, tagBuffer.Size()); boca.DeleteComponent(tagger); } } /* Write ID3v2 tag if requested. */ if (config->GetIntValue("Tags", "EnableID3v2", True) && (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True)))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("id3v2-tag"); if (tagger != NIL) { Buffer id3Buffer; tagger->SetConfiguration(config); tagger->RenderBuffer(id3Buffer, track); driver->WriteData((unsigned char *) "id3 ", 4); Int size = id3Buffer.Size(); if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &size) + i, 1); else for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &size) + i, 1); driver->WriteData(id3Buffer, id3Buffer.Size()); boca.DeleteComponent(tagger); } } /* Write file size to header. */ UnsignedInt fileSize = driver->GetSize() - 8; driver->Seek(4); if (endianness == EndianLittle) for (Int i = 0; i <= 3; i++) driver->WriteData(((unsigned char *) &fileSize) + i, 1); else for (Int i = 3; i >= 0; i--) driver->WriteData(((unsigned char *) &fileSize) + i, 1); driver->Seek(driver->GetSize()); return True; } Int BoCA::EncoderWave::WriteData(Buffer &data) { static Endianness endianness = CPU().GetEndianness(); if (endianness != EndianLittle) BoCA::Utilities::SwitchBufferByteOrder(data, track.GetFormat().bits / 8); return driver->WriteData(data, data.Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wave/wave.h000066400000000000000000000017271516712004000240540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(EncoderWave) namespace BoCA { class EncoderWave : public CS::EncoderComponent { public: static const String &GetComponentSpecs(); EncoderWave(); ~EncoderWave(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderWave) BoCA_END_COMPONENT(EncoderWave) boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/000077500000000000000000000000001516712004000225545ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/Makefile000077500000000000000000000012311516712004000242140ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wma TYPE = encoder VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o wma.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = -lole32 # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/config.cpp000077500000000000000000000417601516712004000245400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureWMA::ConfigID = "WMA"; BoCA::ConfigureWMA::ConfigureWMA() { const Config *config = Config::Get(); uncompressed = config->GetIntValue(ConfigID, "Uncompressed", False); autoselect = config->GetIntValue(ConfigID, "AutoSelectFormat", True); useVBR = config->GetIntValue(ConfigID, "EnableVBR", True); use2Pass = config->GetIntValue(ConfigID, "Enable2Pass", False); useVBRSetting = useVBR; use2PassSetting = use2Pass; supportCBR1Pass = False; supportVBR1Pass = False; supportCBR2Pass = False; supportVBR2Pass = False; quality = config->GetIntValue(ConfigID, "Quality", 90) / 5; ex_WMCreateProfileManager(&profileManager); I18n *i18n = I18n::Get(); i18n->SetContext("Encoders::WMA"); group_codec = new GroupBox(i18n->TranslateString("Select codec"), Point(7, 11), Size(426, 67)); option_uncompressed = new OptionBox(i18n->TranslateString("Write uncompressed WMA files"), Point(10, 13), Size(406, 0), &uncompressed, 1); option_uncompressed->onAction.Connect(&ConfigureWMA::OnToggleCodec, this); option_codec = new OptionBox(i18n->AddColon(i18n->TranslateString("Use codec")), Point(10, 39), Size(100, 0), &uncompressed, 0); option_codec->onAction.Connect(&ConfigureWMA::OnToggleCodec, this); option_format = new OptionBox(i18n->AddColon(i18n->TranslateString("Use format")), Point(10, 39), Size(100, 0), &autoselect, 0); option_format->onAction.Connect(&ConfigureWMA::OnToggleFormat, this); option_codec->SetWidth(Math::Max(option_codec->GetUnscaledTextWidth(), option_format->GetUnscaledTextWidth()) + 21); option_format->SetWidth(option_codec->GetWidth()); combo_codec = new ComboBox(Point(100, 38), Size(200, 0)); group_codec->Add(option_uncompressed); group_codec->Add(option_codec); group_codec->Add(combo_codec); group_format = new GroupBox(i18n->TranslateString("Select codec format"), Point(7, 90), Size(426, 93)); option_autoselect = new OptionBox(i18n->TranslateString("Automatically select format based on settings and input format"), Point(10, 13), Size(406, 0), &autoselect, 1); option_autoselect->onAction.Connect(&ConfigureWMA::OnToggleFormat, this); check_vbr = new CheckBox(i18n->TranslateString("Use VBR encoding"), Point(18 + option_format->GetWidth(), 39), Size(100, 0), &useVBR); check_vbr->onAction.Connect(&ConfigureWMA::OnToggleVBR, this); check_2pass = new CheckBox(i18n->TranslateString("Use 2-pass encoding"), Point(225, 39), Size(100, 0), &use2Pass); check_2pass->onAction.Connect(&ConfigureWMA::OnToggle2Pass, this); check_vbr->SetWidth(Math::Max(120, Math::Max(check_vbr->GetUnscaledTextWidth(), check_2pass->GetUnscaledTextWidth()) + 21)); check_2pass->SetWidth(check_vbr->GetWidth()); combo_format = new ComboBox(Point(18 + option_codec->GetWidth(), 64), Size(200, 0)); combo_codec->SetX(combo_format->GetX()); group_format->Add(option_autoselect); group_format->Add(option_format); group_format->Add(check_vbr); group_format->Add(check_2pass); group_format->Add(combo_format); group_settings = new GroupBox(i18n->TranslateString("Codec settings"), Point(7, 195), Size(426, 67)); check_vbr_setting = new CheckBox(i18n->TranslateString("Use VBR encoding"), Point(10, 14), Size(200, 0), &useVBRSetting); check_vbr_setting->onAction.Connect(&ConfigureWMA::OnToggleVBRSetting, this); check_2pass_setting = new CheckBox(i18n->TranslateString("Use 2-pass encoding"), Point(10, 40), Size(200, 0), &use2PassSetting); check_2pass_setting->onAction.Connect(&ConfigureWMA::OnToggle2PassSetting, this); check_vbr_setting->SetWidth(Math::Max(check_vbr_setting->GetUnscaledTextWidth(), check_2pass_setting->GetUnscaledTextWidth()) + 21); check_2pass_setting->SetWidth(check_vbr_setting->GetWidth()); text_quality = new Text(i18n->AddColon(i18n->TranslateString("Quality")), Point(check_vbr_setting->GetWidth() + 18, 16)); text_bitrate = new Text(i18n->AddColon(i18n->TranslateString("Target bitrate")), Point(check_vbr_setting->GetWidth() + 18, 42)); Int maxTextSize = Math::Max(text_quality->GetUnscaledTextWidth(), text_bitrate->GetUnscaledTextWidth()); text_bitrate_kbps = new Text(i18n->TranslateString("%1 kbps", "Technical").Replace("%1", NIL).Trim(), Point(35, 42)); text_bitrate_kbps->SetOrientation(OR_UPPERRIGHT); text_bitrate_kbps->SetX(text_bitrate_kbps->GetUnscaledTextWidth() + 10); text_quality_value = new Text(String::FromInt(quality * 5), Point(text_bitrate_kbps->GetX(), 16)); text_quality_value->SetOrientation(OR_UPPERRIGHT); slider_quality = new Slider(Point(text_quality->GetX() + maxTextSize + 7, 13), Size(100, 0), OR_HORZ, &quality, 0, 20); slider_quality->onValueChange.Connect(&ConfigureWMA::OnSetQuality, this); combo_bitrate = new ComboBox(Point(slider_quality->GetX(), 39), Size(100, 0)); combo_bitrate->AddEntry("32"); combo_bitrate->AddEntry("48"); combo_bitrate->AddEntry("64"); combo_bitrate->AddEntry("80"); combo_bitrate->AddEntry("96"); combo_bitrate->AddEntry("128"); combo_bitrate->AddEntry("160"); combo_bitrate->AddEntry("192"); combo_bitrate->SelectEntry(String::FromInt(config->GetIntValue(ConfigID, "Bitrate", 128))); group_settings->Add(check_vbr_setting); group_settings->Add(check_2pass_setting); group_settings->Add(text_quality); group_settings->Add(slider_quality); group_settings->Add(text_quality_value); group_settings->Add(text_bitrate); group_settings->Add(combo_bitrate); group_settings->Add(text_bitrate_kbps); Int maxSize = Math::Max(Math::Max(option_uncompressed->GetUnscaledTextWidth(), option_autoselect->GetUnscaledTextWidth()) + 21, Math::Max(option_format->GetWidth() + check_vbr->GetWidth() + check_2pass->GetWidth() + 16, check_vbr_setting->GetWidth() + maxTextSize + 120)); option_uncompressed->SetWidth(maxSize); option_autoselect->SetWidth(maxSize); combo_codec->SetWidth(maxSize - option_codec->GetWidth() - 8); combo_format->SetWidth(maxSize - option_codec->GetWidth() - 8); check_vbr->SetWidth((maxSize - option_format->GetWidth() - 16) / 2); check_2pass->SetX(check_vbr->GetX() + check_vbr->GetWidth() + 8 + (maxSize - option_format->GetWidth()) % 2); check_2pass->SetWidth(check_vbr->GetWidth()); slider_quality->SetWidth(maxSize - maxTextSize - text_quality->GetX() - text_bitrate_kbps->GetX() + 6); combo_bitrate->SetWidth(slider_quality->GetWidth()); group_codec->SetWidth(maxSize + 20); group_format->SetWidth(maxSize + 20); group_settings->SetWidth(maxSize + 20); Add(group_codec); Add(group_format); Add(group_settings); FillCodecComboBox(); if (config->GetIntValue(ConfigID, "Codec", -1) >= 0) combo_codec->SelectNthEntry(config->GetIntValue(ConfigID, "Codec", -1)); combo_codec->onSelectEntry.Connect(&ConfigureWMA::OnSelectCodec, this); OnSelectCodec(); combo_format->SelectNthEntry(config->GetIntValue(ConfigID, "CodecFormat", 0)); OnToggleFormat(); OnToggleCodec(); /* ToDo: Implement 2-pass encoding. * */ check_2pass->Deactivate(); check_2pass_setting->Deactivate(); SetSize(Size(maxSize + 34, 269)); } BoCA::ConfigureWMA::~ConfigureWMA() { DeleteObject(group_codec); DeleteObject(option_uncompressed); DeleteObject(option_codec); DeleteObject(combo_codec); DeleteObject(group_format); DeleteObject(option_autoselect); DeleteObject(option_format); DeleteObject(check_vbr); DeleteObject(check_2pass); DeleteObject(combo_format); DeleteObject(group_settings); DeleteObject(check_vbr_setting); DeleteObject(check_2pass_setting); DeleteObject(text_quality); DeleteObject(slider_quality); DeleteObject(text_quality_value); DeleteObject(text_bitrate); DeleteObject(combo_bitrate); DeleteObject(text_bitrate_kbps); profileManager->Release(); } Int BoCA::ConfigureWMA::SaveSettings() { Config *config = Config::Get(); config->SetIntValue(ConfigID, "Uncompressed", uncompressed); config->SetIntValue(ConfigID, "Codec", combo_codec->GetSelectedEntryNumber()); config->SetIntValue(ConfigID, "AutoSelectFormat", autoselect); config->SetIntValue(ConfigID, "CodecFormat", combo_format->GetSelectedEntryNumber()); if (autoselect) { config->SetIntValue(ConfigID, "EnableVBR", useVBRSetting); config->SetIntValue(ConfigID, "Enable2Pass", use2PassSetting); } else { config->SetIntValue(ConfigID, "EnableVBR", useVBR); config->SetIntValue(ConfigID, "Enable2Pass", use2Pass); } config->SetIntValue(ConfigID, "Bitrate", combo_bitrate->GetSelectedEntry()->GetText().ToInt()); config->SetIntValue(ConfigID, "Quality", quality * 5); return Success(); } Void BoCA::ConfigureWMA::FillCodecComboBox() { combo_codec->RemoveAllEntries(); IWMCodecInfo3 *codecInfo = NIL; HRESULT hr = profileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &codecInfo); if (hr == S_OK) { DWORD numCodecs = 0; hr = codecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &numCodecs); for (DWORD i = 0; i < numCodecs; i++) { DWORD nameLen = 0; hr = codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; hr = codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, name, &nameLen); combo_codec->AddEntry(name); if ( String(name).Contains("Windows Media Audio") && !String(name).Contains("Voice") && !String(name).Contains("Lossless") && !String(name).Contains("Pro")) combo_codec->SelectNthEntry(i); delete [] name; } codecInfo->Release(); } } Void BoCA::ConfigureWMA::FillFormatComboBox() { static UnsignedInt prevCodec = -1; static Bool prevUseVBR = False; static Bool prevUse2Pass = False; DWORD codecIndex = combo_codec->GetSelectedEntryNumber(); if (combo_format->Length() > 0 && codecIndex == prevCodec && useVBR == prevUseVBR && use2Pass == prevUse2Pass) return; prevCodec = codecIndex; prevUseVBR = useVBR; prevUse2Pass = use2Pass; combo_format->RemoveAllEntries(); IWMCodecInfo3 *codecInfo = NIL; HRESULT hr = profileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &codecInfo); if (hr == S_OK) { BOOL falseValue = FALSE; BOOL trueValue = TRUE; DWORD oneValue = 1; DWORD twoValue = 2; if (useVBR) hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &trueValue, sizeof(BOOL)); else hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &falseValue, sizeof(BOOL)); if (use2Pass) hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &twoValue, sizeof(DWORD)); else hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); DWORD numFormats = 0; hr = codecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); for (DWORD i = 0; i < numFormats; i++) { DWORD nameLen = 0; hr = codecInfo->GetCodecFormatDesc(WMMEDIATYPE_Audio, codecIndex, i, NIL, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; hr = codecInfo->GetCodecFormatDesc(WMMEDIATYPE_Audio, codecIndex, i, NIL, name, &nameLen); combo_format->AddEntry(name); delete [] name; } codecInfo->Release(); } combo_format->SelectNthEntry(1); combo_format->SelectNthEntry(0); } Void BoCA::ConfigureWMA::OnToggleCodec() { if (uncompressed) { combo_codec->Deactivate(); group_format->Deactivate(); group_settings->Deactivate(); } else { combo_codec->Activate(); group_format->Activate(); OnToggleFormat(); } } Void BoCA::ConfigureWMA::OnSelectCodec() { IWMCodecInfo3 *codecInfo = NIL; HRESULT hr = profileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &codecInfo); if (hr == S_OK) { DWORD codecIndex = combo_codec->GetSelectedEntryNumber(); supportCBR1Pass = False; supportVBR1Pass = False; supportCBR2Pass = False; supportVBR2Pass = False; /* Check if CBR is supported. */ { BOOL falseValue = FALSE; DWORD oneValue = 1; hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &falseValue, sizeof(BOOL)); hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); DWORD numFormats = 0; hr = codecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (hr == S_OK && numFormats > 0) { supportCBR1Pass = True; DWORD twoValue = 2; hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &twoValue, sizeof(DWORD)); if (hr == S_OK) { hr = codecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (hr == S_OK && numFormats > 0) supportCBR2Pass = True; } } } /* Check if VBR is supported. */ { WMT_ATTR_DATATYPE valueType = WMT_TYPE_BOOL; DWORD valueSize = sizeof(BOOL); BOOL isVBRSupported = FALSE; hr = codecInfo->GetCodecProp(WMMEDIATYPE_Audio, codecIndex, g_wszIsVBRSupported, &valueType, (BYTE *) &isVBRSupported, &valueSize); if (isVBRSupported) { BOOL trueValue = TRUE; DWORD oneValue = 1; hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &trueValue, sizeof(BOOL)); hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); if (hr == S_OK) { DWORD numFormats = 0; hr = codecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (hr == S_OK && numFormats > 0) { supportVBR1Pass = True; DWORD twoValue = 2; hr = codecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &twoValue, sizeof(DWORD)); if (hr == S_OK) { hr = codecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (hr == S_OK && numFormats > 0) supportVBR2Pass = True; } } } } } codecInfo->Release(); } if ( (supportVBR1Pass || supportVBR2Pass) && !(supportCBR1Pass || supportCBR2Pass)) { check_vbr->SetChecked(True); check_vbr_setting->SetChecked(True); } if (!(supportVBR1Pass || supportVBR2Pass) && (supportCBR1Pass || supportCBR2Pass)) { check_vbr->SetChecked(False); check_vbr_setting->SetChecked(False); } OnToggleVBR(); OnToggle2Pass(); OnToggleVBRSetting(); OnToggle2PassSetting(); OnToggleFormat(); if ((supportVBR1Pass || supportVBR2Pass) && (supportCBR1Pass || supportCBR2Pass)) check_vbr_setting->Activate(); else check_vbr_setting->Deactivate(); /* ToDo: Implement 2-pass encoding. * */ /* if ((supportCBR1Pass || supportVBR1Pass) && (supportCBR2Pass || supportVBR2Pass)) check_2pass_setting->Activate(); else check_2pass_setting->Deactivate(); */ } Void BoCA::ConfigureWMA::OnToggleFormat() { if (autoselect) { check_vbr->Deactivate(); check_2pass->Deactivate(); combo_format->Deactivate(); if (combo_codec->GetSelectedEntry()->GetText().Contains("Lossless")) group_settings->Deactivate(); else group_settings->Activate(); /* ToDo: Implement 2-pass encoding. * */ check_2pass_setting->Deactivate(); } else { combo_format->Activate(); group_settings->Deactivate(); OnToggleVBR(); OnToggle2Pass(); } } Void BoCA::ConfigureWMA::OnToggleVBR() { /* ToDo: Implement 2-pass encoding. * */ /* if (useVBR) { if ( supportVBR1Pass && supportVBR2Pass) check_2pass->Activate(); else check_2pass->Deactivate(); } else { if ( supportCBR1Pass && supportCBR2Pass) check_2pass->Activate(); else check_2pass->Deactivate(); } */ FillFormatComboBox(); } Void BoCA::ConfigureWMA::OnToggle2Pass() { if (use2Pass) { if ( supportCBR2Pass && supportVBR2Pass) check_vbr->Activate(); else check_vbr->Deactivate(); } else { if ( supportCBR1Pass && supportVBR1Pass) check_vbr->Activate(); else check_vbr->Deactivate(); } FillFormatComboBox(); } Void BoCA::ConfigureWMA::OnToggleVBRSetting() { if (useVBRSetting) { text_bitrate->Deactivate(); combo_bitrate->Deactivate(); text_bitrate_kbps->Deactivate(); text_quality->Activate(); slider_quality->Activate(); text_quality_value->Activate(); } else { text_bitrate->Activate(); combo_bitrate->Activate(); text_bitrate_kbps->Activate(); text_quality->Deactivate(); slider_quality->Deactivate(); text_quality_value->Deactivate(); } } Void BoCA::ConfigureWMA::OnToggle2PassSetting() { } Void BoCA::ConfigureWMA::OnSetQuality() { text_quality_value->SetText(String::FromInt(quality * 5)); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/config.h000077500000000000000000000041561516712004000242030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_WMACONFIG #define H_WMACONFIG #include #include #include "dllinterface.h" using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureWMA : public ConfigLayer { private: IWMProfileManager *profileManager; GroupBox *group_codec; OptionBox *option_uncompressed; OptionBox *option_codec; ComboBox *combo_codec; GroupBox *group_format; OptionBox *option_autoselect; OptionBox *option_format; CheckBox *check_vbr; CheckBox *check_2pass; ComboBox *combo_format; GroupBox *group_settings; CheckBox *check_vbr_setting; CheckBox *check_2pass_setting; Text *text_quality; Slider *slider_quality; Text *text_quality_value; Text *text_bitrate; ComboBox *combo_bitrate; Text *text_bitrate_kbps; Bool supportCBR1Pass; Bool supportVBR1Pass; Bool supportCBR2Pass; Bool supportVBR2Pass; Int uncompressed; Int autoselect; Bool useVBR; Bool use2Pass; Bool useVBRSetting; Bool use2PassSetting; Int quality; Void FillCodecComboBox(); Void FillFormatComboBox(); public: static const String ConfigID; ConfigureWMA(); ~ConfigureWMA(); Int SaveSettings(); slots: Void OnToggleCodec(); Void OnSelectCodec(); Void OnToggleFormat(); Void OnToggleVBR(); Void OnToggle2Pass(); Void OnToggleVBRSetting(); Void OnToggle2PassSetting(); Void OnSetQuality(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/dllinterface.cpp000077500000000000000000000026301516712004000257200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" WMCREATEWRITER ex_WMCreateWriter = NIL; WMCREATEWRITERFILESINK ex_WMCreateWriterFileSink = NIL; WMCREATEPROFILEMANAGER ex_WMCreateProfileManager = NIL; DynamicLoader *wmvcoredll = NIL; Bool LoadWMVCoreDLL() { wmvcoredll = new DynamicLoader("WMVCore"); ex_WMCreateWriter = (WMCREATEWRITER) wmvcoredll->GetFunctionAddress("WMCreateWriter"); ex_WMCreateWriterFileSink = (WMCREATEWRITERFILESINK) wmvcoredll->GetFunctionAddress("WMCreateWriterFileSink"); ex_WMCreateProfileManager = (WMCREATEPROFILEMANAGER) wmvcoredll->GetFunctionAddress("WMCreateProfileManager"); if (ex_WMCreateWriter == NIL || ex_WMCreateWriterFileSink == NIL || ex_WMCreateProfileManager == NIL) { FreeWMVCoreDLL(); return False; } return True; } Void FreeWMVCoreDLL() { Object::DeleteObject(wmvcoredll); wmvcoredll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/dllinterface.h000077500000000000000000000022441516712004000253660ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *wmvcoredll; Bool LoadWMVCoreDLL(); Void FreeWMVCoreDLL(); typedef HRESULT (STDMETHODCALLTYPE *WMCREATEWRITER) (IUnknown *, IWMWriter **); typedef HRESULT (STDMETHODCALLTYPE *WMCREATEWRITERFILESINK) (IWMWriterFileSink **); typedef HRESULT (STDMETHODCALLTYPE *WMCREATEPROFILEMANAGER) (IWMProfileManager **); extern WMCREATEWRITER ex_WMCreateWriter; extern WMCREATEWRITERFILESINK ex_WMCreateWriterFileSink; extern WMCREATEPROFILEMANAGER ex_WMCreateProfileManager; boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/wma.cpp000066400000000000000000000571371516712004000240610ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "wma.h" #include "config.h" const String &BoCA::EncoderWMA::GetComponentSpecs() { static String componentSpecs; if (wmvcoredll != NIL) { componentSpecs = " \ \ \ \ Windows Media Audio Encoder \ 1.0 \ wma-enc \ encoder \ \ "; Initialize(); IWMProfileManager *profileManager = NIL; IWMCodecInfo3 *codecInfo = NIL; ex_WMCreateProfileManager(&profileManager); if (SUCCEEDED(profileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &codecInfo))) { DWORD numCodecs = 0; codecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &numCodecs); for (DWORD i = 0; i < numCodecs; i++) { DWORD nameLen = 0; codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, name, &nameLen); componentSpecs.Append(" \ \ \ ").Append(name).Append(" \ wma \ WMA Metadata \ \ \ "); delete [] name; } codecInfo->Release(); } profileManager->Release(); Cleanup(); componentSpecs.Append(" \ \ \ \ \ \ \ \ \ \ \ \ \ 0 \ 100 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadWMVCoreDLL(); /* Register initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::EncoderWMA::Initialize); engine->onCleanup.Connect(&BoCA::EncoderWMA::Cleanup); } } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::EncoderWMA::Initialize); engine->onCleanup.Disconnect(&BoCA::EncoderWMA::Cleanup); } FreeWMVCoreDLL(); } Void BoCA::EncoderWMA::Initialize() { /* Init the Microsoft COM library. */ CoInitialize(NIL); } Void BoCA::EncoderWMA::Cleanup() { /* Uninit the Microsoft COM library. */ CoUninitialize(); } BoCA::EncoderWMA::EncoderWMA() { configLayer = NIL; config = NIL; writer = NIL; writerAdvanced = NIL; writerFileSink = NIL; profileManager = NIL; profile = NIL; streamConfig = NIL; samplesWritten = 0; } BoCA::EncoderWMA::~EncoderWMA() { if (config != NIL) Config::Free(config); if (configLayer != NIL) Object::DeleteObject(configLayer); } Int BoCA::EncoderWMA::GetNumberOfPasses() const { /* 2-pass encoding is not supported, yet. */ return 1; } Bool BoCA::EncoderWMA::IsLossless() const { const Config *config = GetConfiguration(); if (config->GetIntValue(ConfigureWMA::ConfigID, "Uncompressed", False)) return True; /* Create profile manager and get codec info. */ IWMProfileManager *pProfileManager = NIL; IWMCodecInfo3 *pCodecInfo = NIL; if (FAILED(ex_WMCreateProfileManager(&pProfileManager))) return False; if (FAILED(pProfileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &pCodecInfo))) { pProfileManager->Release(); return False; } Int defaultCodec = GetDefaultCodec(pCodecInfo); /* Get and check codec name. */ DWORD nameLen = 0; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, config->GetIntValue(ConfigureWMA::ConfigID, "Codec", defaultCodec), NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, config->GetIntValue(ConfigureWMA::ConfigID, "Codec", defaultCodec), name, &nameLen); Bool result = False; if (String(name).Contains("Lossless")) result = True; delete [] name; /* Release profile manager and codec info. */ pCodecInfo->Release(); pProfileManager->Release(); return result; } Bool BoCA::EncoderWMA::Activate() { /* Get configuration. */ config = Config::Copy(GetConfiguration()); ConvertArguments(config); /* Close output file as it will be written directly by Windows Media. */ driver->Close(); /* Create WMA writer object. */ if (FAILED(ex_WMCreateWriter(NIL, &writer))) return False; if (FAILED(writer->QueryInterface(IID_IWMWriterAdvanced, (void **) &writerAdvanced))) { writer->Release(); return False; } /* A temporary file is needed if the path exceeds 255 characters. */ String outputFile = Directory::MakeExtendedPath(File(track.outputFile)); if (track.outputFile.Length() > 255) outputFile = Utilities::GetNonUnicodeTempFileName(track.outputFile); /* Create and open file sink. */ ex_WMCreateWriterFileSink(&writerFileSink); writerFileSink->Open(outputFile); writerAdvanced->AddSink(writerFileSink); /* Create profile manager. */ ex_WMCreateProfileManager(&profileManager); profileManager->CreateEmptyProfile(WMT_VER_9_0, &profile); /* Query codec info. */ IWMCodecInfo3 *pCodecInfo = NIL; profileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &pCodecInfo); Int codec = config->GetIntValue(ConfigureWMA::ConfigID, "Codec", GetDefaultCodec(pCodecInfo)); Int codecFormat = config->GetIntValue(ConfigureWMA::ConfigID, "CodecFormat", 0); Bool uncompressedFormat = config->GetIntValue(ConfigureWMA::ConfigID, "Uncompressed", False); Bool autoSelectFormat = config->GetIntValue(ConfigureWMA::ConfigID, "AutoSelectFormat", True); Bool enableVBR = config->GetIntValue(ConfigureWMA::ConfigID, "EnableVBR", True); Bool enable2Pass = config->GetIntValue(ConfigureWMA::ConfigID, "Enable2Pass", False); DWORD numCodecs = 0; pCodecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &numCodecs); if (codec >= (Int) numCodecs) { codec = GetDefaultCodec(pCodecInfo); autoSelectFormat = True; } if (codec == -1 || numCodecs == 0) uncompressedFormat = True; /* Create stream configuration. */ if (uncompressedFormat) { profile->CreateNewStream(WMMEDIATYPE_Audio, &streamConfig); } else if (!autoSelectFormat) { BOOL falseValue = FALSE; BOOL trueValue = TRUE; DWORD oneValue = 1; DWORD twoValue = 2; if (enableVBR) pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codec, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &trueValue, sizeof(BOOL)); else pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codec, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &falseValue, sizeof(BOOL)); if (enable2Pass) pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codec, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &twoValue, sizeof(DWORD)); else pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codec, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio, codec, codecFormat, &streamConfig); } else { streamConfig = GetBestCodecFormat(pCodecInfo, codec, track.GetFormat()); } /* Check stream configuration. */ if (!streamConfig) { errorState = True; errorString = "Could not create codec configuration."; } /* Set up profile and writer. */ if (!errorState) { streamConfig->SetStreamNumber(1); streamConfig->SetStreamName(String("Audio")); streamConfig->SetConnectionName(String("Audio")); profile->AddStream(streamConfig); writer->SetProfile(profile); if (SetInputFormat(writer, track.GetFormat()) == False) { errorState = True; errorString = "Incompatible sample format."; } } pCodecInfo->Release(); /* Start writing output file. */ if (!errorState) { if (FAILED(writer->BeginWriting())) { errorState = True; errorString = "Could not initialize encoder."; } } /* Release objects in case of an error. */ if (errorState) { if (streamConfig) streamConfig->Release(); profile->Release(); profileManager->Release(); writerFileSink->Release(); writerAdvanced->Release(); writer->Release(); } return !errorState; } Bool BoCA::EncoderWMA::Deactivate() { String outputFile = track.outputFile; if (track.outputFile.Length() > 255) outputFile = Utilities::GetNonUnicodeTempFileName(track.outputFile); /* Delete output file in case of an error. */ if (errorState) { File(outputFile).Delete(); return True; } /* Finish writing output file. */ HRESULT hr = writer->EndWriting(); writerAdvanced->RemoveSink(writerFileSink); streamConfig->Release(); profile->Release(); profileManager->Release(); writerFileSink->Release(); writerAdvanced->Release(); writer->Release(); if (FAILED(hr)) { File(outputFile).Delete(); return False; } /* Write metadata to file. */ if (config->GetIntValue("Tags", "EnableWMAMetadata", True)) { const Info &info = track.GetInfo(); if (info.HasBasicInfo() || (track.tracks.Length() > 0 && config->GetIntValue("Tags", "WriteChapters", True))) { AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("wma-tag"); if (tagger != NIL) { tagger->SetConfiguration(config); tagger->RenderStreamInfo(outputFile, track); boca.DeleteComponent(tagger); } } } /* Move actual output file in place. */ if (outputFile != track.outputFile) { File(track.outputFile).Delete(); File(outputFile).Move(track.outputFile); } return True; } Int BoCA::EncoderWMA::WriteData(Buffer &data) { INSSBuffer *pSample = NIL; if (FAILED(writer->AllocateSample(data.Size(), &pSample))) return -1; BYTE *buffer = NIL; if (!FAILED(pSample->GetBuffer(&buffer))) { memcpy(buffer, data, data.Size()); pSample->SetLength(data.Size()); const Format &format = track.GetFormat(); QWORD cnsSampleTime = samplesWritten * 10000000 / format.channels / format.rate; HRESULT hr = writer->WriteSample(0, cnsSampleTime, WM_SF_CLEANPOINT, pSample); pSample->Release(); if (FAILED(hr)) return -1; samplesWritten += data.Size() / (format.bits / 8); } return data.Size(); } Bool BoCA::EncoderWMA::NextPass() { /* 2-pass encoding is not supported, yet. */ return False; } Bool BoCA::EncoderWMA::SetOutputFormat(Int n) { Config *config = Config::Get(); config->SetIntValue(ConfigureWMA::ConfigID, "Uncompressed", False); config->SetIntValue(ConfigureWMA::ConfigID, "Codec", n); return True; } Bool BoCA::EncoderWMA::ConvertArguments(Config *config) { if (!config->GetIntValue("Settings", "EnableConsole", False)) return False; static const String encoderID = "wma-enc"; /* Create codec info object. */ IWMProfileManager *pProfileManager = NIL; IWMCodecInfo3 *pCodecInfo = NIL; if (FAILED(ex_WMCreateProfileManager(&pProfileManager))) return False; if (FAILED(pProfileManager->QueryInterface(IID_IWMCodecInfo3, (void **) &pCodecInfo))) { pProfileManager->Release(); return False; } /* Set default values. */ if (!config->GetIntValue("Settings", "UserSpecifiedConfig", False)) { config->SetIntValue(ConfigureWMA::ConfigID, "Uncompressed", False); config->SetIntValue(ConfigureWMA::ConfigID, "AutoSelectFormat", True); config->SetIntValue(ConfigureWMA::ConfigID, "EnableVBR", True); config->SetIntValue(ConfigureWMA::ConfigID, "Bitrate", 128); config->SetIntValue(ConfigureWMA::ConfigID, "Quality", 90); config->SetIntValue(ConfigureWMA::ConfigID, "Codec", GetDefaultCodec(pCodecInfo)); } /* Get number of codecs. */ DWORD numCodecs = 0; pCodecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &numCodecs); /* Get command line settings. */ Bool useCBR = config->GetIntValue(encoderID, "Use CBR mode", !config->GetIntValue(ConfigureWMA::ConfigID, "EnableVBR", True)); Int bitrate = config->GetIntValue(ConfigureWMA::ConfigID, "Bitrate", 128); Int quality = config->GetIntValue(ConfigureWMA::ConfigID, "Quality", 90); Int format = config->GetIntValue(ConfigureWMA::ConfigID, "Codec", GetDefaultCodec(pCodecInfo)); String formatName = config->GetIntValue(ConfigureWMA::ConfigID, "Uncompressed", False) ? "uncompressed" : "standard"; if (formatName != "uncompressed") { DWORD nameLen = 0; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, format, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, format, name, &nameLen); if (String(name).Contains("Pro")) formatName = "pro"; else if (String(name).Contains("Lossless")) formatName = "lossless"; else if (String(name).Contains("Voice")) formatName = "voice"; } if (config->GetIntValue(encoderID, "Set CBR bitrate", False)) bitrate = config->GetIntValue(encoderID, "CBR bitrate", bitrate); if (config->GetIntValue(encoderID, "Set VBR quality", False)) quality = config->GetIntValue(encoderID, "VBR quality", quality); if (config->GetIntValue(encoderID, "Set Target format", False)) formatName = config->GetStringValue(encoderID, "Target format", formatName).ToLower(); /* Set configuration values. */ config->SetIntValue(ConfigureWMA::ConfigID, "Uncompressed", formatName == "uncompressed"); config->SetIntValue(ConfigureWMA::ConfigID, "EnableVBR", !useCBR); config->SetIntValue(ConfigureWMA::ConfigID, "Bitrate", Math::Max(32, Math::Min(192, bitrate))); config->SetIntValue(ConfigureWMA::ConfigID, "Quality", Math::Max(0, Math::Min(100, quality))); for (DWORD i = 0; i < numCodecs; i++) { DWORD nameLen = 0; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, i, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; pCodecInfo->GetCodecName(WMMEDIATYPE_Audio, i, name, &nameLen); if (formatName == "pro" && String(name).Contains("Pro")) format = i; else if (formatName == "lossless" && String(name).Contains("Lossless")) format = i; else if (formatName == "voice" && String(name).Contains("Voice")) format = i; delete [] name; } config->SetIntValue(ConfigureWMA::ConfigID, "Codec", format); /* Release codec info object. */ pCodecInfo->Release(); pProfileManager->Release(); return True; } ConfigLayer *BoCA::EncoderWMA::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureWMA(); return configLayer; } /* Select default codec to be used when no codec is set. */ Int BoCA::EncoderWMA::GetDefaultCodec(IWMCodecInfo3 *codecInfo) { Int index = -1; DWORD numCodecs = 0; HRESULT hr = codecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &numCodecs); for (DWORD i = 0; i < numCodecs; i++) { DWORD nameLen = 0; codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, NIL, &nameLen); WCHAR *name = new WCHAR [nameLen]; codecInfo->GetCodecName(WMMEDIATYPE_Audio, i, name, &nameLen); if ( String(name).Contains("Windows Media Audio") && !String(name).Contains("Voice") && !String(name).Contains("Lossless") && !String(name).Contains("Pro")) index = i; delete [] name; } if (hr != S_OK) index = -1; return index; } /* This method will return the format best matching * our requirements for a specified codec. */ IWMStreamConfig *BoCA::EncoderWMA::GetBestCodecFormat(IWMCodecInfo3 *pCodecInfo, DWORD codecIndex, const Format &format) const { BOOL falseValue = FALSE; BOOL trueValue = TRUE; DWORD oneValue = 1; DWORD twoValue = 2; Bool supportCBR = False; Bool supportVBR = False; Bool support1Pass = True; Bool support2Pass = False; /* Check if CBR is supported. */ { pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &falseValue, sizeof(BOOL)); pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); DWORD numFormats = 0; HRESULT hr = pCodecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (!FAILED(hr) && numFormats > 0) supportCBR = True; } /* Check if VBR is supported. */ { WMT_ATTR_DATATYPE valueType = WMT_TYPE_BOOL; DWORD valueSize = sizeof(BOOL); BOOL isVBRSupported = FALSE; pCodecInfo->GetCodecProp(WMMEDIATYPE_Audio, codecIndex, g_wszIsVBRSupported, &valueType, (BYTE *) &isVBRSupported, &valueSize); if (isVBRSupported) { pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &trueValue, sizeof(BOOL)); pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); DWORD numFormats = 0; HRESULT hr = pCodecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); if (!FAILED(hr) && numFormats > 0) supportVBR = True; } } if (supportVBR && (!supportCBR || config->GetIntValue(ConfigureWMA::ConfigID, "EnableVBR", True))) pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &trueValue, sizeof(BOOL)); else pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE *) &falseValue, sizeof(BOOL)); if (support2Pass && (!support1Pass || config->GetIntValue(ConfigureWMA::ConfigID, "Enable2Pass", False))) pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &twoValue, sizeof(DWORD)); else pCodecInfo->SetCodecEnumerationSetting(WMMEDIATYPE_Audio, codecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE *) &oneValue, sizeof(DWORD)); IWMStreamConfig *result = NIL; Int targetBitrate = config->GetIntValue(ConfigureWMA::ConfigID, "Bitrate", 128) * 1000; Int targetQuality = config->GetIntValue(ConfigureWMA::ConfigID, "Quality", 90); Bool useVBR = (supportVBR && config->GetIntValue(ConfigureWMA::ConfigID, "EnableVBR", True)); DWORD bestMatchBitrate = 100000000; DWORD bestMatchQuality = 100000000; DWORD bestMatchSampleRate = 100000000; DWORD bestMatchBits = 100000000; DWORD bestMatchChannels = 100000000; DWORD numFormats = 0; pCodecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio, codecIndex, &numFormats); for (DWORD i = 0; i < numFormats; i++) { IWMStreamConfig *pStreamConfig = NIL; IWMMediaProps *pMediaProps = NIL; pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio, codecIndex, i, &pStreamConfig); pStreamConfig->QueryInterface(IID_IWMMediaProps, (void **) &pMediaProps); DWORD formatBitrate = 0; DWORD formatQuality = 0; pStreamConfig->GetBitrate(&formatBitrate); DWORD mediaTypeSize = 0; pMediaProps->GetMediaType(NIL, &mediaTypeSize); WM_MEDIA_TYPE *mediaType = (WM_MEDIA_TYPE *) new BYTE [mediaTypeSize]; pMediaProps->GetMediaType(mediaType, &mediaTypeSize); if (mediaType->majortype == WMMEDIATYPE_Audio && mediaType->formattype == WMFORMAT_WaveFormatEx) { Bool newBestMatch = False; WAVEFORMATEX *waveFormat = (WAVEFORMATEX *) mediaType->pbFormat; formatQuality = waveFormat->nAvgBytesPerSec & 255; if (Math::Abs(Int(waveFormat->nChannels - format.channels)) < Math::Abs(Int(bestMatchChannels - format.channels))) newBestMatch = True; else if (Math::Abs(Int(waveFormat->nChannels - format.channels)) == Math::Abs(Int(bestMatchChannels - format.channels)) && Math::Abs(Int(waveFormat->nSamplesPerSec - (Unsigned) format.rate)) < Math::Abs(Int(bestMatchSampleRate - (Unsigned) format.rate))) newBestMatch = True; else if (Math::Abs(Int(waveFormat->nChannels - format.channels)) == Math::Abs(Int(bestMatchChannels - format.channels)) && Math::Abs(Int(waveFormat->nSamplesPerSec - (Unsigned) format.rate)) == Math::Abs(Int(bestMatchSampleRate - (Unsigned) format.rate)) && Math::Abs(Int(waveFormat->wBitsPerSample - format.bits)) < Math::Abs(Int(bestMatchBits - format.bits))) newBestMatch = True; else if (Math::Abs(Int(waveFormat->nChannels - format.channels)) == Math::Abs(Int(bestMatchChannels - format.channels)) && Math::Abs(Int(waveFormat->nSamplesPerSec - (Unsigned) format.rate)) == Math::Abs(Int(bestMatchSampleRate - (Unsigned) format.rate)) && Math::Abs(Int(waveFormat->wBitsPerSample - format.bits)) == Math::Abs(Int(bestMatchBits - format.bits)) && ((!useVBR && Math::Abs(Int(formatBitrate - targetBitrate)) < Math::Abs(Int(bestMatchBitrate - targetBitrate))) || ( useVBR && Math::Abs(Int(formatQuality - targetQuality)) < Math::Abs(Int(bestMatchQuality - targetQuality))))) newBestMatch = True; if (newBestMatch) { if (result != NIL) result->Release(); result = pStreamConfig; result->AddRef(); bestMatchChannels = waveFormat->nChannels; bestMatchBits = waveFormat->wBitsPerSample; bestMatchSampleRate = waveFormat->nSamplesPerSec; bestMatchBitrate = formatBitrate; bestMatchQuality = formatQuality; } } delete [] mediaType; pMediaProps->Release(); pStreamConfig->Release(); } return result; } /* This method will set the input format to the * specified format. */ Bool BoCA::EncoderWMA::SetInputFormat(IWMWriter *pWriter, const Format &format) { WM_MEDIA_TYPE mediaType; mediaType.majortype = WMMEDIATYPE_Audio; mediaType.subtype = WMMEDIASUBTYPE_PCM; mediaType.bFixedSizeSamples = True; mediaType.bTemporalCompression = False; mediaType.lSampleSize = (format.bits / 8) * format.channels; mediaType.formattype = WMFORMAT_WaveFormatEx; mediaType.pUnk = NIL; WAVEFORMATEX waveFormat; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = format.channels; waveFormat.nSamplesPerSec = format.rate; waveFormat.nAvgBytesPerSec = format.rate * (format.bits / 8) * format.channels; waveFormat.nBlockAlign = (format.bits / 8) * format.channels; waveFormat.wBitsPerSample = format.bits; waveFormat.cbSize = 0; mediaType.cbFormat = sizeof(waveFormat); mediaType.pbFormat = (BYTE *) &waveFormat; IWMInputMediaProps *pInputProps = NIL; if (!FAILED(pWriter->GetInputProps(0, &pInputProps))) { pInputProps->SetMediaType(&mediaType); HRESULT hr = writer->SetInputProps(0, pInputProps); pInputProps->Release(); return !FAILED(hr); } return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/encoder/wma/wma.h000066400000000000000000000034171516712004000235160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(EncoderWMA) namespace BoCA { class EncoderWMA : public CS::EncoderComponent { private: ConfigLayer *configLayer; Config *config; IWMWriter *writer; IWMWriterAdvanced *writerAdvanced; IWMWriterFileSink *writerFileSink; IWMProfileManager *profileManager; IWMProfile *profile; IWMStreamConfig *streamConfig; Int64 samplesWritten; Buffer samplesBuffer; static Int GetDefaultCodec(IWMCodecInfo3 *); IWMStreamConfig *GetBestCodecFormat(IWMCodecInfo3 *, DWORD, const Format &) const; Bool SetInputFormat(IWMWriter *, const Format &); static Bool ConvertArguments(Config *); public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); EncoderWMA(); ~EncoderWMA(); Int GetNumberOfPasses() const; Bool IsLossless() const; Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool NextPass(); Bool SetOutputFormat(Int); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_ENCODER_COMPONENT(EncoderWMA) BoCA_END_COMPONENT(EncoderWMA) boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/000077500000000000000000000000001516712004000223655ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/Makefile000077500000000000000000000012661516712004000240350ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = statustime .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/000077500000000000000000000000001516712004000245675ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/Makefile000077500000000000000000000011701516712004000262310ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = statustime TYPE = extension VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = layer.o lengthdisplay.o lengthstatus.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/layer.cpp000077500000000000000000000220111516712004000264060ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "layer.h" BoCA::LayerLengthStatus::LayerLengthStatus() { String resourcesPath; #ifndef __WIN32__ if (Directory(S::System::System::GetResourcesDirectory().Append("freac")).Exists()) resourcesPath = S::System::System::GetResourcesDirectory().Append("freac").Append(Directory::GetDirectoryDelimiter()); #endif tracks.EnableLocking(); tracks_selected.EnableLocking(); tracks_unselected.EnableLocking(); seconds = 0; approx = 0; unknown = 0; seconds_selected = 0; approx_selected = 0; unknown_selected = 0; seconds_unselected = 0; approx_unselected = 0; unknown_unselected = 0; display_selected = new LengthDisplay(ImageLoader::Load(String(resourcesPath).Append("icons/select/select-all.png"))); display_unselected = new LengthDisplay(ImageLoader::Load(String(resourcesPath).Append("icons/select/select-none.png"))); display_all = new LengthDisplay(ImageLoader::Load(String(resourcesPath).Append("icons/select/select-toggle.png"))); Add(display_selected); Add(display_unselected); Add(display_all); UpdateLengthDisplays(); SetOrientation(OR_UPPERRIGHT); /* Connect slots. */ JobList *joblist = JobList::Get(); joblist->onApplicationAddTrack.Connect(&LayerLengthStatus::OnApplicationAddTrack, this); joblist->onApplicationModifyTrack.Connect(&LayerLengthStatus::OnApplicationModifyTrack, this); joblist->onApplicationRemoveTrack.Connect(&LayerLengthStatus::OnApplicationRemoveTrack, this); joblist->onApplicationMarkTrack.Connect(&LayerLengthStatus::OnApplicationMarkTrack, this); joblist->onApplicationUnmarkTrack.Connect(&LayerLengthStatus::OnApplicationUnmarkTrack, this); joblist->onApplicationRemoveAllTracks.Connect(&LayerLengthStatus::OnApplicationRemoveAllTracks, this); } BoCA::LayerLengthStatus::~LayerLengthStatus() { /* Disconnect slots. */ JobList *joblist = JobList::Get(); joblist->onApplicationAddTrack.Disconnect(&LayerLengthStatus::OnApplicationAddTrack, this); joblist->onApplicationModifyTrack.Disconnect(&LayerLengthStatus::OnApplicationModifyTrack, this); joblist->onApplicationRemoveTrack.Disconnect(&LayerLengthStatus::OnApplicationRemoveTrack, this); joblist->onApplicationMarkTrack.Disconnect(&LayerLengthStatus::OnApplicationMarkTrack, this); joblist->onApplicationUnmarkTrack.Disconnect(&LayerLengthStatus::OnApplicationUnmarkTrack, this); joblist->onApplicationRemoveAllTracks.Disconnect(&LayerLengthStatus::OnApplicationRemoveAllTracks, this); DeleteObject(display_selected); DeleteObject(display_unselected); DeleteObject(display_all); } Void BoCA::LayerLengthStatus::UpdateLengthDisplays() { /* Update displayed values. */ Surface *surface = (IsVisible() ? GetDrawSurface() : NIL); if (surface) surface->StartPaint(container->GetVisibleArea()); display_selected->SetText(GetLengthString(seconds_selected, approx_selected, unknown_selected)); display_unselected->SetText(GetLengthString(seconds_unselected, approx_unselected, unknown_unselected)); display_all->SetText(GetLengthString(seconds, approx, unknown)); display_selected->SetPosition(Point(0, 0)); display_unselected->SetPosition(Point(display_selected->GetWidth() + 3, 0)); display_all->SetPosition(Point(display_selected->GetWidth() + display_unselected->GetWidth() + 6, 0)); SetSize(Size(display_all->GetWidth() + display_selected->GetWidth() + display_unselected->GetWidth() + 6, display_all->GetHeight())); if (surface) { container->Paint(SP_UPDATE); surface->EndPaint(); } } Void BoCA::LayerLengthStatus::AddTrack(const Track &track, Int64 &seconds, Int &approx, Int &unknown) { const Format &format = track.GetFormat(); if (track.length >= 0 && format.rate > 0) { seconds += Math::Round(Float(track.length) / format.rate); } else if (track.approxLength >= 0 && format.rate > 0) { seconds += Math::Round(Float(track.approxLength) / format.rate); approx++; } else { unknown++; } } Void BoCA::LayerLengthStatus::RemoveTrack(const Track &track, Int64 &seconds, Int &approx, Int &unknown) { const Format &format = track.GetFormat(); if (track.length >= 0 && format.rate > 0) { seconds -= Math::Round(Float(track.length) / format.rate); } else if (track.approxLength >= 0 && format.rate > 0) { seconds -= Math::Round(Float(track.approxLength) / format.rate); approx--; } else { unknown--; } } const String &BoCA::LayerLengthStatus::GetLengthString(Int64 seconds, Int approx, Int unknown) { static String string; static wchar_t sign[2] = { 0x2248, 0 }; string = String(unknown ? "> " : NIL).Append(approx ? String(sign).Append(" ") : String()) .Append(seconds >= 3600 ? String(seconds / 3600 < 10 ? "0" : NIL).Append(String::FromInt(seconds / 3600 )).Append(":") : String()) .Append(seconds % 3600 / 60 < 10 ? "0" : NIL).Append(String::FromInt(seconds % 3600 / 60)).Append(":") .Append(seconds % 3600 % 60 < 10 ? "0" : NIL).Append(String::FromInt(seconds % 3600 % 60)); return string; } /* Called when a track is added to the application joblist. * ---- * Adds entries to tracks. */ Void BoCA::LayerLengthStatus::OnApplicationAddTrack(const Track &track) { tracks.Add(track, track.GetTrackID()); tracks_selected.Add(track, track.GetTrackID()); AddTrack(track, seconds, approx, unknown); AddTrack(track, seconds_selected, approx_selected, unknown_selected); UpdateLengthDisplays(); } /* Called when a track is modified in the application joblist. * ---- * Updates track entries. */ Void BoCA::LayerLengthStatus::OnApplicationModifyTrack(const Track &track) { const Track &knownTrack = tracks.Get(track.GetTrackID()); RemoveTrack(knownTrack, seconds, approx, unknown); AddTrack(track, seconds, approx, unknown); tracks.Remove(track.GetTrackID()); tracks.Add(track, track.GetTrackID()); if (tracks_selected.Get(track.GetTrackID()) != NIL) { const Track &knownTrack = tracks_selected.Get(track.GetTrackID()); RemoveTrack(knownTrack, seconds_selected, approx_selected, unknown_selected); AddTrack(track, seconds_selected, approx_selected, unknown_selected); tracks_selected.Remove(track.GetTrackID()); tracks_selected.Add(track, track.GetTrackID()); } else if (tracks_unselected.Remove(track.GetTrackID()) != NIL) { const Track &knownTrack = tracks_unselected.Get(track.GetTrackID()); RemoveTrack(knownTrack, seconds_unselected, approx_unselected, unknown_unselected); AddTrack(track, seconds_unselected, approx_unselected, unknown_unselected); tracks_unselected.Remove(track.GetTrackID()); tracks_unselected.Add(track, track.GetTrackID()); } UpdateLengthDisplays(); } /* Called when a track is removed from the application joblist. * ---- * Removes our corresponding entry from tracks. */ Void BoCA::LayerLengthStatus::OnApplicationRemoveTrack(const Track &track) { tracks.Remove(track.GetTrackID()); RemoveTrack(track, seconds, approx, unknown); if (tracks_selected.Remove(track.GetTrackID())) RemoveTrack(track, seconds_selected, approx_selected, unknown_selected); else if (tracks_unselected.Remove(track.GetTrackID())) RemoveTrack(track, seconds_unselected, approx_unselected, unknown_unselected); UpdateLengthDisplays(); } /* Called when a track is marked by the application. * ---- * Adds the track to tracks_selected, removes it from tracks_unselected. */ Void BoCA::LayerLengthStatus::OnApplicationMarkTrack(const Track &track) { tracks_selected.Add(track, track.GetTrackID()); tracks_unselected.Remove(track.GetTrackID()); AddTrack(track, seconds_selected, approx_selected, unknown_selected); RemoveTrack(track, seconds_unselected, approx_unselected, unknown_unselected); UpdateLengthDisplays(); } /* Called when a track is unmarked in the application joblist. * ---- * Adds the track to tracks_unselected, removes it from tracks_selected. */ Void BoCA::LayerLengthStatus::OnApplicationUnmarkTrack(const Track &track) { tracks_unselected.Add(track, track.GetTrackID()); tracks_selected.Remove(track.GetTrackID()); AddTrack(track, seconds_unselected, approx_unselected, unknown_unselected); RemoveTrack(track, seconds_selected, approx_selected, unknown_selected); UpdateLengthDisplays(); } /* Called when all track are removed from the application joblist at once. * ---- * Clears all internal arrays. */ Void BoCA::LayerLengthStatus::OnApplicationRemoveAllTracks() { tracks.RemoveAll(); tracks_selected.RemoveAll(); tracks_unselected.RemoveAll(); seconds = 0; approx = 0; unknown = 0; seconds_selected = 0; approx_selected = 0; unknown_selected = 0; seconds_unselected = 0; approx_unselected = 0; unknown_unselected = 0; UpdateLengthDisplays(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/layer.h000077500000000000000000000035521516712004000260640ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_LENGTHSTATUS_LAYER #define H_LENGTHSTATUS_LAYER #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; #include "lengthdisplay.h" namespace BoCA { class LayerLengthStatus : public Layer { private: Array tracks; Int64 seconds; Int approx; Int unknown; Array tracks_selected; Int64 seconds_selected; Int approx_selected; Int unknown_selected; Array tracks_unselected; Int64 seconds_unselected; Int approx_unselected; Int unknown_unselected; LengthDisplay *display_all; LengthDisplay *display_selected; LengthDisplay *display_unselected; Void UpdateLengthDisplays(); Void AddTrack(const Track &, Int64 &, Int &, Int &); Void RemoveTrack(const Track &, Int64 &, Int &, Int &); const String &GetLengthString(Int64, Int, Int); slots: Void OnApplicationAddTrack(const Track &); Void OnApplicationModifyTrack(const Track &); Void OnApplicationRemoveTrack(const Track &); Void OnApplicationMarkTrack(const Track &); Void OnApplicationUnmarkTrack(const Track &); Void OnApplicationRemoveAllTracks(); public: LayerLengthStatus(); ~LayerLengthStatus(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/lengthdisplay.cpp000077500000000000000000000044041516712004000301470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "lengthdisplay.h" BoCA::LengthDisplay::LengthDisplay(const Bitmap &iBitmap) : Widget(Point(0, 0), Size(42, 14)) { bitmap = iBitmap; } BoCA::LengthDisplay::~LengthDisplay() { } Int BoCA::LengthDisplay::Paint(Int message) { if (!IsRegistered()) return Error(); if (!IsVisible()) return Success(); switch (message) { case SP_PAINT: { Surface *surface = container->GetDrawSurface(); Rect frame = Rect(GetRealPosition(), GetRealSize()); surface->Box(frame, GetBackgroundColor(), Rect::Filled); surface->Frame(frame, FRAME_DOWN); /* Draw bitmap. */ Size bitmapSize = bitmap.GetSize(); Size scaledSize = bitmapSize / 2 * surface->GetSurfaceDPI() / 96.0; Int bitmapOffset = bitmap != NIL ? (frame.GetHeight() - scaledSize.cy) / 2.0 : 2; if (bitmap != NIL) { if (bitmapSize != scaledSize && bitmapScaled.GetSize() != scaledSize) bitmapScaled = bitmap.Scale(scaledSize); if (bitmapSize == scaledSize) surface->BlitFromBitmap(bitmap, Rect(Point(0, 0), scaledSize), Rect(frame.GetPosition() + Point(bitmapOffset, bitmapOffset), scaledSize)); else surface->BlitFromBitmap(bitmapScaled, Rect(Point(0, 0), scaledSize), Rect(frame.GetPosition() + Point(bitmapOffset, bitmapOffset), scaledSize)); } /* Draw text. */ Int textOffset = Math::Round((frame.GetHeight() - scaledTextSize.cy) / 2.0); surface->SetText(text, frame + Point(scaledSize.cx + 2 * bitmapOffset - 1, textOffset - 1), font); } break; } return Success(); } S::Int BoCA::LengthDisplay::SetText(const String &newText) { Widget::SetText(newText); SetWidth(unscaledTextSize.cx + bitmap.GetSize().cx / 2 + 6); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/lengthdisplay.h000077500000000000000000000015261516712004000276160ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include namespace BoCA { class LengthDisplay : public Widget { private: Bitmap bitmap; Bitmap bitmapScaled; public: Int Paint(Int); LengthDisplay(const Bitmap &); ~LengthDisplay(); accessors: Int SetText(const String &); }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/lengthstatus.cpp000077500000000000000000000025341516712004000300270ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "lengthstatus.h" const String &BoCA::LengthStatus::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Total Track Length Display \ 1.0 \ statustime-ext \ extension \ \ \ "; return componentSpecs; } BoCA::LengthStatus::LengthStatus() { statusBarLayer = NIL; getStatusBarLayer.Connect(&LengthStatus::GetStatusBarLayer, this); } BoCA::LengthStatus::~LengthStatus() { if (statusBarLayer != NIL) Object::DeleteObject(statusBarLayer); } Layer *BoCA::LengthStatus::GetStatusBarLayer() { if (statusBarLayer == NIL) statusBarLayer = new LayerLengthStatus(); return statusBarLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/extension/statustime/lengthstatus.h000077500000000000000000000017641516712004000275000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "layer.h" BoCA_BEGIN_COMPONENT(LengthStatus) namespace BoCA { class LengthStatus : public CS::ExtensionComponent { private: LayerLengthStatus *statusBarLayer; public: static const String &GetComponentSpecs(); LengthStatus(); ~LengthStatus(); callbacks: Layer *GetStatusBarLayer(); }; }; BoCA_DEFINE_EXTENSION_COMPONENT(LengthStatus) BoCA_END_COMPONENT(LengthStatus) boca-1.0.7+git20260412.690d4ffe+dfsg/components/other/000077500000000000000000000000001516712004000214725ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/other/Makefile000077500000000000000000000012541516712004000231370ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/000077500000000000000000000000001516712004000217115ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/Makefile000077500000000000000000000022051516712004000233530ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = ifeq ($(BUILD_LINUX),True) FOLDERS += pulseaudio else ifeq ($(BUILD_OSX),True) FOLDERS += coreaudio else ifeq ($(BUILD_FREEBSD),True) FOLDERS += oss else ifeq ($(BUILD_OPENBSD),True) FOLDERS += oss else ifeq ($(BUILD_NETBSD),True) FOLDERS += oss else ifeq ($(BUILD_SOLARIS),True) FOLDERS += oss else ifeq ($(BUILD_HAIKU),True) FOLDERS += haiku else ifeq ($(BUILD_WIN32),True) FOLDERS += directsound waveout ifeq ($(BUILD_X86),True) FOLDERS += winamp endif endif .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/alsa/000077500000000000000000000000001516712004000226315ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/alsa/Makefile000066400000000000000000000011301516712004000242640ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = alsa TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = alsa.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lasound # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/alsa/alsa.cpp000066400000000000000000000106671516712004000242670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "alsa.h" const String &BoCA::OutputALSA::GetComponentSpecs() { static String componentSpecs; snd_pcm_t *playback_handle = NIL; if (snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) >= 0) { snd_pcm_close(playback_handle); componentSpecs = " \ \ \ \ ALSA Output Plugin \ 1.0 \ alsa-out \ output \ oss-out \ \ \ \ \ \ "; } return componentSpecs; } BoCA::OutputALSA::OutputALSA() { playback_handle = NIL; } BoCA::OutputALSA::~OutputALSA() { } Bool BoCA::OutputALSA::Activate() { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); if (snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) return False; snd_pcm_hw_params_t *hw_params = NIL; snd_pcm_hw_params_malloc(&hw_params); snd_pcm_hw_params_any(playback_handle, hw_params); snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_buffer_size(playback_handle, hw_params, format.rate * format.channels * (format.bits / 8) / 4); if (format.bits == 8 ) snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_U8); else if (format.bits == 16 ) snd_pcm_hw_params_set_format(playback_handle, hw_params, endianness == EndianBig ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE); else if (format.bits == 32 && !format.fp) snd_pcm_hw_params_set_format(playback_handle, hw_params, endianness == EndianBig ? SND_PCM_FORMAT_S32_BE : SND_PCM_FORMAT_S32_LE); else if (format.bits == 32 && format.fp) snd_pcm_hw_params_set_format(playback_handle, hw_params, endianness == EndianBig ? SND_PCM_FORMAT_FLOAT_BE : SND_PCM_FORMAT_FLOAT_LE); snd_pcm_hw_params_set_rate(playback_handle, hw_params, format.rate, 0); snd_pcm_hw_params_set_channels(playback_handle, hw_params, format.channels); snd_pcm_hw_params(playback_handle, hw_params); snd_pcm_hw_params_free(hw_params); if (snd_pcm_prepare(playback_handle) < 0) return False; return True; } Bool BoCA::OutputALSA::Deactivate() { snd_pcm_close(playback_handle); playback_handle = NIL; return True; } Int BoCA::OutputALSA::WriteData(Buffer &data) { const Format &format = track.GetFormat(); snd_pcm_sframes_t frames = -1; /* Change to ALSA channel order. */ if (format.channels == 5) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_0, Channel::ALSA_5_0); else if (format.channels == 6) Utilities::ChangeChannelOrder(data, format, Channel::Default_5_1, Channel::ALSA_5_1); /* Output samples. */ frames = snd_pcm_writei(playback_handle, data, data.Size() / format.channels / (format.bits / 8)); if (frames < 0) return 0; return frames * format.channels * (format.bits / 8); } Bool BoCA::OutputALSA::Finish() { if (playback_handle == NIL) return False; if (snd_pcm_drain(playback_handle) < 0) return False; return True; } Int BoCA::OutputALSA::CanWrite() { if (playback_handle == NIL) return 0; if (snd_pcm_state(playback_handle) == SND_PCM_STATE_PAUSED) return 0; const Format &format = track.GetFormat(); snd_pcm_sframes_t frames = snd_pcm_avail(playback_handle); if (frames < 0) return 0; return frames * format.channels * (format.bits / 8); } Int BoCA::OutputALSA::SetPause(Bool pause) { if (playback_handle == NIL) return Error(); if (snd_pcm_pause(playback_handle, pause ? 1 : 0) < 0) return Error(); return Success(); } Bool BoCA::OutputALSA::IsPlaying() { if (playback_handle == NIL) return False; if (snd_pcm_state(playback_handle) == SND_PCM_STATE_RUNNING) return True; return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/alsa/alsa.h000066400000000000000000000021311516712004000237170ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(OutputALSA) namespace BoCA { class OutputALSA : public CS::OutputComponent { private: snd_pcm_t *playback_handle; public: static const String &GetComponentSpecs(); OutputALSA(); ~OutputALSA(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool Finish(); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputALSA) BoCA_END_COMPONENT(OutputALSA) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/coreaudio/000077500000000000000000000000001516712004000236635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/coreaudio/Makefile000066400000000000000000000012061516712004000253220ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = coreaudio TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = coreaudio.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -framework CoreServices -framework AudioUnit # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/coreaudio/coreaudio.cpp000066400000000000000000000174471516712004000263560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include namespace CA { # include # include # include }; #include "coreaudio.h" #ifndef MAC_OS_X_VERSION_10_6 # define MAC_OS_X_VERSION_10_6 1060 #endif using namespace smooth::Threads; const String &BoCA::OutputCoreAudio::GetComponentSpecs() { static String componentSpecs; /* See if we can find an output audio unit. */ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 CA::ComponentDescription description; #else CA::AudioComponentDescription description; #endif description.componentType = CA::kAudioUnitType_Output; description.componentSubType = CA::kAudioUnitSubType_DefaultOutput; description.componentManufacturer = CA::kAudioUnitManufacturer_Apple; description.componentFlags = 0; description.componentFlagsMask = 0; #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 if (CA::FindNextComponent(NIL, &description) != NIL) #else if (CA::AudioComponentFindNext(NIL, &description) != NIL) #endif { componentSpecs = " \ \ \ \ CoreAudio Output Plugin \ 1.0 \ coreaudio-out \ output \ \ \ "; } return componentSpecs; } namespace BoCA { CA::OSStatus AudioCallback(void *, CA::AudioUnitRenderActionFlags *, const CA::AudioTimeStamp *, CA::UInt32, CA::UInt32, CA::AudioBufferList *); }; BoCA::OutputCoreAudio::OutputCoreAudio() { audioUnit = NIL; paused = False; samplesBufferMutex = new Mutex(); } BoCA::OutputCoreAudio::~OutputCoreAudio() { delete samplesBufferMutex; } Bool BoCA::OutputCoreAudio::Activate() { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); /* Find default output audio unit. */ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 CA::ComponentDescription description; CA::Component component; #else CA::AudioComponentDescription description; CA::AudioComponent component; #endif description.componentType = CA::kAudioUnitType_Output; description.componentSubType = CA::kAudioUnitSubType_DefaultOutput; description.componentManufacturer = CA::kAudioUnitManufacturer_Apple; description.componentFlags = 0; description.componentFlagsMask = 0; #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 component = CA::FindNextComponent(NIL, &description); #else component = CA::AudioComponentFindNext(NIL, &description); #endif if (component == NIL) return False; /* Initialize audio unit. */ #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 if (CA::OpenAComponent(component, &audioUnit) != 0) return False; #else if (CA::AudioComponentInstanceNew(component, &audioUnit) != 0) return False; #endif if (CA::AudioUnitInitialize(audioUnit) != 0) return False; /* Set stream format. */ CA::AudioStreamBasicDescription streamFormat; streamFormat.mFormatID = CA::kAudioFormatLinearPCM; streamFormat.mFormatFlags = CA::kLinearPCMFormatFlagIsPacked; streamFormat.mFormatFlags |= format.fp ? CA::kLinearPCMFormatFlagIsFloat : 0; streamFormat.mFormatFlags |= format.sign && !format.fp ? CA::kLinearPCMFormatFlagIsSignedInteger : 0; streamFormat.mFormatFlags |= endianness == EndianBig ? CA::kLinearPCMFormatFlagIsBigEndian : 0; streamFormat.mSampleRate = format.rate; streamFormat.mChannelsPerFrame = format.channels; streamFormat.mBitsPerChannel = format.bits; streamFormat.mFramesPerPacket = 1; streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame * streamFormat.mBitsPerChannel / 8; streamFormat.mBytesPerPacket = streamFormat.mFramesPerPacket * streamFormat.mBytesPerFrame; if (CA::AudioUnitSetProperty(audioUnit, CA::kAudioUnitProperty_StreamFormat, CA::kAudioUnitScope_Input, 0, &streamFormat, sizeof(streamFormat)) != 0) return False; /* Set audio callback. */ CA::AURenderCallbackStruct audioCallback; audioCallback.inputProc = AudioCallback; audioCallback.inputProcRefCon = this; if (CA::AudioUnitSetProperty(audioUnit, CA::kAudioUnitProperty_SetRenderCallback, CA::kAudioUnitScope_Input, 0, &audioCallback, sizeof(audioCallback)) != 0) return False; /* Preallocate sample buffer. */ samplesBuffer.Resize((format.rate / 4 + 2048) * format.channels * (format.bits / 8)); samplesBuffer.Resize(0); /* Start audio unit. */ if (CA::AudioOutputUnitStart(audioUnit) != 0) return False; paused = False; return True; } Bool BoCA::OutputCoreAudio::Deactivate() { /* Stop audio unit. */ if (CA::AudioOutputUnitStop(audioUnit) != 0) return False; /* Remove audio callback. */ struct CA::AURenderCallbackStruct audioCallback; audioCallback.inputProc = 0; audioCallback.inputProcRefCon = 0; if (CA::AudioUnitSetProperty(audioUnit, CA::kAudioUnitProperty_SetRenderCallback, CA::kAudioUnitScope_Input, 0, &audioCallback, sizeof(audioCallback)) != 0) return False; #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 if (CA::CloseComponent(audioUnit) != 0) return False; #else if (CA::AudioComponentInstanceDispose(audioUnit) != 0) return False; #endif audioUnit = NIL; return True; } Int BoCA::OutputCoreAudio::WriteData(Buffer &data) { samplesBufferMutex->Lock(); Int bytes = samplesBuffer.Size(); samplesBuffer.Resize(bytes + data.Size()); memcpy(samplesBuffer + bytes, data, data.Size()); samplesBufferMutex->Release(); return data.Size(); } Int BoCA::OutputCoreAudio::CanWrite() { if (audioUnit == NIL || paused) return 0; const Format &format = track.GetFormat(); samplesBufferMutex->Lock(); Int canWrite = (format.rate / 4 + 2048) * format.channels * (format.bits / 8) - samplesBuffer.Size(); samplesBufferMutex->Release(); return canWrite; } Int BoCA::OutputCoreAudio::SetPause(Bool pause) { if (audioUnit == NIL) return Error(); CA::OSStatus status = 0; if (pause) status = CA::AudioOutputUnitStop(audioUnit); else status = CA::AudioOutputUnitStart(audioUnit); if (status != 0) return Error(); if (pause) paused = True; else paused = False; return Success(); } Bool BoCA::OutputCoreAudio::IsPlaying() { if (audioUnit == NIL) return False; samplesBufferMutex->Lock(); Bool isPlaying = (samplesBuffer.Size() > 0); samplesBufferMutex->Release(); return isPlaying; } CA::OSStatus BoCA::AudioCallback(void *inClientData, CA::AudioUnitRenderActionFlags *ioActionFlags, const CA::AudioTimeStamp *inTimeStamp, CA::UInt32 inBusNumber, CA::UInt32 inNumberFrames, CA::AudioBufferList *ioData) { OutputCoreAudio *component = (OutputCoreAudio *) inClientData; component->samplesBufferMutex->Lock(); Int numBytes = Math::Min(component->samplesBuffer.Size(), ioData->mBuffers[0].mDataByteSize); /* Copy samples to output buffer. */ memcpy(ioData->mBuffers[0].mData, component->samplesBuffer, numBytes); ioData->mBuffers[0].mDataByteSize = numBytes; ioData->mNumberBuffers = 1; /* Move remaining samples to the start of the buffer. */ memmove(component->samplesBuffer, component->samplesBuffer + numBytes, component->samplesBuffer.Size() - numBytes); component->samplesBuffer.Resize(component->samplesBuffer.Size() - numBytes); component->samplesBufferMutex->Release(); return CA::kAudioHardwareNoError; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/coreaudio/coreaudio.h000066400000000000000000000025421516712004000260110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(OutputCoreAudio) namespace BoCA { class OutputCoreAudio : public CS::OutputComponent { friend CA::OSStatus AudioCallback(void *, CA::AudioUnitRenderActionFlags *, const CA::AudioTimeStamp *, CA::UInt32, CA::UInt32, CA::AudioBufferList *); private: CA::AudioUnit audioUnit; Bool paused; Buffer samplesBuffer; Threads::Mutex *samplesBufferMutex; public: static const String &GetComponentSpecs(); OutputCoreAudio(); ~OutputCoreAudio(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputCoreAudio) BoCA_END_COMPONENT(OutputCoreAudio) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/directsound/000077500000000000000000000000001516712004000242345ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/directsound/Makefile000066400000000000000000000012001516712004000256650ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = directsound TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = directsound.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lole32 -ldsound -ldxguid -lksguid # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/directsound/directsound.cpp000066400000000000000000000210311516712004000272600ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "directsound.h" const String &BoCA::OutputDirectSound::GetComponentSpecs() { static String componentSpecs; Initialize(); IDirectSound8 *directSound = NIL; if (DirectSoundCreate8(&DSDEVID_DefaultPlayback, &directSound, NIL) == DS_OK) { /* Query device capabilities. */ DSCAPS caps; caps.dwSize = sizeof(DSCAPS); directSound->GetCaps(&caps); directSound->Release(); /* Set component specs. */ String rateString = String::FromInt(caps.dwMinSecondarySampleRate).Append("-") .Append(String::FromInt(caps.dwMaxSecondarySampleRate)); componentSpecs = String(" \ \ \ \ DirectSound Output Plugin \ 1.0 \ directsound-out \ output \ waveout-out \ \ \ \ \ \ "); } Cleanup(); return componentSpecs; } Void smooth::AttachDLL(Void *instance) { /* Register initialization and cleanup handlers. */ BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::OutputDirectSound::Initialize); engine->onCleanup.Connect(&BoCA::OutputDirectSound::Cleanup); } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::OutputDirectSound::Initialize); engine->onCleanup.Disconnect(&BoCA::OutputDirectSound::Cleanup); } Void BoCA::OutputDirectSound::Initialize() { /* Init the Microsoft COM library. */ CoInitialize(NIL); } Void BoCA::OutputDirectSound::Cleanup() { /* Uninit the Microsoft COM library. */ CoUninitialize(); } BoCA::OutputDirectSound::OutputDirectSound() { directSound = NIL; primaryBuffer = NIL; workBuffer = NIL; bufferSize = 0; bufferPos = 0; firstBlock = True; } BoCA::OutputDirectSound::~OutputDirectSound() { } Bool BoCA::OutputDirectSound::Activate() { const Format &format = track.GetFormat(); /* Set helper variables. */ firstBlock = True; bufferSize = format.rate * format.channels * (format.bits / 8) / 2; /* Init wave format descriptor. */ WAVEFORMATEXTENSIBLE wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE)); wfx.Format.nSamplesPerSec = format.rate; wfx.Format.wBitsPerSample = format.bits; wfx.Format.nChannels = format.channels; wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.nBlockAlign = (wfx.Format.wBitsPerSample >> 3) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nBlockAlign * wfx.Format.nSamplesPerSec; wfx.SubFormat = format.fp ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM; wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample; if (format.channels == 1) wfx.dwChannelMask = SPEAKER_FRONT_CENTER; else if (format.channels == 2) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; else if (format.channels == 3) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER; else if (format.channels == 4) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 5) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 6) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 7) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; else if (format.channels == 8) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; /* Open audio device. */ DirectSoundCreate8(&DSDEVID_DefaultPlayback, &directSound, NIL); directSound->SetCooperativeLevel((HWND) Window::GetNthWindow(0)->GetSystemWindow(), DSSCL_PRIORITY); /* Create primary sound buffer. */ DSBUFFERDESC soundBuffDesc; ZeroMemory(&soundBuffDesc, sizeof(DSBUFFERDESC)); soundBuffDesc.dwSize = sizeof(DSBUFFERDESC); soundBuffDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (directSound->CreateSoundBuffer(&soundBuffDesc, &primaryBuffer, NIL) != DS_OK) { directSound->Release(); return False; } if (primaryBuffer->SetFormat((WAVEFORMATEX *) &wfx) != DS_OK) { primaryBuffer->Release(); directSound->Release(); return False; } /* Create secondary sound buffer. */ soundBuffDesc.dwFlags = DSBCAPS_GLOBALFOCUS; soundBuffDesc.dwBufferBytes = bufferSize; soundBuffDesc.lpwfxFormat = (WAVEFORMATEX *) &wfx; if (directSound->CreateSoundBuffer(&soundBuffDesc, &workBuffer, NIL) != DS_OK) { primaryBuffer->Release(); directSound->Release(); return False; } return True; } Bool BoCA::OutputDirectSound::Deactivate() { workBuffer->Stop(); workBuffer->Release(); primaryBuffer->Release(); directSound->Release(); return True; } Int BoCA::OutputDirectSound::WriteData(Buffer &data) { Int size = data.Size(); Int bytesWritten = 0; /* Loop until all bytes are fed to the buffer. */ while (size > 0) { /* Get current playback position. */ DWORD playCursor = bufferSize; if (!firstBlock) workBuffer->GetCurrentPosition(&playCursor, NIL); if (playCursor == bufferPos) S::System::System::Sleep(25); /* Lock buffer and feed samples. */ HRESULT hr = DS_OK; Void *block1 = NIL; Void *block2 = NIL; DWORD block1Size = 0; DWORD block2Size = 0; if (playCursor >= bufferPos) hr = workBuffer->Lock(bufferPos, Math::Min(size, playCursor - bufferPos), &block1, &block1Size, NIL, NIL, 0); else hr = workBuffer->Lock(bufferPos, Math::Min(size, playCursor - bufferPos + bufferSize), &block1, &block1Size, &block2, &block2Size, 0); if (hr == DS_OK) { if (block1 != NIL) memcpy(block1, data + bytesWritten, block1Size); if (block2 != NIL) memcpy(block2, data + bytesWritten + block1Size, block2Size); workBuffer->Unlock(block1, block1Size, block2, block2Size); size -= block1Size + block2Size; bufferPos += block1Size + block2Size; bytesWritten += block1Size + block2Size; if (bufferPos >= bufferSize) bufferPos -= bufferSize; } /* Start playback. */ if (firstBlock) workBuffer->Play(0, 0, DSBPLAY_LOOPING); firstBlock = False; } return bytesWritten; } Bool BoCA::OutputDirectSound::Finish() { /* Fill buffer with null samples. */ Buffer buffer(bufferSize); memset(buffer, 0, bufferSize); WriteData(buffer); /* Stop playing the buffer as we must have * reached the null samples at this point. */ workBuffer->Stop(); return True; } Int BoCA::OutputDirectSound::CanWrite() { if (workBuffer == NIL) return 0; if (firstBlock) return bufferSize; DWORD playCursor = 0; workBuffer->GetCurrentPosition(&playCursor, NIL); if (playCursor >= bufferPos) return playCursor - bufferPos; else return playCursor - bufferPos + bufferSize; } Int BoCA::OutputDirectSound::SetPause(Bool pause) { if (workBuffer == NIL) return Error(); if (pause) workBuffer->Stop(); else workBuffer->Play(0, 0, DSBPLAY_LOOPING); return Success(); } Bool BoCA::OutputDirectSound::IsPlaying() { if (workBuffer == NIL) return False; /* Get and check buffer status. */ DWORD status = 0; workBuffer->GetStatus(&status); if (status & DSBSTATUS_PLAYING) return True; else return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/directsound/directsound.h000066400000000000000000000025571516712004000267410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include BoCA_BEGIN_COMPONENT(OutputDirectSound) namespace BoCA { class OutputDirectSound : public CS::OutputComponent { private: IDirectSound8 *directSound; IDirectSoundBuffer *primaryBuffer; IDirectSoundBuffer *workBuffer; UnsignedInt bufferSize; UnsignedInt bufferPos; Bool firstBlock; public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); OutputDirectSound(); ~OutputDirectSound(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool Finish(); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputDirectSound) BoCA_END_COMPONENT(OutputDirectSound) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/haiku/000077500000000000000000000000001516712004000230125ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/haiku/Makefile000066400000000000000000000011311516712004000244460ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = haiku TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = haiku.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lmedia # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/haiku/haiku.cpp000066400000000000000000000104101516712004000246130ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "haiku.h" using namespace smooth::Threads; const String &BoCA::OutputHaiku::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Haiku Output Plugin \ 1.0 \ haiku-out \ output \ \ \ \ \ "; return componentSpecs; } namespace BoCA { void PlayBuffer(void *, void *, size_t, const media_raw_audio_format &); }; BoCA::OutputHaiku::OutputHaiku() { player = NIL; paused = False; samplesBufferMutex = new Mutex(); } BoCA::OutputHaiku::~OutputHaiku() { delete samplesBufferMutex; } Bool BoCA::OutputHaiku::Activate() { static Endianness endianness = CPU().GetEndianness(); /* Define stream format. */ const Format &format = track.GetFormat(); media_raw_audio_format fmt = media_raw_audio_format::wildcard; fmt.buffer_size = 2048 * format.channels * (format.bits / 8); fmt.byte_order = (endianness == EndianBig ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN); fmt.frame_rate = format.rate; fmt.channel_count = format.channels; if (format.bits == 8 ) fmt.format = media_raw_audio_format::B_AUDIO_CHAR; else if (format.bits == 16 ) fmt.format = media_raw_audio_format::B_AUDIO_SHORT; else if (format.bits == 32 && !format.fp) fmt.format = media_raw_audio_format::B_AUDIO_INT; else if (format.bits == 32 && format.fp) fmt.format = media_raw_audio_format::B_AUDIO_FLOAT; /* Preallocate sample buffer. */ samplesBuffer.Resize((format.rate / 4 + 2048) * format.channels * (format.bits / 8)); samplesBuffer.Resize(0); /* Start sound player. */ player = new BSoundPlayer(&fmt, "Haiku Output Plugin", PlayBuffer, NULL, this); player->SetHasData(true); player->Start(); paused = False; return True; } Bool BoCA::OutputHaiku::Deactivate() { /* Stop sound player. */ player->Stop(); delete player; player = NIL; return True; } Int BoCA::OutputHaiku::WriteData(Buffer &data) { samplesBufferMutex->Lock(); Int bytes = samplesBuffer.Size(); samplesBuffer.Resize(bytes + data.Size()); memcpy(samplesBuffer + bytes, data, data.Size()); samplesBufferMutex->Release(); return data.Size(); } Int BoCA::OutputHaiku::CanWrite() { if (player == NIL || paused) return 0; const Format &format = track.GetFormat(); samplesBufferMutex->Lock(); Int canWrite = (format.rate / 4 + 2048) * format.channels * (format.bits / 8) - samplesBuffer.Size(); samplesBufferMutex->Release(); return canWrite; } Int BoCA::OutputHaiku::SetPause(Bool pause) { if (player == NIL) return Error(); if (pause) player->Stop(false, false); else player->Start(); paused = pause; return Success(); } Bool BoCA::OutputHaiku::IsPlaying() { if (player == NIL) return False; samplesBufferMutex->Lock(); Bool isPlaying = (samplesBuffer.Size() > 0); samplesBufferMutex->Release(); return isPlaying; } void BoCA::PlayBuffer(void *cookie, void *buffer, size_t size, const media_raw_audio_format &format) { OutputHaiku *component = (OutputHaiku *) cookie; component->samplesBufferMutex->Lock(); UnsignedInt numBytes = Math::Min(component->samplesBuffer.Size(), size); /* Copy samples to output buffer. */ if (numBytes < size) memset(buffer, 0, size); memcpy(buffer, component->samplesBuffer, numBytes); /* Move remaining samples to the start of the buffer. */ memmove(component->samplesBuffer, component->samplesBuffer + numBytes, component->samplesBuffer.Size() - numBytes); component->samplesBuffer.Resize(component->samplesBuffer.Size() - numBytes); component->samplesBufferMutex->Release(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/haiku/haiku.h000066400000000000000000000023751516712004000242730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(OutputHaiku) namespace BoCA { class OutputHaiku : public CS::OutputComponent { friend void PlayBuffer(void *, void *, size_t, const media_raw_audio_format &); private: BSoundPlayer *player; Bool paused; Buffer samplesBuffer; Threads::Mutex *samplesBufferMutex; public: static const String &GetComponentSpecs(); OutputHaiku(); ~OutputHaiku(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputHaiku) BoCA_END_COMPONENT(OutputHaiku) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/oss/000077500000000000000000000000001516712004000225155ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/oss/Makefile000066400000000000000000000013761516712004000241640ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = oss TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = oss.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: ifeq ($(BUILD_OPENBSD),True) LIBS = -lossaudio else ifeq ($(BUILD_NETBSD),True) LIBS = -lossaudio endif # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/oss/oss.cpp000066400000000000000000000070771516712004000240400ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef __OpenBSD__ # include #else # include #endif #include #include #include "oss.h" const String &BoCA::OutputOSS::GetComponentSpecs() { static String componentSpecs; int device_fd = NIL; #if defined __OpenBSD__ || defined __NetBSD__ if ((device_fd = open("/dev/sound", O_WRONLY, 0)) >= 0) #else if ((device_fd = open("/dev/dsp", O_WRONLY, 0)) >= 0) #endif { close(device_fd); componentSpecs = " \ \ \ \ OSS Output Plugin \ 1.0 \ oss-out \ output \ \ \ \ "; #ifdef AFMT_S32_LE componentSpecs.Append(" \ \ \ \ "); #endif componentSpecs.Append(" \ \ \ \ "); } return componentSpecs; } BoCA::OutputOSS::OutputOSS() { device_fd = -1; paused = False; } BoCA::OutputOSS::~OutputOSS() { } Bool BoCA::OutputOSS::Activate() { static Endianness endianness = CPU().GetEndianness(); const Format &format = track.GetFormat(); #if defined __OpenBSD__ || defined __NetBSD__ if ((device_fd = open("/dev/sound", O_WRONLY, 0)) < 0) return False; #else if ((device_fd = open("/dev/dsp", O_WRONLY, 0)) < 0) return False; #endif int samples = 0; if (format.bits == 8) samples = AFMT_U8; else if (format.bits == 16) samples = (endianness == EndianBig ? AFMT_S16_BE : AFMT_S16_LE); #ifdef AFMT_S32_LE else if (format.bits == 32) samples = (endianness == EndianBig ? AFMT_S32_BE : AFMT_S32_LE); #endif int channels = format.channels; int rate = format.rate; if (ioctl(device_fd, SNDCTL_DSP_SETFMT, &samples) == -1) return False; if (ioctl(device_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) return False; if (ioctl(device_fd, SNDCTL_DSP_SPEED, &rate) == -1) return False; return True; } Bool BoCA::OutputOSS::Deactivate() { close(device_fd); device_fd = -1; return True; } Int BoCA::OutputOSS::WriteData(Buffer &data) { Int bytes = write(device_fd, data, data.Size()); if (bytes < 0) return 0; return bytes; } Int BoCA::OutputOSS::CanWrite() { if (device_fd == -1) return 0; if (paused) return 0; const Format &format = track.GetFormat(); return format.rate * format.channels * (format.bits / 8) / 4; } Int BoCA::OutputOSS::SetPause(Bool pause) { if (device_fd == -1) return Error(); #ifdef SNDCTL_DSP_SKIP if (pause) ioctl(device_fd, SNDCTL_DSP_SKIP, NIL); #endif paused = pause; return Success(); } Bool BoCA::OutputOSS::IsPlaying() { if (device_fd == -1) return False; #ifdef SNDCTL_DSP_CURRENT_OPTR oss_count_t ptr; if (ioctl(device_fd, SNDCTL_DSP_CURRENT_OPTR, &ptr) == 0) { if (ptr.fifo_samples > 0) return True; } #else count_info ci; if (ioctl(device_fd, SNDCTL_DSP_GETOPTR, &ci) == 0) { if (ci.ptr > 0) return True; } #endif return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/oss/oss.h000066400000000000000000000021071516712004000234720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(OutputOSS) namespace BoCA { class OutputOSS : public CS::OutputComponent { private: int device_fd; Bool paused; public: static const String &GetComponentSpecs(); OutputOSS(); ~OutputOSS(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputOSS) BoCA_END_COMPONENT(OutputOSS) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/pulseaudio/000077500000000000000000000000001516712004000240635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/pulseaudio/Makefile000066400000000000000000000011431516712004000255220ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = pulseaudio TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = pulseaudio.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = -lpulse # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/pulseaudio/pulseaudio.cpp000066400000000000000000000156001516712004000267430ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "pulseaudio.h" const String &BoCA::OutputPulseAudio::GetComponentSpecs() { static String componentSpecs; Initialize(); if (context != NIL) { componentSpecs = " \ \ \ \ PulseAudio Output Plugin \ 1.0 \ pulseaudio-out \ output \ alsa-out \ oss-out \ \ \ \ \ \ "; } Cleanup(); return componentSpecs; } Void smooth::AttachDLL(Void *instance) { /* Register initialization and cleanup handlers. */ BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::OutputPulseAudio::Initialize); engine->onCleanup.Connect(&BoCA::OutputPulseAudio::Cleanup); } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::OutputPulseAudio::Initialize); engine->onCleanup.Disconnect(&BoCA::OutputPulseAudio::Cleanup); } pa_threaded_mainloop *BoCA::OutputPulseAudio::mainloop = NIL; pa_context *BoCA::OutputPulseAudio::context = NIL; Void BoCA::OutputPulseAudio::Initialize() { String applicationName = Application::Get()->getScreenName.Call(); /* Connect to PulseAudio server. */ mainloop = pa_threaded_mainloop_new(); context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), applicationName); if (pa_context_connect(context, NIL, PA_CONTEXT_NOFLAGS, NIL) >= 0) { /* Start threaded main loop. */ pa_threaded_mainloop_start(mainloop); /* Wait for context to become ready. */ while (true) { pa_threaded_mainloop_lock(mainloop); pa_context_state_t state = pa_context_get_state(context); pa_threaded_mainloop_unlock(mainloop); if (state == PA_CONTEXT_READY) return; if (!PA_CONTEXT_IS_GOOD(state)) break; } } /* Free context on error. */ pa_context_unref(context); context = NIL; } Void BoCA::OutputPulseAudio::Cleanup() { /* Disconnect context. */ if (context != NIL) { pa_threaded_mainloop_lock(mainloop); pa_context_disconnect(context); pa_context_unref(context); pa_threaded_mainloop_unlock(mainloop); } /* Stop threaded main loop. */ pa_threaded_mainloop_stop(mainloop); pa_threaded_mainloop_free(mainloop); mainloop = NIL; context = NIL; } BoCA::OutputPulseAudio::OutputPulseAudio() { stream = NIL; } BoCA::OutputPulseAudio::~OutputPulseAudio() { } Bool BoCA::OutputPulseAudio::Activate() { String applicationName = Application::Get()->getScreenName.Call(); /* Fill sample format spec. */ const Format &format = track.GetFormat(); pa_sample_spec sampleSpec; sampleSpec.channels = format.channels; sampleSpec.rate = format.rate; if (format.bits == 8 ) sampleSpec.format = PA_SAMPLE_U8; else if (format.bits == 16 ) sampleSpec.format = PA_SAMPLE_S16NE; else if (format.bits == 32 && !format.fp) sampleSpec.format = PA_SAMPLE_S32NE; else if (format.bits == 32 && format.fp) sampleSpec.format = PA_SAMPLE_FLOAT32NE; /* Create channel map. */ pa_channel_map channelMap; pa_channel_map_init_auto(&channelMap, sampleSpec.channels, PA_CHANNEL_MAP_WAVEEX); /* Create stream. */ stream = pa_stream_new(context, applicationName, &sampleSpec, &channelMap); /* Connect stream to playback. */ pa_buffer_attr bufferAttr; bufferAttr.maxlength = (uint32_t) -1; bufferAttr.tlength = format.rate / 4 * format.channels * (format.bits / 8); bufferAttr.prebuf = (uint32_t) -1; bufferAttr.minreq = (uint32_t) -1; bufferAttr.fragsize = (uint32_t) -1; pa_threaded_mainloop_lock(mainloop); pa_stream_connect_playback(stream, NIL, &bufferAttr, PA_STREAM_NOFLAGS, NIL, NIL); pa_threaded_mainloop_unlock(mainloop); /* Wait for stream to become ready. */ while (true) { pa_threaded_mainloop_lock(mainloop); pa_stream_state_t state = pa_stream_get_state(stream); pa_threaded_mainloop_unlock(mainloop); if (state == PA_STREAM_READY) break; if (!PA_STREAM_IS_GOOD(state)) return False; } return True; } Bool BoCA::OutputPulseAudio::Deactivate() { /* Disconnect stream. */ if (stream != NIL) { pa_threaded_mainloop_lock(mainloop); pa_stream_disconnect(stream); pa_stream_unref(stream); pa_threaded_mainloop_unlock(mainloop); } stream = NIL; return True; } Int BoCA::OutputPulseAudio::WriteData(Buffer &data) { if (stream == NIL) return 0; /* Output samples. */ pa_threaded_mainloop_lock(mainloop); Int size = data.Size(); if (pa_stream_write(stream, data, data.Size(), NIL, 0, PA_SEEK_RELATIVE) < 0) size = 0; pa_threaded_mainloop_unlock(mainloop); return size; } Bool BoCA::OutputPulseAudio::Finish() { if (stream == NIL) return False; pa_threaded_mainloop_lock(mainloop); pa_operation *operation = pa_stream_drain(stream, NIL, NIL); if (operation == NIL) { pa_threaded_mainloop_unlock(mainloop); return False; } pa_operation_unref(operation); pa_threaded_mainloop_unlock(mainloop); return True; } Int BoCA::OutputPulseAudio::CanWrite() { if (stream == NIL) return 0; pa_threaded_mainloop_lock(mainloop); size_t size = pa_stream_writable_size(stream); pa_threaded_mainloop_unlock(mainloop); return size; } Int BoCA::OutputPulseAudio::SetPause(Bool pause) { if (stream == NIL) return Error(); pa_threaded_mainloop_lock(mainloop); pa_operation *operation = pa_stream_cork(stream, pause ? 1 : 0, NIL, NIL); if (operation == NIL) { pa_threaded_mainloop_unlock(mainloop); return Error(); } pa_operation_unref(operation); if (!pause) { /* Resume playback immediately after pause. */ pa_operation *operation = pa_stream_trigger(stream, NIL, NIL); if (operation != NIL) pa_operation_unref(operation); } pa_threaded_mainloop_unlock(mainloop); return Success(); } Bool BoCA::OutputPulseAudio::IsPlaying() { if (stream == NIL) return False; pa_threaded_mainloop_lock(mainloop); Bool playing = False; const pa_buffer_attr *attributes = pa_stream_get_buffer_attr(stream); if (pa_stream_writable_size(stream) < attributes->tlength) playing = True; pa_threaded_mainloop_unlock(mainloop); return playing; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/pulseaudio/pulseaudio.h000066400000000000000000000024101516712004000264030ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(OutputPulseAudio) namespace BoCA { class OutputPulseAudio : public CS::OutputComponent { private: static pa_threaded_mainloop *mainloop; static pa_context *context; pa_stream *stream; public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); OutputPulseAudio(); ~OutputPulseAudio(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Bool Finish(); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputPulseAudio) BoCA_END_COMPONENT(OutputPulseAudio) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/waveout/000077500000000000000000000000001516712004000234035ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/waveout/Makefile000077500000000000000000000013351516712004000250500ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = waveout TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = waveout.o # Enter additional defines here: ifeq ($(BUILD_WIN32),True) DEFINE = -DUNICODE endif # Enter additional library dependencies here: LIBS = -lwinmm -lksguid # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/waveout/license.txt000077500000000000000000000031341516712004000255720ustar00rootroot00000000000000This component is based on code from the Winamp WaveOut plugin by Peter Pawlowski --------------------------------------------------------------------------------- Copyright (c) 2001-2002, Peter Pawlowski All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/waveout/waveout.cpp000066400000000000000000000244351516712004000256110ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "waveout.h" #include const String &BoCA::OutputWaveOut::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ WaveOut Output Plugin \ 1.0 \ waveout-out \ output \ \ \ \ \ \ "; return componentSpecs; } BoCA::OutputWaveOut::OutputWaveOut() { hWaveOut = NIL; hEvent = NIL; write_ptr = 0; p_time = 0; paused = False; needplay = False; stop = False; newpause = False; buffer = NIL; buf_size = 0; buf_size_used = 0; maxblock = 0; minblock = 0; avgblock = 0; n_playing = 0; data_written = 0; last_time = 0; thread = NIL; memset(&sync, 0, sizeof(sync)); } BoCA::OutputWaveOut::~OutputWaveOut() { } Bool BoCA::OutputWaveOut::Activate() { const Format &format = track.GetFormat(); hWaveOut = NIL; write_ptr = 0; p_time = 0; paused = False; needplay = False; stop = False; newpause = False; InitializeCriticalSection(&sync); /* Init wave format descriptor. */ WAVEFORMATEXTENSIBLE wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE)); wfx.Format.nSamplesPerSec = format.rate; wfx.Format.wBitsPerSample = format.bits; wfx.Format.nChannels = format.channels; wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.nBlockAlign = (wfx.Format.wBitsPerSample >> 3) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nBlockAlign * wfx.Format.nSamplesPerSec; wfx.SubFormat = format.fp ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM; wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample; if (format.channels == 1) wfx.dwChannelMask = SPEAKER_FRONT_CENTER; else if (format.channels == 2) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; else if (format.channels == 3) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER; else if (format.channels == 4) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 5) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 6) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; else if (format.channels == 7) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; else if (format.channels == 8) wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; /* Open audio device. */ hEvent = CreateEvent(0, 0, 0, 0); MMRESULT mr = waveOutOpen(&hWaveOut, WAVE_MAPPER, (WAVEFORMATEX *) &wfx, (DWORD) (Int64) hEvent, 0, CALLBACK_EVENT); if (mr) { String e = String("Unknown MMSYSTEM error."); String e2 = String("Unknown error."); wchar_t waveOutError[MAXERRORLENGTH]; if (waveOutGetErrorText(mr, waveOutError, MAXERRORLENGTH) == MMSYSERR_NOERROR) e = waveOutError; switch (mr) { case 32: /* fixme: some broken drivers blow mmsystem032 for no reason, with "standard" 44khz/16bps/stereo, need better error message when pcm format isn't weird */ e2 = String("Unsupported PCM format (").Append(String::FromInt(format.rate)).Append(" Hz, ").Append(String::FromInt(format.bits)).Append(" bits per sample, ").Append(String::FromInt(format.channels)).Append(" channels). Please change format settings in input plug-in configuration or change output device in waveOut plug-in configuration."); break; case 4: e2 = String("Another program is using your soundcard. Please change output device (in waveOut plug-in configuration), switch to DirectSound output (in Winamp preferences / plug-ins / output) or get a soundcard which can play multiple streams."); break; case 2: e2 = String("No sound devices found. Please buy a soundcard first (or install proper drivers if you think that you have one).\nMore info can be found at http://www.geocities.com/mmsystem002/"); break; case 20: e2 = String("Internal driver error; please reboot your computer."); break; case 7: e2 = String("Please reinstall soundcard drivers."); break; case 8: // fixme break; } errorString = String(e2).Append("\n\nError code: ").Append(String::FromInt(mr)).Append("\nWindows error message: \n\"").Append(e).Append("\""); errorState = True; return False; } buf_size = MulDiv(2000, wfx.Format.nAvgBytesPerSec, 1000); maxblock = 0x10000; minblock = 0x100; avgblock = buf_size >> 4; if (maxblock > buf_size >> 2) maxblock = buf_size >> 2; if (avgblock > maxblock) avgblock = maxblock; if (maxblock < minblock) maxblock = minblock; if (avgblock < minblock) avgblock = minblock; buffer = (char *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, buf_size + maxblock); // extra space at the end of the buffer n_playing = 0; data_written = 0; buf_size_used = 0; last_time = 0; waveOutRestart(hWaveOut); /* Start worker thread. */ thread = NonBlocking0<>(&OutputWaveOut::WorkerThread, this).Call(); return True; } Bool BoCA::OutputWaveOut::Deactivate() { EnterCriticalSection(&sync); stop = True; SetEvent(hEvent); LeaveCriticalSection(&sync); /* Wait for worker thread to exit. */ thread->Wait(); if (hEvent) CloseHandle(hEvent); if (hWaveOut) { waveOutReset(hWaveOut); for (Int i = 0; i < headers.Length(); i++) { WAVEHDR *hdr = headers.GetNth(i); if (hdr->dwFlags & WHDR_PREPARED) { waveOutUnprepareHeader(hWaveOut, hdr, sizeof(WAVEHDR)); } delete hdr; headers.RemoveNth(i--); } waveOutClose(hWaveOut); } if (buffer) LocalFree(buffer); DeleteCriticalSection(&sync); return True; } Int BoCA::OutputWaveOut::WriteData(Buffer &data) { UnsignedByte *_data = (UnsignedByte *) data; Int size = data.Size(); Int bytesWritten = 0; EnterCriticalSection(&sync); while (size > 0) { UINT ptr = (data_written + write_ptr) % buf_size; UINT delta = size; if (ptr + delta > buf_size) delta = buf_size - ptr; memcpy(buffer + ptr, _data, delta); _data += delta; size -= delta; bytesWritten += delta; data_written += delta; } if (bytesWritten) SetEvent(hEvent); // new shit, time to update LeaveCriticalSection(&sync); return bytesWritten; } Int BoCA::OutputWaveOut::CanWrite() { EnterCriticalSection(&sync); Int bytes = paused ? 0 : buf_size - buf_size_used - data_written; LeaveCriticalSection(&sync); return bytes; } Int BoCA::OutputWaveOut::SetPause(Bool pause) { EnterCriticalSection(&sync); newpause = pause ? True : False; // needs to be done in our thread to keep stupid win2k/xp happy SetEvent(hEvent); LeaveCriticalSection(&sync); while (paused != newpause) S::System::System::Sleep(0); return Success(); } Bool BoCA::OutputWaveOut::IsPlaying() { if (!hWaveOut) return False; EnterCriticalSection(&sync); // needs to be done in our thread if (!paused) { needplay = True; SetEvent(hEvent); } const Format &format = track.GetFormat(); Int r = MulDiv(buf_size_used + data_written, 1000, (format.bits >> 3) * format.channels * format.rate); if (paused) r -= p_time; else if (n_playing) r -= timeGetTime() - last_time; LeaveCriticalSection(&sync); return (r > 0); } Void BoCA::OutputWaveOut::WorkerThread() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); const Format &format = track.GetFormat(); while (hWaveOut) { WaitForSingleObject(hEvent, INFINITE); EnterCriticalSection(&sync); if (stop) { LeaveCriticalSection(&sync); break; } for (Int i = 0; i < headers.Length(); i++) { WAVEHDR *hdr = headers.GetNth(i); if (hdr->dwFlags & WHDR_DONE) { n_playing--; buf_size_used -= hdr->dwBufferLength; last_time = timeGetTime(); waveOutUnprepareHeader(hWaveOut, hdr, sizeof(WAVEHDR)); delete hdr; headers.RemoveNth(i--); } } if (!paused && newpause) { paused = True; if (hWaveOut) waveOutPause(hWaveOut); p_time = timeGetTime() - last_time; } if (paused && !newpause) { paused = False; if (hWaveOut) waveOutRestart(hWaveOut); last_time = timeGetTime() - p_time; } UINT limit = 0; if (!needplay && !n_playing && limit < avgblock) limit = avgblock; else if (buf_size_used < (buf_size >> 1) || n_playing < 3) limit = minblock; // skipping warning, blow whatever we have else limit = avgblock; // just a block while (data_written > limit) { UINT d = (data_written > maxblock) ? maxblock : data_written; d -= d % ((format.bits >> 3) * format.channels); if (!d) break; data_written -= d; buf_size_used += d; WAVEHDR *hdr = new WAVEHDR; ZeroMemory(hdr, sizeof(WAVEHDR)); hdr->dwBufferLength = d; hdr->dwBytesRecorded = d; hdr->lpData = buffer + write_ptr; headers.Add(hdr); write_ptr += d; if (write_ptr > buf_size) { write_ptr -= buf_size; memcpy(buffer + buf_size, buffer, write_ptr); } n_playing++; waveOutPrepareHeader(hWaveOut, hdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, hdr, sizeof(WAVEHDR)); // important: make all waveOutWrite calls from *our* thread to keep win2k/xp happy if (n_playing == 1) last_time = timeGetTime(); } needplay = False; LeaveCriticalSection(&sync); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/waveout/waveout.h000066400000000000000000000030421516712004000252450ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include BoCA_BEGIN_COMPONENT(OutputWaveOut) namespace BoCA { class OutputWaveOut : public CS::OutputComponent { private: HWAVEOUT hWaveOut; Array headers; Threads::Thread *thread; Bool stop; CRITICAL_SECTION sync; HANDLE hEvent; char *buffer; UINT buf_size, buf_size_used; UINT data_written, write_ptr; UINT minblock, maxblock, avgblock; DWORD last_time; DWORD p_time; UINT n_playing; Bool paused; Bool needplay; Bool newpause; Void WorkerThread(); public: static const String &GetComponentSpecs(); OutputWaveOut(); ~OutputWaveOut(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputWaveOut) BoCA_END_COMPONENT(OutputWaveOut) boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/000077500000000000000000000000001516712004000232045ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/Makefile000077500000000000000000000012261516712004000246500ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = winamp TYPE = output VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o winamp.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/config.cpp000077500000000000000000000070761516712004000251720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureWinamp::ConfigID = "WinampOut"; BoCA::ConfigureWinamp::ConfigureWinamp() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Extensions::Winamp Adapter"); list_output = new ListBox(Point(7, 7), Size(425, 170)); list_output->SetFlags(LF_MULTICHECKBOX); list_output->onSelectEntry.Connect(&ConfigureWinamp::SelectOutputPlugin, this); list_output->onMarkEntry.Connect(&ConfigureWinamp::SelectOutputPlugin, this); button_output = new Button(i18n->TranslateString("Configure"), Point(440, 7), Size()); button_output->onAction.Connect(&ConfigureWinamp::ConfigureOutputPlugin, this); button_output->Deactivate(); button_output_about = new Button(i18n->TranslateString("About"), Point(440, 37), Size()); button_output_about->onAction.Connect(&ConfigureWinamp::AboutOutputPlugin, this); button_output_about->Deactivate(); for (Int i = 0; i < winamp_out_modules.Length(); i++) { if (winamp_out_modules.GetNth(i)->version == OUT_VER) list_output->AddEntry(winamp_out_modules.GetNth(i)->description, config->GetIntValue(ConfigID, "OutputPlugin", 0) == i); else list_output->AddEntry((wchar_t *) winamp_out_modules.GetNth(i)->description, config->GetIntValue(ConfigID, "OutputPlugin", 0) == i); } Add(list_output); Add(button_output); Add(button_output_about); SetSize(Size(527, 184)); } BoCA::ConfigureWinamp::~ConfigureWinamp() { DeleteObject(list_output); DeleteObject(button_output); DeleteObject(button_output_about); } Int BoCA::ConfigureWinamp::SaveSettings() { Config *config = Config::Get(); Int plugin = -1; for (Int i = 0; i < list_output->Length(); i++) if (list_output->GetNthEntry(i)->IsMarked()) plugin = i; config->SetIntValue(ConfigID, "OutputPlugin", plugin); return Success(); } Void BoCA::ConfigureWinamp::SelectOutputPlugin() { ListEntry *selectedEntry = list_output->GetSelectedEntry(); if (selectedEntry == NIL) return; button_output->Activate(); button_output_about->Activate(); /* Make sure only one entry is marked at any time. */ if (selectedEntry->IsMarked()) { /* Unmark any other plugins. */ for (Int i = 0; i < list_output->Length(); i++) if (list_output->GetNthEntry(i) != selectedEntry) list_output->GetNthEntry(i)->SetMark(False); } else { /* Mark this plugin if no other plugin is marked. */ Bool selected = False; for (Int i = 0; i < list_output->Length(); i++) if (list_output->GetNthEntry(i)->IsMarked()) selected = True; if (!selected) selectedEntry->SetMark(True); } } Void BoCA::ConfigureWinamp::ConfigureOutputPlugin() { if (list_output->GetSelectedEntry() == NIL) return; winamp_out_modules.GetNth(list_output->GetSelectedEntryNumber())->Config((HWND) GetContainerWindow()->GetSystemWindow()); } Void BoCA::ConfigureWinamp::AboutOutputPlugin() { if (list_output->GetSelectedEntry() == NIL) return; winamp_out_modules.GetNth(list_output->GetSelectedEntryNumber())->About((HWND) GetContainerWindow()->GetSystemWindow()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/config.h000077500000000000000000000022051516712004000246240ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_WINAMPCONFIG #define H_WINAMPCONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureWinamp : public ConfigLayer { private: ListBox *list_output; Button *button_output; Button *button_output_about; slots: Void SelectOutputPlugin(); Void ConfigureOutputPlugin(); Void AboutOutputPlugin(); public: static const String ConfigID; ConfigureWinamp(); ~ConfigureWinamp(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/dllinterface.cpp000077500000000000000000000042621516712004000263530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" Array winamp_out_plugins; Array winamp_out_modules; Bool LoadWinampDLLs() { MoveFileA(GUI::Application::GetApplicationDirectory().Append("plugins\\plugins.ini"), GUI::Application::GetApplicationDirectory().Append("freac.ini")); Directory directory = GUI::Application::GetApplicationDirectory().Append("plugins\\"); const Array &out_dlls = directory.GetFilesByPattern("out_*.dll"); for (Int i = 0; i < out_dlls.Length(); i++) { DynamicLoader *dll = new DynamicLoader(out_dlls.GetNth(i)); if (dll == NIL) continue; /* Get winampGetOutModule function address. */ Out_Module *(*proc)() = (Out_Module *(*)()) dll->GetFunctionAddress("winampGetOutModule"); if (proc == NIL) { Object::DeleteObject(dll); continue; } /* Get output module description. */ Out_Module *module = proc(); if (module->version != OUT_VER && module->version != OUT_VER_U) { Object::DeleteObject(dll); continue; } /* Add module to list. */ winamp_out_plugins.Add(dll); winamp_out_modules.Add(module); module->hDllInstance = (HINSTANCE) dll->GetSystemModuleHandle(); module->hMainWindow = NULL; module->Init(); } return True; } Void FreeWinampDLLs() { for (Int j = 0; j < winamp_out_plugins.Length(); j++) { winamp_out_modules.GetNth(j)->Quit(); Object::DeleteObject(winamp_out_plugins.GetNth(j)); } winamp_out_plugins.RemoveAll(); winamp_out_modules.RemoveAll(); MoveFileA(GUI::Application::GetApplicationDirectory().Append("freac.ini"), GUI::Application::GetApplicationDirectory().Append("plugins\\plugins.ini")); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/dllinterface.h000077500000000000000000000015451516712004000260210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include using namespace smooth; using namespace smooth::System; extern Array winamp_out_plugins; extern Array winamp_out_modules; Bool LoadWinampDLLs(); Void FreeWinampDLLs(); boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/winamp.cpp000066400000000000000000000045461516712004000252140ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "winamp.h" #include "config.h" const String &BoCA::OutputWinamp::GetComponentSpecs() { static String componentSpecs; if (winamp_out_plugins.Length() > 0) { componentSpecs = " \ \ \ \ Winamp Output Plug-In Adapter \ 1.0 \ winamp-out \ output \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadWinampDLLs(); } Void smooth::DetachDLL() { FreeWinampDLLs(); } BoCA::OutputWinamp::OutputWinamp() { configLayer = NIL; module = NIL; } BoCA::OutputWinamp::~OutputWinamp() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::OutputWinamp::Activate() { const Config *config = GetConfiguration(); const Format &format = track.GetFormat(); module = winamp_out_modules.GetNth(config->GetIntValue(ConfigureWinamp::ConfigID, "OutputPlugin", 0)); return (module->Open(format.rate, format.channels, format.bits, 0, 0) >= 0); } Bool BoCA::OutputWinamp::Deactivate() { module->Close(); return True; } Int BoCA::OutputWinamp::WriteData(Buffer &data) { module->Write((char *) (UnsignedByte *) data, data.Size()); return data.Size(); } ConfigLayer *BoCA::OutputWinamp::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureWinamp(); return configLayer; } Int BoCA::OutputWinamp::CanWrite() { return module->CanWrite(); } Int BoCA::OutputWinamp::SetPause(Bool pause) { module->Pause(pause); return Success(); } Bool BoCA::OutputWinamp::IsPlaying() { return module->IsPlaying(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/output/winamp/winamp.h000066400000000000000000000022541516712004000246530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(OutputWinamp) namespace BoCA { class OutputWinamp : public CS::OutputComponent { private: ConfigLayer *configLayer; Out_Module *module; public: static const String &GetComponentSpecs(); OutputWinamp(); ~OutputWinamp(); Bool Activate(); Bool Deactivate(); Int WriteData(Buffer &); ConfigLayer *GetConfigurationLayer(); Int CanWrite(); Int SetPause(Bool); Bool IsPlaying(); }; }; BoCA_DEFINE_OUTPUT_COMPONENT(OutputWinamp) BoCA_END_COMPONENT(OutputWinamp) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/000077500000000000000000000000001516712004000222125ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/Makefile000066400000000000000000000013121516712004000236470ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = cuesheet m3u pls vclt wpl xspf .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/cuesheet/000077500000000000000000000000001516712004000240175ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/cuesheet/Makefile000066400000000000000000000011311516712004000254530ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cuesheet TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = cuesheet.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/cuesheet/cuesheet.cpp000066400000000000000000000162401516712004000263330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "cuesheet.h" using namespace smooth::IO; const String &BoCA::PlaylistCueSheet::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Cue Sheet Playlist \ 1.0 \ cuesheet-playlist \ playlist \ \ \ "; return componentSpecs; } BoCA::PlaylistCueSheet::PlaylistCueSheet() { } BoCA::PlaylistCueSheet::~PlaylistCueSheet() { } Error BoCA::PlaylistCueSheet::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); /* Get configuration. */ const Config *config = GetConfiguration(); Bool replaceExistingComments = config->GetIntValue("Tags", "ReplaceExistingComments", False); String defaultComment = config->GetStringValue("Tags", "DefaultComment", NIL); Bool preserveReplayGain = config->GetIntValue("Tags", "PreserveReplayGain", True); /* Create cue sheet file. */ String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) { Utilities::ErrorMessage("Could not create cue sheet file:\n\n%1", actualFile); return Error(); } /* Write UTF-8 BOM and set output format. */ out.OutputNumberRaw(0xEFBBBF, 3); String::OutputFormat outputFormat("UTF-8"); /* Check if all tracks belong to the same album and * if we need to create a single or multi file cue sheet. */ Bool artistConsistent = True; Bool albumConsistent = True; Bool commentConsistent = True; Bool albumGainConsistent = True; for (Int c = 0; c < trackList.Length() - 1; c++) { const Track &track = trackList.GetNth(c); const Track &track1 = trackList.GetNth(c + 1); const Info &info = track.GetInfo(); const Info &info1 = track1.GetInfo(); const String &artist = info.HasOtherInfo(INFO_ALBUMARTIST) ? info.GetOtherInfo(INFO_ALBUMARTIST) : info.artist; const String &artist1 = info1.HasOtherInfo(INFO_ALBUMARTIST) ? info1.GetOtherInfo(INFO_ALBUMARTIST) : info1.artist; if (artist != artist1) artistConsistent = False; if (info.album != info1.album) albumConsistent = False; if (info.comment != info1.comment) commentConsistent = False; if (info.album_gain != info1.album_gain || info.album_peak != info1.album_peak) albumGainConsistent = False; } /* Metadata. */ I18n *i18n = I18n::Get(); const Info &info = trackList.GetNth(0).GetInfo(); const String &artist = info.HasOtherInfo(INFO_ALBUMARTIST) ? info.GetOtherInfo(INFO_ALBUMARTIST) : info.artist; /* Output per album metadata. */ if (artistConsistent && albumConsistent) { if (info.genre != NIL) out.OutputLine(String("REM GENRE \"").Append(EscapeString(info.genre)).Append("\"")); if (info.year > 0) out.OutputLine(String("REM DATE ").Append(String::FromInt(info.year))); } if (info.comment != NIL && commentConsistent && !replaceExistingComments) out.OutputLine(String("REM COMMENT \"").Append(EscapeString(info.comment)).Append("\"")); else if (defaultComment != NIL) out.OutputLine(String("REM COMMENT \"").Append(EscapeString(defaultComment)).Append("\"")); if (artistConsistent) out.OutputLine(String("PERFORMER \"").Append(artist.Length() > 0 ? EscapeString(artist) : i18n->TranslateString("unknown artist")).Append("\"")); if (albumConsistent) out.OutputLine(String("TITLE \"").Append(info.album.Length() > 0 ? EscapeString(info.album) : i18n->TranslateString("unknown album")).Append("\"")); /* Save Replay Gain info. */ if (albumGainConsistent && preserveReplayGain) { if (info.album_gain != NIL && info.album_peak != NIL) { out.OutputLine(String("REM REPLAYGAIN_ALBUM_GAIN ").Append(info.album_gain)); out.OutputLine(String("REM REPLAYGAIN_ALBUM_PEAK ").Append(info.album_peak)); } } /* Write actual track data. */ String previousFile; for (Int i = 0; i < trackList.Length(); i++) { const Track &track = trackList.GetNth(i); const Format &format = track.GetFormat(); const Info &info = track.GetInfo(); if (track.fileName != previousFile) out.OutputLine(String("FILE \"").Append(Utilities::GetRelativeFileName(track.fileName, actualFile)).Append("\" ").Append(GetFileType(track.fileName))); out.OutputLine(String(" TRACK ").Append(i < 9 ? "0" : NIL).Append(String::FromInt(i + 1)).Append(" AUDIO")); if ((track.cdTrack > 0 && info.mcdi.GetNthEntryPreEmphasis(track.cdTrack - 1)) || info.GetOtherInfo(INFO_PRE_EMPHASIS).ToInt()) out.OutputLine(" FLAGS PRE"); out.OutputLine(String(" TITLE \"").Append(info.title.Length() > 0 ? EscapeString(info.title) : i18n->TranslateString("unknown title")).Append("\"")); if (!artistConsistent || info.artist != artist) out.OutputLine(String(" PERFORMER \"").Append(info.artist.Length() > 0 ? EscapeString(info.artist) : i18n->TranslateString("unknown artist")).Append("\"")); if (!commentConsistent && info.comment != NIL && !replaceExistingComments) out.OutputLine(String(" REM COMMENT \"").Append(EscapeString(info.comment)).Append("\"")); if (info.isrc != NIL) out.OutputLine(String(" ISRC ").Append(info.isrc)); /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { out.OutputLine(String(" REM REPLAYGAIN_TRACK_GAIN ").Append(info.track_gain)); out.OutputLine(String(" REM REPLAYGAIN_TRACK_PEAK ").Append(info.track_peak)); } } /* Save index. */ Int64 minutes = track.sampleOffset / format.rate / 60; Int seconds = (track.sampleOffset - (minutes * 60 * format.rate)) / format.rate ; Int frames = (track.sampleOffset - (seconds * format.rate) - (minutes * 60 * format.rate)) * 75 / format.rate ; out.OutputLine(String(" INDEX 01 ").Append(minutes < 10 ? "0" : NIL).Append(String::FromInt(minutes)).Append(":") .Append(seconds < 10 ? "0" : NIL).Append(String::FromInt(seconds)).Append(":") .Append(frames < 10 ? "0" : NIL).Append(String::FromInt(frames ))); previousFile = track.fileName; } out.Close(); return Success(); } String BoCA::PlaylistCueSheet::GetFileType(const String &fileName) { String fileType = "WAVE"; if (fileName.ToLower().EndsWith(".mp3")) fileType = "MP3"; else if (fileName.ToLower().EndsWith(".aiff")) fileType = "AIFF"; return fileType; } String BoCA::PlaylistCueSheet::EscapeString(const String &string) { const Array &lines = string.Explode("\n"); String result; foreach (const String &line, lines) result.Append(result == NIL ? "" : " // ").Append(line.Trim().Replace("\"", "''")); return result; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/cuesheet/cuesheet.h000066400000000000000000000020531516712004000257750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistCueSheet) namespace BoCA { class PlaylistCueSheet : public CS::PlaylistComponent { private: String GetFileType(const String &); static String EscapeString(const String &); public: static const String &GetComponentSpecs(); PlaylistCueSheet(); ~PlaylistCueSheet(); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistCueSheet) BoCA_END_COMPONENT(PlaylistCueSheet) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/m3u/000077500000000000000000000000001516712004000227165ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/m3u/Makefile000066400000000000000000000011171516712004000243560ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = m3u TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = m3u.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/m3u/m3u.cpp000066400000000000000000000114631516712004000241330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "m3u.h" using namespace smooth::IO; const String &BoCA::PlaylistM3U::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ M3U Playlist \ 1.0 \ m3u-playlist \ playlist \ \ M3U Playlist \ m3u \ \ \ M3U Playlist (Unicode) \ m3u8 \ \ \ \ "; return componentSpecs; } BoCA::PlaylistM3U::PlaylistM3U() { } BoCA::PlaylistM3U::~PlaylistM3U() { } Bool BoCA::PlaylistM3U::CanOpenFile(const String &file) { String lcFile = file.ToLower(); return lcFile.EndsWith(".m3u") || lcFile.EndsWith(".m3u8"); } const Array &BoCA::PlaylistM3U::ReadPlaylist(const String &file) { InStream in(STREAM_FILE, file, IS_READ); /* Detect input format. */ String::InputFormat inputFormat("ISO-8859-1"); if (in.InputNumberRaw(3) == 0xEFBBBF) { /* Found UTF-8 BOM. */ String::SetInputFormat("UTF-8"); } else { in.Seek(0); /* Check for UTF-8, otherwise use ISO-8859-1. */ String data = in.InputString(in.Size()); String dataUTF; if (dataUTF.ImportFrom("UTF-8", data.ConvertTo("ISO-8859-1")) == Success() && dataUTF != data) { /* Encoding appears to be UTF-8. */ String::SetInputFormat("UTF-8"); } in.Seek(0); } /* Parse file line by line. */ while (in.GetPos() < in.Size()) { String line = in.InputLine(); if (line == NIL || line.StartsWith("#")) continue; /* Get file name. */ String fileName = line; /* Handle file:// URIs as written to .m3u files by VLC. */ if (fileName.StartsWith("file://")) { fileName = fileName.Tail(fileName.Length() - 7).Replace("/", Directory::GetDirectoryDelimiter()); fileName = Encoding::URLEncode::Decode(fileName); #ifdef __WIN32__ if (fileName.StartsWith(Directory::GetDirectoryDelimiter()) && fileName[2] == ':') fileName = fileName.Tail(fileName.Length() - 1); #endif } /* Handle relative paths. */ String resolvedFileName = fileName; if (Utilities::IsRelativePath(resolvedFileName)) resolvedFileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(resolvedFileName); /* If file is not found, try interpreting the file name using the default system encoding. */ if (!File(resolvedFileName).Exists()) { String::InputFormat inputFormat(String::GetDefaultEncoding()); String nativeFileName = fileName.ConvertTo("ISO-8859-1"); if (Utilities::IsRelativePath(nativeFileName)) nativeFileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(nativeFileName); if (File(nativeFileName).Exists()) resolvedFileName = nativeFileName; } /* Add track to track list. */ Track track; track.fileName = resolvedFileName; trackList.Add(track); } in.Close(); return trackList; } Error BoCA::PlaylistM3U::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); String::OutputFormat outputFormat(file.EndsWith(".m3u8") ? "UTF-8" : "ISO-8859-1"); String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) { Utilities::ErrorMessage("Could not create playlist file:\n\n%1", actualFile); return Error(); } BoCA::I18n *i18n = BoCA::I18n::Get(); out.OutputLine("#EXTM3U"); foreach (const Track &track, trackList) { /* Special handling for CD tracks on Windows. */ String fileName = Utilities::GetCDTrackFileName(track); /* Write info to file. */ const Info &info = track.GetInfo(); out.OutputLine(String("#EXTINF:") .Append(String::FromInt(track.length == -1 ? -1 : Math::Round((Float) track.length / track.GetFormat().rate))).Append(",") .Append(info.artist.Length() > 0 ? info.artist : i18n->TranslateString("unknown artist")).Append(" - ").Append(info.title.Length() > 0 ? info.title : i18n->TranslateString("unknown title"))); out.OutputLine(Utilities::GetRelativeFileName(fileName, actualFile)); } out.Close(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/m3u/m3u.h000066400000000000000000000020041516712004000235670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistM3U) namespace BoCA { class PlaylistM3U : public CS::PlaylistComponent { public: static const String &GetComponentSpecs(); PlaylistM3U(); ~PlaylistM3U(); Bool CanOpenFile(const String &); const Array &ReadPlaylist(const String &); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistM3U) BoCA_END_COMPONENT(PlaylistM3U) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/pls/000077500000000000000000000000001516712004000230105ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/pls/Makefile000066400000000000000000000011171516712004000244500ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = pls TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = pls.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/pls/pls.cpp000066400000000000000000000116441516712004000243200ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2020 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "pls.h" using namespace smooth::IO; const String &BoCA::PlaylistPLS::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ PLS Playlist \ 1.0 \ pls-playlist \ playlist \ \ PLS Playlist \ pls \ \ \ \ "; return componentSpecs; } BoCA::PlaylistPLS::PlaylistPLS() { } BoCA::PlaylistPLS::~PlaylistPLS() { } Bool BoCA::PlaylistPLS::CanOpenFile(const String &file) { InStream in(STREAM_FILE, file, IS_READ); /* Skip UTF-8 BOM. */ String::InputFormat inputFormat("ISO-8859-1"); if (in.InputNumberRaw(3) != 0xEFBBBF) in.Seek(0); /* Check file format. */ while (in.GetPos() < in.Size()) { String line = in.InputLine(); if (line == "[playlist]") return True; else if (line != NIL && !line.StartsWith(";")) return False; } return False; } const Array &BoCA::PlaylistPLS::ReadPlaylist(const String &file) { InStream in(STREAM_FILE, file, IS_READ); /* Detect input format. */ String::InputFormat inputFormat("ISO-8859-1"); if (in.InputNumberRaw(3) == 0xEFBBBF) { /* Found UTF-8 BOM. */ String::SetInputFormat("UTF-8"); } else { in.Seek(0); /* Check for UTF-8, otherwise use ISO-8859-1. */ String data = in.InputString(in.Size()); String dataUTF; if (dataUTF.ImportFrom("UTF-8", data.ConvertTo("ISO-8859-1")) == Success() && dataUTF != data) { /* Encoding appears to be UTF-8. */ String::SetInputFormat("UTF-8"); } in.Seek(0); } /* Parse file line by line. */ while (in.GetPos() < in.Size()) { String line = in.InputLine(); if (!line.StartsWith("File")) continue; /* Get file name. */ String fileName = line.Tail(line.Length() - line.Find("=") - 1); /* Handle relative paths. */ String resolvedFileName = fileName; if (Utilities::IsRelativePath(resolvedFileName)) resolvedFileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(resolvedFileName); /* If file is not found, try interpreting the file name using the default system encoding. */ if (!File(resolvedFileName).Exists()) { String::InputFormat inputFormat(String::GetDefaultEncoding()); String nativeFileName = fileName.ConvertTo("ISO-8859-1"); if (Utilities::IsRelativePath(nativeFileName)) nativeFileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(nativeFileName); if (File(nativeFileName).Exists()) resolvedFileName = nativeFileName; } /* Add track to track list. */ Track track; track.fileName = resolvedFileName; trackList.Add(track); } in.Close(); return trackList; } Error BoCA::PlaylistPLS::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); String::OutputFormat outputFormat("ISO-8859-1"); String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) { Utilities::ErrorMessage("Could not create playlist file:\n\n%1", actualFile); return Error(); } BoCA::I18n *i18n = BoCA::I18n::Get(); out.OutputLine("[playlist]"); out.OutputLine("Version=2"); out.OutputLine(NIL); out.OutputLine(String("NumberOfEntries=").Append(String::FromInt(trackList.Length()))); for (Int i = 0; i < trackList.Length(); i++) { const Track &track = trackList.GetNth(i); /* Special handling for CD tracks on Windows. */ String fileName = Utilities::GetCDTrackFileName(track); /* Write info to file. */ const Info &info = track.GetInfo(); out.OutputLine(NIL); out.OutputLine(String("File").Append(String::FromInt(i + 1)).Append("=").Append(Utilities::GetRelativeFileName(fileName, actualFile))); out.OutputLine(String("Title").Append(String::FromInt(i + 1)).Append("=").Append(info.artist.Length() > 0 ? info.artist : i18n->TranslateString("unknown artist")).Append(" - ").Append(info.title.Length() > 0 ? info.title : i18n->TranslateString("unknown title"))); out.OutputLine(String("Length").Append(String::FromInt(i + 1)).Append("=").Append(String::FromInt(track.length == -1 ? -1 : Math::Round((Float) track.length / track.GetFormat().rate)))); } out.Close(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/pls/pls.h000066400000000000000000000020041516712004000237530ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistPLS) namespace BoCA { class PlaylistPLS : public CS::PlaylistComponent { public: static const String &GetComponentSpecs(); PlaylistPLS(); ~PlaylistPLS(); Bool CanOpenFile(const String &); const Array &ReadPlaylist(const String &); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistPLS) BoCA_END_COMPONENT(PlaylistPLS) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/vclt/000077500000000000000000000000001516712004000231625ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/vclt/Makefile000066400000000000000000000011211516712004000246150ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = vclt TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = vclt.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/vclt/vclt.cpp000066400000000000000000000111351516712004000246370ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "vclt.h" using namespace smooth::IO; const String &BoCA::PlaylistVCLT::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ VCLT Playlist \ 1.0 \ vclt-playlist \ playlist \ \ VCLT Playlist \ vclt \ \ \ \ "; return componentSpecs; } BoCA::PlaylistVCLT::PlaylistVCLT() { } BoCA::PlaylistVCLT::~PlaylistVCLT() { } Bool BoCA::PlaylistVCLT::CanOpenFile(const String &file) { return file.ToLower().EndsWith(".vclt"); } const Array &BoCA::PlaylistVCLT::ReadPlaylist(const String &file) { String::InputFormat inputFormat("UTF-8"); InStream in(STREAM_FILE, file, IS_READ); while (in.GetPos() < in.Size()) { String line = in.InputLine(); if (!line.StartsWith("FILENAME=")) continue; /* Get file name. */ String fileName = line.Tail(line.Length() - 9); /* Handle relative paths. */ if (Utilities::IsRelativePath(fileName)) fileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(fileName); /* Add track to track list. */ Track track; track.fileName = fileName; trackList.Add(track); } in.Close(); return trackList; } Error BoCA::PlaylistVCLT::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); String::OutputFormat outputFormat("UTF-8"); String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) { Utilities::ErrorMessage("Could not create playlist file:\n\n%1", actualFile); return Error(); } foreach (const Track &track, trackList) { /* Special handling for CD tracks on Windows. */ String fileName = Utilities::GetCDTrackFileName(track); /* Convert directory delimiters unless drive is mentioned. */ fileName = Utilities::GetRelativeFileName(fileName, actualFile); if (fileName[1] != ':') fileName.Replace("\\", "/"); /* Write info to file. */ const Info &info = track.GetInfo(); const Format &format = track.GetFormat(); out.OutputString(String("FILENAME=").Append(fileName).Append("\n")); out.OutputString(String("AUDIOINFO=").Append("rate:").Append(String::FromInt(format.rate)).Append("Hz ") .Append("bits:").Append(String::FromInt(format.bits)).Append(" ") .Append("channels:").Append(String::FromInt(format.channels)).Append("\n")); if (track.length >= 0 || track.approxLength >= 0) { Int64 mseconds = 0; if (track.length >= 0) mseconds = Math::Round(Float(track.length) / (Float(format.rate) / 1000)); else if (track.approxLength >= 0) mseconds = Math::Round(Float(track.approxLength) / (Float(format.rate) / 1000)); Int hours = mseconds / 1000 / 3600; Int minutes = mseconds / 1000 % 3600 / 60; Int seconds = mseconds / 1000 % 3600 % 60; Int msecs = mseconds % 1000; out.OutputString(String("LENGTH=").Append(hours > 0 ? String( hours < 10 ? "0" : NIL).Append(String::FromInt(hours)).Append(":") : String()) .Append( String( minutes < 10 ? "0" : NIL).Append(String::FromInt(minutes))).Append(":") .Append( String( seconds < 10 ? "0" : NIL).Append(String::FromInt(seconds))).Append(".") .Append( String(msecs < 10 ? "00" : msecs < 100 ? "0" : NIL).Append(String::FromInt(msecs))).Append("\n")); } if (info.artist != NIL) out.OutputString(String("ARTIST=").Append(info.artist).Append("\n")); if (info.title != NIL) out.OutputString(String("TITLE=").Append(info.title).Append("\n")); if (info.album != NIL) out.OutputString(String("ALBUM=").Append(info.album).Append("\n")); if (info.track > 0) out.OutputString(String("TRACKNUMBER=").Append(String(info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track))).Append("\n")); out.OutputString("==\n"); } out.Close(); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/vclt/vclt.h000066400000000000000000000020121516712004000242760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistVCLT) namespace BoCA { class PlaylistVCLT : public CS::PlaylistComponent { public: static const String &GetComponentSpecs(); PlaylistVCLT(); ~PlaylistVCLT(); Bool CanOpenFile(const String &); const Array &ReadPlaylist(const String &); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistVCLT) BoCA_END_COMPONENT(PlaylistVCLT) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/wpl/000077500000000000000000000000001516712004000230145ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/wpl/Makefile000066400000000000000000000011171516712004000244540ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wpl TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = wpl.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/wpl/wpl.cpp000066400000000000000000000105121516712004000243210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "wpl.h" using namespace smooth::IO; const String &BoCA::PlaylistWPL::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Windows Media Playlist \ 1.0 \ wpl-playlist \ playlist \ \ Windows Media Playlist \ wpl \ \ \ \ "; return componentSpecs; } BoCA::PlaylistWPL::PlaylistWPL() { } BoCA::PlaylistWPL::~PlaylistWPL() { } Bool BoCA::PlaylistWPL::CanOpenFile(const String &file) { InStream in(STREAM_FILE, file, IS_READ); if (in.InputLine().Contains(" &BoCA::PlaylistWPL::ReadPlaylist(const String &file) { /* Read file and replace WPL marker with XML. */ String format = String::SetInputFormat("UTF-8"); InStream in(STREAM_FILE, file, IS_READ); String wpl = in.InputString(in.Size()).Replace("ParseMemory(wplChar, strlen(wplChar)); XML::Node *body = doc->GetRootNode()->GetNodeByName("body"); if (body == NIL) { delete doc; return trackList; } XML::Node *seq = body->GetNodeByName("seq"); if (seq == NIL) { delete doc; return trackList; } for (Int i = 0; i < seq->GetNOfNodes(); i++) { XML::Node *media = seq->GetNthNode(i); if (media->GetName() != "media") continue; XML::Attribute *src = media->GetAttributeByName("src"); if (src == NIL) continue; /* Get file name. */ String fileName = src->GetContent(); /* Handle relative paths. */ if (Utilities::IsRelativePath(fileName)) fileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(fileName); /* Add track to track list. */ Track track; track.fileName = fileName; trackList.Add(track); } delete doc; return trackList; } Error BoCA::PlaylistWPL::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) { Utilities::ErrorMessage("Could not create playlist file:\n\n%1", actualFile); return Error(); } /* Create XML document. */ XML::Document *doc = new XML::Document(); XML::Node *smil = new XML::Node("smil"); XML::Node *head = smil->AddNode("head"); XML::Node *itemCount = head->AddNode("meta"); itemCount->SetAttribute("name", "ItemCount"); itemCount->SetAttribute("content", String::FromInt(trackList.Length())); XML::Node *body = smil->AddNode("body"); XML::Node *seq = body->AddNode("seq"); /* Add tracks. */ foreach (const Track &track, trackList) { /* Special handling for CD tracks on Windows. */ String fileName = Utilities::GetRelativeFileName(Utilities::GetCDTrackFileName(track), actualFile); /* Add info to XML. */ XML::Node *media = seq->AddNode("media"); media->SetAttribute("src", fileName); } /* Write XML to temporary file. */ doc->SetEncoding("UTF-8"); doc->SetRootNode(smil); doc->SaveFile(String(actualFile).Append(".xml")); delete doc; delete smil; /* Convert to WPL and clean up. */ String::InputFormat inputFormat("UTF-8"); String::OutputFormat outputFormat("UTF-8"); InStream in(STREAM_FILE, String(actualFile).Append(".xml"), IS_READ); String wpl = in.InputString(in.Size()).Replace(" * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistWPL) namespace BoCA { class PlaylistWPL : public CS::PlaylistComponent { public: static const String &GetComponentSpecs(); PlaylistWPL(); ~PlaylistWPL(); Bool CanOpenFile(const String &); const Array &ReadPlaylist(const String &); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistWPL) BoCA_END_COMPONENT(PlaylistWPL) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/000077500000000000000000000000001516712004000231725ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/Makefile000066400000000000000000000031531516712004000246340ustar00rootroot00000000000000########## BoCA component makefile ########## .NOTPARALLEL: # Change these variables to fit your project: TARGET = xspf TYPE = playlist VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = xspf.o # Enter additional defines here: DEFINE = ifeq ($(USE_BUNDLED_LIBEXPAT),True) DEFINE += -I"$(SRCDIR)"/expat endif ifeq ($(USE_BUNDLED_LIBURIPARSER),True) DEFINE += -I"$(SRCDIR)" endif ifeq ($(USE_BUNDLED_LIBXSPF),True) DEFINE += -I"$(SRCDIR)" endif # Enter additional library dependencies here: ifeq ($(USE_BUNDLED_LIBXSPF),True) LIBS = xspf/libxspf.a else LIBS = -lxspf endif ifeq ($(USE_BUNDLED_LIBEXPAT),True) LIBS += expat/libexpat.a else LIBS += -lexpat endif ifeq ($(USE_BUNDLED_LIBURIPARSER),True) LIBS += uriparser/liburiparser.a else LIBS += -luriparser endif # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = ifeq ($(USE_BUNDLED_LIBEXPAT),True) ALLCMD1 += $(call makein,expat) CLEANCMD1 += $(call cleanin,expat) endif ifeq ($(USE_BUNDLED_LIBURIPARSER),True) ifneq ($(ALLCMD1),) ALLCMD1 += && CLEANCMD1 += && endif ALLCMD1 += $(call makein,uriparser) CLEANCMD1 += $(call cleanin,uriparser) endif ifeq ($(USE_BUNDLED_LIBXSPF),True) ifneq ($(ALLCMD1),) ALLCMD1 += && CLEANCMD1 += && endif ALLCMD1 += $(call makein,xspf) CLEANCMD1 += $(call cleanin,xspf) endif INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/000077500000000000000000000000001516712004000243135ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/Makefile000066400000000000000000000006341516712004000257560ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = xmlparse.o xmlrole.o xmltok.o TARGET = libexpat.a CCOPTS = -I"$(SRCDIR)" -DHAVE_EXPAT_CONFIG_H AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/ascii.h000066400000000000000000000071421516712004000255600ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1999-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2007 Karl Waclawek Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define ASCII_A 0x41 #define ASCII_B 0x42 #define ASCII_C 0x43 #define ASCII_D 0x44 #define ASCII_E 0x45 #define ASCII_F 0x46 #define ASCII_G 0x47 #define ASCII_H 0x48 #define ASCII_I 0x49 #define ASCII_J 0x4A #define ASCII_K 0x4B #define ASCII_L 0x4C #define ASCII_M 0x4D #define ASCII_N 0x4E #define ASCII_O 0x4F #define ASCII_P 0x50 #define ASCII_Q 0x51 #define ASCII_R 0x52 #define ASCII_S 0x53 #define ASCII_T 0x54 #define ASCII_U 0x55 #define ASCII_V 0x56 #define ASCII_W 0x57 #define ASCII_X 0x58 #define ASCII_Y 0x59 #define ASCII_Z 0x5A #define ASCII_a 0x61 #define ASCII_b 0x62 #define ASCII_c 0x63 #define ASCII_d 0x64 #define ASCII_e 0x65 #define ASCII_f 0x66 #define ASCII_g 0x67 #define ASCII_h 0x68 #define ASCII_i 0x69 #define ASCII_j 0x6A #define ASCII_k 0x6B #define ASCII_l 0x6C #define ASCII_m 0x6D #define ASCII_n 0x6E #define ASCII_o 0x6F #define ASCII_p 0x70 #define ASCII_q 0x71 #define ASCII_r 0x72 #define ASCII_s 0x73 #define ASCII_t 0x74 #define ASCII_u 0x75 #define ASCII_v 0x76 #define ASCII_w 0x77 #define ASCII_x 0x78 #define ASCII_y 0x79 #define ASCII_z 0x7A #define ASCII_0 0x30 #define ASCII_1 0x31 #define ASCII_2 0x32 #define ASCII_3 0x33 #define ASCII_4 0x34 #define ASCII_5 0x35 #define ASCII_6 0x36 #define ASCII_7 0x37 #define ASCII_8 0x38 #define ASCII_9 0x39 #define ASCII_TAB 0x09 #define ASCII_SPACE 0x20 #define ASCII_EXCL 0x21 #define ASCII_QUOT 0x22 #define ASCII_AMP 0x26 #define ASCII_APOS 0x27 #define ASCII_MINUS 0x2D #define ASCII_PERIOD 0x2E #define ASCII_COLON 0x3A #define ASCII_SEMI 0x3B #define ASCII_LT 0x3C #define ASCII_EQUALS 0x3D #define ASCII_GT 0x3E #define ASCII_LSQB 0x5B #define ASCII_RSQB 0x5D #define ASCII_UNDERSCORE 0x5F #define ASCII_LPAREN 0x28 #define ASCII_RPAREN 0x29 #define ASCII_FF 0x0C #define ASCII_SLASH 0x2F #define ASCII_HASH 0x23 #define ASCII_PIPE 0x7C #define ASCII_COMMA 0x2C boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/asciitab.h000066400000000000000000000067001516712004000262460ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/expat.h000066400000000000000000001272751516712004000256230ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2000-2005 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2016 Cristian Rodríguez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James Copyright (c) 2022 Thijs Schreijer Copyright (c) 2023 Hanno Böck Copyright (c) 2023 Sony Corporation / Snild Dolkow Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> Copyright (c) 2025 Matthew Fernandez Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef Expat_INCLUDED # define Expat_INCLUDED 1 # include # include "expat_external.h" # ifdef __cplusplus extern "C" { # endif struct XML_ParserStruct; typedef struct XML_ParserStruct *XML_Parser; typedef unsigned char XML_Bool; # define XML_TRUE ((XML_Bool)1) # define XML_FALSE ((XML_Bool)0) /* The XML_Status enum gives the possible return values for several API functions. The preprocessor #defines are included so this stanza can be added to code that still needs to support older versions of Expat 1.95.x: #ifndef XML_STATUS_OK #define XML_STATUS_OK 1 #define XML_STATUS_ERROR 0 #endif Otherwise, the #define hackery is quite ugly and would have been dropped. */ enum XML_Status { XML_STATUS_ERROR = 0, # define XML_STATUS_ERROR XML_STATUS_ERROR XML_STATUS_OK = 1, # define XML_STATUS_OK XML_STATUS_OK XML_STATUS_SUSPENDED = 2 # define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED }; enum XML_Error { XML_ERROR_NONE, XML_ERROR_NO_MEMORY, XML_ERROR_SYNTAX, XML_ERROR_NO_ELEMENTS, XML_ERROR_INVALID_TOKEN, XML_ERROR_UNCLOSED_TOKEN, XML_ERROR_PARTIAL_CHAR, XML_ERROR_TAG_MISMATCH, XML_ERROR_DUPLICATE_ATTRIBUTE, XML_ERROR_JUNK_AFTER_DOC_ELEMENT, XML_ERROR_PARAM_ENTITY_REF, XML_ERROR_UNDEFINED_ENTITY, XML_ERROR_RECURSIVE_ENTITY_REF, XML_ERROR_ASYNC_ENTITY, XML_ERROR_BAD_CHAR_REF, XML_ERROR_BINARY_ENTITY_REF, XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, XML_ERROR_MISPLACED_XML_PI, XML_ERROR_UNKNOWN_ENCODING, XML_ERROR_INCORRECT_ENCODING, XML_ERROR_UNCLOSED_CDATA_SECTION, XML_ERROR_EXTERNAL_ENTITY_HANDLING, XML_ERROR_NOT_STANDALONE, XML_ERROR_UNEXPECTED_STATE, XML_ERROR_ENTITY_DECLARED_IN_PE, XML_ERROR_FEATURE_REQUIRES_XML_DTD, XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, /* Added in 1.95.7. */ XML_ERROR_UNBOUND_PREFIX, /* Added in 1.95.8. */ XML_ERROR_UNDECLARING_PREFIX, XML_ERROR_INCOMPLETE_PE, XML_ERROR_XML_DECL, XML_ERROR_TEXT_DECL, XML_ERROR_PUBLICID, XML_ERROR_SUSPENDED, XML_ERROR_NOT_SUSPENDED, XML_ERROR_ABORTED, XML_ERROR_FINISHED, XML_ERROR_SUSPEND_PE, /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS, XML_ERROR_RESERVED_NAMESPACE_URI, /* Added in 2.2.1. */ XML_ERROR_INVALID_ARGUMENT, /* Added in 2.3.0. */ XML_ERROR_NO_BUFFER, /* Added in 2.4.0. */ XML_ERROR_AMPLIFICATION_LIMIT_BREACH, /* Added in 2.6.4. */ XML_ERROR_NOT_STARTED, }; enum XML_Content_Type { XML_CTYPE_EMPTY = 1, XML_CTYPE_ANY, XML_CTYPE_MIXED, XML_CTYPE_NAME, XML_CTYPE_CHOICE, XML_CTYPE_SEQ }; enum XML_Content_Quant { XML_CQUANT_NONE, XML_CQUANT_OPT, XML_CQUANT_REP, XML_CQUANT_PLUS }; /* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be XML_CQUANT_NONE, and the other fields will be zero or NULL. If type == XML_CTYPE_MIXED, then quant will be NONE or REP and numchildren will contain number of elements that may be mixed in and children point to an array of XML_Content cells that will be all of XML_CTYPE_NAME type with no quantification. If type == XML_CTYPE_NAME, then the name points to the name, and the numchildren field will be zero and children will be NULL. The quant fields indicates any quantifiers placed on the name. CHOICE and SEQ will have name NULL, the number of children in numchildren and children will point, recursively, to an array of XML_Content cells. The EMPTY, ANY, and MIXED types will only occur at top level. */ typedef struct XML_cp XML_Content; struct XML_cp { enum XML_Content_Type type; enum XML_Content_Quant quant; XML_Char *name; unsigned int numchildren; XML_Content *children; }; /* This is called for an element declaration. See above for description of the model argument. It's the user code's responsibility to free model when finished with it. See XML_FreeContentModel. There is no need to free the model from the handler, it can be kept around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, XML_Content *model); XMLPARSEAPI(void) XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); /* The Attlist declaration handler is called for *each* attribute. So a single Attlist declaration with multiple attributes declared will generate multiple calls to this handler. The "default" parameter may be NULL in the case of the "#IMPLIED" or "#REQUIRED" keyword. The "isrequired" parameter will be true and the default value will be NULL in the case of "#REQUIRED". If "isrequired" is true and default is non-NULL, then this is a "#FIXED" default. */ typedef void(XMLCALL *XML_AttlistDeclHandler)( void *userData, const XML_Char *elname, const XML_Char *attname, const XML_Char *att_type, const XML_Char *dflt, int isrequired); XMLPARSEAPI(void) XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); /* The XML declaration handler is called for *both* XML declarations and text declarations. The way to distinguish is that the version parameter will be NULL for text declarations. The encoding parameter may be NULL for XML declarations. The standalone parameter will be -1, 0, or 1 indicating respectively that there was no standalone parameter in the declaration, that it was given as no, or that it was given as yes. */ typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, const XML_Char *version, const XML_Char *encoding, int standalone); XMLPARSEAPI(void) XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); typedef struct { void *(*malloc_fcn)(size_t size); void *(*realloc_fcn)(void *ptr, size_t size); void (*free_fcn)(void *ptr); } XML_Memory_Handling_Suite; /* Constructs a new parser; encoding is the encoding specified by the external protocol or NULL if there is none specified. */ XMLPARSEAPI(XML_Parser) XML_ParserCreate(const XML_Char *encoding); /* Constructs a new parser and namespace processor. Element type names and attribute names that belong to a namespace will be expanded; unprefixed attribute names are never expanded; unprefixed element type names are expanded only if there is a default namespace. The expanded name is the concatenation of the namespace URI, the namespace separator character, and the local part of the name. If the namespace separator is '\0' then the namespace URI and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). If a namespace separator is chosen that can be part of a URI or part of an XML name, splitting an expanded name back into its 1, 2 or 3 original parts on application level in the element handler may end up vulnerable, so these are advised against; sane choices for a namespace separator are e.g. '\n' (line feed) and '|' (pipe). Note that Expat does not validate namespace URIs (beyond encoding) against RFC 3986 today (and is not required to do so with regard to the XML 1.0 namespaces specification) but it may start doing that in future releases. Before that, an application using Expat must be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); /* Constructs a new parser using the memory management suite referred to by memsuite. If memsuite is NULL, then use the standard library memory suite. If namespaceSeparator is non-NULL it creates a parser with namespace processing as described above. The character pointed at will serve as the namespace separator. All further memory operations used for the created parser will come from the given suite. */ XMLPARSEAPI(XML_Parser) XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *namespaceSeparator); /* Prepare a parser object to be reused. This is particularly valuable when memory allocation overhead is disproportionately high, such as when a large number of small documents need to be parsed. All handlers are cleared from the parser, except for the unknownEncodingHandler. The parser's external state is re-initialized except for the values of ns and ns_triplets. Added in Expat 1.95.3. */ XMLPARSEAPI(XML_Bool) XML_ParserReset(XML_Parser parser, const XML_Char *encoding); /* atts is array of name/value pairs, terminated by 0; names and values are 0 terminated. */ typedef void(XMLCALL *XML_StartElementHandler)(void *userData, const XML_Char *name, const XML_Char **atts); typedef void(XMLCALL *XML_EndElementHandler)(void *userData, const XML_Char *name); /* s is not 0 terminated. */ typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, const XML_Char *s, int len); /* target and data are 0 terminated */ typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, const XML_Char *target, const XML_Char *data); /* data is 0 terminated */ typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); /* This is called for any characters in the XML document for which there is no applicable handler. This includes both characters that are part of markup which is of a kind that is not reported (comments, markup declarations), or characters that are part of a construct which could be reported but for which no handler has been supplied. The characters are passed exactly as they were in the XML document except that they will be encoded in UTF-8 or UTF-16. Line boundaries are not normalized. Note that a byte order mark character is not passed to the default handler. There are no guarantees about how characters are divided between calls to the default handler: for example, a comment might be split between multiple calls. */ typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, int len); /* This is called for the start of the DOCTYPE declaration, before any DTD or internal subset is parsed. */ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *doctypeName, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset); /* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); /* This is called for entity declarations. The is_parameter_entity argument will be non-zero if the entity is a parameter entity, zero otherwise. For internal entities (), value will be non-NULL and systemId, publicID, and notationName will be NULL. The value string is NOT null-terminated; the length is provided in the value_length argument. Since it is legal to have zero-length values, do not use this argument to test for internal entities. For external entities, value will be NULL and systemId will be non-NULL. The publicId argument will be NULL unless a public identifier was provided. The notationName argument will have a non-NULL value only for unparsed entity declarations. Note that is_parameter_entity can't be changed to XML_Bool, since that would break binary compatibility. */ typedef void(XMLCALL *XML_EntityDeclHandler)( void *userData, const XML_Char *entityName, int is_parameter_entity, const XML_Char *value, int value_length, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); XMLPARSEAPI(void) XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity. The base argument is whatever was set by XML_SetBase. The entityName, systemId and notationName arguments will never be NULL. The other arguments may be. */ typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); /* This is called for a declaration of notation. The base argument is whatever was set by XML_SetBase. The notationName will never be NULL. The other arguments can be. */ typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* When namespace processing is enabled, these are called once for each namespace declaration. The call to the start and end element handlers occur between the calls to the start and end namespace declaration handlers. For an xmlns attribute, prefix will be NULL. For an xmlns="" attribute, uri will be NULL. */ typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, const XML_Char *prefix, const XML_Char *uri); typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, const XML_Char *prefix); /* This is called if the document is not standalone, that is, it has an external subset or a reference to a parameter entity, but does not have standalone="yes". If this handler returns XML_STATUS_ERROR, then processing will not continue, and the parser will return a XML_ERROR_NOT_STANDALONE error. If parameter entity parsing is enabled, then in addition to the conditions above this handler will only be called if the referenced entity was actually read. */ typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The application can parse it immediately or later using XML_ExternalEntityParserCreate. The parser argument is the parser parsing the entity containing the reference; it can be passed as the parser argument to XML_ExternalEntityParserCreate. The systemId argument is the system identifier as specified in the entity declaration; it will not be NULL. The base argument is the system identifier that should be used as the base for resolving systemId if systemId was relative; this is set by XML_SetBase; it may be NULL. The publicId argument is the public identifier as specified in the entity declaration, or NULL if none was specified; the whitespace in the public identifier will have been normalized as required by the XML spec. The context argument specifies the parsing context in the format expected by the context argument to XML_ExternalEntityParserCreate; context is valid only until the handler returns, so if the referenced entity is to be parsed later, it must be copied. context is NULL only when the entity is a parameter entity. The handler should return XML_STATUS_ERROR if processing should not continue because of a fatal error in the handling of the external entity. In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING error. Note that unlike other handlers the first argument is the parser, not userData. */ typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* This is called in two situations: 1) An entity reference is encountered for which no declaration has been read *and* this is not an error. 2) An internal entity reference is read, but not expanded, because XML_SetDefaultHandler has been called. Note: skipped parameter entities in declarations and skipped general entities in attribute values cannot be reported, because the event would be out of sync with the reporting of the declarations or attribute values */ typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, const XML_Char *entityName, int is_parameter_entity); /* This structure is filled in by the XML_UnknownEncodingHandler to provide information to the parser about encodings that are unknown to the parser. The map[b] member gives information about byte sequences whose first byte is b. If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. If map[b] is -1, then the byte sequence is malformed. If map[b] is -n, where n >= 2, then b is the first byte of an n-byte sequence that encodes a single Unicode scalar value. The data member will be passed as the first argument to the convert function. The convert function is used to convert multibyte sequences; s will point to a n-byte sequence where map[(unsigned char)*s] == -n. The convert function must return the Unicode scalar value represented by this byte sequence or -1 if the byte sequence is malformed. The convert function may be NULL if the encoding is a single-byte encoding, that is if map[b] >= -1 for all bytes b. When the parser is finished with the encoding, then if release is not NULL, it will call release passing it the data member; once release has been called, the convert function will not be called again. Expat places certain restrictions on the encodings that are supported using this mechanism. 1. Every ASCII character that can appear in a well-formed XML document, other than the characters $@\^`{}~ must be represented by a single byte, and that byte must be the same byte that represents that character in ASCII. 2. No character may require more than 4 bytes to encode. 3. All characters encoded must have Unicode scalar values <= 0xFFFF, (i.e., characters that would be encoded by surrogates in UTF-16 are not allowed). Note that this restriction doesn't apply to the built-in support for UTF-8 and UTF-16. 4. No Unicode character may be encoded by more than one distinct sequence of bytes. */ typedef struct { int map[256]; void *data; int(XMLCALL *convert)(void *data, const char *s); void(XMLCALL *release)(void *data); } XML_Encoding; /* This is called for an encoding that is unknown to the parser. The encodingHandlerData argument is that which was passed as the second argument to XML_SetUnknownEncodingHandler. The name argument gives the name of the encoding as specified in the encoding declaration. If the callback can provide information about the encoding, it must fill in the XML_Encoding structure, and return XML_STATUS_OK. Otherwise it must return XML_STATUS_ERROR. If info does not describe a suitable encoding, then the parser will return an XML_ERROR_UNKNOWN_ENCODING error. */ typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); XMLPARSEAPI(void) XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end); XMLPARSEAPI(void) XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); XMLPARSEAPI(void) XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); XMLPARSEAPI(void) XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler); XMLPARSEAPI(void) XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler); XMLPARSEAPI(void) XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); XMLPARSEAPI(void) XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end); XMLPARSEAPI(void) XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start); XMLPARSEAPI(void) XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end); /* This sets the default handler and also inhibits expansion of internal entities. These entity references will be passed to the default handler, or to the skipped entity handler, if one is set. */ XMLPARSEAPI(void) XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); /* This sets the default handler but does not inhibit expansion of internal entities. The entity reference will not be passed to the default handler. */ XMLPARSEAPI(void) XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); XMLPARSEAPI(void) XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start); XMLPARSEAPI(void) XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); XMLPARSEAPI(void) XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler); XMLPARSEAPI(void) XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); XMLPARSEAPI(void) XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end); XMLPARSEAPI(void) XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start); XMLPARSEAPI(void) XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end); XMLPARSEAPI(void) XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler); XMLPARSEAPI(void) XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler); /* If a non-NULL value for arg is specified here, then it will be passed as the first argument to the external entity ref handler instead of the parser object. */ XMLPARSEAPI(void) XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); XMLPARSEAPI(void) XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler); XMLPARSEAPI(void) XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData); /* This can be called within a handler for a start element, end element, processing instruction or character data. It causes the corresponding markup to be passed to the default handler. */ XMLPARSEAPI(void) XML_DefaultCurrent(XML_Parser parser); /* If do_nst is non-zero, and namespace processing is in effect, and a name has a prefix (i.e. an explicit namespace qualifier) then that name is returned as a triplet in a single string separated by the separator character specified when the parser was created: URI + sep + local_name + sep + prefix. If do_nst is zero, then namespace information is returned in the default manner (URI + sep + local_name) whether or not the name has a prefix. Note: Calling XML_SetReturnNSTriplet after XML_Parse or XML_ParseBuffer has no effect. */ XMLPARSEAPI(void) XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); /* This value is passed as the userData argument to callbacks. */ XMLPARSEAPI(void) XML_SetUserData(XML_Parser parser, void *userData); /* Returns the last value set by XML_SetUserData or NULL. */ # define XML_GetUserData(parser) (*(void **)(parser)) /* This is equivalent to supplying an encoding argument to XML_ParserCreate. On success XML_SetEncoding returns non-zero, zero otherwise. Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer has no effect and returns XML_STATUS_ERROR. */ XMLPARSEAPI(enum XML_Status) XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); /* If this function is called, then the parser will be passed as the first argument to callbacks instead of userData. The userData will still be accessible using XML_GetUserData. */ XMLPARSEAPI(void) XML_UseParserAsHandlerArg(XML_Parser parser); /* If useDTD == XML_TRUE is passed to this function, then the parser will assume that there is an external subset, even if none is specified in the document. In such a case the parser will call the externalEntityRefHandler with a value of NULL for the systemId argument (the publicId and context arguments will be NULL as well). Note: For the purpose of checking WFC: Entity Declared, passing useDTD == XML_TRUE will make the parser behave as if the document had a DTD with an external subset. Note: If this function is called, then this must be done before the first call to XML_Parse or XML_ParseBuffer, since it will have no effect after that. Returns XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. Note: If the document does not have a DOCTYPE declaration at all, then startDoctypeDeclHandler and endDoctypeDeclHandler will not be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD. Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); /* Sets the base to be used for resolving relative URIs in system identifiers in declarations. Resolving relative identifiers is left to the application: this value will be passed through as the base argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base argument will be copied. Returns XML_STATUS_ERROR if out of memory, XML_STATUS_OK otherwise. */ XMLPARSEAPI(enum XML_Status) XML_SetBase(XML_Parser parser, const XML_Char *base); XMLPARSEAPI(const XML_Char *) XML_GetBase(XML_Parser parser); /* Returns the number of the attribute/value pairs passed in last call to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this corresponds to an index into the atts array passed to the XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to XML_StartElementHandler, or -1 if there is no ID attribute or parser == NULL. Each attribute/value pair counts as 2; thus this corresponds to an index into the atts array passed to the XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); # ifdef XML_ATTR_INFO /* Source file byte offsets for the start and end of attribute names and values. The value indices are exclusive of surrounding quotes; thus in a UTF-8 source file an attribute value of "blah" will yield: info->valueEnd - info->valueStart = 4 bytes. */ typedef struct { XML_Index nameStart; /* Offset to beginning of the attribute name. */ XML_Index nameEnd; /* Offset after the attribute name's last byte. */ XML_Index valueStart; /* Offset to beginning of the attribute value. */ XML_Index valueEnd; /* Offset after the attribute value's last byte. */ } XML_AttrInfo; /* Returns an array of XML_AttrInfo structures for the attribute/value pairs passed in last call to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 1; thus the number of entries in the array is XML_GetSpecifiedAttributeCount(parser) / 2. */ XMLPARSEAPI(const XML_AttrInfo *) XML_GetAttributeInfo(XML_Parser parser); # endif /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). Though the return values for these functions has always been described as a Boolean value, the implementation, at least for the 1.95.x series, has always returned exactly one of the XML_Status values. */ XMLPARSEAPI(enum XML_Status) XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); XMLPARSEAPI(void *) XML_GetBuffer(XML_Parser parser, int len); XMLPARSEAPI(enum XML_Status) XML_ParseBuffer(XML_Parser parser, int len, int isFinal); /* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. Must be called from within a call-back handler, except when aborting (resumable = 0) an already suspended parser. Some call-backs may still follow because they would otherwise get lost. Examples: - endElementHandler() for empty elements when stopped in startElementHandler(), - endNameSpaceDeclHandler() when stopped in endElementHandler(), and possibly others. Can be called from most handlers, including DTD related call-backs, except when parsing an external parameter entity and resumable != 0. Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. Possible error codes: - XML_ERROR_SUSPENDED: when suspending an already suspended parser. - XML_ERROR_FINISHED: when the parser has already finished. - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. When resumable != 0 (true) then parsing is suspended, that is, XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. *Note*: This will be applied to the current parser instance only, that is, if there is a parent parser then it will continue parsing when the externalEntityRefHandler() returns. It is up to the implementation of the externalEntityRefHandler() to call XML_StopParser() on the parent parser (recursively), if one wants to stop parsing altogether. When suspended, parsing can be resumed by calling XML_ResumeParser(). */ XMLPARSEAPI(enum XML_Status) XML_StopParser(XML_Parser parser, XML_Bool resumable); /* Resumes parsing after it has been suspended with XML_StopParser(). Must not be called from within a handler call-back. Returns same status codes as XML_Parse() or XML_ParseBuffer(). Additional error code XML_ERROR_NOT_SUSPENDED possible. *Note*: This must be called on the most deeply nested child parser instance first, and on its parent parser only after the child parser has finished, to be applied recursively until the document entity's parser is restarted. That is, the parent parser will not resume by itself and it is up to the application to call XML_ResumeParser() on it at the appropriate moment. */ XMLPARSEAPI(enum XML_Status) XML_ResumeParser(XML_Parser parser); enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; typedef struct { enum XML_Parsing parsing; XML_Bool finalBuffer; } XML_ParsingStatus; /* Returns status of parser with respect to being initialized, parsing, finished, or suspended and processing the final buffer. XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED */ XMLPARSEAPI(void) XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); /* Creates an XML_Parser object that can parse an external general entity; context is a '\0'-terminated string specifying the parse context; encoding is a '\0'-terminated string giving the name of the externally specified encoding, or NULL if there is no externally specified encoding. The context string consists of a sequence of tokens separated by formfeeds (\f); a token consisting of a name specifies that the general entity of the name is open; a token of the form prefix=uri specifies the namespace for a particular prefix; a token of the form =uri specifies the default namespace. This can be called at any point after the first call to an ExternalEntityRefHandler so longer as the parser has not yet been freed. The new parser is completely independent and may safely be used in a separate thread. The handlers and userData are initialized from the parser argument. Returns NULL if out of memory. Otherwise returns a new XML_Parser object. */ XMLPARSEAPI(XML_Parser) XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); enum XML_ParamEntityParsing { XML_PARAM_ENTITY_PARSING_NEVER, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, XML_PARAM_ENTITY_PARSING_ALWAYS }; /* Controls parsing of parameter entities (including the external DTD subset). If parsing of parameter entities is enabled, then references to external parameter entities (including the external DTD subset) will be passed to the handler set with XML_SetExternalEntityRefHandler. The context passed will be 0. Unlike external general entities, external parameter entities can only be parsed synchronously. If the external parameter entity is to be parsed, it must be parsed during the call to the external entity ref handler: the complete sequence of XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during this call. After XML_ExternalEntityParserCreate has been called to create the parser for the external parameter entity (context must be 0 for this call), it is illegal to make any calls on the old parser until XML_ParserFree has been called on the newly created parser. If the library has been compiled without support for parameter entity parsing (ie without XML_DTD being defined), then XML_SetParamEntityParsing will return 0 if parsing of parameter entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0. Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing parsing); /* Sets the hash salt to use for internal hash calculations. Helps in preventing DoS attacks based on predicting hash function behavior. This must be called before parsing is started. Returns 1 if successful, 0 when called after parsing has started. Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. */ XMLPARSEAPI(enum XML_Error) XML_GetErrorCode(XML_Parser parser); /* These functions return information about the current parse location. They may be called from any callback called to report some parse event; in this case the location is the location of the first of the sequence of characters that generated the event. When called from callbacks generated by declarations in the document prologue, the location identified isn't as neatly defined, but will be within the relevant markup. When called outside of the callback functions, the position indicated will be just past the last parse event (regardless of whether there was an associated callback). They may also be called after returning from a call to XML_Parse or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above. Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber return 0 to indicate an error. Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); /* Return the number of bytes in the current event. Returns 0 if the event is in an internal entity. */ XMLPARSEAPI(int) XML_GetCurrentByteCount(XML_Parser parser); /* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets the integer pointed to by offset to the offset within this buffer of the current parse position, and sets the integer pointed to by size to the size of this buffer (the number of input bytes). Otherwise returns a NULL pointer. Also returns a NULL pointer if a parse isn't active. NOTE: The character pointer returned should not be used outside the handler that makes the call. */ XMLPARSEAPI(const char *) XML_GetInputContext(XML_Parser parser, int *offset, int *size); /* For backwards compatibility with previous versions. */ # define XML_GetErrorLineNumber XML_GetCurrentLineNumber # define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber # define XML_GetErrorByteIndex XML_GetCurrentByteIndex /* Frees the content model passed to the element declaration handler */ XMLPARSEAPI(void) XML_FreeContentModel(XML_Parser parser, XML_Content *model); /* Exposing the memory handling functions used in Expat */ XMLPARSEAPI(void *) XML_ATTR_MALLOC XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); XMLPARSEAPI(void *) XML_ATTR_ALLOC_SIZE(3) XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); XMLPARSEAPI(void) XML_MemFree(XML_Parser parser, void *ptr); /* Frees memory used by the parser. */ XMLPARSEAPI(void) XML_ParserFree(XML_Parser parser); /* Returns a string describing the error. */ XMLPARSEAPI(const XML_LChar *) XML_ErrorString(enum XML_Error code); /* Return a string containing the version number of this expat */ XMLPARSEAPI(const XML_LChar *) XML_ExpatVersion(void); typedef struct { int major; int minor; int micro; } XML_Expat_Version; /* Return an XML_Expat_Version structure containing numeric version number information for this version of expat. */ XMLPARSEAPI(XML_Expat_Version) XML_ExpatVersionInfo(void); /* Added in Expat 1.95.5. */ enum XML_FeatureEnum { XML_FEATURE_END = 0, XML_FEATURE_UNICODE, XML_FEATURE_UNICODE_WCHAR_T, XML_FEATURE_DTD, XML_FEATURE_CONTEXT_BYTES, XML_FEATURE_MIN_SIZE, XML_FEATURE_SIZEOF_XML_CHAR, XML_FEATURE_SIZEOF_XML_LCHAR, XML_FEATURE_NS, XML_FEATURE_LARGE_SIZE, XML_FEATURE_ATTR_INFO, /* Added in Expat 2.4.0. */ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, /* Added in Expat 2.6.0. */ XML_FEATURE_GE, /* Added in Expat 2.7.2. */ XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT, XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT, /* Additional features must be added to the end of this enum. */ }; typedef struct { enum XML_FeatureEnum feature; const XML_LChar *name; long int value; } XML_Feature; XMLPARSEAPI(const XML_Feature *) XML_GetFeatureList(void); # if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1) /* Added in Expat 2.4.0 for XML_DTD defined and * added in Expat 2.6.0 for XML_GE == 1. */ XMLPARSEAPI(XML_Bool) XML_SetBillionLaughsAttackProtectionMaximumAmplification( XML_Parser parser, float maximumAmplificationFactor); /* Added in Expat 2.4.0 for XML_DTD defined and * added in Expat 2.6.0 for XML_GE == 1. */ XMLPARSEAPI(XML_Bool) XML_SetBillionLaughsAttackProtectionActivationThreshold( XML_Parser parser, unsigned long long activationThresholdBytes); /* Added in Expat 2.7.2. */ XMLPARSEAPI(XML_Bool) XML_SetAllocTrackerMaximumAmplification(XML_Parser parser, float maximumAmplificationFactor); /* Added in Expat 2.7.2. */ XMLPARSEAPI(XML_Bool) XML_SetAllocTrackerActivationThreshold( XML_Parser parser, unsigned long long activationThresholdBytes); # endif /* Added in Expat 2.6.0. */ XMLPARSEAPI(XML_Bool) XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); /* Expat follows the semantic versioning convention. See https://semver.org */ # define XML_MAJOR_VERSION 2 # define XML_MINOR_VERSION 7 # define XML_MICRO_VERSION 5 # ifdef __cplusplus } # endif #endif /* not Expat_INCLUDED */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/expat_config.h000066400000000000000000000100041516712004000271250ustar00rootroot00000000000000/* expat_config.h. Generated from expat_config.h.in by configure. */ /* expat_config.h.in. Generated from configure.ac by autoheader. */ #ifndef EXPAT_CONFIG_H #define EXPAT_CONFIG_H 1 /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* 1234 = LILENDIAN, 4321 = BIGENDIAN */ #define BYTEORDER 1234 /* Define to 1 if you have the `arc4random' function. */ /* #undef HAVE_ARC4RANDOM */ /* Define to 1 if you have the `arc4random_buf' function. */ /* #undef HAVE_ARC4RANDOM_BUF */ /* define if the compiler supports basic C++11 syntax */ /* #undef HAVE_CXX11 */ /* Define to 1 if you have the header file. */ /* #undef HAVE_DLFCN_H */ /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the 'getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getrandom' function. */ /* #undef HAVE_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have a working 'mmap' system call. */ /* #undef HAVE_MMAP */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have `syscall' and `SYS_getrandom'. */ /* #undef HAVE_SYSCALL_GETRANDOM */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ #define PACKAGE "expat" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "https://github.com/libexpat/libexpat/issues" /* Define to the full name of this package. */ #define PACKAGE_NAME "expat" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "expat 2.7.5" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "expat" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "2.7.5" /* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "2.7.5" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to allow retrieving the byte offsets for attribute names and values. */ /* #undef XML_ATTR_INFO */ /* Define to specify how much context to retain around the current parse point, 0 to disable. */ #define XML_CONTEXT_BYTES 1024 /* Define to include code reading entropy from `/dev/urandom'. */ #define XML_DEV_URANDOM 1 /* Define to make parameter entity parsing functionality available. */ #define XML_DTD 1 /* Define as 1/0 to enable/disable support for general entities. */ #define XML_GE 1 /* Define to make XML Namespaces functionality available. */ #define XML_NS 1 /* Define to empty if 'const' does not conform to ANSI C. */ /* #undef const */ /* Define to 'long int' if does not define. */ /* #undef off_t */ #endif // ndef EXPAT_CONFIG_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/expat_external.h000066400000000000000000000137721516712004000275210ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2000-2004 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2016 Cristian Rodríguez Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2018 Yury Gribov Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef Expat_External_INCLUDED # define Expat_External_INCLUDED 1 /* External API definitions */ /* Expat tries very hard to make the API boundary very specifically defined. There are two macros defined to control this boundary; each of these can be defined before including this header to achieve some different behavior, but doing so it not recommended or tested frequently. XMLCALL - The calling convention to use for all calls across the "library boundary." This will default to cdecl, and try really hard to tell the compiler that's what we want. XMLIMPORT - Whatever magic is needed to note that a function is to be imported from a dynamically loaded library (.dll, .so, or .sl, depending on your platform). The XMLCALL macro was added in Expat 1.95.7. The only one which is expected to be directly useful in client code is XMLCALL. Note that on at least some Unix versions, the Expat library must be compiled with the cdecl calling convention as the default since system headers may assume the cdecl convention. */ # ifndef XMLCALL # if defined(_MSC_VER) # define XMLCALL __cdecl # elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) # define XMLCALL __attribute__((cdecl)) # else /* For any platform which uses this definition and supports more than one calling convention, we need to extend this definition to declare the convention used on that platform, if it's possible to do so. If this is the case for your platform, please file a bug report with information on how to identify your platform via the C pre-processor and how to specify the same calling convention as the platform's malloc() implementation. */ # define XMLCALL # endif # endif /* not defined XMLCALL */ # if ! defined(XML_STATIC) && ! defined(XMLIMPORT) # ifndef XML_BUILDING_EXPAT /* using Expat from an application */ # if defined(_MSC_VER) && ! defined(__BEOS__) && ! defined(__CYGWIN__) # define XMLIMPORT __declspec(dllimport) # endif # endif # endif /* not defined XML_STATIC */ # ifndef XML_ENABLE_VISIBILITY # define XML_ENABLE_VISIBILITY 0 # endif # if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY # define XMLIMPORT __attribute__((visibility("default"))) # endif /* If we didn't define it above, define it away: */ # ifndef XMLIMPORT # define XMLIMPORT # endif # if defined(__GNUC__) \ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) # define XML_ATTR_MALLOC __attribute__((__malloc__)) # else # define XML_ATTR_MALLOC # endif # if defined(__GNUC__) \ && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) # define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) # else # define XML_ATTR_ALLOC_SIZE(x) # endif # define XMLPARSEAPI(type) XMLIMPORT type XMLCALL # ifdef __cplusplus extern "C" { # endif # ifdef XML_UNICODE_WCHAR_T # ifndef XML_UNICODE # define XML_UNICODE # endif # if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) # error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" # endif # endif # ifdef XML_UNICODE /* Information is UTF-16 encoded. */ # ifdef XML_UNICODE_WCHAR_T typedef wchar_t XML_Char; typedef wchar_t XML_LChar; # else typedef unsigned short XML_Char; typedef char XML_LChar; # endif /* XML_UNICODE_WCHAR_T */ # else /* Information is UTF-8 encoded. */ typedef char XML_Char; typedef char XML_LChar; # endif /* XML_UNICODE */ # ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ typedef long long XML_Index; typedef unsigned long long XML_Size; # else typedef long XML_Index; typedef unsigned long XML_Size; # endif /* XML_LARGE_SIZE */ # ifdef __cplusplus } # endif #endif /* not Expat_External_INCLUDED */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/iasciitab.h000066400000000000000000000070061516712004000264170ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/internal.h000066400000000000000000000160701516712004000263040ustar00rootroot00000000000000/* internal.h Internal definitions used by Expat. This is not needed to compile client code. The following calling convention macros are defined for frequently called functions: FASTCALL - Used for those internal functions that have a simple body and a low number of arguments and local variables. PTRCALL - Used for functions called though function pointers. PTRFASTCALL - Like PTRCALL, but for low number of arguments. inline - Used for selected internal functions for which inlining may improve performance on some platforms. Note: Use of these macros is based on judgement, not hard rules, and therefore subject to change. __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 2002-2003 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2003 Greg Stein Copyright (c) 2016-2025 Sebastian Pipping Copyright (c) 2018 Yury Gribov Copyright (c) 2019 David Loffredo Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__) /* We'll use this version by default only where we know it helps. regparm() generates warnings on Solaris boxes. See SF bug #692878. Instability reported with egcs on a RedHat Linux 7.3. Let's comment out: #define FASTCALL __attribute__((stdcall, regparm(3))) and let's try this: */ # define FASTCALL __attribute__((regparm(3))) # define PTRFASTCALL __attribute__((regparm(3))) #endif /* Using __fastcall seems to have an unexpected negative effect under MS VC++, especially for function pointers, so we won't use it for now on that platform. It may be reconsidered for a future release if it can be made more effective. Likely reason: __fastcall on Windows is like stdcall, therefore the compiler cannot perform stack optimizations for call clusters. */ /* Make sure all of these are defined if they aren't already. */ #ifndef FASTCALL # define FASTCALL #endif #ifndef PTRCALL # define PTRCALL #endif #ifndef PTRFASTCALL # define PTRFASTCALL #endif #ifndef XML_MIN_SIZE # if ! defined(__cplusplus) && ! defined(inline) # ifdef __GNUC__ # define inline __inline # endif /* __GNUC__ */ # endif #endif /* XML_MIN_SIZE */ #ifdef __cplusplus # define inline inline #else # ifndef inline # define inline # endif #endif #include // ULONG_MAX #include // size_t #if defined(_WIN32) \ && (! defined(__USE_MINGW_ANSI_STDIO) \ || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0)) # define EXPAT_FMT_ULL(midpart) "%" midpart "I64u" # if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u" # else # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" # endif #else # define EXPAT_FMT_ULL(midpart) "%" midpart "llu" # if ! defined(ULONG_MAX) # error Compiler did not define ULONG_MAX for us # elif ULONG_MAX == 18446744073709551615u // 2^64-1 # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu" # elif defined(__wasm32__) // 32bit mode Emscripten or WASI SDK # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "zu" # else # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" # endif #endif #ifndef UNUSED_P # define UNUSED_P(p) (void)p #endif /* NOTE BEGIN If you ever patch these defaults to greater values for non-attack XML payload in your environment, please file a bug report with libexpat. Thank you! */ #define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \ 100.0f #define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \ 8388608 // 8 MiB, 2^23 #define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f #define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT \ 67108864 // 64 MiB, 2^26 // NOTE: If function expat_alloc was user facing, EXPAT_MALLOC_ALIGNMENT would // have to take sizeof(long double) into account #define EXPAT_MALLOC_ALIGNMENT sizeof(long long) // largest parser (sub)member #define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t)) /* NOTE END */ #include "expat.h" // so we can use type XML_Parser below #ifdef __cplusplus extern "C" { #endif void _INTERNAL_trim_to_complete_utf8_characters(const char *from, const char **fromLimRef); #if defined(XML_GE) && XML_GE == 1 unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser); unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); const char *unsignedCharToPrintable(unsigned char c); #endif extern #if ! defined(XML_TESTING) const #endif XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c #if defined(XML_TESTING) void *expat_malloc(XML_Parser parser, size_t size, int sourceLine); void expat_free(XML_Parser parser, void *ptr, int sourceLine); void *expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine); extern unsigned int g_bytesScanned; // used for testing only #endif #ifdef __cplusplus } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/latin1tab.h000066400000000000000000000067651516712004000263610ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/nametab.h000066400000000000000000000215241516712004000260770ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 2000 Clark Cooper Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ static const unsigned namingBitmap[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, }; static const unsigned char nmstrtPages[] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const unsigned char namePages[] = { 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/siphash.h000066400000000000000000000313261516712004000261300ustar00rootroot00000000000000/* ========================================================================== * siphash.h - SipHash-2-4 in a single header file * -------------------------------------------------------------------------- * Derived by William Ahern from the reference implementation[1] published[2] * by Jean-Philippe Aumasson and Daniel J. Berstein. * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below. * Licensed under the CC0 Public Domain Dedication license. * * 1. https://www.131002.net/siphash/siphash24.c * 2. https://www.131002.net/siphash/ * -------------------------------------------------------------------------- * HISTORY: * * 2020-10-03 (Sebastian Pipping) * - Drop support for Visual Studio 9.0/2008 and earlier * * 2019-08-03 (Sebastian Pipping) * - Mark part of sip24_valid as to be excluded from clang-format * - Re-format code using clang-format 9 * * 2018-07-08 (Anton Maklakov) * - Add "fall through" markers for GCC's -Wimplicit-fallthrough * * 2017-11-03 (Sebastian Pipping) * - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined * * 2017-07-25 (Vadim Zeitlin) * - Fix use of SIPHASH_MAIN macro * * 2017-07-05 (Sebastian Pipping) * - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++ * - Add const qualifiers at two places * - Ensure <=80 characters line length (assuming tab width 4) * * 2017-06-23 (Victor Stinner) * - Address Win64 compile warnings * * 2017-06-18 (Sebastian Pipping) * - Clarify license note in the header * - Address C89 issues: * - Stop using inline keyword (and let compiler decide) * - Replace _Bool by int * - Turn macro siphash24 into a function * - Address invalid conversion (void pointer) by explicit cast * - Address lack of stdint.h for Visual Studio 2003 to 2008 * - Always expose sip24_valid (for self-tests) * * 2012-11-04 - Born. (William Ahern) * -------------------------------------------------------------------------- * USAGE: * * SipHash-2-4 takes as input two 64-bit words as the key, some number of * message bytes, and outputs a 64-bit word as the message digest. This * implementation employs two data structures: a struct sipkey for * representing the key, and a struct siphash for representing the hash * state. * * For converting a 16-byte unsigned char array to a key, use either the * macro sip_keyof or the routine sip_tokey. The former instantiates a * compound literal key, while the latter requires a key object as a * parameter. * * unsigned char secret[16]; * arc4random_buf(secret, sizeof secret); * struct sipkey *key = sip_keyof(secret); * * For hashing a message, use either the convenience macro siphash24 or the * routines sip24_init, sip24_update, and sip24_final. * * struct siphash state; * void *msg; * size_t len; * uint64_t hash; * * sip24_init(&state, key); * sip24_update(&state, msg, len); * hash = sip24_final(&state); * * or * * hash = siphash24(msg, len, key); * * To convert the 64-bit hash value to a canonical 8-byte little-endian * binary representation, use either the macro sip_binof or the routine * sip_tobin. The former instantiates and returns a compound literal array, * while the latter requires an array object as a parameter. * -------------------------------------------------------------------------- * NOTES: * * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers * lacking compound literal support. Instead, you must use the lower-level * interfaces which take as parameters the temporary state objects. * * o Uppercase macros may evaluate parameters more than once. Lowercase * macros should not exhibit any such side effects. * ========================================================================== */ #ifndef SIPHASH_H #define SIPHASH_H #include /* size_t */ #include /* uint64_t uint32_t uint8_t */ /* * Workaround to not require a C++11 compiler for using ULL suffix * if this code is included and compiled as C++; related GCC warning is: * warning: use of C++11 long long integer constant [-Wlong-long] */ #define SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low)) #define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) #define SIP_U32TO8_LE(p, v) \ (p)[0] = (uint8_t)((v) >> 0); \ (p)[1] = (uint8_t)((v) >> 8); \ (p)[2] = (uint8_t)((v) >> 16); \ (p)[3] = (uint8_t)((v) >> 24); #define SIP_U64TO8_LE(p, v) \ SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); #define SIP_U8TO64_LE(p) \ (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \ | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \ | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) #define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0} struct siphash { uint64_t v0, v1, v2, v3; unsigned char buf[8], *p; uint64_t c; }; /* struct siphash */ #define SIP_KEYLEN 16 struct sipkey { uint64_t k[2]; }; /* struct sipkey */ #define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k)) static struct sipkey * sip_tokey(struct sipkey *key, const void *src) { key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); return key; } /* sip_tokey() */ #ifdef SIPHASH_TOBIN # define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v)) static void * sip_tobin(void *dst, uint64_t u64) { SIP_U64TO8_LE((unsigned char *)dst, u64); return dst; } /* sip_tobin() */ #endif /* SIPHASH_TOBIN */ static void sip_round(struct siphash *H, const int rounds) { int i; for (i = 0; i < rounds; i++) { H->v0 += H->v1; H->v1 = SIP_ROTL(H->v1, 13); H->v1 ^= H->v0; H->v0 = SIP_ROTL(H->v0, 32); H->v2 += H->v3; H->v3 = SIP_ROTL(H->v3, 16); H->v3 ^= H->v2; H->v0 += H->v3; H->v3 = SIP_ROTL(H->v3, 21); H->v3 ^= H->v0; H->v2 += H->v1; H->v1 = SIP_ROTL(H->v1, 17); H->v1 ^= H->v2; H->v2 = SIP_ROTL(H->v2, 32); } } /* sip_round() */ static struct siphash * sip24_init(struct siphash *H, const struct sipkey *key) { H->v0 = SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; H->v1 = SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; H->v2 = SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; H->v3 = SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; H->p = H->buf; H->c = 0; return H; } /* sip24_init() */ #define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)]) static struct siphash * sip24_update(struct siphash *H, const void *src, size_t len) { const unsigned char *p = (const unsigned char *)src, *pe = p + len; uint64_t m; do { while (p < pe && H->p < sip_endof(H->buf)) *H->p++ = *p++; if (H->p < sip_endof(H->buf)) break; m = SIP_U8TO64_LE(H->buf); H->v3 ^= m; sip_round(H, 2); H->v0 ^= m; H->p = H->buf; H->c += 8; } while (p < pe); return H; } /* sip24_update() */ static uint64_t sip24_final(struct siphash *H) { const char left = (char)(H->p - H->buf); uint64_t b = (H->c + left) << 56; switch (left) { case 7: b |= (uint64_t)H->buf[6] << 48; /* fall through */ case 6: b |= (uint64_t)H->buf[5] << 40; /* fall through */ case 5: b |= (uint64_t)H->buf[4] << 32; /* fall through */ case 4: b |= (uint64_t)H->buf[3] << 24; /* fall through */ case 3: b |= (uint64_t)H->buf[2] << 16; /* fall through */ case 2: b |= (uint64_t)H->buf[1] << 8; /* fall through */ case 1: b |= (uint64_t)H->buf[0] << 0; /* fall through */ case 0: break; } H->v3 ^= b; sip_round(H, 2); H->v0 ^= b; H->v2 ^= 0xff; sip_round(H, 4); return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; } /* sip24_final() */ static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) { struct siphash state = SIPHASH_INITIALIZER; return sip24_final(sip24_update(sip24_init(&state, key), src, len)); } /* siphash24() */ /* * SipHash-2-4 output with * k = 00 01 02 ... * and * in = (empty string) * in = 00 (1 byte) * in = 00 01 (2 bytes) * in = 00 01 02 (3 bytes) * ... * in = 00 01 02 ... 3e (63 bytes) */ static int sip24_valid(void) { /* clang-format off */ static const unsigned char vectors[64][8] = { { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } }; /* clang-format on */ unsigned char in[64]; struct sipkey k; size_t i; sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" "\012\013\014\015\016\017"); for (i = 0; i < sizeof in; ++i) { in[i] = (unsigned char)i; if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) return 0; } return 1; } /* sip24_valid() */ #ifdef SIPHASH_MAIN # include int main(void) { const int ok = sip24_valid(); if (ok) puts("OK"); else puts("FAIL"); return ! ok; } /* main() */ #endif /* SIPHASH_MAIN */ #endif /* SIPHASH_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/utf8tab.h000066400000000000000000000067021516712004000260460ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2017 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/winconfig.h000066400000000000000000000037661516712004000264630ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Greg Stein Copyright (c) 2005 Karl Waclawek Copyright (c) 2017-2023 Sebastian Pipping Copyright (c) 2023 Orgad Shaneh Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef WINCONFIG_H #define WINCONFIG_H #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include #undef WIN32_LEAN_AND_MEAN #include #include #endif /* ndef WINCONFIG_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmlparse.c000066400000000000000000011371151516712004000263230ustar00rootroot00000000000000/* 93c1caa66e2b0310459482516af05505b57c5cb7b96df777105308fc585c85d1 (2.7.5+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2000-2006 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016 Eric Rahm Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2016 Gaurav Copyright (c) 2016 Thomas Beutlich Copyright (c) 2016 Gustavo Grieco Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Ed Schouten Copyright (c) 2017-2022 Rhodri James Copyright (c) 2017 Václav Slavík Copyright (c) 2017 Viktor Szakats Copyright (c) 2017 Chanho Park Copyright (c) 2017 Rolf Eike Beer Copyright (c) 2017 Hans Wennborg Copyright (c) 2018 Anton Maklakov Copyright (c) 2018 Benjamin Peterson Copyright (c) 2018 Marco Maggi Copyright (c) 2018 Mariusz Zaborski Copyright (c) 2019 David Loffredo Copyright (c) 2019-2020 Ben Wagner Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Donghee Na Copyright (c) 2022 Samanta Navarro Copyright (c) 2022 Jeffrey Walton Copyright (c) 2022 Jann Horn Copyright (c) 2022 Sean McBride Copyright (c) 2023 Owain Davies Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow Copyright (c) 2024-2025 Berkay Eren Ürün Copyright (c) 2024 Hanno Böck Copyright (c) 2025 Matthew Fernandez Copyright (c) 2025 Atrem Borovik Copyright (c) 2025 Alfonso Gregory Copyright (c) 2026 Rosen Penev Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define XML_BUILDING_EXPAT 1 #include "expat_config.h" #if ! defined(XML_GE) || (1 - XML_GE - 1 == 2) || (XML_GE < 0) || (XML_GE > 1) # error XML_GE (for general entities) must be defined, non-empty, either 1 or 0 (0 to disable, 1 to enable; 1 is a common default) #endif #if defined(XML_DTD) && XML_GE == 0 # error Either undefine XML_DTD or define XML_GE to 1. #endif #if ! defined(XML_CONTEXT_BYTES) || (1 - XML_CONTEXT_BYTES - 1 == 2) \ || (XML_CONTEXT_BYTES + 0 < 0) # error XML_CONTEXT_BYTES must be defined, non-empty and >=0 (0 to disable, >=1 to enable; 1024 is a common default) #endif #if defined(HAVE_SYSCALL_GETRANDOM) # if ! defined(_GNU_SOURCE) # define _GNU_SOURCE 1 /* syscall prototype */ # endif #endif #ifdef _WIN32 /* force stdlib to define rand_s() */ # if ! defined(_CRT_RAND_S) # define _CRT_RAND_S # endif #endif #include #include #include /* memset(), memcpy() */ #include #include /* INT_MAX, UINT_MAX */ #include /* fprintf */ #include /* getenv, rand_s */ #include /* SIZE_MAX, uintptr_t */ #include /* isnan */ #ifdef _WIN32 # define getpid GetCurrentProcessId #else # include /* gettimeofday() */ # include /* getpid() */ # include /* getpid() */ # include /* O_RDONLY */ # include #endif #ifdef _WIN32 # include "winconfig.h" #endif #include "ascii.h" #include "expat.h" #include "siphash.h" #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) # if defined(HAVE_GETRANDOM) # include /* getrandom */ # else # include /* syscall */ # include /* SYS_getrandom */ # endif # if ! defined(GRND_NONBLOCK) # define GRND_NONBLOCK 0x0001 # endif /* defined(GRND_NONBLOCK) */ #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ && ! defined(XML_POOR_ENTROPY) # error You do not have support for any sources of high quality entropy \ enabled. For end user security, that is probably not what you want. \ \ Your options include: \ * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ * BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ * BSD / macOS (including <10.7) / glibc >=2.36 (arc4random): HAVE_ARC4RANDOM, \ * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ XML_POOR_ENTROPY; you have been warned. \ \ If you have reasons to patch this detection code away or need changes \ to the build system, please open a bug. Thank you! #endif #ifdef XML_UNICODE # define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX # define XmlConvert XmlUtf16Convert # define XmlGetInternalEncoding XmlGetUtf16InternalEncoding # define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS # define XmlEncode XmlUtf16Encode # define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) typedef unsigned short ICHAR; #else # define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX # define XmlConvert XmlUtf8Convert # define XmlGetInternalEncoding XmlGetUtf8InternalEncoding # define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS # define XmlEncode XmlUtf8Encode # define MUST_CONVERT(enc, s) (! (enc)->isUtf8) typedef char ICHAR; #endif #ifndef XML_NS # define XmlInitEncodingNS XmlInitEncoding # define XmlInitUnknownEncodingNS XmlInitUnknownEncoding # undef XmlGetInternalEncodingNS # define XmlGetInternalEncodingNS XmlGetInternalEncoding # define XmlParseXmlDeclNS XmlParseXmlDecl #endif #ifdef XML_UNICODE # ifdef XML_UNICODE_WCHAR_T # define XML_T(x) (const wchar_t) x # define XML_L(x) L##x # else # define XML_T(x) (const unsigned short)x # define XML_L(x) x # endif #else # define XML_T(x) x # define XML_L(x) x #endif /* Round up n to be a multiple of sz, where sz is a power of 2. */ #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) /* Do safe (NULL-aware) pointer arithmetic */ #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) #define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b)) #include "internal.h" #include "xmltok.h" #include "xmlrole.h" typedef const XML_Char *KEY; typedef struct { KEY name; } NAMED; typedef struct { NAMED **v; unsigned char power; size_t size; size_t used; XML_Parser parser; } HASH_TABLE; static size_t keylen(KEY s); static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); /* For probing (after a collision) we need a step size relative prime to the hash table size, which is a power of 2. We use double-hashing, since we can calculate a second hash value cheaply by taking those bits of the first hash value that were discarded (masked out) when the table index was calculated: index = hash & mask, where mask = table->size - 1. We limit the maximum step size to table->size / 4 (mask >> 2) and make it odd, since odd numbers are always relative prime to a power of 2. */ #define SECOND_HASH(hash, mask, power) \ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) #define PROBE_STEP(hash, mask, power) \ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) typedef struct { NAMED **p; NAMED **end; } HASH_TABLE_ITER; #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ #define INIT_DATA_BUF_SIZE 1024 #define INIT_ATTS_SIZE 16 #define INIT_ATTS_VERSION 0xFFFFFFFF #define INIT_BLOCK_SIZE 1024 #define INIT_BUFFER_SIZE 1024 #define EXPAND_SPARE 24 typedef struct binding { struct prefix *prefix; struct binding *nextTagBinding; struct binding *prevPrefixBinding; const struct attribute_id *attId; XML_Char *uri; int uriLen; int uriAlloc; } BINDING; typedef struct prefix { const XML_Char *name; BINDING *binding; } PREFIX; typedef struct { const XML_Char *str; const XML_Char *localPart; const XML_Char *prefix; int strLen; int uriLen; int prefixLen; } TAG_NAME; /* TAG represents an open element. The name of the element is stored in both the document and API encodings. The memory buffer 'buf' is a separately-allocated memory area which stores the name. During the XML_Parse()/ XML_ParseBuffer() when the element is open, the memory for the 'raw' version of the name (in the document encoding) is shared with the document buffer. If the element is open across calls to XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to contain the 'raw' name as well. A parser reuses these structures, maintaining a list of allocated TAG objects in a free list. */ typedef struct tag { struct tag *parent; /* parent of this element */ const char *rawName; /* tagName in the original encoding */ int rawNameLength; TAG_NAME name; /* tagName in the API encoding */ union { char *raw; /* for byte-level access (rawName storage) */ XML_Char *str; /* for character-level access (converted name) */ } buf; /* buffer for name components */ char *bufEnd; /* end of the buffer */ BINDING *bindings; } TAG; typedef struct { const XML_Char *name; const XML_Char *textPtr; int textLen; /* length in XML_Chars */ int processed; /* # of processed bytes - when suspended */ const XML_Char *systemId; const XML_Char *base; const XML_Char *publicId; const XML_Char *notation; XML_Bool open; XML_Bool hasMore; /* true if entity has not been completely processed */ /* An entity can be open while being already completely processed (hasMore == XML_FALSE). The reason is the delayed closing of entities until their inner entities are processed and closed */ XML_Bool is_param; XML_Bool is_internal; /* true if declared in internal subset outside PE */ } ENTITY; typedef struct { enum XML_Content_Type type; enum XML_Content_Quant quant; const XML_Char *name; int firstchild; int lastchild; int childcnt; int nextsib; } CONTENT_SCAFFOLD; #define INIT_SCAFFOLD_ELEMENTS 32 typedef struct block { struct block *next; int size; XML_Char s[]; } BLOCK; typedef struct { BLOCK *blocks; BLOCK *freeBlocks; const XML_Char *end; XML_Char *ptr; XML_Char *start; XML_Parser parser; } STRING_POOL; /* The XML_Char before the name is used to determine whether an attribute has been specified. */ typedef struct attribute_id { XML_Char *name; PREFIX *prefix; XML_Bool maybeTokenized; XML_Bool xmlns; } ATTRIBUTE_ID; typedef struct { const ATTRIBUTE_ID *id; XML_Bool isCdata; const XML_Char *value; } DEFAULT_ATTRIBUTE; typedef struct { unsigned long version; unsigned long hash; const XML_Char *uriName; } NS_ATT; typedef struct { const XML_Char *name; PREFIX *prefix; const ATTRIBUTE_ID *idAtt; int nDefaultAtts; int allocDefaultAtts; DEFAULT_ATTRIBUTE *defaultAtts; } ELEMENT_TYPE; typedef struct { HASH_TABLE generalEntities; HASH_TABLE elementTypes; HASH_TABLE attributeIds; HASH_TABLE prefixes; STRING_POOL pool; STRING_POOL entityValuePool; /* false once a parameter entity reference has been skipped */ XML_Bool keepProcessing; /* true once an internal or external PE reference has been encountered; this includes the reference to an external subset */ XML_Bool hasParamEntityRefs; XML_Bool standalone; #ifdef XML_DTD /* indicates if external PE has been read */ XML_Bool paramEntityRead; HASH_TABLE paramEntities; #endif /* XML_DTD */ PREFIX defaultPrefix; /* === scaffolding for building content model === */ XML_Bool in_eldecl; CONTENT_SCAFFOLD *scaffold; unsigned contentStringLen; unsigned scaffSize; unsigned scaffCount; int scaffLevel; int *scaffIndex; } DTD; enum EntityType { ENTITY_INTERNAL, ENTITY_ATTRIBUTE, ENTITY_VALUE, }; typedef struct open_internal_entity { const char *internalEventPtr; const char *internalEventEndPtr; struct open_internal_entity *next; ENTITY *entity; int startTagLevel; XML_Bool betweenDecl; /* WFC: PE Between Declarations */ enum EntityType type; } OPEN_INTERNAL_ENTITY; enum XML_Account { XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */ XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity expansion */ XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */ }; #if XML_GE == 1 typedef unsigned long long XmlBigCount; typedef struct accounting { XmlBigCount countBytesDirect; XmlBigCount countBytesIndirect; unsigned long debugLevel; float maximumAmplificationFactor; // >=1.0 unsigned long long activationThresholdBytes; } ACCOUNTING; typedef struct MALLOC_TRACKER { XmlBigCount bytesAllocated; XmlBigCount peakBytesAllocated; // updated live only for debug level >=2 unsigned long debugLevel; float maximumAmplificationFactor; // >=1.0 XmlBigCount activationThresholdBytes; } MALLOC_TRACKER; typedef struct entity_stats { unsigned int countEverOpened; unsigned int currentDepth; unsigned int maximumDepthSeen; unsigned long debugLevel; } ENTITY_STATS; #endif /* XML_GE == 1 */ typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, const char *end, const char **endPtr); static Processor prologProcessor; static Processor prologInitProcessor; static Processor contentProcessor; static Processor cdataSectionProcessor; #ifdef XML_DTD static Processor ignoreSectionProcessor; static Processor externalParEntProcessor; static Processor externalParEntInitProcessor; static Processor entityValueProcessor; static Processor entityValueInitProcessor; #endif /* XML_DTD */ static Processor epilogProcessor; static Processor errorProcessor; static Processor externalEntityInitProcessor; static Processor externalEntityInitProcessor2; static Processor externalEntityInitProcessor3; static Processor externalEntityContentProcessor; static Processor internalEntityProcessor; static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const char *next); static enum XML_Error initializeEncoding(XML_Parser parser); static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, int tok, const char *next, const char **nextPtr, XML_Bool haveMore, XML_Bool allowClosingDoctype, enum XML_Account account); static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl, enum EntityType type); static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr, XML_Bool haveMore, enum XML_Account account); static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore, enum XML_Account account); #ifdef XML_DTD static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ static void freeBindings(XML_Parser parser, BINDING *bindings); static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr, enum XML_Account account); static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr); static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, XML_Bool isId, const XML_Char *value, XML_Parser parser); static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account); static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account, const char **nextPtr); static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType); #if XML_GE == 1 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end, enum XML_Account account, const char **nextPtr); static enum XML_Error callStoreEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end, enum XML_Account account); #else static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity); #endif static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static const XML_Char *getContext(XML_Parser parser); static XML_Bool setContext(XML_Parser parser, const XML_Char *context); static void FASTCALL normalizePublicId(XML_Char *s); static DTD *dtdCreate(XML_Parser parser); /* do not call if m_parentParser != NULL */ static void dtdReset(DTD *p, XML_Parser parser); static void dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser); static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, XML_Parser parser); static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, STRING_POOL *newPool, const HASH_TABLE *oldTable); static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize); static void FASTCALL hashTableInit(HASH_TABLE *table, XML_Parser parser); static void FASTCALL hashTableClear(HASH_TABLE *table); static void FASTCALL hashTableDestroy(HASH_TABLE *table); static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table); static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter); static void FASTCALL poolInit(STRING_POOL *pool, XML_Parser parser); static void FASTCALL poolClear(STRING_POOL *pool); static void FASTCALL poolDestroy(STRING_POOL *pool); static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, const XML_Char *s); static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s); static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, const XML_Char *s); static int FASTCALL nextScaffoldPart(XML_Parser parser); static XML_Content *build_model(XML_Parser parser); static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, const char *end); static XML_Char *copyString(const XML_Char *s, XML_Parser parser); static unsigned long generate_hash_secret_salt(XML_Parser parser); static XML_Bool startParsing(XML_Parser parser); static XML_Parser parserCreate(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, DTD *dtd, XML_Parser parentParser); static void parserInit(XML_Parser parser, const XML_Char *encodingName); #if XML_GE == 1 static float accountingGetCurrentAmplification(XML_Parser rootParser); static void accountingReportStats(XML_Parser originParser, const char *epilog); static void accountingOnAbort(XML_Parser originParser); static void accountingReportDiff(XML_Parser rootParser, unsigned int levelsAwayFromRootParser, const char *before, const char *after, ptrdiff_t bytesMore, int source_line, enum XML_Account account); static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, const char *before, const char *after, int source_line, enum XML_Account account); static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity, const char *action, int sourceLine); static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity, int sourceLine); static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity, int sourceLine); #endif /* XML_GE == 1 */ static XML_Parser getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff); static unsigned long getDebugLevel(const char *variableName, unsigned long defaultDebugLevel); #define poolStart(pool) ((pool)->start) #define poolLength(pool) ((pool)->ptr - (pool)->start) #define poolChop(pool) ((void)--(pool->ptr)) #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) #define poolAppendChar(pool, c) \ (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ ? 0 \ : ((*((pool)->ptr)++ = c), 1)) #if ! defined(XML_TESTING) const #endif XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c #if defined(XML_TESTING) unsigned int g_bytesScanned = 0; // used for testing only #endif struct XML_ParserStruct { /* The first member must be m_userData so that the XML_GetUserData macro works. */ void *m_userData; void *m_handlerArg; // How the four parse buffer pointers below relate in time and space: // // m_buffer <= m_bufferPtr <= m_bufferEnd <= m_bufferLim // | | | | // <--parsed-->| | | // <---parsing--->| | // <--unoccupied-->| // <---------total-malloced/realloced-------->| char *m_buffer; // malloc/realloc base pointer of parse buffer const XML_Memory_Handling_Suite m_mem; const char *m_bufferPtr; // first character to be parsed char *m_bufferEnd; // past last character to be parsed const char *m_bufferLim; // allocated end of m_buffer XML_Index m_parseEndByteIndex; const char *m_parseEndPtr; size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */ XML_Bool m_reparseDeferralEnabled; int m_lastBufferRequestSize; XML_Char *m_dataBuf; XML_Char *m_dataBufEnd; XML_StartElementHandler m_startElementHandler; XML_EndElementHandler m_endElementHandler; XML_CharacterDataHandler m_characterDataHandler; XML_ProcessingInstructionHandler m_processingInstructionHandler; XML_CommentHandler m_commentHandler; XML_StartCdataSectionHandler m_startCdataSectionHandler; XML_EndCdataSectionHandler m_endCdataSectionHandler; XML_DefaultHandler m_defaultHandler; XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; XML_NotationDeclHandler m_notationDeclHandler; XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; XML_NotStandaloneHandler m_notStandaloneHandler; XML_ExternalEntityRefHandler m_externalEntityRefHandler; XML_Parser m_externalEntityRefHandlerArg; XML_SkippedEntityHandler m_skippedEntityHandler; XML_UnknownEncodingHandler m_unknownEncodingHandler; XML_ElementDeclHandler m_elementDeclHandler; XML_AttlistDeclHandler m_attlistDeclHandler; XML_EntityDeclHandler m_entityDeclHandler; XML_XmlDeclHandler m_xmlDeclHandler; const ENCODING *m_encoding; INIT_ENCODING m_initEncoding; const ENCODING *m_internalEncoding; const XML_Char *m_protocolEncodingName; XML_Bool m_ns; XML_Bool m_ns_triplets; void *m_unknownEncodingMem; void *m_unknownEncodingData; void *m_unknownEncodingHandlerData; void(XMLCALL *m_unknownEncodingRelease)(void *); PROLOG_STATE m_prologState; Processor *m_processor; enum XML_Error m_errorCode; const char *m_eventPtr; const char *m_eventEndPtr; const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; OPEN_INTERNAL_ENTITY *m_freeInternalEntities; OPEN_INTERNAL_ENTITY *m_openAttributeEntities; OPEN_INTERNAL_ENTITY *m_freeAttributeEntities; OPEN_INTERNAL_ENTITY *m_openValueEntities; OPEN_INTERNAL_ENTITY *m_freeValueEntities; XML_Bool m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; const XML_Char *m_doctypeName; const XML_Char *m_doctypeSysid; const XML_Char *m_doctypePubid; const XML_Char *m_declAttributeType; const XML_Char *m_declNotationName; const XML_Char *m_declNotationPublicId; ELEMENT_TYPE *m_declElementType; ATTRIBUTE_ID *m_declAttributeId; XML_Bool m_declAttributeIsCdata; XML_Bool m_declAttributeIsId; DTD *m_dtd; const XML_Char *m_curBase; TAG *m_tagStack; TAG *m_freeTagList; BINDING *m_inheritedBindings; BINDING *m_freeBindingList; int m_attsSize; int m_nSpecifiedAtts; int m_idAttIndex; ATTRIBUTE *m_atts; NS_ATT *m_nsAtts; unsigned long m_nsAttsVersion; unsigned char m_nsAttsPower; #ifdef XML_ATTR_INFO XML_AttrInfo *m_attInfo; #endif POSITION m_position; STRING_POOL m_tempPool; STRING_POOL m_temp2Pool; char *m_groupConnector; unsigned int m_groupSize; XML_Char m_namespaceSeparator; XML_Parser m_parentParser; XML_ParsingStatus m_parsingStatus; #ifdef XML_DTD XML_Bool m_isParamEntity; XML_Bool m_useForeignDTD; enum XML_ParamEntityParsing m_paramEntityParsing; #endif unsigned long m_hash_secret_salt; #if XML_GE == 1 ACCOUNTING m_accounting; MALLOC_TRACKER m_alloc_tracker; ENTITY_STATS m_entity_stats; #endif XML_Bool m_reenter; }; #if XML_GE == 1 # define MALLOC(parser, s) (expat_malloc((parser), (s), __LINE__)) # define REALLOC(parser, p, s) (expat_realloc((parser), (p), (s), __LINE__)) # define FREE(parser, p) (expat_free((parser), (p), __LINE__)) #else # define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) # define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) # define FREE(parser, p) (parser->m_mem.free_fcn((p))) #endif #if XML_GE == 1 static void expat_heap_stat(XML_Parser rootParser, char operator, XmlBigCount absDiff, XmlBigCount newTotal, XmlBigCount peakTotal, int sourceLine) { // NOTE: This can be +infinity or -nan const float amplification = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect; fprintf( stderr, "expat: Allocations(%p): Direct " EXPAT_FMT_ULL("10") ", allocated %c" EXPAT_FMT_ULL( "10") " to " EXPAT_FMT_ULL("10") " (" EXPAT_FMT_ULL("10") " peak), amplification %8.2f (xmlparse.c:%d)\n", (void *)rootParser, rootParser->m_accounting.countBytesDirect, operator, absDiff, newTotal, peakTotal, (double)amplification, sourceLine); } static bool expat_heap_increase_tolerable(XML_Parser rootParser, XmlBigCount increase, int sourceLine) { assert(rootParser != NULL); assert(increase > 0); XmlBigCount newTotal = 0; bool tolerable = true; // Detect integer overflow if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated < increase) { tolerable = false; } else { newTotal = rootParser->m_alloc_tracker.bytesAllocated + increase; if (newTotal >= rootParser->m_alloc_tracker.activationThresholdBytes) { assert(newTotal > 0); // NOTE: This can be +infinity when dividing by zero but not -nan const float amplification = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect; if (amplification > rootParser->m_alloc_tracker.maximumAmplificationFactor) { tolerable = false; } } } if (! tolerable && (rootParser->m_alloc_tracker.debugLevel >= 1)) { expat_heap_stat(rootParser, '+', increase, newTotal, newTotal, sourceLine); } return tolerable; } # if defined(XML_TESTING) void * # else static void * # endif expat_malloc(XML_Parser parser, size_t size, int sourceLine) { // Detect integer overflow if (SIZE_MAX - size < sizeof(size_t) + EXPAT_MALLOC_PADDING) { return NULL; } const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(rootParser->m_parentParser == NULL); const size_t bytesToAllocate = sizeof(size_t) + EXPAT_MALLOC_PADDING + size; if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated < bytesToAllocate) { return NULL; // i.e. signal integer overflow as out-of-memory } if (! expat_heap_increase_tolerable(rootParser, bytesToAllocate, sourceLine)) { return NULL; // i.e. signal violation as out-of-memory } // Actually allocate void *const mallocedPtr = parser->m_mem.malloc_fcn(bytesToAllocate); if (mallocedPtr == NULL) { return NULL; } // Update in-block recorded size *(size_t *)mallocedPtr = size; // Update accounting rootParser->m_alloc_tracker.bytesAllocated += bytesToAllocate; // Report as needed if (rootParser->m_alloc_tracker.debugLevel >= 2) { if (rootParser->m_alloc_tracker.bytesAllocated > rootParser->m_alloc_tracker.peakBytesAllocated) { rootParser->m_alloc_tracker.peakBytesAllocated = rootParser->m_alloc_tracker.bytesAllocated; } expat_heap_stat(rootParser, '+', bytesToAllocate, rootParser->m_alloc_tracker.bytesAllocated, rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine); } return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING; } # if defined(XML_TESTING) void # else static void # endif expat_free(XML_Parser parser, void *ptr, int sourceLine) { assert(parser != NULL); if (ptr == NULL) { return; } const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(rootParser->m_parentParser == NULL); // Extract size (to the eyes of malloc_fcn/realloc_fcn) and // the original pointer returned by malloc/realloc void *const mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t); const size_t bytesAllocated = sizeof(size_t) + EXPAT_MALLOC_PADDING + *(size_t *)mallocedPtr; // Update accounting assert(rootParser->m_alloc_tracker.bytesAllocated >= bytesAllocated); rootParser->m_alloc_tracker.bytesAllocated -= bytesAllocated; // Report as needed if (rootParser->m_alloc_tracker.debugLevel >= 2) { expat_heap_stat(rootParser, '-', bytesAllocated, rootParser->m_alloc_tracker.bytesAllocated, rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine); } // NOTE: This may be freeing rootParser, so freeing has to come last parser->m_mem.free_fcn(mallocedPtr); } # if defined(XML_TESTING) void * # else static void * # endif expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) { assert(parser != NULL); if (ptr == NULL) { return expat_malloc(parser, size, sourceLine); } if (size == 0) { expat_free(parser, ptr, sourceLine); return NULL; } const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(rootParser->m_parentParser == NULL); // Extract original size (to the eyes of the caller) and the original // pointer returned by malloc/realloc void *mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t); const size_t prevSize = *(size_t *)mallocedPtr; // Classify upcoming change const bool isIncrease = (size > prevSize); const size_t absDiff = (size > prevSize) ? (size - prevSize) : (prevSize - size); // Ask for permission from accounting if (isIncrease) { if (! expat_heap_increase_tolerable(rootParser, absDiff, sourceLine)) { return NULL; // i.e. signal violation as out-of-memory } } // NOTE: Integer overflow detection has already been done for us // by expat_heap_increase_tolerable(..) above assert(SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size); // Actually allocate mallocedPtr = parser->m_mem.realloc_fcn( mallocedPtr, sizeof(size_t) + EXPAT_MALLOC_PADDING + size); if (mallocedPtr == NULL) { return NULL; } // Update accounting if (isIncrease) { assert((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated >= absDiff); rootParser->m_alloc_tracker.bytesAllocated += absDiff; } else { // i.e. decrease assert(rootParser->m_alloc_tracker.bytesAllocated >= absDiff); rootParser->m_alloc_tracker.bytesAllocated -= absDiff; } // Report as needed if (rootParser->m_alloc_tracker.debugLevel >= 2) { if (rootParser->m_alloc_tracker.bytesAllocated > rootParser->m_alloc_tracker.peakBytesAllocated) { rootParser->m_alloc_tracker.peakBytesAllocated = rootParser->m_alloc_tracker.bytesAllocated; } expat_heap_stat(rootParser, isIncrease ? '+' : '-', absDiff, rootParser->m_alloc_tracker.bytesAllocated, rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine); } // Update in-block recorded size *(size_t *)mallocedPtr = size; return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING; } #endif // XML_GE == 1 XML_Parser XMLCALL XML_ParserCreate(const XML_Char *encodingName) { return XML_ParserCreate_MM(encodingName, NULL, NULL); } XML_Parser XMLCALL XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { XML_Char tmp[2] = {nsSep, 0}; return XML_ParserCreate_MM(encodingName, NULL, tmp); } // "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; /* To avoid warnings about unused functions: */ #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) # if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) /* Obtain entropy on Linux 3.17+ */ static int writeRandomBytes_getrandom_nonblock(void *target, size_t count) { int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const unsigned int getrandomFlags = GRND_NONBLOCK; do { void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; assert(bytesToWrite <= INT_MAX); const int bytesWrittenMore = # if defined(HAVE_GETRANDOM) (int)getrandom(currentTarget, bytesToWrite, getrandomFlags); # else (int)syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); # endif if (bytesWrittenMore > 0) { bytesWrittenTotal += bytesWrittenMore; if (bytesWrittenTotal >= count) success = 1; } } while (! success && (errno == EINTR)); return success; } # endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) /* Extract entropy from /dev/urandom */ static int writeRandomBytes_dev_urandom(void *target, size_t count) { int success = 0; /* full count bytes written? */ size_t bytesWrittenTotal = 0; const int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) { return 0; } do { void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); const size_t bytesToWrite = count - bytesWrittenTotal; const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); if (bytesWrittenMore > 0) { bytesWrittenTotal += bytesWrittenMore; if (bytesWrittenTotal >= count) success = 1; } } while (! success && (errno == EINTR)); close(fd); return success; } # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) static void writeRandomBytes_arc4random(void *target, size_t count) { size_t bytesWrittenTotal = 0; while (bytesWrittenTotal < count) { const uint32_t random32 = arc4random(); size_t i = 0; for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); i++, bytesWrittenTotal++) { const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); ((uint8_t *)target)[bytesWrittenTotal] = random8; } } } #endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ #ifdef _WIN32 /* Provide declaration of rand_s() for MinGW-32 (not 64, which has it), as it didn't declare it in its header prior to version 5.3.0 of its runtime package (mingwrt, containing stdlib.h). The upstream fix was introduced at https://osdn.net/projects/mingw/ticket/39658 . */ # if defined(__MINGW32__) && defined(__MINGW32_VERSION) \ && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR) __declspec(dllimport) int rand_s(unsigned int *); # endif /* Obtain entropy on Windows using the rand_s() function which * generates cryptographically secure random numbers. Internally it * uses RtlGenRandom API which is present in Windows XP and later. */ static int writeRandomBytes_rand_s(void *target, size_t count) { size_t bytesWrittenTotal = 0; while (bytesWrittenTotal < count) { unsigned int random32 = 0; size_t i = 0; if (rand_s(&random32)) return 0; /* failure */ for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); i++, bytesWrittenTotal++) { const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); ((uint8_t *)target)[bytesWrittenTotal] = random8; } } return 1; /* success */ } #endif /* _WIN32 */ #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) static unsigned long gather_time_entropy(void) { # ifdef _WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); /* never fails */ return ft.dwHighDateTime ^ ft.dwLowDateTime; # else struct timeval tv; int gettimeofday_res; gettimeofday_res = gettimeofday(&tv, NULL); # if defined(NDEBUG) (void)gettimeofday_res; # else assert(gettimeofday_res == 0); # endif /* defined(NDEBUG) */ /* Microseconds time is <20 bits entropy */ return tv.tv_usec; # endif } #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ static unsigned long ENTROPY_DEBUG(const char *label, unsigned long entropy) { if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) { fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); } return entropy; } static unsigned long generate_hash_secret_salt(XML_Parser parser) { unsigned long entropy; (void)parser; /* "Failproof" high quality providers: */ #if defined(HAVE_ARC4RANDOM_BUF) arc4random_buf(&entropy, sizeof(entropy)); return ENTROPY_DEBUG("arc4random_buf", entropy); #elif defined(HAVE_ARC4RANDOM) writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); return ENTROPY_DEBUG("arc4random", entropy); #else /* Try high quality providers first .. */ # ifdef _WIN32 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("rand_s", entropy); } # elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("getrandom", entropy); } # endif # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { return ENTROPY_DEBUG("/dev/urandom", entropy); } # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ /* .. and self-made low quality for backup: */ entropy = gather_time_entropy(); # if ! defined(__wasi__) /* Process ID is 0 bits entropy if attacker has local access */ entropy ^= getpid(); # endif /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ if (sizeof(unsigned long) == 4) { return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); } else { return ENTROPY_DEBUG("fallback(8)", entropy * (unsigned long)2305843009213693951ULL); } #endif } static unsigned long get_hash_secret_salt(XML_Parser parser) { const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(! rootParser->m_parentParser); return rootParser->m_hash_secret_salt; } static enum XML_Error callProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start); if (parser->m_reparseDeferralEnabled && ! parser->m_parsingStatus.finalBuffer) { // Heuristic: don't try to parse a partial token again until the amount of // available data has increased significantly. const size_t had_before = parser->m_partialTokenBytesBefore; // ...but *do* try anyway if we're close to causing a reallocation. size_t available_buffer = EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); #if XML_CONTEXT_BYTES > 0 available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES); #endif available_buffer += EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd); // m_lastBufferRequestSize is never assigned a value < 0, so the cast is ok const bool enough = (have_now >= 2 * had_before) || ((size_t)parser->m_lastBufferRequestSize > available_buffer); if (! enough) { *endPtr = start; // callers may expect this to be set return XML_ERROR_NONE; } } #if defined(XML_TESTING) g_bytesScanned += (unsigned)have_now; #endif // Run in a loop to eliminate dangerous recursion depths enum XML_Error ret; *endPtr = start; while (1) { // Use endPtr as the new start in each iteration, since it will // be set to the next start point by m_processor. ret = parser->m_processor(parser, *endPtr, end, endPtr); // Make parsing status (and in particular XML_SUSPENDED) take // precedence over re-enter flag when they disagree if (parser->m_parsingStatus.parsing != XML_PARSING) { parser->m_reenter = XML_FALSE; } if (! parser->m_reenter) { break; } parser->m_reenter = XML_FALSE; if (ret != XML_ERROR_NONE) return ret; } if (ret == XML_ERROR_NONE) { // if we consumed nothing, remember what we had on this parse attempt. if (*endPtr == start) { parser->m_partialTokenBytesBefore = have_now; } else { parser->m_partialTokenBytesBefore = 0; } } return ret; } static XML_Bool /* only valid for root parser */ startParsing(XML_Parser parser) { /* hash functions must be initialized before setContext() is called */ if (parser->m_hash_secret_salt == 0) parser->m_hash_secret_salt = generate_hash_secret_salt(parser); if (parser->m_ns) { /* implicit context only set for root parser, since child parsers (i.e. external entity parsers) will inherit it */ return setContext(parser, implicitContext); } return XML_TRUE; } XML_Parser XMLCALL XML_ParserCreate_MM(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep) { return parserCreate(encodingName, memsuite, nameSep, NULL, NULL); } static XML_Parser parserCreate(const XML_Char *encodingName, const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, DTD *dtd, XML_Parser parentParser) { XML_Parser parser = NULL; #if XML_GE == 1 const size_t increase = sizeof(size_t) + EXPAT_MALLOC_PADDING + sizeof(struct XML_ParserStruct); if (parentParser != NULL) { const XML_Parser rootParser = getRootParserOf(parentParser, NULL); if (! expat_heap_increase_tolerable(rootParser, increase, __LINE__)) { return NULL; } } #else UNUSED_P(parentParser); #endif if (memsuite) { XML_Memory_Handling_Suite *mtemp; #if XML_GE == 1 void *const sizeAndParser = memsuite->malloc_fcn(sizeof(size_t) + EXPAT_MALLOC_PADDING + sizeof(struct XML_ParserStruct)); if (sizeAndParser != NULL) { *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct); parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t) + EXPAT_MALLOC_PADDING); #else parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); if (parser != NULL) { #endif mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); mtemp->malloc_fcn = memsuite->malloc_fcn; mtemp->realloc_fcn = memsuite->realloc_fcn; mtemp->free_fcn = memsuite->free_fcn; } } else { XML_Memory_Handling_Suite *mtemp; #if XML_GE == 1 void *const sizeAndParser = malloc(sizeof(size_t) + EXPAT_MALLOC_PADDING + sizeof(struct XML_ParserStruct)); if (sizeAndParser != NULL) { *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct); parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t) + EXPAT_MALLOC_PADDING); #else parser = malloc(sizeof(struct XML_ParserStruct)); if (parser != NULL) { #endif mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); mtemp->malloc_fcn = malloc; mtemp->realloc_fcn = realloc; mtemp->free_fcn = free; } } // cppcheck-suppress[memleak symbolName=sizeAndParser] // Cppcheck >=2.18.0 if (! parser) return parser; #if XML_GE == 1 // Initialize .m_alloc_tracker memset(&parser->m_alloc_tracker, 0, sizeof(MALLOC_TRACKER)); if (parentParser == NULL) { parser->m_alloc_tracker.debugLevel = getDebugLevel("EXPAT_MALLOC_DEBUG", 0u); parser->m_alloc_tracker.maximumAmplificationFactor = EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT; parser->m_alloc_tracker.activationThresholdBytes = EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT; // NOTE: This initialization needs to come this early because these fields // are read by allocation tracking code parser->m_parentParser = NULL; parser->m_accounting.countBytesDirect = 0; } else { parser->m_parentParser = parentParser; } // Record XML_ParserStruct allocation we did a few lines up before const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(rootParser->m_parentParser == NULL); assert(SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated >= increase); rootParser->m_alloc_tracker.bytesAllocated += increase; // Report on allocation if (rootParser->m_alloc_tracker.debugLevel >= 2) { if (rootParser->m_alloc_tracker.bytesAllocated > rootParser->m_alloc_tracker.peakBytesAllocated) { rootParser->m_alloc_tracker.peakBytesAllocated = rootParser->m_alloc_tracker.bytesAllocated; } expat_heap_stat(rootParser, '+', increase, rootParser->m_alloc_tracker.bytesAllocated, rootParser->m_alloc_tracker.peakBytesAllocated, __LINE__); } #else parser->m_parentParser = NULL; #endif // XML_GE == 1 parser->m_buffer = NULL; parser->m_bufferLim = NULL; parser->m_attsSize = INIT_ATTS_SIZE; parser->m_atts = MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); if (parser->m_atts == NULL) { FREE(parser, parser); return NULL; } #ifdef XML_ATTR_INFO parser->m_attInfo = MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo)); if (parser->m_attInfo == NULL) { FREE(parser, parser->m_atts); FREE(parser, parser); return NULL; } #endif parser->m_dataBuf = MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); if (parser->m_dataBuf == NULL) { FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, parser->m_attInfo); #endif FREE(parser, parser); return NULL; } parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; if (dtd) parser->m_dtd = dtd; else { parser->m_dtd = dtdCreate(parser); if (parser->m_dtd == NULL) { FREE(parser, parser->m_dataBuf); FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, parser->m_attInfo); #endif FREE(parser, parser); return NULL; } } parser->m_freeBindingList = NULL; parser->m_freeTagList = NULL; parser->m_freeInternalEntities = NULL; parser->m_freeAttributeEntities = NULL; parser->m_freeValueEntities = NULL; parser->m_groupSize = 0; parser->m_groupConnector = NULL; parser->m_unknownEncodingHandler = NULL; parser->m_unknownEncodingHandlerData = NULL; parser->m_namespaceSeparator = ASCII_EXCL; parser->m_ns = XML_FALSE; parser->m_ns_triplets = XML_FALSE; parser->m_nsAtts = NULL; parser->m_nsAttsVersion = 0; parser->m_nsAttsPower = 0; parser->m_protocolEncodingName = NULL; poolInit(&parser->m_tempPool, parser); poolInit(&parser->m_temp2Pool, parser); parserInit(parser, encodingName); if (encodingName && ! parser->m_protocolEncodingName) { if (dtd) { // We need to stop the upcoming call to XML_ParserFree from happily // destroying parser->m_dtd because the DTD is shared with the parent // parser and the only guard that keeps XML_ParserFree from destroying // parser->m_dtd is parser->m_isParamEntity but it will be set to // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all). parser->m_dtd = NULL; } XML_ParserFree(parser); return NULL; } if (nameSep) { parser->m_ns = XML_TRUE; parser->m_internalEncoding = XmlGetInternalEncodingNS(); parser->m_namespaceSeparator = *nameSep; } else { parser->m_internalEncoding = XmlGetInternalEncoding(); } return parser; } static void parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_processor = prologInitProcessor; XmlPrologStateInit(&parser->m_prologState); if (encodingName != NULL) { parser->m_protocolEncodingName = copyString(encodingName, parser); } parser->m_curBase = NULL; XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); parser->m_userData = NULL; parser->m_handlerArg = NULL; parser->m_startElementHandler = NULL; parser->m_endElementHandler = NULL; parser->m_characterDataHandler = NULL; parser->m_processingInstructionHandler = NULL; parser->m_commentHandler = NULL; parser->m_startCdataSectionHandler = NULL; parser->m_endCdataSectionHandler = NULL; parser->m_defaultHandler = NULL; parser->m_startDoctypeDeclHandler = NULL; parser->m_endDoctypeDeclHandler = NULL; parser->m_unparsedEntityDeclHandler = NULL; parser->m_notationDeclHandler = NULL; parser->m_startNamespaceDeclHandler = NULL; parser->m_endNamespaceDeclHandler = NULL; parser->m_notStandaloneHandler = NULL; parser->m_externalEntityRefHandler = NULL; parser->m_externalEntityRefHandlerArg = parser; parser->m_skippedEntityHandler = NULL; parser->m_elementDeclHandler = NULL; parser->m_attlistDeclHandler = NULL; parser->m_entityDeclHandler = NULL; parser->m_xmlDeclHandler = NULL; parser->m_bufferPtr = parser->m_buffer; parser->m_bufferEnd = parser->m_buffer; parser->m_parseEndByteIndex = 0; parser->m_parseEndPtr = NULL; parser->m_partialTokenBytesBefore = 0; parser->m_reparseDeferralEnabled = g_reparseDeferralEnabledDefault; parser->m_lastBufferRequestSize = 0; parser->m_declElementType = NULL; parser->m_declAttributeId = NULL; parser->m_declEntity = NULL; parser->m_doctypeName = NULL; parser->m_doctypeSysid = NULL; parser->m_doctypePubid = NULL; parser->m_declAttributeType = NULL; parser->m_declNotationName = NULL; parser->m_declNotationPublicId = NULL; parser->m_declAttributeIsCdata = XML_FALSE; parser->m_declAttributeIsId = XML_FALSE; memset(&parser->m_position, 0, sizeof(POSITION)); parser->m_errorCode = XML_ERROR_NONE; parser->m_eventPtr = NULL; parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; parser->m_openInternalEntities = NULL; parser->m_openAttributeEntities = NULL; parser->m_openValueEntities = NULL; parser->m_defaultExpandInternalEntities = XML_TRUE; parser->m_tagLevel = 0; parser->m_tagStack = NULL; parser->m_inheritedBindings = NULL; parser->m_nSpecifiedAtts = 0; parser->m_unknownEncodingMem = NULL; parser->m_unknownEncodingRelease = NULL; parser->m_unknownEncodingData = NULL; parser->m_parsingStatus.parsing = XML_INITIALIZED; // Reentry can only be triggered inside m_processor calls parser->m_reenter = XML_FALSE; #ifdef XML_DTD parser->m_isParamEntity = XML_FALSE; parser->m_useForeignDTD = XML_FALSE; parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif parser->m_hash_secret_salt = 0; #if XML_GE == 1 memset(&parser->m_accounting, 0, sizeof(ACCOUNTING)); parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u); parser->m_accounting.maximumAmplificationFactor = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT; parser->m_accounting.activationThresholdBytes = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT; memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS)); parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u); #endif } /* moves list of bindings to m_freeBindingList */ static void FASTCALL moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; bindings = bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; } } XML_Bool XMLCALL XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; OPEN_INTERNAL_ENTITY *openEntityList; if (parser == NULL) return XML_FALSE; if (parser->m_parentParser) return XML_FALSE; /* move m_tagStack to m_freeTagList */ tStk = parser->m_tagStack; while (tStk) { TAG *tag = tStk; tStk = tStk->parent; tag->parent = parser->m_freeTagList; moveToFreeBindingList(parser, tag->bindings); tag->bindings = NULL; parser->m_freeTagList = tag; } /* move m_openInternalEntities to m_freeInternalEntities */ openEntityList = parser->m_openInternalEntities; while (openEntityList) { OPEN_INTERNAL_ENTITY *openEntity = openEntityList; openEntityList = openEntity->next; openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; } /* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but * for attributes) */ openEntityList = parser->m_openAttributeEntities; while (openEntityList) { OPEN_INTERNAL_ENTITY *openEntity = openEntityList; openEntityList = openEntity->next; openEntity->next = parser->m_freeAttributeEntities; parser->m_freeAttributeEntities = openEntity; } /* move m_openValueEntities to m_freeValueEntities (i.e. same task but * for value entities) */ openEntityList = parser->m_openValueEntities; while (openEntityList) { OPEN_INTERNAL_ENTITY *openEntity = openEntityList; openEntityList = openEntity->next; openEntity->next = parser->m_freeValueEntities; parser->m_freeValueEntities = openEntity; } moveToFreeBindingList(parser, parser->m_inheritedBindings); FREE(parser, parser->m_unknownEncodingMem); if (parser->m_unknownEncodingRelease) parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); poolClear(&parser->m_tempPool); poolClear(&parser->m_temp2Pool); FREE(parser, (void *)parser->m_protocolEncodingName); parser->m_protocolEncodingName = NULL; parserInit(parser, encodingName); dtdReset(parser->m_dtd, parser); return XML_TRUE; } static XML_Bool parserBusy(XML_Parser parser) { switch (parser->m_parsingStatus.parsing) { case XML_PARSING: case XML_SUSPENDED: return XML_TRUE; case XML_INITIALIZED: case XML_FINISHED: default: return XML_FALSE; } } enum XML_Status XMLCALL XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser == NULL) return XML_STATUS_ERROR; /* Block after XML_Parse()/XML_ParseBuffer() has been called. XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ if (parserBusy(parser)) return XML_STATUS_ERROR; /* Get rid of any previous encoding name */ FREE(parser, (void *)parser->m_protocolEncodingName); if (encodingName == NULL) /* No new encoding name */ parser->m_protocolEncodingName = NULL; else { /* Copy the new encoding name into allocated memory */ parser->m_protocolEncodingName = copyString(encodingName, parser); if (! parser->m_protocolEncodingName) return XML_STATUS_ERROR; } return XML_STATUS_OK; } XML_Parser XMLCALL XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, const XML_Char *encodingName) { XML_Parser parser = oldParser; DTD *newDtd = NULL; DTD *oldDtd; XML_StartElementHandler oldStartElementHandler; XML_EndElementHandler oldEndElementHandler; XML_CharacterDataHandler oldCharacterDataHandler; XML_ProcessingInstructionHandler oldProcessingInstructionHandler; XML_CommentHandler oldCommentHandler; XML_StartCdataSectionHandler oldStartCdataSectionHandler; XML_EndCdataSectionHandler oldEndCdataSectionHandler; XML_DefaultHandler oldDefaultHandler; XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; XML_NotationDeclHandler oldNotationDeclHandler; XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; XML_NotStandaloneHandler oldNotStandaloneHandler; XML_ExternalEntityRefHandler oldExternalEntityRefHandler; XML_SkippedEntityHandler oldSkippedEntityHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler; void *oldUnknownEncodingHandlerData; XML_ElementDeclHandler oldElementDeclHandler; XML_AttlistDeclHandler oldAttlistDeclHandler; XML_EntityDeclHandler oldEntityDeclHandler; XML_XmlDeclHandler oldXmlDeclHandler; ELEMENT_TYPE *oldDeclElementType; void *oldUserData; void *oldHandlerArg; XML_Bool oldDefaultExpandInternalEntities; XML_Parser oldExternalEntityRefHandlerArg; #ifdef XML_DTD enum XML_ParamEntityParsing oldParamEntityParsing; int oldInEntityValue; #endif XML_Bool oldns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ unsigned long oldhash_secret_salt; XML_Bool oldReparseDeferralEnabled; /* Validate the oldParser parameter before we pull everything out of it */ if (oldParser == NULL) return NULL; /* Stash the original parser contents on the stack */ oldDtd = parser->m_dtd; oldStartElementHandler = parser->m_startElementHandler; oldEndElementHandler = parser->m_endElementHandler; oldCharacterDataHandler = parser->m_characterDataHandler; oldProcessingInstructionHandler = parser->m_processingInstructionHandler; oldCommentHandler = parser->m_commentHandler; oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; oldDefaultHandler = parser->m_defaultHandler; oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; oldNotationDeclHandler = parser->m_notationDeclHandler; oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; oldNotStandaloneHandler = parser->m_notStandaloneHandler; oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; oldSkippedEntityHandler = parser->m_skippedEntityHandler; oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; oldUnknownEncodingHandlerData = parser->m_unknownEncodingHandlerData; oldElementDeclHandler = parser->m_elementDeclHandler; oldAttlistDeclHandler = parser->m_attlistDeclHandler; oldEntityDeclHandler = parser->m_entityDeclHandler; oldXmlDeclHandler = parser->m_xmlDeclHandler; oldDeclElementType = parser->m_declElementType; oldUserData = parser->m_userData; oldHandlerArg = parser->m_handlerArg; oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; #ifdef XML_DTD oldParamEntityParsing = parser->m_paramEntityParsing; oldInEntityValue = parser->m_prologState.inEntityValue; #endif oldns_triplets = parser->m_ns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ oldhash_secret_salt = parser->m_hash_secret_salt; oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled; #ifdef XML_DTD if (! context) newDtd = oldDtd; #endif /* XML_DTD */ /* Note that the magical uses of the pre-processor to make field access look more like C++ require that `parser' be overwritten here. This makes this function more painful to follow than it would be otherwise. */ if (parser->m_ns) { XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd, oldParser); } else { parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd, oldParser); } if (! parser) return NULL; parser->m_startElementHandler = oldStartElementHandler; parser->m_endElementHandler = oldEndElementHandler; parser->m_characterDataHandler = oldCharacterDataHandler; parser->m_processingInstructionHandler = oldProcessingInstructionHandler; parser->m_commentHandler = oldCommentHandler; parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; parser->m_defaultHandler = oldDefaultHandler; parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; parser->m_notationDeclHandler = oldNotationDeclHandler; parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; parser->m_notStandaloneHandler = oldNotStandaloneHandler; parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; parser->m_skippedEntityHandler = oldSkippedEntityHandler; parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; parser->m_unknownEncodingHandlerData = oldUnknownEncodingHandlerData; parser->m_elementDeclHandler = oldElementDeclHandler; parser->m_attlistDeclHandler = oldAttlistDeclHandler; parser->m_entityDeclHandler = oldEntityDeclHandler; parser->m_xmlDeclHandler = oldXmlDeclHandler; parser->m_declElementType = oldDeclElementType; parser->m_userData = oldUserData; if (oldUserData == oldHandlerArg) parser->m_handlerArg = parser->m_userData; else parser->m_handlerArg = parser; if (oldExternalEntityRefHandlerArg != oldParser) parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; parser->m_ns_triplets = oldns_triplets; parser->m_hash_secret_salt = oldhash_secret_salt; parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled; parser->m_parentParser = oldParser; #ifdef XML_DTD parser->m_paramEntityParsing = oldParamEntityParsing; parser->m_prologState.inEntityValue = oldInEntityValue; if (context) { #endif /* XML_DTD */ if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, parser) || ! setContext(parser, context)) { XML_ParserFree(parser); return NULL; } parser->m_processor = externalEntityInitProcessor; #ifdef XML_DTD } else { /* The DTD instance referenced by parser->m_dtd is shared between the document's root parser and external PE parsers, therefore one does not need to call setContext. In addition, one also *must* not call setContext, because this would overwrite existing prefix->binding pointers in parser->m_dtd with ones that get destroyed with the external PE parser. This would leave those prefixes with dangling pointers. */ parser->m_isParamEntity = XML_TRUE; XmlPrologStateInitExternalEntity(&parser->m_prologState); parser->m_processor = externalParEntInitProcessor; } #endif /* XML_DTD */ return parser; } static void FASTCALL destroyBindings(BINDING *bindings, XML_Parser parser) { for (;;) { BINDING *b = bindings; if (! b) break; bindings = b->nextTagBinding; FREE(parser, b->uri); FREE(parser, b); } } void XMLCALL XML_ParserFree(XML_Parser parser) { TAG *tagList; OPEN_INTERNAL_ENTITY *entityList; if (parser == NULL) return; /* free m_tagStack and m_freeTagList */ tagList = parser->m_tagStack; for (;;) { TAG *p; if (tagList == NULL) { if (parser->m_freeTagList == NULL) break; tagList = parser->m_freeTagList; parser->m_freeTagList = NULL; } p = tagList; tagList = tagList->parent; FREE(parser, p->buf.raw); destroyBindings(p->bindings, parser); FREE(parser, p); } /* free m_openInternalEntities and m_freeInternalEntities */ entityList = parser->m_openInternalEntities; for (;;) { OPEN_INTERNAL_ENTITY *openEntity; if (entityList == NULL) { if (parser->m_freeInternalEntities == NULL) break; entityList = parser->m_freeInternalEntities; parser->m_freeInternalEntities = NULL; } openEntity = entityList; entityList = entityList->next; FREE(parser, openEntity); } /* free m_openAttributeEntities and m_freeAttributeEntities */ entityList = parser->m_openAttributeEntities; for (;;) { OPEN_INTERNAL_ENTITY *openEntity; if (entityList == NULL) { if (parser->m_freeAttributeEntities == NULL) break; entityList = parser->m_freeAttributeEntities; parser->m_freeAttributeEntities = NULL; } openEntity = entityList; entityList = entityList->next; FREE(parser, openEntity); } /* free m_openValueEntities and m_freeValueEntities */ entityList = parser->m_openValueEntities; for (;;) { OPEN_INTERNAL_ENTITY *openEntity; if (entityList == NULL) { if (parser->m_freeValueEntities == NULL) break; entityList = parser->m_freeValueEntities; parser->m_freeValueEntities = NULL; } openEntity = entityList; entityList = entityList->next; FREE(parser, openEntity); } destroyBindings(parser->m_freeBindingList, parser); destroyBindings(parser->m_inheritedBindings, parser); poolDestroy(&parser->m_tempPool); poolDestroy(&parser->m_temp2Pool); FREE(parser, (void *)parser->m_protocolEncodingName); #ifdef XML_DTD /* external parameter entity parsers share the DTD structure parser->m_dtd with the root parser, so we must not destroy it */ if (! parser->m_isParamEntity && parser->m_dtd) #else if (parser->m_dtd) #endif /* XML_DTD */ dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, parser); FREE(parser, parser->m_atts); #ifdef XML_ATTR_INFO FREE(parser, parser->m_attInfo); #endif FREE(parser, parser->m_groupConnector); // NOTE: We are avoiding FREE(..) here because parser->m_buffer // is not being allocated with MALLOC(..) but with plain // .malloc_fcn(..). parser->m_mem.free_fcn(parser->m_buffer); FREE(parser, parser->m_dataBuf); FREE(parser, parser->m_nsAtts); FREE(parser, parser->m_unknownEncodingMem); if (parser->m_unknownEncodingRelease) parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); FREE(parser, parser); } void XMLCALL XML_UseParserAsHandlerArg(XML_Parser parser) { if (parser != NULL) parser->m_handlerArg = parser; } enum XML_Error XMLCALL XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parserBusy(parser)) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; parser->m_useForeignDTD = useDTD; return XML_ERROR_NONE; #else UNUSED_P(useDTD); return XML_ERROR_FEATURE_REQUIRES_XML_DTD; #endif } void XMLCALL XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { if (parser == NULL) return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parserBusy(parser)) return; parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } void XMLCALL XML_SetUserData(XML_Parser parser, void *p) { if (parser == NULL) return; if (parser->m_handlerArg == parser->m_userData) parser->m_handlerArg = parser->m_userData = p; else parser->m_userData = p; } enum XML_Status XMLCALL XML_SetBase(XML_Parser parser, const XML_Char *p) { if (parser == NULL) return XML_STATUS_ERROR; if (p) { p = poolCopyString(&parser->m_dtd->pool, p); if (! p) return XML_STATUS_ERROR; parser->m_curBase = p; } else parser->m_curBase = NULL; return XML_STATUS_OK; } const XML_Char *XMLCALL XML_GetBase(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_curBase; } int XMLCALL XML_GetSpecifiedAttributeCount(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_nSpecifiedAtts; } int XMLCALL XML_GetIdAttributeIndex(XML_Parser parser) { if (parser == NULL) return -1; return parser->m_idAttIndex; } #ifdef XML_ATTR_INFO const XML_AttrInfo *XMLCALL XML_GetAttributeInfo(XML_Parser parser) { if (parser == NULL) return NULL; return parser->m_attInfo; } #endif void XMLCALL XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) { if (parser == NULL) return; parser->m_startElementHandler = start; parser->m_endElementHandler = end; } void XMLCALL XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { if (parser != NULL) parser->m_startElementHandler = start; } void XMLCALL XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { if (parser != NULL) parser->m_endElementHandler = end; } void XMLCALL XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { if (parser != NULL) parser->m_characterDataHandler = handler; } void XMLCALL XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { if (parser != NULL) parser->m_processingInstructionHandler = handler; } void XMLCALL XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { if (parser != NULL) parser->m_commentHandler = handler; } void XMLCALL XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) { if (parser == NULL) return; parser->m_startCdataSectionHandler = start; parser->m_endCdataSectionHandler = end; } void XMLCALL XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { if (parser != NULL) parser->m_startCdataSectionHandler = start; } void XMLCALL XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { if (parser != NULL) parser->m_endCdataSectionHandler = end; } void XMLCALL XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; parser->m_defaultExpandInternalEntities = XML_FALSE; } void XMLCALL XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { if (parser == NULL) return; parser->m_defaultHandler = handler; parser->m_defaultExpandInternalEntities = XML_TRUE; } void XMLCALL XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end) { if (parser == NULL) return; parser->m_startDoctypeDeclHandler = start; parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { if (parser != NULL) parser->m_startDoctypeDeclHandler = start; } void XMLCALL XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { if (parser != NULL) parser->m_endDoctypeDeclHandler = end; } void XMLCALL XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { if (parser != NULL) parser->m_unparsedEntityDeclHandler = handler; } void XMLCALL XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { if (parser != NULL) parser->m_notationDeclHandler = handler; } void XMLCALL XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) { if (parser == NULL) return; parser->m_startNamespaceDeclHandler = start; parser->m_endNamespaceDeclHandler = end; } void XMLCALL XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { if (parser != NULL) parser->m_startNamespaceDeclHandler = start; } void XMLCALL XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { if (parser != NULL) parser->m_endNamespaceDeclHandler = end; } void XMLCALL XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { if (parser != NULL) parser->m_notStandaloneHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { if (parser != NULL) parser->m_externalEntityRefHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { if (parser == NULL) return; if (arg) parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; else parser->m_externalEntityRefHandlerArg = parser; } void XMLCALL XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler) { if (parser != NULL) parser->m_skippedEntityHandler = handler; } void XMLCALL XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *data) { if (parser == NULL) return; parser->m_unknownEncodingHandler = handler; parser->m_unknownEncodingHandlerData = data; } void XMLCALL XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { if (parser != NULL) parser->m_elementDeclHandler = eldecl; } void XMLCALL XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { if (parser != NULL) parser->m_attlistDeclHandler = attdecl; } void XMLCALL XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { if (parser != NULL) parser->m_entityDeclHandler = handler; } void XMLCALL XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { if (parser != NULL) parser->m_xmlDeclHandler = handler; } int XMLCALL XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing peParsing) { if (parser == NULL) return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parserBusy(parser)) return 0; #ifdef XML_DTD parser->m_paramEntityParsing = peParsing; return 1; #else return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; #endif } int XMLCALL XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { if (parser == NULL) return 0; const XML_Parser rootParser = getRootParserOf(parser, NULL); assert(! rootParser->m_parentParser); /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (parserBusy(rootParser)) return 0; rootParser->m_hash_secret_salt = hash_salt; return 1; } enum XML_Status XMLCALL XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { if (parser != NULL) parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; return XML_STATUS_ERROR; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } /* fall through */ default: parser->m_parsingStatus.parsing = XML_PARSING; } #if XML_CONTEXT_BYTES == 0 if (parser->m_bufferPtr == parser->m_bufferEnd) { const char *end; int nLeftOver; enum XML_Status result; /* Detect overflow (a+b > MAX <==> b > MAX-a) */ if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { parser->m_errorCode = XML_ERROR_NO_MEMORY; parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } // though this isn't a buffer request, we assume that `len` is the app's // preferred buffer fill size, and therefore save it here. parser->m_lastBufferRequestSize = len; parser->m_parseEndByteIndex += len; parser->m_positionPtr = s; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; parser->m_errorCode = callProcessor(parser, s, parser->m_parseEndPtr = s + len, &end); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { parser->m_parsingStatus.parsing = XML_FINISHED; return XML_STATUS_OK; } /* fall through */ default: result = XML_STATUS_OK; } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position); nLeftOver = s + len - end; if (nLeftOver) { // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED // (and XML_ERROR_FINISHED) from XML_GetBuffer. const enum XML_Parsing originalStatus = parser->m_parsingStatus.parsing; parser->m_parsingStatus.parsing = XML_PARSING; void *const temp = XML_GetBuffer(parser, nLeftOver); parser->m_parsingStatus.parsing = originalStatus; // GetBuffer may have overwritten this, but we want to remember what the // app requested, not how many bytes were left over after parsing. parser->m_lastBufferRequestSize = len; if (temp == NULL) { // NOTE: parser->m_errorCode has already been set by XML_GetBuffer(). parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } // Since we know that the buffer was empty and XML_CONTEXT_BYTES is 0, we // don't have any data to preserve, and can copy straight into the start // of the buffer rather than the GetBuffer return pointer (which may be // pointing further into the allocated buffer). memcpy(parser->m_buffer, end, nLeftOver); } parser->m_bufferPtr = parser->m_buffer; parser->m_bufferEnd = parser->m_buffer + nLeftOver; parser->m_positionPtr = parser->m_bufferPtr; parser->m_parseEndPtr = parser->m_bufferEnd; parser->m_eventPtr = parser->m_bufferPtr; parser->m_eventEndPtr = parser->m_bufferPtr; return result; } #endif /* XML_CONTEXT_BYTES == 0 */ void *buff = XML_GetBuffer(parser, len); if (buff == NULL) return XML_STATUS_ERROR; if (len > 0) { assert(s != NULL); // make sure s==NULL && len!=0 was rejected above memcpy(buff, s, len); } return XML_ParseBuffer(parser, len, isFinal); } enum XML_Status XMLCALL XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { const char *start; enum XML_Status result = XML_STATUS_OK; if (parser == NULL) return XML_STATUS_ERROR; if (len < 0) { parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; return XML_STATUS_ERROR; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_INITIALIZED: /* Has someone called XML_GetBuffer successfully before? */ if (! parser->m_bufferPtr) { parser->m_errorCode = XML_ERROR_NO_BUFFER; return XML_STATUS_ERROR; } if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } /* fall through */ default: parser->m_parsingStatus.parsing = XML_PARSING; } start = parser->m_bufferPtr; parser->m_positionPtr = start; parser->m_bufferEnd += len; parser->m_parseEndPtr = parser->m_bufferEnd; parser->m_parseEndByteIndex += len; parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; parser->m_errorCode = callProcessor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (isFinal) { parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default:; /* should not happen */ } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } void *XMLCALL XML_GetBuffer(XML_Parser parser, int len) { if (parser == NULL) return NULL; if (len < 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_errorCode = XML_ERROR_SUSPENDED; return NULL; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return NULL; default:; } // whether or not the request succeeds, `len` seems to be the app's preferred // buffer fill size; remember it. parser->m_lastBufferRequestSize = len; if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd) || parser->m_buffer == NULL) { #if XML_CONTEXT_BYTES > 0 int keep; #endif /* XML_CONTEXT_BYTES > 0 */ /* Do not invoke signed arithmetic overflow: */ int neededSize = (int)((unsigned)len + (unsigned)EXPAT_SAFE_PTR_DIFF( parser->m_bufferEnd, parser->m_bufferPtr)); if (neededSize < 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } #if XML_CONTEXT_BYTES > 0 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; /* Detect and prevent integer overflow */ if (keep > INT_MAX - neededSize) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } neededSize += keep; #endif /* XML_CONTEXT_BYTES > 0 */ if (parser->m_buffer && parser->m_bufferPtr && neededSize <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { #if XML_CONTEXT_BYTES > 0 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { int offset = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) - keep; /* The buffer pointers cannot be NULL here; we have at least some bytes * in the buffer */ memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep); parser->m_bufferEnd -= offset; parser->m_bufferPtr -= offset; } #else memmove(parser->m_buffer, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); parser->m_bufferEnd = parser->m_buffer + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); parser->m_bufferPtr = parser->m_buffer; #endif /* XML_CONTEXT_BYTES > 0 */ } else { char *newBuf; int bufferSize = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer); if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { /* Do not invoke signed arithmetic overflow: */ bufferSize = (int)(2U * (unsigned)bufferSize); } while (bufferSize < neededSize && bufferSize > 0); if (bufferSize <= 0) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } // NOTE: We are avoiding MALLOC(..) here to leave limiting // the input size to the application using Expat. newBuf = parser->m_mem.malloc_fcn(bufferSize); if (newBuf == NULL) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } parser->m_bufferLim = newBuf + bufferSize; #if XML_CONTEXT_BYTES > 0 if (parser->m_bufferPtr) { memcpy(newBuf, &parser->m_bufferPtr[-keep], EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep); // NOTE: We are avoiding FREE(..) here because parser->m_buffer // is not being allocated with MALLOC(..) but with plain // .malloc_fcn(..). parser->m_mem.free_fcn(parser->m_buffer); parser->m_buffer = newBuf; parser->m_bufferEnd = parser->m_buffer + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep; parser->m_bufferPtr = parser->m_buffer + keep; } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; parser->m_bufferPtr = parser->m_buffer = newBuf; } #else if (parser->m_bufferPtr) { memcpy(newBuf, parser->m_bufferPtr, EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); // NOTE: We are avoiding FREE(..) here because parser->m_buffer // is not being allocated with MALLOC(..) but with plain // .malloc_fcn(..). parser->m_mem.free_fcn(parser->m_buffer); parser->m_bufferEnd = newBuf + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); } else { /* This must be a brand new buffer with no data in it yet */ parser->m_bufferEnd = newBuf; } parser->m_bufferPtr = parser->m_buffer = newBuf; #endif /* XML_CONTEXT_BYTES > 0 */ } parser->m_eventPtr = parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; } return parser->m_bufferEnd; } static void triggerReenter(XML_Parser parser) { parser->m_reenter = XML_TRUE; } enum XML_Status XMLCALL XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { case XML_INITIALIZED: parser->m_errorCode = XML_ERROR_NOT_STARTED; return XML_STATUS_ERROR; case XML_SUSPENDED: if (resumable) { parser->m_errorCode = XML_ERROR_SUSPENDED; return XML_STATUS_ERROR; } parser->m_parsingStatus.parsing = XML_FINISHED; break; case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; case XML_PARSING: if (resumable) { #ifdef XML_DTD if (parser->m_isParamEntity) { parser->m_errorCode = XML_ERROR_SUSPEND_PE; return XML_STATUS_ERROR; } #endif parser->m_parsingStatus.parsing = XML_SUSPENDED; } else parser->m_parsingStatus.parsing = XML_FINISHED; break; default: assert(0); } return XML_STATUS_OK; } enum XML_Status XMLCALL XML_ResumeParser(XML_Parser parser) { enum XML_Status result = XML_STATUS_OK; if (parser == NULL) return XML_STATUS_ERROR; if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; return XML_STATUS_ERROR; } parser->m_parsingStatus.parsing = XML_PARSING; parser->m_errorCode = callProcessor( parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); if (parser->m_errorCode != XML_ERROR_NONE) { parser->m_eventEndPtr = parser->m_eventPtr; parser->m_processor = errorProcessor; return XML_STATUS_ERROR; } else { switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: result = XML_STATUS_SUSPENDED; break; case XML_INITIALIZED: case XML_PARSING: if (parser->m_parsingStatus.finalBuffer) { parser->m_parsingStatus.parsing = XML_FINISHED; return result; } default:; } } XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position); parser->m_positionPtr = parser->m_bufferPtr; return result; } void XMLCALL XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { if (parser == NULL) return; assert(status != NULL); *status = parser->m_parsingStatus; } enum XML_Error XMLCALL XML_GetErrorCode(XML_Parser parser) { if (parser == NULL) return XML_ERROR_INVALID_ARGUMENT; return parser->m_errorCode; } XML_Index XMLCALL XML_GetCurrentByteIndex(XML_Parser parser) { if (parser == NULL) return -1; if (parser->m_eventPtr) return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr)); return -1; } int XMLCALL XML_GetCurrentByteCount(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventEndPtr && parser->m_eventPtr) return (int)(parser->m_eventEndPtr - parser->m_eventPtr); return 0; } const char *XMLCALL XML_GetInputContext(XML_Parser parser, int *offset, int *size) { #if XML_CONTEXT_BYTES > 0 if (parser == NULL) return NULL; if (parser->m_eventPtr && parser->m_buffer) { if (offset != NULL) *offset = (int)(parser->m_eventPtr - parser->m_buffer); if (size != NULL) *size = (int)(parser->m_bufferEnd - parser->m_buffer); return parser->m_buffer; } #else (void)parser; (void)offset; (void)size; #endif /* XML_CONTEXT_BYTES > 0 */ return (const char *)0; } XML_Size XMLCALL XML_GetCurrentLineNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.lineNumber + 1; } XML_Size XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser) { if (parser == NULL) return 0; if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position); parser->m_positionPtr = parser->m_eventPtr; } return parser->m_position.columnNumber; } void XMLCALL XML_FreeContentModel(XML_Parser parser, XML_Content *model) { if (parser == NULL) return; // NOTE: We are avoiding FREE(..) here because the content model // has been created using plain .malloc_fcn(..) rather than MALLOC(..). parser->m_mem.free_fcn(model); } void *XMLCALL XML_MemMalloc(XML_Parser parser, size_t size) { if (parser == NULL) return NULL; // NOTE: We are avoiding MALLOC(..) here to not include // user allocations with allocation tracking and limiting. return parser->m_mem.malloc_fcn(size); } void *XMLCALL XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { if (parser == NULL) return NULL; // NOTE: We are avoiding REALLOC(..) here to not include // user allocations with allocation tracking and limiting. return parser->m_mem.realloc_fcn(ptr, size); } void XMLCALL XML_MemFree(XML_Parser parser, void *ptr) { if (parser == NULL) return; // NOTE: We are avoiding FREE(..) here because XML_MemMalloc and // XML_MemRealloc are not using MALLOC(..) and REALLOC(..) // but plain .malloc_fcn(..) and .realloc_fcn(..), internally. parser->m_mem.free_fcn(ptr); } void XMLCALL XML_DefaultCurrent(XML_Parser parser) { if (parser == NULL) return; if (parser->m_defaultHandler) { if (parser->m_openInternalEntities) reportDefault(parser, parser->m_internalEncoding, parser->m_openInternalEntities->internalEventPtr, parser->m_openInternalEntities->internalEventEndPtr); else reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr); } } const XML_LChar *XMLCALL XML_ErrorString(enum XML_Error code) { switch (code) { case XML_ERROR_NONE: return NULL; case XML_ERROR_NO_MEMORY: return XML_L("out of memory"); case XML_ERROR_SYNTAX: return XML_L("syntax error"); case XML_ERROR_NO_ELEMENTS: return XML_L("no element found"); case XML_ERROR_INVALID_TOKEN: return XML_L("not well-formed (invalid token)"); case XML_ERROR_UNCLOSED_TOKEN: return XML_L("unclosed token"); case XML_ERROR_PARTIAL_CHAR: return XML_L("partial character"); case XML_ERROR_TAG_MISMATCH: return XML_L("mismatched tag"); case XML_ERROR_DUPLICATE_ATTRIBUTE: return XML_L("duplicate attribute"); case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return XML_L("junk after document element"); case XML_ERROR_PARAM_ENTITY_REF: return XML_L("illegal parameter entity reference"); case XML_ERROR_UNDEFINED_ENTITY: return XML_L("undefined entity"); case XML_ERROR_RECURSIVE_ENTITY_REF: return XML_L("recursive entity reference"); case XML_ERROR_ASYNC_ENTITY: return XML_L("asynchronous entity"); case XML_ERROR_BAD_CHAR_REF: return XML_L("reference to invalid character number"); case XML_ERROR_BINARY_ENTITY_REF: return XML_L("reference to binary entity"); case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return XML_L("reference to external entity in attribute"); case XML_ERROR_MISPLACED_XML_PI: return XML_L("XML or text declaration not at start of entity"); case XML_ERROR_UNKNOWN_ENCODING: return XML_L("unknown encoding"); case XML_ERROR_INCORRECT_ENCODING: return XML_L("encoding specified in XML declaration is incorrect"); case XML_ERROR_UNCLOSED_CDATA_SECTION: return XML_L("unclosed CDATA section"); case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return XML_L("error in processing external entity reference"); case XML_ERROR_NOT_STANDALONE: return XML_L("document is not standalone"); case XML_ERROR_UNEXPECTED_STATE: return XML_L("unexpected parser state - please send a bug report"); case XML_ERROR_ENTITY_DECLARED_IN_PE: return XML_L("entity declared in parameter entity"); case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return XML_L("requested feature requires XML_DTD support in Expat"); case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return XML_L("cannot change setting once parsing has begun"); /* Added in 1.95.7. */ case XML_ERROR_UNBOUND_PREFIX: return XML_L("unbound prefix"); /* Added in 1.95.8. */ case XML_ERROR_UNDECLARING_PREFIX: return XML_L("must not undeclare prefix"); case XML_ERROR_INCOMPLETE_PE: return XML_L("incomplete markup in parameter entity"); case XML_ERROR_XML_DECL: return XML_L("XML declaration not well-formed"); case XML_ERROR_TEXT_DECL: return XML_L("text declaration not well-formed"); case XML_ERROR_PUBLICID: return XML_L("illegal character(s) in public id"); case XML_ERROR_SUSPENDED: return XML_L("parser suspended"); case XML_ERROR_NOT_SUSPENDED: return XML_L("parser not suspended"); case XML_ERROR_ABORTED: return XML_L("parsing aborted"); case XML_ERROR_FINISHED: return XML_L("parsing finished"); case XML_ERROR_SUSPEND_PE: return XML_L("cannot suspend in external parameter entity"); /* Added in 2.0.0. */ case XML_ERROR_RESERVED_PREFIX_XML: return XML_L( "reserved prefix (xml) must not be undeclared or bound to another namespace name"); case XML_ERROR_RESERVED_PREFIX_XMLNS: return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); case XML_ERROR_RESERVED_NAMESPACE_URI: return XML_L( "prefix must not be bound to one of the reserved namespace names"); /* Added in 2.2.5. */ case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ return XML_L("invalid argument"); /* Added in 2.3.0. */ case XML_ERROR_NO_BUFFER: return XML_L( "a successful prior call to function XML_GetBuffer is required"); /* Added in 2.4.0. */ case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: return XML_L( "limit on input amplification factor (from DTD and entities) breached"); /* Added in 2.6.4. */ case XML_ERROR_NOT_STARTED: return XML_L("parser not started"); } return NULL; } const XML_LChar *XMLCALL XML_ExpatVersion(void) { /* V1 is used to string-ize the version number. However, it would string-ize the actual version macro *names* unless we get them substituted before being passed to V1. CPP is defined to expand a macro, then rescan for more expansions. Thus, we use V2 to expand the version macros, then CPP will expand the resulting V1() macro with the correct numerals. */ /* ### I'm assuming cpp is portable in this respect... */ #define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) #define V2(a, b, c) XML_L("expat_") V1(a, b, c) return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); #undef V1 #undef V2 } XML_Expat_Version XMLCALL XML_ExpatVersionInfo(void) { XML_Expat_Version version; version.major = XML_MAJOR_VERSION; version.minor = XML_MINOR_VERSION; version.micro = XML_MICRO_VERSION; return version; } const XML_Feature *XMLCALL XML_GetFeatureList(void) { static const XML_Feature features[] = { {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), sizeof(XML_Char)}, {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), sizeof(XML_LChar)}, #ifdef XML_UNICODE {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, #endif #ifdef XML_UNICODE_WCHAR_T {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, #endif #ifdef XML_DTD {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, #endif #if XML_CONTEXT_BYTES > 0 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), XML_CONTEXT_BYTES}, #endif #ifdef XML_MIN_SIZE {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, #endif #ifdef XML_NS {XML_FEATURE_NS, XML_L("XML_NS"), 0}, #endif #ifdef XML_LARGE_SIZE {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, #endif #ifdef XML_ATTR_INFO {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, #endif #if XML_GE == 1 /* Added in Expat 2.4.0 for XML_DTD defined and * added in Expat 2.6.0 for XML_GE == 1. */ {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, XML_L("XML_BLAP_MAX_AMP"), (long int) EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT}, {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, XML_L("XML_BLAP_ACT_THRES"), EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT}, /* Added in Expat 2.6.0. */ {XML_FEATURE_GE, XML_L("XML_GE"), 0}, /* Added in Expat 2.7.2. */ {XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT, XML_L("XML_AT_MAX_AMP"), (long int)EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT}, {XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT, XML_L("XML_AT_ACT_THRES"), (long int)EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT}, #endif {XML_FEATURE_END, NULL, 0}}; return features; } #if XML_GE == 1 XML_Bool XMLCALL XML_SetBillionLaughsAttackProtectionMaximumAmplification( XML_Parser parser, float maximumAmplificationFactor) { if ((parser == NULL) || (parser->m_parentParser != NULL) || isnan(maximumAmplificationFactor) || (maximumAmplificationFactor < 1.0f)) { return XML_FALSE; } parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor; return XML_TRUE; } XML_Bool XMLCALL XML_SetBillionLaughsAttackProtectionActivationThreshold( XML_Parser parser, unsigned long long activationThresholdBytes) { if ((parser == NULL) || (parser->m_parentParser != NULL)) { return XML_FALSE; } parser->m_accounting.activationThresholdBytes = activationThresholdBytes; return XML_TRUE; } XML_Bool XMLCALL XML_SetAllocTrackerMaximumAmplification(XML_Parser parser, float maximumAmplificationFactor) { if ((parser == NULL) || (parser->m_parentParser != NULL) || isnan(maximumAmplificationFactor) || (maximumAmplificationFactor < 1.0f)) { return XML_FALSE; } parser->m_alloc_tracker.maximumAmplificationFactor = maximumAmplificationFactor; return XML_TRUE; } XML_Bool XMLCALL XML_SetAllocTrackerActivationThreshold( XML_Parser parser, unsigned long long activationThresholdBytes) { if ((parser == NULL) || (parser->m_parentParser != NULL)) { return XML_FALSE; } parser->m_alloc_tracker.activationThresholdBytes = activationThresholdBytes; return XML_TRUE; } #endif /* XML_GE == 1 */ XML_Bool XMLCALL XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) { if (parser != NULL && (enabled == XML_TRUE || enabled == XML_FALSE)) { parser->m_reparseDeferralEnabled = enabled; return XML_TRUE; } return XML_FALSE; } /* Initially tag->rawName always points into the parse buffer; for those TAG instances opened while the current parse buffer was processed, and not yet closed, we need to store tag->rawName in a more permanent location, since the parse buffer is about to be discarded. */ static XML_Bool storeRawNames(XML_Parser parser) { TAG *tag = parser->m_tagStack; while (tag) { size_t bufSize; size_t nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); size_t rawNameLen; char *rawNameBuf = tag->buf.raw + nameLen; /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything below it in the stack is already been accounted for in a previous call to this function. */ if (tag->rawName == rawNameBuf) break; /* For reuse purposes we need to ensure that the size of tag->buf is a multiple of sizeof(XML_Char). */ rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); /* Detect and prevent integer overflow. */ if (rawNameLen > (size_t)INT_MAX - nameLen) return XML_FALSE; bufSize = nameLen + rawNameLen; if (bufSize > (size_t)(tag->bufEnd - tag->buf.raw)) { char *temp = REALLOC(parser, tag->buf.raw, bufSize); if (temp == NULL) return XML_FALSE; /* if tag->name.str points to tag->buf.str (only when namespace processing is off) then we have to update it */ if (tag->name.str == tag->buf.str) tag->name.str = (XML_Char *)temp; /* if tag->name.localPart is set (when namespace processing is on) then update it as well, since it will always point into tag->buf */ if (tag->name.localPart) tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - tag->buf.str); tag->buf.raw = temp; tag->bufEnd = temp + bufSize; rawNameBuf = temp + nameLen; } memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); tag->rawName = rawNameBuf; tag = tag->parent; } return XML_TRUE; } static enum XML_Error PTRCALL contentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doContent( parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); if (result == XML_ERROR_NONE) { if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error PTRCALL externalEntityInitProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; parser->m_processor = externalEntityInitProcessor2; return externalEntityInitProcessor2(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityInitProcessor2(XML_Parser parser, const char *start, const char *end, const char **endPtr) { const char *next = start; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(parser->m_encoding, start, end, &next); switch (tok) { case XML_TOK_BOM: #if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, start, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #endif /* XML_GE == 1 */ /* If we are at the end of the buffer, this would cause the next stage, i.e. externalEntityInitProcessor3, to pass control directly to doContent (by detecting XML_TOK_NONE) without processing any xml text declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. */ if (next == end && ! parser->m_parsingStatus.finalBuffer) { *endPtr = next; return XML_ERROR_NONE; } start = next; break; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } parser->m_eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } parser->m_eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } parser->m_processor = externalEntityInitProcessor3; return externalEntityInitProcessor3(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityInitProcessor3(XML_Parser parser, const char *start, const char *end, const char **endPtr) { int tok; const char *next = start; /* XmlContentTok doesn't always set the last arg */ parser->m_eventPtr = start; tok = XmlContentTok(parser->m_encoding, start, end, &next); /* Note: These bytes are accounted later in: - processXmlDecl - externalEntityContentProcessor */ parser->m_eventEndPtr = next; switch (tok) { case XML_TOK_XML_DECL: { enum XML_Error result; result = processXmlDecl(parser, 1, start, next); if (result != XML_ERROR_NONE) return result; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *endPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; case XML_PARSING: if (parser->m_reenter) { return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE } /* Fall through */ default: start = next; } } break; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *endPtr = start; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; } parser->m_processor = externalEntityContentProcessor; parser->m_tagLevel = 1; return externalEntityContentProcessor(parser, start, end, endPtr); } static enum XML_Error PTRCALL externalEntityContentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_ENTITY_EXPANSION); if (result == XML_ERROR_NONE) { if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; } return result; } static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *s, const char *end, const char **nextPtr, XML_Bool haveMore, enum XML_Account account) { /* save one level of indirection */ DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; for (;;) { const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); #if XML_GE == 1 const char *accountAfter = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR)) ? (haveMore ? s /* i.e. 0 bytes */ : end) : next; if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__, account)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #endif *eventEndPP = next; switch (tok) { case XML_TOK_TRAILING_CR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } *eventEndPP = end; if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? */ if (startTagLevel == 0) return XML_ERROR_NO_ELEMENTS; if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } if (startTagLevel > 0) { if (parser->m_tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_NO_ELEMENTS; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; XML_Char ch = (XML_Char)XmlPredefinedEntityName( enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { #if XML_GE == 1 /* NOTE: We are replacing 4-6 characters original input for 1 character * so there is no amplification and hence recording without * protection. */ accountingDiffTolerated(parser, tok, (char *)&ch, ((char *)&ch) + sizeof(XML_Char), __LINE__, XML_ACCOUNT_ENTITY_EXPANSION); #endif /* XML_GE == 1 */ if (parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); poolDiscard(&dtd->pool); /* First, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity or default handler. */ if (! dtd->hasParamEntityRefs || dtd->standalone) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) return XML_ERROR_ENTITY_DECLARED_IN_PE; } else if (! entity) { if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } if (entity->open) return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->notation) return XML_ERROR_BINARY_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; if (! parser->m_defaultExpandInternalEntities) { if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } result = processEntity(parser, entity, XML_FALSE, ENTITY_INTERNAL); if (result != XML_ERROR_NONE) return result; } else if (parser->m_externalEntityRefHandler) { const XML_Char *context; entity->open = XML_TRUE; context = getContext(parser); entity->open = XML_FALSE; if (! context) return XML_ERROR_NO_MEMORY; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, context, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; poolDiscard(&parser->m_tempPool); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; } case XML_TOK_START_TAG_NO_ATTS: /* fall through */ case XML_TOK_START_TAG_WITH_ATTS: { TAG *tag; enum XML_Error result; XML_Char *toPtr; if (parser->m_freeTagList) { tag = parser->m_freeTagList; parser->m_freeTagList = parser->m_freeTagList->parent; } else { tag = MALLOC(parser, sizeof(TAG)); if (! tag) return XML_ERROR_NO_MEMORY; tag->buf.raw = MALLOC(parser, INIT_TAG_BUF_SIZE); if (! tag->buf.raw) { FREE(parser, tag); return XML_ERROR_NO_MEMORY; } tag->bufEnd = tag->buf.raw + INIT_TAG_BUF_SIZE; } tag->bindings = NULL; tag->parent = parser->m_tagStack; parser->m_tagStack = tag; tag->name.localPart = NULL; tag->name.prefix = NULL; tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); ++parser->m_tagLevel; { const char *rawNameEnd = tag->rawName + tag->rawNameLength; const char *fromPtr = tag->rawName; toPtr = tag->buf.str; for (;;) { int convLen; const enum XML_Convert_Result convert_res = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); convLen = (int)(toPtr - tag->buf.str); if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } if (SIZE_MAX / 2 < (size_t)(tag->bufEnd - tag->buf.raw)) return XML_ERROR_NO_MEMORY; const size_t bufSize = (size_t)(tag->bufEnd - tag->buf.raw) * 2; { char *temp = REALLOC(parser, tag->buf.raw, bufSize); if (temp == NULL) return XML_ERROR_NO_MEMORY; tag->buf.raw = temp; tag->bufEnd = temp + bufSize; toPtr = (XML_Char *)temp + convLen; } } } tag->name.str = tag->buf.str; *toPtr = XML_T('\0'); result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); if (result) return result; if (parser->m_startElementHandler) parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, (const XML_Char **)parser->m_atts); else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); poolClear(&parser->m_tempPool); break; } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: /* fall through */ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { const char *rawName = s + enc->minBytesPerChar; enum XML_Error result; BINDING *bindings = NULL; XML_Bool noElmHandlers = XML_TRUE; TAG_NAME name; name.str = poolStoreString(&parser->m_tempPool, enc, rawName, rawName + XmlNameLength(enc, rawName)); if (! name.str) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); result = storeAtts(parser, enc, s, &name, &bindings, XML_ACCOUNT_NONE /* token spans whole start tag */); if (result != XML_ERROR_NONE) { freeBindings(parser, bindings); return result; } poolFinish(&parser->m_tempPool); if (parser->m_startElementHandler) { parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts); noElmHandlers = XML_FALSE; } if (parser->m_endElementHandler) { if (parser->m_startElementHandler) *eventPP = *eventEndPP; parser->m_endElementHandler(parser->m_handlerArg, name.str); noElmHandlers = XML_FALSE; } if (noElmHandlers && parser->m_defaultHandler) reportDefault(parser, enc, s, next); poolClear(&parser->m_tempPool); freeBindings(parser, bindings); } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { if (parser->m_parsingStatus.parsing == XML_SUSPENDED || (parser->m_parsingStatus.parsing == XML_PARSING && parser->m_reenter)) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); } break; case XML_TOK_END_TAG: if (parser->m_tagLevel == startTagLevel) return XML_ERROR_ASYNC_ENTITY; else { int len; const char *rawName; TAG *tag = parser->m_tagStack; rawName = s + enc->minBytesPerChar * 2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength || memcmp(tag->rawName, rawName, len) != 0) { *eventPP = rawName; return XML_ERROR_TAG_MISMATCH; } parser->m_tagStack = tag->parent; tag->parent = parser->m_freeTagList; parser->m_freeTagList = tag; --parser->m_tagLevel; if (parser->m_endElementHandler) { const XML_Char *localPart; const XML_Char *prefix; XML_Char *uri; localPart = tag->name.localPart; if (parser->m_ns && localPart) { /* localPart and prefix may have been overwritten in tag->name.str, since this points to the binding->uri buffer which gets reused; so we have to add them again */ uri = (XML_Char *)tag->name.str + tag->name.uriLen; /* don't need to check for space - already done in storeAtts() */ while (*localPart) *uri++ = *localPart++; prefix = tag->name.prefix; if (parser->m_ns_triplets && prefix) { *uri++ = parser->m_namespaceSeparator; while (*prefix) *uri++ = *prefix++; } *uri = XML_T('\0'); } parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); while (tag->bindings) { BINDING *b = tag->bindings; if (parser->m_endNamespaceDeclHandler) parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); tag->bindings = tag->bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { if (parser->m_parsingStatus.parsing == XML_SUSPENDED || (parser->m_parsingStatus.parsing == XML_PARSING && parser->m_reenter)) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); } } break; case XML_TOK_CHAR_REF: { int n = XmlCharRefNumber(enc, s); if (n < 0) return XML_ERROR_BAD_CHAR_REF; if (parser->m_characterDataHandler) { XML_Char buf[XML_ENCODE_MAX]; parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; case XML_TOK_DATA_NEWLINE: if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_CDATA_SECT_OPEN: { enum XML_Error result; if (parser->m_startCdataSectionHandler) parser->m_startCdataSectionHandler(parser->m_handlerArg); /* BEGIN disabled code */ /* Suppose you doing a transformation on a document that involves changing only the character data. You set up a defaultHandler and a characterDataHandler. The defaultHandler simply copies characters through. The characterDataHandler does the transformation and writes the characters out escaping them as necessary. This case will fail to work if we leave out the following two lines (because & and < inside CDATA sections will be incorrectly escaped). However, now we have a start/endCdataSectionHandler, so it seems easier to let the user deal with this. */ else if ((0) && parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); /* END disabled code */ else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account); if (result != XML_ERROR_NONE) return result; else if (! next) { parser->m_processor = cdataSectionProcessor; return result; } } break; case XML_TOK_TRAILING_RSQB: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } if (parser->m_characterDataHandler) { if (MUST_CONVERT(enc, s)) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); parser->m_characterDataHandler( parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); } else parser->m_characterDataHandler( parser->m_handlerArg, (const XML_Char *)s, (int)((const XML_Char *)end - (const XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, end); /* We are at the end of the final buffer, should we check for XML_SUSPENDED, XML_FINISHED? */ if (startTagLevel == 0) { *eventPP = end; return XML_ERROR_NO_ELEMENTS; } if (parser->m_tagLevel != startTagLevel) { *eventPP = end; return XML_ERROR_ASYNC_ENTITY; } *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_DATA_CHARS: { XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; const enum XML_Convert_Result convert_res = XmlConvert( enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; charDataHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else charDataHandler(parser->m_handlerArg, (const XML_Char *)s, (int)((const XML_Char *)next - (const XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_PI: if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; default: /* All of the tokens produced by XmlContentTok() have their own * explicit cases, so this default is not strictly necessary. * However it is a useful safety net, so we retain the code and * simply exclude it from the coverage tests. * * LCOV_EXCL_START */ if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; /* LCOV_EXCL_STOP */ } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *eventPP = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: *eventPP = next; return XML_ERROR_ABORTED; case XML_PARSING: if (parser->m_reenter) { *nextPtr = next; return XML_ERROR_NONE; } /* Fall through */ default:; *eventPP = s = next; } } /* not reached */ } /* This function does not call free() on the allocated memory, merely * moving it to the parser's m_freeBindingList where it can be freed or * reused as appropriate. */ static void freeBindings(XML_Parser parser, BINDING *bindings) { while (bindings) { BINDING *b = bindings; /* m_startNamespaceDeclHandler will have been called for this * binding in addBindings(), so call the end handler now. */ if (parser->m_endNamespaceDeclHandler) parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); bindings = bindings->nextTagBinding; b->nextTagBinding = parser->m_freeBindingList; parser->m_freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } } /* Precondition: all arguments must be non-NULL; Purpose: - normalize attributes - check attributes for well-formedness - generate namespace aware attribute names (URI, prefix) - build list of attributes for startElementHandler - default attributes - process namespace declarations (check and report them) - generate namespace aware element name (URI, prefix) */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, TAG_NAME *tagNamePtr, BINDING **bindingsPtr, enum XML_Account account) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ELEMENT_TYPE *elementType; int nDefaultAtts; const XML_Char **appAtts; /* the attribute list for the application */ int attIndex = 0; int prefixLen; int i; int n; XML_Char *uri; int nPrefixes = 0; BINDING *binding; const XML_Char *localPart; /* lookup the element type name */ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); if (! elementType) { const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); if (! name) return XML_ERROR_NO_MEMORY; elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (! elementType) return XML_ERROR_NO_MEMORY; if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) return XML_ERROR_NO_MEMORY; } nDefaultAtts = elementType->nDefaultAtts; /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); /* Detect and prevent integer overflow */ if (n > INT_MAX - nDefaultAtts) { return XML_ERROR_NO_MEMORY; } if (n + nDefaultAtts > parser->m_attsSize) { int oldAttsSize = parser->m_attsSize; ATTRIBUTE *temp; #ifdef XML_ATTR_INFO XML_AttrInfo *temp2; #endif /* Detect and prevent integer overflow */ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { return XML_ERROR_NO_MEMORY; } parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(ATTRIBUTE)) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } #endif temp = REALLOC(parser, parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } parser->m_atts = temp; #ifdef XML_ATTR_INFO /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ # if UINT_MAX >= SIZE_MAX if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(XML_AttrInfo)) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } # endif temp2 = REALLOC(parser, parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } parser->m_attInfo = temp2; #endif if (n > oldAttsSize) XmlGetAttributes(enc, attStr, n, parser->m_atts); } appAtts = (const XML_Char **)parser->m_atts; for (i = 0; i < n; i++) { ATTRIBUTE *currAtt = &parser->m_atts[i]; #ifdef XML_ATTR_INFO XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; #endif /* add the name and value to the attribute list */ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, currAtt->name + XmlNameLength(enc, currAtt->name)); if (! attId) return XML_ERROR_NO_MEMORY; #ifdef XML_ATTR_INFO currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); currAttInfo->nameEnd = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); currAttInfo->valueStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valuePtr); currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd); #endif /* Detect duplicate attributes by their QNames. This does not work when namespace processing is turned on and different prefixes for the same namespace are used. For this case we have a check further down. */ if ((attId->name)[-1]) { if (enc == parser->m_encoding) parser->m_eventPtr = parser->m_atts[i].name; return XML_ERROR_DUPLICATE_ATTRIBUTE; } (attId->name)[-1] = 1; appAtts[attIndex++] = attId->name; if (! parser->m_atts[i].normalized) { enum XML_Error result; XML_Bool isCdata = XML_TRUE; /* figure out whether declared as other than CDATA */ if (attId->maybeTokenized) { int j; for (j = 0; j < nDefaultAtts; j++) { if (attId == elementType->defaultAtts[j].id) { isCdata = elementType->defaultAtts[j].isCdata; break; } } } /* normalize the attribute value */ result = storeAttributeValue( parser, enc, isCdata, parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd, &parser->m_tempPool, account); if (result) return result; appAtts[attIndex] = poolStart(&parser->m_tempPool); poolFinish(&parser->m_tempPool); } else { /* the value did not need normalizing */ appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd); if (appAtts[attIndex] == 0) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); } /* handle prefixed attribute names */ if (attId->prefix) { if (attId->xmlns) { /* deal with namespace declarations here */ enum XML_Error result = addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr); if (result) return result; --attIndex; } else { /* deal with other prefixed names later */ attIndex++; nPrefixes++; (attId->name)[-1] = 2; } } else attIndex++; } /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ parser->m_nSpecifiedAtts = attIndex; if (elementType->idAtt && (elementType->idAtt->name)[-1]) { for (i = 0; i < attIndex; i += 2) if (appAtts[i] == elementType->idAtt->name) { parser->m_idAttIndex = i; break; } } else parser->m_idAttIndex = -1; /* do attribute defaulting */ for (i = 0; i < nDefaultAtts; i++) { const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; if (! (da->id->name)[-1] && da->value) { if (da->id->prefix) { if (da->id->xmlns) { enum XML_Error result = addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr); if (result) return result; } else { (da->id->name)[-1] = 2; nPrefixes++; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } else { (da->id->name)[-1] = 1; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } } appAtts[attIndex] = 0; /* expand prefixed attribute names, check for duplicates, and clear flags that say whether attributes were specified */ i = 0; if (nPrefixes) { unsigned int j; /* hash table index */ unsigned long version = parser->m_nsAttsVersion; /* Detect and prevent invalid shift */ if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { return XML_ERROR_NO_MEMORY; } unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ if ((nPrefixes << 1) >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ NS_ATT *temp; /* hash table size must also be a power of 2 and >= 8 */ while (nPrefixes >> parser->m_nsAttsPower++) ; if (parser->m_nsAttsPower < 3) parser->m_nsAttsPower = 3; /* Detect and prevent invalid shift */ if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } nsAttsSize = 1u << parser->m_nsAttsPower; /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if (nsAttsSize > SIZE_MAX / sizeof(NS_ATT)) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } #endif temp = REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); if (! temp) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; } parser->m_nsAtts = temp; version = 0; /* force re-initialization of m_nsAtts hash table */ } /* using a version flag saves us from initializing m_nsAtts every time */ if (! version) { /* initialize version flags when version wraps around */ version = INIT_ATTS_VERSION; for (j = nsAttsSize; j != 0;) parser->m_nsAtts[--j].version = version; } parser->m_nsAttsVersion = --version; /* expand prefixed names and check for duplicates */ for (; i < attIndex; i += 2) { const XML_Char *s = appAtts[i]; if (s[-1] == 2) { /* prefixed */ ATTRIBUTE_ID *id; const BINDING *b; unsigned long uriHash; struct siphash sip_state; struct sipkey sip_key; copy_salt_to_sipkey(parser, &sip_key); sip24_init(&sip_state, &sip_key); ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); if (! id || ! id->prefix) { /* This code is walking through the appAtts array, dealing * with (in this case) a prefixed attribute name. To be in * the array, the attribute must have already been bound, so * has to have passed through the hash table lookup once * already. That implies that an entry for it already * exists, so the lookup above will return a pointer to * already allocated memory. There is no opportunaity for * the allocator to fail, so the condition above cannot be * fulfilled. * * Since it is difficult to be certain that the above * analysis is complete, we retain the test and merely * remove the code from coverage tests. */ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } b = id->prefix->binding; if (! b) return XML_ERROR_UNBOUND_PREFIX; for (j = 0; j < (unsigned int)b->uriLen; j++) { const XML_Char c = b->uri[j]; if (! poolAppendChar(&parser->m_tempPool, c)) return XML_ERROR_NO_MEMORY; } sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); while (*s++ != XML_T(ASCII_COLON)) ; sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); do { /* copies null terminator */ if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); uriHash = (unsigned long)sip24_final(&sip_state); { /* Check hash table for duplicate of expanded name (uriName). Derived from code in lookup(parser, HASH_TABLE *table, ...). */ unsigned char step = 0; unsigned long mask = nsAttsSize - 1; j = uriHash & mask; /* index into hash table */ while (parser->m_nsAtts[j].version == version) { /* for speed we compare stored hash values first */ if (uriHash == parser->m_nsAtts[j].hash) { const XML_Char *s1 = poolStart(&parser->m_tempPool); const XML_Char *s2 = parser->m_nsAtts[j].uriName; /* s1 is null terminated, but not s2 */ for (; *s1 == *s2 && *s1 != 0; s1++, s2++) ; if (*s1 == 0) return XML_ERROR_DUPLICATE_ATTRIBUTE; } if (! step) step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); j < step ? (j += nsAttsSize - step) : (j -= step); } } if (parser->m_ns_triplets) { /* append namespace separator and prefix */ parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; s = b->prefix->name; do { if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_ERROR_NO_MEMORY; } while (*s++); } /* store expanded name in attribute list */ s = poolStart(&parser->m_tempPool); poolFinish(&parser->m_tempPool); appAtts[i] = s; /* fill empty slot with new version, uriName and hash value */ parser->m_nsAtts[j].version = version; parser->m_nsAtts[j].hash = uriHash; parser->m_nsAtts[j].uriName = s; if (! --nPrefixes) { i += 2; break; } } else /* not prefixed */ ((XML_Char *)s)[-1] = 0; /* clear flag */ } } /* clear flags for the remaining attributes */ for (; i < attIndex; i += 2) ((XML_Char *)(appAtts[i]))[-1] = 0; for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; if (! parser->m_ns) return XML_ERROR_NONE; /* expand the element type name */ if (elementType->prefix) { binding = elementType->prefix->binding; if (! binding) return XML_ERROR_UNBOUND_PREFIX; localPart = tagNamePtr->str; while (*localPart++ != XML_T(ASCII_COLON)) ; } else if (dtd->defaultPrefix.binding) { binding = dtd->defaultPrefix.binding; localPart = tagNamePtr->str; } else return XML_ERROR_NONE; prefixLen = 0; if (parser->m_ns_triplets && binding->prefix->name) { while (binding->prefix->name[prefixLen++]) ; /* prefixLen includes null terminator */ } tagNamePtr->localPart = localPart; tagNamePtr->uriLen = binding->uriLen; tagNamePtr->prefix = binding->prefix->name; tagNamePtr->prefixLen = prefixLen; for (i = 0; localPart[i++];) ; /* i includes null terminator */ /* Detect and prevent integer overflow */ if (binding->uriLen > INT_MAX - prefixLen || i > INT_MAX - (binding->uriLen + prefixLen)) { return XML_ERROR_NO_MEMORY; } n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; /* Detect and prevent integer overflow */ if (n > INT_MAX - EXPAND_SPARE) { return XML_ERROR_NO_MEMORY; } /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((unsigned)(n + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif uri = MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); if (! uri) return XML_ERROR_NO_MEMORY; binding->uriAlloc = n + EXPAND_SPARE; memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); for (p = parser->m_tagStack; p; p = p->parent) if (p->name.str == binding->uri) p->name.str = uri; FREE(parser, binding->uri); binding->uri = uri; } /* if m_namespaceSeparator != '\0' then uri includes it already */ uri = binding->uri + binding->uriLen; memcpy(uri, localPart, i * sizeof(XML_Char)); /* we always have a namespace separator between localPart and prefix */ if (prefixLen) { uri += i - 1; *uri = parser->m_namespaceSeparator; /* replace null terminator */ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); } tagNamePtr->str = binding->uri; return XML_ERROR_NONE; } static XML_Bool is_rfc3986_uri_char(XML_Char candidate) { // For the RFC 3986 ANBF grammar see // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A switch (candidate) { // From rule "ALPHA" (uppercase half) case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': // From rule "ALPHA" (lowercase half) case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': // From rule "DIGIT" case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // From rule "pct-encoded" case '%': // From rule "unreserved" case '-': case '.': case '_': case '~': // From rule "gen-delims" case ':': case '/': case '?': case '#': case '[': case ']': case '@': // From rule "sub-delims" case '!': case '$': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case ';': case '=': return XML_TRUE; default: return XML_FALSE; } } /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; static const int xmlnsLen = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; XML_Bool mustBeXML = XML_FALSE; XML_Bool isXML = XML_TRUE; XML_Bool isXMLNS = XML_TRUE; BINDING *b; int len; /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ if (*uri == XML_T('\0') && prefix->name) return XML_ERROR_UNDECLARING_PREFIX; if (prefix->name && prefix->name[0] == XML_T(ASCII_x) && prefix->name[1] == XML_T(ASCII_m) && prefix->name[2] == XML_T(ASCII_l)) { /* Not allowed to bind xmlns */ if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) && prefix->name[5] == XML_T('\0')) return XML_ERROR_RESERVED_PREFIX_XMLNS; if (prefix->name[3] == XML_T('\0')) mustBeXML = XML_TRUE; } for (len = 0; uri[len]; len++) { if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) isXML = XML_FALSE; if (! mustBeXML && isXMLNS && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; // NOTE: While Expat does not validate namespace URIs against RFC 3986 // today (and is not REQUIRED to do so with regard to the XML 1.0 // namespaces specification) we have to at least make sure, that // the application on top of Expat (that is likely splitting expanded // element names ("qualified names") of form // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces // in its element handler code) cannot be confused by an attacker // putting additional namespace separator characters into namespace // declarations. That would be ambiguous and not to be expected. // // While the HTML API docs of function XML_ParserCreateNS have been // advising against use of a namespace separator character that can // appear in a URI for >20 years now, some widespread applications // are using URI characters (':' (colon) in particular) for a // namespace separator, in practice. To keep these applications // functional, we only reject namespaces URIs containing the // application-chosen namespace separator if the chosen separator // is a non-URI character with regard to RFC 3986. if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } isXML = isXML && len == xmlLen; isXMLNS = isXMLNS && len == xmlnsLen; if (mustBeXML != isXML) return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML : XML_ERROR_RESERVED_NAMESPACE_URI; if (isXMLNS) return XML_ERROR_RESERVED_NAMESPACE_URI; if (parser->m_namespaceSeparator) len++; if (parser->m_freeBindingList) { b = parser->m_freeBindingList; if (len > b->uriAlloc) { /* Detect and prevent integer overflow */ if (len > INT_MAX - EXPAND_SPARE) { return XML_ERROR_NO_MEMORY; } /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif XML_Char *temp = REALLOC(parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) return XML_ERROR_NO_MEMORY; b->uri = temp; b->uriAlloc = len + EXPAND_SPARE; } parser->m_freeBindingList = b->nextTagBinding; } else { b = MALLOC(parser, sizeof(BINDING)); if (! b) return XML_ERROR_NO_MEMORY; /* Detect and prevent integer overflow */ if (len > INT_MAX - EXPAND_SPARE) { return XML_ERROR_NO_MEMORY; } /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif b->uri = MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (! b->uri) { FREE(parser, b); return XML_ERROR_NO_MEMORY; } b->uriAlloc = len + EXPAND_SPARE; } b->uriLen = len; memcpy(b->uri, uri, len * sizeof(XML_Char)); if (parser->m_namespaceSeparator) b->uri[len - 1] = parser->m_namespaceSeparator; b->prefix = prefix; b->attId = attId; b->prevPrefixBinding = prefix->binding; /* NULL binding when default namespace undeclared */ if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) prefix->binding = NULL; else prefix->binding = b; b->nextTagBinding = *bindingsPtr; *bindingsPtr = b; /* if attId == NULL then we are not starting a namespace scope */ if (attId && parser->m_startNamespaceDeclHandler) parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, prefix->binding ? uri : 0); return XML_ERROR_NONE; } /* The idea here is to avoid using stack for each CDATA section when the whole file is parsed with one call. */ static enum XML_Error PTRCALL cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doCdataSection( parser, parser->m_encoding, &start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); if (result != XML_ERROR_NONE) return result; if (start) { if (parser->m_parentParser) { /* we are parsing an external entity */ parser->m_processor = externalEntityContentProcessor; return externalEntityContentProcessor(parser, start, end, endPtr); } else { parser->m_processor = contentProcessor; return contentProcessor(parser, start, end, endPtr); } } return result; } /* startPtr gets set to non-null if the section is closed, and to null if the section is not yet closed. */ static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore, enum XML_Account account) { const char *s = *startPtr; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } *eventPP = s; *startPtr = NULL; for (;;) { const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ int tok = XmlCdataSectionTok(enc, s, end, &next); #if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #else UNUSED_P(account); #endif *eventEndPP = next; switch (tok) { case XML_TOK_CDATA_SECT_CLOSE: if (parser->m_endCdataSectionHandler) parser->m_endCdataSectionHandler(parser->m_handlerArg); /* BEGIN disabled code */ /* see comment under XML_TOK_CDATA_SECT_OPEN */ else if ((0) && parser->m_characterDataHandler) parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0); /* END disabled code */ else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; case XML_TOK_DATA_NEWLINE: if (parser->m_characterDataHandler) { XML_Char c = 0xA; parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_DATA_CHARS: { XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; if (charDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; const enum XML_Convert_Result convert_res = XmlConvert( enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = next; charDataHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } } else charDataHandler(parser->m_handlerArg, (const XML_Char *)s, (int)((const XML_Char *)next - (const XML_Char *)s)); } else if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_CDATA_SECTION; default: /* Every token returned by XmlCdataSectionTok() has its own * explicit case, so this default case will never be executed. * We retain it as a safety net and exclude it from the coverage * statistics. * * LCOV_EXCL_START */ *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *eventPP = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: *eventPP = next; return XML_ERROR_ABORTED; case XML_PARSING: if (parser->m_reenter) { return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE } /* Fall through */ default:; *eventPP = s = next; } } /* not reached */ } #ifdef XML_DTD /* The idea here is to avoid using stack for each IGNORE section when the whole file is parsed with one call. */ static enum XML_Error PTRCALL ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer); if (result != XML_ERROR_NONE) return result; if (start) { parser->m_processor = prologProcessor; return prologProcessor(parser, start, end, endPtr); } return result; } /* startPtr gets set to non-null is the section is closed, and to null if the section is not yet closed. */ static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore) { const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ int tok; const char *s = *startPtr; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; *eventPP = s; eventEndPP = &parser->m_eventEndPtr; } else { /* It's not entirely clear, but it seems the following two lines * of code cannot be executed. The only occasions on which 'enc' * is not 'encoding' are when this function is called * from the internal entity processing, and IGNORE sections are an * error in internal entities. * * Since it really isn't clear that this is true, we keep the code * and just remove it from our coverage tests. * * LCOV_EXCL_START */ eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } *eventPP = s; *startPtr = NULL; tok = XmlIgnoreSectionTok(enc, s, end, &next); # if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } # endif *eventEndPP = next; switch (tok) { case XML_TOK_IGNORE_SECT: if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; *nextPtr = next; if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; else return XML_ERROR_NONE; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: if (haveMore) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ default: /* All of the tokens that XmlIgnoreSectionTok() returns have * explicit cases to handle them, so this default case is never * executed. We keep it as a safety net anyway, and remove it * from our test coverage statistics. * * LCOV_EXCL_START */ *eventPP = next; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } /* not reached */ } #endif /* XML_DTD */ static enum XML_Error initializeEncoding(XML_Parser parser) { const char *s; #ifdef XML_UNICODE char encodingBuf[128]; /* See comments about `protocolEncodingName` in parserInit() */ if (! parser->m_protocolEncodingName) s = NULL; else { int i; for (i = 0; parser->m_protocolEncodingName[i]; i++) { if (i == sizeof(encodingBuf) - 1 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { encodingBuf[0] = '\0'; break; } encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; } encodingBuf[i] = '\0'; s = encodingBuf; } #else s = parser->m_protocolEncodingName; #endif if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( &parser->m_initEncoding, &parser->m_encoding, s)) return XML_ERROR_NONE; return handleUnknownEncoding(parser, parser->m_protocolEncodingName); } static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const char *next) { const char *encodingName = NULL; const XML_Char *storedEncName = NULL; const ENCODING *newEncoding = NULL; const char *version = NULL; const char *versionend = NULL; const XML_Char *storedversion = NULL; int standalone = -1; #if XML_GE == 1 if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #endif if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, &version, &versionend, &encodingName, &newEncoding, &standalone)) { if (isGeneralTextEntity) return XML_ERROR_TEXT_DECL; else return XML_ERROR_XML_DECL; } if (! isGeneralTextEntity && standalone == 1) { parser->m_dtd->standalone = XML_TRUE; #ifdef XML_DTD if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; #endif /* XML_DTD */ } if (parser->m_xmlDeclHandler) { if (encodingName != NULL) { storedEncName = poolStoreString( &parser->m_temp2Pool, parser->m_encoding, encodingName, encodingName + XmlNameLength(parser->m_encoding, encodingName)); if (! storedEncName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_temp2Pool); } if (version) { storedversion = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, versionend - parser->m_encoding->minBytesPerChar); if (! storedversion) return XML_ERROR_NO_MEMORY; } parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone); } else if (parser->m_defaultHandler) reportDefault(parser, parser->m_encoding, s, next); if (parser->m_protocolEncodingName == NULL) { if (newEncoding) { /* Check that the specified encoding does not conflict with what * the parser has already deduced. Do we have the same number * of bytes in the smallest representation of a character? If * this is UTF-16, is it the same endianness? */ if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar || (newEncoding->minBytesPerChar == 2 && newEncoding != parser->m_encoding)) { parser->m_eventPtr = encodingName; return XML_ERROR_INCORRECT_ENCODING; } parser->m_encoding = newEncoding; } else if (encodingName) { enum XML_Error result; if (! storedEncName) { storedEncName = poolStoreString( &parser->m_temp2Pool, parser->m_encoding, encodingName, encodingName + XmlNameLength(parser->m_encoding, encodingName)); if (! storedEncName) return XML_ERROR_NO_MEMORY; } result = handleUnknownEncoding(parser, storedEncName); poolClear(&parser->m_temp2Pool); if (result == XML_ERROR_UNKNOWN_ENCODING) parser->m_eventPtr = encodingName; return result; } } if (storedEncName || storedversion) poolClear(&parser->m_temp2Pool); return XML_ERROR_NONE; } static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser->m_unknownEncodingHandler) { XML_Encoding info; int i; for (i = 0; i < 256; i++) info.map[i] = -1; info.convert = NULL; info.data = NULL; info.release = NULL; if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName, &info)) { ENCODING *enc; parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); if (! parser->m_unknownEncodingMem) { if (info.release) info.release(info.data); return XML_ERROR_NO_MEMORY; } enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( parser->m_unknownEncodingMem, info.map, info.convert, info.data); if (enc) { parser->m_unknownEncodingData = info.data; parser->m_unknownEncodingRelease = info.release; parser->m_encoding = enc; return XML_ERROR_NONE; } } if (info.release != NULL) info.release(info.data); } return XML_ERROR_UNKNOWN_ENCODING; } static enum XML_Error PTRCALL prologInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; parser->m_processor = prologProcessor; return prologProcessor(parser, s, end, nextPtr); } #ifdef XML_DTD static enum XML_Error PTRCALL externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; /* we know now that XML_Parse(Buffer) has been called, so we consider the external parameter entity read */ parser->m_dtd->paramEntityRead = XML_TRUE; if (parser->m_prologState.inEntityValue) { parser->m_processor = entityValueInitProcessor; return entityValueInitProcessor(parser, s, end, nextPtr); } else { parser->m_processor = externalParEntProcessor; return externalParEntProcessor(parser, s, end, nextPtr); } } static enum XML_Error PTRCALL entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { int tok; const char *start = s; const char *next = start; parser->m_eventPtr = start; for (;;) { tok = XmlPrologTok(parser->m_encoding, start, end, &next); /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in: - storeEntityValue - processXmlDecl */ parser->m_eventEndPtr = next; if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } /* found end of entity value - can store it now */ return storeEntityValue(parser, parser->m_encoding, s, end, XML_ACCOUNT_DIRECT, NULL); } else if (tok == XML_TOK_XML_DECL) { enum XML_Error result; result = processXmlDecl(parser, 0, start, next); if (result != XML_ERROR_NONE) return result; /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For * that to happen, a parameter entity parsing handler must have attempted * to suspend the parser, which fails and raises an error. The parser can * be aborted, but can't be suspended. */ if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; *nextPtr = next; /* stop scanning for text declaration - we found one */ parser->m_processor = entityValueProcessor; return entityValueProcessor(parser, next, end, nextPtr); } /* XmlPrologTok has now set the encoding based on the BOM it found, and we must move s and nextPtr forward to consume the BOM. If we didn't, and got XML_TOK_NONE from the next XmlPrologTok call, we would leave the BOM in the buffer and return. On the next call to this function, our XmlPrologTok call would return XML_TOK_INVALID, since it is not valid to have multiple BOMs. */ else if (tok == XML_TOK_BOM) { # if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } # endif *nextPtr = next; s = next; } /* If we get this token, we have the start of what might be a normal tag, but not a declaration (i.e. it doesn't begin with "m_eventPtr = start; } } static enum XML_Error PTRCALL externalParEntProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { const char *next = s; int tok; tok = XmlPrologTok(parser->m_encoding, s, end, &next); if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } } /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. However, when parsing an external subset, doProlog will not accept a BOM as valid, and report a syntax error, so we have to skip the BOM, and account for the BOM bytes. */ else if (tok == XML_TOK_BOM) { if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } s = next; tok = XmlPrologTok(parser->m_encoding, s, end, &next); } parser->m_processor = prologProcessor; return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, XML_ACCOUNT_DIRECT); } static enum XML_Error PTRCALL entityValueProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { const char *start = s; const char *next = s; const ENCODING *enc = parser->m_encoding; int tok; for (;;) { tok = XmlPrologTok(enc, start, end, &next); /* Note: These bytes are accounted later in: - storeEntityValue */ if (tok <= 0) { if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_NONE: /* start == end */ default: break; } /* found end of entity value - can store it now */ return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT, NULL); } /* If we get this token, we have the start of what might be a normal tag, but not a declaration (i.e. it doesn't begin with "m_encoding, s, end, &next); return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, XML_ACCOUNT_DIRECT); } static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, int tok, const char *next, const char **nextPtr, XML_Bool haveMore, XML_Bool allowClosingDoctype, enum XML_Account account) { #ifdef XML_DTD static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; #endif /* XML_DTD */ static const XML_Char atypeCDATA[] = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; static const XML_Char atypeIDREF[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; static const XML_Char atypeIDREFS[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; static const XML_Char atypeENTITY[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; static const XML_Char atypeENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0'}; static const XML_Char atypeNMTOKEN[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; static const XML_Char atypeNMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0'}; static const XML_Char notationPrefix[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; #ifndef XML_DTD UNUSED_P(account); #endif /* save one level of indirection */ DTD *const dtd = parser->m_dtd; const char **eventPP; const char **eventEndPP; enum XML_Content_Quant quant; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); } for (;;) { int role; XML_Bool handleDefault = XML_TRUE; *eventPP = s; *eventEndPP = next; if (tok <= 0) { if (haveMore && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case -XML_TOK_PROLOG_S: tok = -tok; break; case XML_TOK_NONE: #ifdef XML_DTD /* for internal PE NOT referenced between declarations */ if (enc != parser->m_encoding && ! parser->m_openInternalEntities->betweenDecl) { *nextPtr = s; return XML_ERROR_NONE; } /* WFC: PE Between Declarations - must check that PE contains complete markup, not only for external PEs, but also for internal PEs if the reference occurs between declarations. */ if (parser->m_isParamEntity || enc != parser->m_encoding) { if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) == XML_ROLE_ERROR) return XML_ERROR_INCOMPLETE_PE; *nextPtr = s; return XML_ERROR_NONE; } #endif /* XML_DTD */ return XML_ERROR_NO_ELEMENTS; default: tok = -tok; next = end; break; } } role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); #if XML_GE == 1 switch (role) { case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl # ifdef XML_DTD case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl # endif break; default: if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } } #endif switch (role) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); if (result != XML_ERROR_NONE) return result; enc = parser->m_encoding; handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_NAME: if (parser->m_startDoctypeDeclHandler) { parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next); if (! parser->m_doctypeName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); parser->m_doctypePubid = NULL; handleDefault = XML_FALSE; } parser->m_doctypeSysid = NULL; /* always initialize to NULL */ break; case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: if (parser->m_startDoctypeDeclHandler) { parser->m_startDoctypeDeclHandler( parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, parser->m_doctypePubid, 1); parser->m_doctypeName = NULL; poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } break; #ifdef XML_DTD case XML_ROLE_TEXT_DECL: { enum XML_Error result = processXmlDecl(parser, 1, s, next); if (result != XML_ERROR_NONE) return result; enc = parser->m_encoding; handleDefault = XML_FALSE; } break; #endif /* XML_DTD */ case XML_ROLE_DOCTYPE_PUBLIC_ID: #ifdef XML_DTD parser->m_useForeignDTD = XML_FALSE; parser->m_declEntity = (ENTITY *)lookup( parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { XML_Char *pubId; if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; pubId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! pubId) return XML_ERROR_NO_MEMORY; normalizePublicId(pubId); poolFinish(&parser->m_tempPool); parser->m_doctypePubid = pubId; handleDefault = XML_FALSE; goto alreadyChecked; } /* fall through */ case XML_ROLE_ENTITY_PUBLIC_ID: if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; alreadyChecked: if (dtd->keepProcessing && parser->m_declEntity) { XML_Char *tem = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declEntity->publicId = tem; poolFinish(&dtd->pool); /* Don't suppress the default handler if we fell through from * the XML_ROLE_DOCTYPE_PUBLIC_ID case. */ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_DOCTYPE_CLOSE: if (allowClosingDoctype != XML_TRUE) { /* Must not close doctype from within expanded parameter entities */ return XML_ERROR_INVALID_TOKEN; } if (parser->m_doctypeName) { parser->m_startDoctypeDeclHandler( parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, parser->m_doctypePubid, 0); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } /* parser->m_doctypeSysid will be non-NULL in the case of a previous XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler was not set, indicating an external subset */ #ifdef XML_DTD if (parser->m_doctypeSysid || parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! entity) { /* The external subset name "#" will have already been * inserted into the hash table at the start of the * external entity parsing, so no allocation will happen * and lookup() cannot fail. */ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ } if (parser->m_useForeignDTD) entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ else if (! parser->m_doctypeSysid) dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } parser->m_useForeignDTD = XML_FALSE; } #endif /* XML_DTD */ if (parser->m_endDoctypeDeclHandler) { parser->m_endDoctypeDeclHandler(parser->m_handlerArg); handleDefault = XML_FALSE; } break; case XML_ROLE_INSTANCE_START: #ifdef XML_DTD /* if there is no DOCTYPE declaration then now is the last chance to read the foreign DTD */ if (parser->m_useForeignDTD) { XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! entity) return XML_ERROR_NO_MEMORY; entity->base = parser->m_curBase; dtd->paramEntityRead = XML_FALSE; if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; if (dtd->paramEntityRead) { if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; } /* if we didn't read the foreign DTD then this means that there is no external subset and we must reset dtd->hasParamEntityRefs */ else dtd->hasParamEntityRefs = hadParamEntityRefs; /* end of DTD - no need to update dtd->keepProcessing */ } } #endif /* XML_DTD */ parser->m_processor = contentProcessor; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: parser->m_declElementType = getElementType(parser, enc, s, next); if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_NAME: parser->m_declAttributeId = getAttributeId(parser, enc, s, next); if (! parser->m_declAttributeId) return XML_ERROR_NO_MEMORY; parser->m_declAttributeIsCdata = XML_FALSE; parser->m_declAttributeType = NULL; parser->m_declAttributeIsId = XML_FALSE; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_CDATA: parser->m_declAttributeIsCdata = XML_TRUE; parser->m_declAttributeType = atypeCDATA; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ID: parser->m_declAttributeIsId = XML_TRUE; parser->m_declAttributeType = atypeID; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREF: parser->m_declAttributeType = atypeIDREF; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: parser->m_declAttributeType = atypeIDREFS; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: parser->m_declAttributeType = atypeENTITY; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: parser->m_declAttributeType = atypeENTITIES; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: parser->m_declAttributeType = atypeNMTOKEN; goto checkAttListDeclHandler; case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: parser->m_declAttributeType = atypeNMTOKENS; checkAttListDeclHandler: if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTRIBUTE_ENUM_VALUE: case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: if (dtd->keepProcessing && parser->m_attlistDeclHandler) { const XML_Char *prefix; if (parser->m_declAttributeType) { prefix = enumValueSep; } else { prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix : enumValueStart); } if (! poolAppendString(&parser->m_tempPool, prefix)) return XML_ERROR_NO_MEMORY; if (! poolAppend(&parser->m_tempPool, enc, s, next)) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; handleDefault = XML_FALSE; } break; case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { if (! defineAttribute(parser->m_declElementType, parser->m_declAttributeId, parser->m_declAttributeIsCdata, parser->m_declAttributeIsId, 0, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; parser->m_attlistDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, parser->m_declAttributeId->name, parser->m_declAttributeType, 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); handleDefault = XML_FALSE; } } poolClear(&parser->m_tempPool); break; case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: case XML_ROLE_FIXED_ATTRIBUTE_VALUE: if (dtd->keepProcessing) { const XML_Char *attVal; enum XML_Error result = storeAttributeValue( parser, enc, parser->m_declAttributeIsCdata, s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool, XML_ACCOUNT_NONE); if (result) return result; attVal = poolStart(&dtd->pool); poolFinish(&dtd->pool); /* ID attributes aren't allowed to have a default */ if (! defineAttribute( parser->m_declElementType, parser->m_declAttributeId, parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) return XML_ERROR_NO_MEMORY; if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) || (*parser->m_declAttributeType == XML_T(ASCII_N) && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { /* Enumerated or Notation type */ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; parser->m_declAttributeType = parser->m_tempPool.start; poolFinish(&parser->m_tempPool); } *eventEndPP = s; parser->m_attlistDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, parser->m_declAttributeId->name, parser->m_declAttributeType, attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } break; case XML_ROLE_ENTITY_VALUE: if (dtd->keepProcessing) { #if XML_GE == 1 // This will store the given replacement text in // parser->m_declEntity->textPtr. enum XML_Error result = callStoreEntityValue( parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar, XML_ACCOUNT_NONE); if (parser->m_declEntity) { parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); poolFinish(&dtd->entityValuePool); if (parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->is_param, parser->m_declEntity->textPtr, parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); handleDefault = XML_FALSE; } } else poolDiscard(&dtd->entityValuePool); if (result != XML_ERROR_NONE) return result; #else // This will store "&entity123;" in parser->m_declEntity->textPtr // to end up as "&entity123;" in the handler. if (parser->m_declEntity != NULL) { const enum XML_Error result = storeSelfEntityValue(parser, parser->m_declEntity); if (result != XML_ERROR_NONE) return result; if (parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->is_param, parser->m_declEntity->textPtr, parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); handleDefault = XML_FALSE; } } #endif } break; case XML_ROLE_DOCTYPE_SYSTEM_ID: #ifdef XML_DTD parser->m_useForeignDTD = XML_FALSE; #endif /* XML_DTD */ dtd->hasParamEntityRefs = XML_TRUE; if (parser->m_startDoctypeDeclHandler) { parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (parser->m_doctypeSysid == NULL) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } #ifdef XML_DTD else /* use externalSubsetName to make parser->m_doctypeSysid non-NULL for the case where no parser->m_startDoctypeDeclHandler is set */ parser->m_doctypeSysid = externalSubsetName; #endif /* XML_DTD */ if (! dtd->standalone #ifdef XML_DTD && ! parser->m_paramEntityParsing #endif /* XML_DTD */ && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; #ifndef XML_DTD break; #else /* XML_DTD */ if (! parser->m_declEntity) { parser->m_declEntity = (ENTITY *)lookup( parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; parser->m_declEntity->publicId = NULL; } #endif /* XML_DTD */ /* fall through */ case XML_ROLE_ENTITY_SYSTEM_ID: if (dtd->keepProcessing && parser->m_declEntity) { parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! parser->m_declEntity->systemId) return XML_ERROR_NO_MEMORY; parser->m_declEntity->base = parser->m_curBase; poolFinish(&dtd->pool); /* Don't suppress the default handler if we fell through from * the XML_ROLE_DOCTYPE_SYSTEM_ID case. */ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_COMPLETE: #if XML_GE == 0 // This will store "&entity123;" in entity->textPtr // to end up as "&entity123;" in the handler. if (parser->m_declEntity != NULL) { const enum XML_Error result = storeSelfEntityValue(parser, parser->m_declEntity); if (result != XML_ERROR_NONE) return result; } #endif if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); handleDefault = XML_FALSE; } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (dtd->keepProcessing && parser->m_declEntity) { parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); if (! parser->m_declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd->pool); if (parser->m_unparsedEntityDeclHandler) { *eventEndPP = s; parser->m_unparsedEntityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; } else if (parser->m_entityDeclHandler) { *eventEndPP = s; parser->m_entityDeclHandler( parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, parser->m_declEntity->base, parser->m_declEntity->systemId, parser->m_declEntity->publicId, parser->m_declEntity->notation); handleDefault = XML_FALSE; } } break; case XML_ROLE_GENERAL_ENTITY_NAME: { if (XmlPredefinedEntityName(enc, s, next)) { parser->m_declEntity = NULL; break; } if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (! name) return XML_ERROR_NO_MEMORY; parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); parser->m_declEntity->publicId = NULL; parser->m_declEntity->is_param = XML_FALSE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ parser->m_declEntity->is_internal = ! (parser->m_parentParser || parser->m_openInternalEntities); if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } } break; case XML_ROLE_PARAM_ENTITY_NAME: #ifdef XML_DTD if (dtd->keepProcessing) { const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); if (! name) return XML_ERROR_NO_MEMORY; parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, sizeof(ENTITY)); if (! parser->m_declEntity) return XML_ERROR_NO_MEMORY; if (parser->m_declEntity->name != name) { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } else { poolFinish(&dtd->pool); parser->m_declEntity->publicId = NULL; parser->m_declEntity->is_param = XML_TRUE; /* if we have a parent parser or are reading an internal parameter entity, then the entity declaration is not considered "internal" */ parser->m_declEntity->is_internal = ! (parser->m_parentParser || parser->m_openInternalEntities); if (parser->m_entityDeclHandler) handleDefault = XML_FALSE; } } else { poolDiscard(&dtd->pool); parser->m_declEntity = NULL; } #else /* not XML_DTD */ parser->m_declEntity = NULL; #endif /* XML_DTD */ break; case XML_ROLE_NOTATION_NAME: parser->m_declNotationPublicId = NULL; parser->m_declNotationName = NULL; if (parser->m_notationDeclHandler) { parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next); if (! parser->m_declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_PUBLIC_ID: if (! XmlIsPublicId(enc, s, next, eventPP)) return XML_ERROR_PUBLICID; if (parser ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); parser->m_declNotationPublicId = tem; poolFinish(&parser->m_tempPool); handleDefault = XML_FALSE; } break; case XML_ROLE_NOTATION_SYSTEM_ID: if (parser->m_declNotationName && parser->m_notationDeclHandler) { const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! systemId) return XML_ERROR_NO_MEMORY; *eventEndPP = s; parser->m_notationDeclHandler( parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, systemId, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { *eventEndPP = s; parser->m_notationDeclHandler( parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 0, parser->m_declNotationPublicId); handleDefault = XML_FALSE; } poolClear(&parser->m_tempPool); break; case XML_ROLE_ERROR: switch (tok) { case XML_TOK_PARAM_ENTITY_REF: /* PE references in internal subset are not allowed within declarations. */ return XML_ERROR_PARAM_ENTITY_REF; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; default: return XML_ERROR_SYNTAX; } #ifdef XML_DTD case XML_ROLE_IGNORE_SECT: { enum XML_Error result; if (parser->m_defaultHandler) reportDefault(parser, enc, s, next); handleDefault = XML_FALSE; result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); if (result != XML_ERROR_NONE) return result; else if (! next) { parser->m_processor = ignoreSectionProcessor; return result; } } break; #endif /* XML_DTD */ case XML_ROLE_GROUP_OPEN: if (parser->m_prologState.level >= parser->m_groupSize) { if (parser->m_groupSize) { { /* Detect and prevent integer overflow */ if (parser->m_groupSize > (unsigned int)(-1) / 2u) { return XML_ERROR_NO_MEMORY; } char *const new_connector = REALLOC( parser, parser->m_groupConnector, parser->m_groupSize *= 2); if (new_connector == NULL) { parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } parser->m_groupConnector = new_connector; } if (dtd->scaffIndex) { /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if (parser->m_groupSize > SIZE_MAX / sizeof(int)) { parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } #endif int *const new_scaff_index = REALLOC( parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); if (new_scaff_index == NULL) { parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } dtd->scaffIndex = new_scaff_index; } } else { parser->m_groupConnector = MALLOC(parser, parser->m_groupSize = 32); if (! parser->m_groupConnector) { parser->m_groupSize = 0; return XML_ERROR_NO_MEMORY; } } } parser->m_groupConnector[parser->m_prologState.level] = 0; if (dtd->in_eldecl) { int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; assert(dtd->scaffIndex != NULL); dtd->scaffIndex[dtd->scaffLevel] = myindex; dtd->scaffLevel++; dtd->scaffold[myindex].type = XML_CTYPE_SEQ; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_GROUP_SEQUENCE: if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) return XML_ERROR_SYNTAX; parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; if (dtd->in_eldecl && parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_GROUP_CHOICE: if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) return XML_ERROR_SYNTAX; if (dtd->in_eldecl && ! parser->m_groupConnector[parser->m_prologState.level] && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type != XML_CTYPE_MIXED)) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_CHOICE; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; break; case XML_ROLE_PARAM_ENTITY_REF: #ifdef XML_DTD case XML_ROLE_INNER_PARAM_ENTITY_REF: dtd->hasParamEntityRefs = XML_TRUE; if (! parser->m_paramEntityParsing) dtd->keepProcessing = dtd->standalone; else { const XML_Char *name; ENTITY *entity; name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&dtd->pool); /* first, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal, otherwise call the skipped entity handler */ if (parser->m_prologState.documentEntity && (dtd->standalone ? ! parser->m_openInternalEntities : ! dtd->hasParamEntityRefs)) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) { /* It's hard to exhaustively search the code to be sure, * but there doesn't seem to be a way of executing the * following line. There are two cases: * * If 'standalone' is false, the DTD must have no * parameter entities or we wouldn't have passed the outer * 'if' statement. That means the only entity in the hash * table is the external subset name "#" which cannot be * given as a parameter entity name in XML syntax, so the * lookup must have returned NULL and we don't even reach * the test for an internal entity. * * If 'standalone' is true, it does not seem to be * possible to create entities taking this code path that * are not internal entities, so fail the test above. * * Because this analysis is very uncertain, the code is * being left in place and merely removed from the * coverage test statistics. */ return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ } } else if (! entity) { dtd->keepProcessing = dtd->standalone; /* cannot report skipped entities in declarations */ if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) { parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); handleDefault = XML_FALSE; } break; } if (entity->open) return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->textPtr) { enum XML_Error result; XML_Bool betweenDecl = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL); if (result != XML_ERROR_NONE) return result; handleDefault = XML_FALSE; break; } if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; entityTrackingOnOpen(parser, entity, __LINE__); if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) { entityTrackingOnClose(parser, entity, __LINE__); entity->open = XML_FALSE; return XML_ERROR_EXTERNAL_ENTITY_HANDLING; } entityTrackingOnClose(parser, entity, __LINE__); entity->open = XML_FALSE; handleDefault = XML_FALSE; if (! dtd->paramEntityRead) { dtd->keepProcessing = dtd->standalone; break; } } else { dtd->keepProcessing = dtd->standalone; break; } } #endif /* XML_DTD */ if (! dtd->standalone && parser->m_notStandaloneHandler && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) return XML_ERROR_NOT_STANDALONE; break; /* Element declaration stuff */ case XML_ROLE_ELEMENT_NAME: if (parser->m_elementDeclHandler) { parser->m_declElementType = getElementType(parser, enc, s, next); if (! parser->m_declElementType) return XML_ERROR_NO_MEMORY; dtd->scaffLevel = 0; dtd->scaffCount = 0; dtd->in_eldecl = XML_TRUE; handleDefault = XML_FALSE; } break; case XML_ROLE_CONTENT_ANY: case XML_ROLE_CONTENT_EMPTY: if (dtd->in_eldecl) { if (parser->m_elementDeclHandler) { // NOTE: We are avoiding MALLOC(..) here to so that // applications that are not using XML_FreeContentModel but // plain free(..) or .free_fcn() to free the content model's // memory are safe. XML_Content *content = parser->m_mem.malloc_fcn(sizeof(XML_Content)); if (! content) return XML_ERROR_NO_MEMORY; content->quant = XML_CQUANT_NONE; content->name = NULL; content->numchildren = 0; content->children = NULL; content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY : XML_CTYPE_EMPTY); *eventEndPP = s; parser->m_elementDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, content); handleDefault = XML_FALSE; } dtd->in_eldecl = XML_FALSE; } break; case XML_ROLE_CONTENT_PCDATA: if (dtd->in_eldecl) { dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type = XML_CTYPE_MIXED; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_CONTENT_ELEMENT: quant = XML_CQUANT_NONE; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_OPT: quant = XML_CQUANT_OPT; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_REP: quant = XML_CQUANT_REP; goto elementContent; case XML_ROLE_CONTENT_ELEMENT_PLUS: quant = XML_CQUANT_PLUS; elementContent: if (dtd->in_eldecl) { ELEMENT_TYPE *el; const XML_Char *name; size_t nameLen; const char *nxt = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); int myindex = nextScaffoldPart(parser); if (myindex < 0) return XML_ERROR_NO_MEMORY; dtd->scaffold[myindex].type = XML_CTYPE_NAME; dtd->scaffold[myindex].quant = quant; el = getElementType(parser, enc, s, nxt); if (! el) return XML_ERROR_NO_MEMORY; name = el->name; dtd->scaffold[myindex].name = name; nameLen = 0; while (name[nameLen++]) ; /* Detect and prevent integer overflow */ if (nameLen > UINT_MAX - dtd->contentStringLen) { return XML_ERROR_NO_MEMORY; } dtd->contentStringLen += (unsigned)nameLen; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } break; case XML_ROLE_GROUP_CLOSE: quant = XML_CQUANT_NONE; goto closeGroup; case XML_ROLE_GROUP_CLOSE_OPT: quant = XML_CQUANT_OPT; goto closeGroup; case XML_ROLE_GROUP_CLOSE_REP: quant = XML_CQUANT_REP; goto closeGroup; case XML_ROLE_GROUP_CLOSE_PLUS: quant = XML_CQUANT_PLUS; closeGroup: if (dtd->in_eldecl) { if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; dtd->scaffLevel--; dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; if (dtd->scaffLevel == 0) { if (! handleDefault) { XML_Content *model = build_model(parser); if (! model) return XML_ERROR_NO_MEMORY; *eventEndPP = s; parser->m_elementDeclHandler( parser->m_handlerArg, parser->m_declElementType->name, model); } dtd->in_eldecl = XML_FALSE; dtd->contentStringLen = 0; } } break; /* End element declaration stuff */ case XML_ROLE_PI: if (! reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; case XML_ROLE_COMMENT: if (! reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; handleDefault = XML_FALSE; break; case XML_ROLE_NONE: switch (tok) { case XML_TOK_BOM: handleDefault = XML_FALSE; break; } break; case XML_ROLE_DOCTYPE_NONE: if (parser->m_startDoctypeDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ENTITY_NONE: if (dtd->keepProcessing && parser->m_entityDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_NOTATION_NONE: if (parser->m_notationDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ATTLIST_NONE: if (dtd->keepProcessing && parser->m_attlistDeclHandler) handleDefault = XML_FALSE; break; case XML_ROLE_ELEMENT_NONE: if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; break; } /* end of big switch */ if (handleDefault && parser->m_defaultHandler) reportDefault(parser, enc, s, next); switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; case XML_PARSING: if (parser->m_reenter) { *nextPtr = next; return XML_ERROR_NONE; } /* Fall through */ default: s = next; tok = XmlPrologTok(enc, s, end, &next); } } /* not reached */ } static enum XML_Error PTRCALL epilogProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { parser->m_processor = epilogProcessor; parser->m_eventPtr = s; for (;;) { const char *next = NULL; int tok = XmlPrologTok(parser->m_encoding, s, end, &next); #if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, XML_ACCOUNT_DIRECT)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #endif parser->m_eventEndPtr = next; switch (tok) { /* report partial linebreak - it might be the last token */ case -XML_TOK_PROLOG_S: if (parser->m_defaultHandler) { reportDefault(parser, parser->m_encoding, s, next); if (parser->m_parsingStatus.parsing == XML_FINISHED) return XML_ERROR_ABORTED; } *nextPtr = next; return XML_ERROR_NONE; case XML_TOK_NONE: *nextPtr = s; return XML_ERROR_NONE; case XML_TOK_PROLOG_S: if (parser->m_defaultHandler) reportDefault(parser, parser->m_encoding, s, next); break; case XML_TOK_PI: if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (! reportComment(parser, parser->m_encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_INVALID: parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (! parser->m_parsingStatus.finalBuffer) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; default: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: parser->m_eventPtr = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: parser->m_eventPtr = next; return XML_ERROR_ABORTED; case XML_PARSING: if (parser->m_reenter) { return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE } /* Fall through */ default:; parser->m_eventPtr = s = next; } } } static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl, enum EntityType type) { OPEN_INTERNAL_ENTITY *openEntity, **openEntityList, **freeEntityList; switch (type) { case ENTITY_INTERNAL: parser->m_processor = internalEntityProcessor; openEntityList = &parser->m_openInternalEntities; freeEntityList = &parser->m_freeInternalEntities; break; case ENTITY_ATTRIBUTE: openEntityList = &parser->m_openAttributeEntities; freeEntityList = &parser->m_freeAttributeEntities; break; case ENTITY_VALUE: openEntityList = &parser->m_openValueEntities; freeEntityList = &parser->m_freeValueEntities; break; /* default case serves merely as a safety net in case of a * wrong entityType. Therefore we exclude the following lines * from the test coverage. * * LCOV_EXCL_START */ default: // Should not reach here assert(0); /* LCOV_EXCL_STOP */ } if (*freeEntityList) { openEntity = *freeEntityList; *freeEntityList = openEntity->next; } else { openEntity = MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); if (! openEntity) return XML_ERROR_NO_MEMORY; } entity->open = XML_TRUE; entity->hasMore = XML_TRUE; #if XML_GE == 1 entityTrackingOnOpen(parser, entity, __LINE__); #endif entity->processed = 0; openEntity->next = *openEntityList; *openEntityList = openEntity; openEntity->entity = entity; openEntity->type = type; openEntity->startTagLevel = parser->m_tagLevel; openEntity->betweenDecl = betweenDecl; openEntity->internalEventPtr = NULL; openEntity->internalEventEndPtr = NULL; // Only internal entities make use of the reenter flag // therefore no need to set it for other entity types if (type == ENTITY_INTERNAL) { triggerReenter(parser); } return XML_ERROR_NONE; } static enum XML_Error PTRCALL internalEntityProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { UNUSED_P(s); UNUSED_P(end); UNUSED_P(nextPtr); ENTITY *entity; const char *textStart, *textEnd; const char *next; enum XML_Error result; OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; if (! openEntity) return XML_ERROR_UNEXPECTED_STATE; entity = openEntity->entity; // This will return early if (entity->hasMore) { textStart = ((const char *)entity->textPtr) + entity->processed; textEnd = (const char *)(entity->textPtr + entity->textLen); /* Set a safe default value in case 'next' does not get set */ next = textStart; if (entity->is_param) { int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok, next, &next, XML_FALSE, XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); } else { result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding, textStart, textEnd, &next, XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); } if (result != XML_ERROR_NONE) return result; // Check if entity is complete, if not, mark down how much of it is // processed if (textEnd != next && (parser->m_parsingStatus.parsing == XML_SUSPENDED || (parser->m_parsingStatus.parsing == XML_PARSING && parser->m_reenter))) { entity->processed = (int)(next - (const char *)entity->textPtr); return result; } // Entity is complete. We cannot close it here since we need to first // process its possible inner entities (which are added to the // m_openInternalEntities during doProlog or doContent calls above) entity->hasMore = XML_FALSE; if (! entity->is_param && (openEntity->startTagLevel != parser->m_tagLevel)) { return XML_ERROR_ASYNC_ENTITY; } triggerReenter(parser); return result; } // End of entity processing, "if" block will return here // Remove fully processed openEntity from open entity list. #if XML_GE == 1 entityTrackingOnClose(parser, entity, __LINE__); #endif // openEntity is m_openInternalEntities' head, as we set it at the start of // this function and we skipped doProlog and doContent calls with hasMore set // to false. This means we can directly remove the head of // m_openInternalEntities assert(parser->m_openInternalEntities == openEntity); entity->open = XML_FALSE; parser->m_openInternalEntities = parser->m_openInternalEntities->next; /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; if (parser->m_openInternalEntities == NULL) { parser->m_processor = entity->is_param ? prologProcessor : contentProcessor; } triggerReenter(parser); return XML_ERROR_NONE; } static enum XML_Error PTRCALL errorProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { UNUSED_P(s); UNUSED_P(end); UNUSED_P(nextPtr); return parser->m_errorCode; } static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account) { const char *next = ptr; enum XML_Error result = XML_ERROR_NONE; while (1) { if (! parser->m_openAttributeEntities) { result = appendAttributeValue(parser, enc, isCdata, next, end, pool, account, &next); } else { OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openAttributeEntities; if (! openEntity) return XML_ERROR_UNEXPECTED_STATE; ENTITY *const entity = openEntity->entity; const char *const textStart = ((const char *)entity->textPtr) + entity->processed; const char *const textEnd = (const char *)(entity->textPtr + entity->textLen); /* Set a safe default value in case 'next' does not get set */ const char *nextInEntity = textStart; if (entity->hasMore) { result = appendAttributeValue( parser, parser->m_internalEncoding, isCdata, textStart, textEnd, pool, XML_ACCOUNT_ENTITY_EXPANSION, &nextInEntity); if (result != XML_ERROR_NONE) break; // Check if entity is complete, if not, mark down how much of it is // processed. A XML_SUSPENDED check here is not required as // appendAttributeValue will never suspend the parser. if (textEnd != nextInEntity) { entity->processed = (int)(nextInEntity - (const char *)entity->textPtr); continue; } // Entity is complete. We cannot close it here since we need to first // process its possible inner entities (which are added to the // m_openAttributeEntities during appendAttributeValue) entity->hasMore = XML_FALSE; continue; } // End of entity processing, "if" block skips the rest // Remove fully processed openEntity from open entity list. #if XML_GE == 1 entityTrackingOnClose(parser, entity, __LINE__); #endif // openEntity is m_openAttributeEntities' head, since we set it at the // start of this function and because we skipped appendAttributeValue call // with hasMore set to false. This means we can directly remove the head // of m_openAttributeEntities assert(parser->m_openAttributeEntities == openEntity); entity->open = XML_FALSE; parser->m_openAttributeEntities = parser->m_openAttributeEntities->next; /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeAttributeEntities; parser->m_freeAttributeEntities = openEntity; } // Break if an error occurred or there is nothing left to process if (result || (parser->m_openAttributeEntities == NULL && end == next)) { break; } } if (result) return result; if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) poolChop(pool); if (! poolAppendChar(pool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; return XML_ERROR_NONE; } static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account, const char **nextPtr) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ #ifndef XML_DTD UNUSED_P(account); #endif for (;;) { const char *next = ptr; /* XmlAttributeValueTok doesn't always set the last arg */ int tok = XmlAttributeValueTok(enc, ptr, end, &next); #if XML_GE == 1 if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) { accountingOnAbort(parser); return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; } #endif switch (tok) { case XML_TOK_NONE: if (nextPtr) { *nextPtr = next; } return XML_ERROR_NONE; case XML_TOK_INVALID: if (enc == parser->m_encoding) parser->m_eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(enc, ptr); if (n < 0) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_BAD_CHAR_REF; } if (! isCdata && n == 0x20 /* space */ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; n = XmlEncode(n, (ICHAR *)buf); /* The XmlEncode() functions can never return 0 here. That * error return happens if the code point passed in is either * negative or greater than or equal to 0x110000. The * XmlCharRefNumber() functions will all return a number * strictly less than 0x110000 or a negative value if an error * occurred. The negative value is intercepted above, so * XmlEncode() is never passed a value it might return an * error for. */ for (i = 0; i < n; i++) { if (! poolAppendChar(pool, buf[i])) return XML_ERROR_NO_MEMORY; } } break; case XML_TOK_DATA_CHARS: if (! poolAppend(pool, enc, ptr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: next = ptr + enc->minBytesPerChar; /* fall through */ case XML_TOK_ATTRIBUTE_VALUE_S: case XML_TOK_DATA_NEWLINE: if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; if (! poolAppendChar(pool, 0x20)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; bool checkEntityDecl; XML_Char ch = (XML_Char)XmlPredefinedEntityName( enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { #if XML_GE == 1 /* NOTE: We are replacing 4-6 characters original input for 1 character * so there is no amplification and hence recording without * protection. */ accountingDiffTolerated(parser, tok, (char *)&ch, ((char *)&ch) + sizeof(XML_Char), __LINE__, XML_ACCOUNT_ENTITY_EXPANSION); #endif /* XML_GE == 1 */ if (! poolAppendChar(pool, ch)) return XML_ERROR_NO_MEMORY; break; } name = poolStoreString(&parser->m_temp2Pool, enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); poolDiscard(&parser->m_temp2Pool); /* First, determine if a check for an existing declaration is needed; if yes, check that the entity exists, and that it is internal. */ if (pool == &dtd->pool) /* are we called from prolog? */ checkEntityDecl = #ifdef XML_DTD parser->m_prologState.documentEntity && #endif /* XML_DTD */ (dtd->standalone ? ! parser->m_openInternalEntities : ! dtd->hasParamEntityRefs); else /* if (pool == &parser->m_tempPool): we are called from content */ checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; if (checkEntityDecl) { if (! entity) return XML_ERROR_UNDEFINED_ENTITY; else if (! entity->is_internal) return XML_ERROR_ENTITY_DECLARED_IN_PE; } else if (! entity) { /* Cannot report skipped entity here - see comments on parser->m_skippedEntityHandler. if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ /* Cannot call the default handler because this would be out of sync with the call to the startElementHandler. if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) reportDefault(parser, enc, ptr, next); */ break; } if (entity->open) { if (enc == parser->m_encoding) { /* It does not appear that this line can be executed. * * The "if (entity->open)" check catches recursive entity * definitions. In order to be called with an open * entity, it must have gone through this code before and * been through the recursive call to * appendAttributeValue() some lines below. That call * sets the local encoding ("enc") to the parser's * internal encoding (internal_utf8 or internal_utf16), * which can never be the same as the principle encoding. * It doesn't appear there is another code path that gets * here with entity->open being TRUE. * * Since it is not certain that this logic is watertight, * we keep the line and merely exclude it from coverage * tests. */ parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ } return XML_ERROR_RECURSIVE_ENTITY_REF; } if (entity->notation) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_BINARY_ENTITY_REF; } if (! entity->textPtr) { if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; result = processEntity(parser, entity, XML_FALSE, ENTITY_ATTRIBUTE); if ((result == XML_ERROR_NONE) && (nextPtr != NULL)) { *nextPtr = next; } return result; } } break; default: /* The only token returned by XmlAttributeValueTok() that does * not have an explicit case here is XML_TOK_PARTIAL_CHAR. * Getting that would require an entity name to contain an * incomplete XML character (e.g. \xE2\x82); however previous * tokenisers will have already recognised and rejected such * names before XmlAttributeValueTok() gets a look-in. This * default case should be retained as a safety net, but the code * excluded from coverage tests. * * LCOV_EXCL_START */ if (enc == parser->m_encoding) parser->m_eventPtr = ptr; return XML_ERROR_UNEXPECTED_STATE; /* LCOV_EXCL_STOP */ } ptr = next; } /* not reached */ } #if XML_GE == 1 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd, enum XML_Account account, const char **nextPtr) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ STRING_POOL *pool = &(dtd->entityValuePool); enum XML_Error result = XML_ERROR_NONE; # ifdef XML_DTD int oldInEntityValue = parser->m_prologState.inEntityValue; parser->m_prologState.inEntityValue = 1; # else UNUSED_P(account); # endif /* XML_DTD */ /* never return Null for the value argument in EntityDeclHandler, since this would indicate an external entity; therefore we have to make sure that entityValuePool.start is not null */ if (! pool->blocks) { if (! poolGrow(pool)) return XML_ERROR_NO_MEMORY; } const char *next = entityTextPtr; /* Nothing to tokenize. */ if (entityTextPtr >= entityTextEnd) { result = XML_ERROR_NONE; goto endEntityValue; } for (;;) { next = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, account)) { accountingOnAbort(parser); result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH; goto endEntityValue; } switch (tok) { case XML_TOK_PARAM_ENTITY_REF: # ifdef XML_DTD if (parser->m_isParamEntity || enc != parser->m_encoding) { const XML_Char *name; ENTITY *entity; name = poolStoreString(&parser->m_tempPool, enc, entityTextPtr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (! name) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); poolDiscard(&parser->m_tempPool); if (! entity) { /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ /* cannot report skipped entity here - see comments on parser->m_skippedEntityHandler if (parser->m_skippedEntityHandler) parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); */ dtd->keepProcessing = dtd->standalone; goto endEntityValue; } if (entity->open || (entity == parser->m_declEntity)) { if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_RECURSIVE_ENTITY_REF; goto endEntityValue; } if (entity->systemId) { if (parser->m_externalEntityRefHandler) { dtd->paramEntityRead = XML_FALSE; entity->open = XML_TRUE; entityTrackingOnOpen(parser, entity, __LINE__); if (! parser->m_externalEntityRefHandler( parser->m_externalEntityRefHandlerArg, 0, entity->base, entity->systemId, entity->publicId)) { entityTrackingOnClose(parser, entity, __LINE__); entity->open = XML_FALSE; result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; goto endEntityValue; } entityTrackingOnClose(parser, entity, __LINE__); entity->open = XML_FALSE; if (! dtd->paramEntityRead) dtd->keepProcessing = dtd->standalone; } else dtd->keepProcessing = dtd->standalone; } else { result = processEntity(parser, entity, XML_FALSE, ENTITY_VALUE); goto endEntityValue; } break; } # endif /* XML_DTD */ /* In the internal subset, PE references are not legal within markup declarations, e.g entity values in this case. */ parser->m_eventPtr = entityTextPtr; result = XML_ERROR_PARAM_ENTITY_REF; goto endEntityValue; case XML_TOK_NONE: result = XML_ERROR_NONE; goto endEntityValue; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: if (! poolAppend(pool, enc, entityTextPtr, next)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } break; case XML_TOK_TRAILING_CR: next = entityTextPtr + enc->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && ! poolGrow(pool)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } *(pool->ptr)++ = 0xA; break; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(enc, entityTextPtr); if (n < 0) { if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_BAD_CHAR_REF; goto endEntityValue; } n = XmlEncode(n, (ICHAR *)buf); /* The XmlEncode() functions can never return 0 here. That * error return happens if the code point passed in is either * negative or greater than or equal to 0x110000. The * XmlCharRefNumber() functions will all return a number * strictly less than 0x110000 or a negative value if an error * occurred. The negative value is intercepted above, so * XmlEncode() is never passed a value it might return an * error for. */ for (i = 0; i < n; i++) { if (pool->end == pool->ptr && ! poolGrow(pool)) { result = XML_ERROR_NO_MEMORY; goto endEntityValue; } *(pool->ptr)++ = buf[i]; } } break; case XML_TOK_PARTIAL: if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; case XML_TOK_INVALID: if (enc == parser->m_encoding) parser->m_eventPtr = next; result = XML_ERROR_INVALID_TOKEN; goto endEntityValue; default: /* This default case should be unnecessary -- all the tokens * that XmlEntityValueTok() can return have their own explicit * cases -- but should be retained for safety. We do however * exclude it from the coverage statistics. * * LCOV_EXCL_START */ if (enc == parser->m_encoding) parser->m_eventPtr = entityTextPtr; result = XML_ERROR_UNEXPECTED_STATE; goto endEntityValue; /* LCOV_EXCL_STOP */ } entityTextPtr = next; } endEntityValue: # ifdef XML_DTD parser->m_prologState.inEntityValue = oldInEntityValue; # endif /* XML_DTD */ // If 'nextPtr' is given, it should be updated during the processing if (nextPtr != NULL) { *nextPtr = next; } return result; } static enum XML_Error callStoreEntityValue(XML_Parser parser, const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd, enum XML_Account account) { const char *next = entityTextPtr; enum XML_Error result = XML_ERROR_NONE; while (1) { if (! parser->m_openValueEntities) { result = storeEntityValue(parser, enc, next, entityTextEnd, account, &next); } else { OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openValueEntities; if (! openEntity) return XML_ERROR_UNEXPECTED_STATE; ENTITY *const entity = openEntity->entity; const char *const textStart = ((const char *)entity->textPtr) + entity->processed; const char *const textEnd = (const char *)(entity->textPtr + entity->textLen); /* Set a safe default value in case 'next' does not get set */ const char *nextInEntity = textStart; if (entity->hasMore) { result = storeEntityValue(parser, parser->m_internalEncoding, textStart, textEnd, XML_ACCOUNT_ENTITY_EXPANSION, &nextInEntity); if (result != XML_ERROR_NONE) break; // Check if entity is complete, if not, mark down how much of it is // processed. A XML_SUSPENDED check here is not required as // appendAttributeValue will never suspend the parser. if (textEnd != nextInEntity) { entity->processed = (int)(nextInEntity - (const char *)entity->textPtr); continue; } // Entity is complete. We cannot close it here since we need to first // process its possible inner entities (which are added to the // m_openValueEntities during storeEntityValue) entity->hasMore = XML_FALSE; continue; } // End of entity processing, "if" block skips the rest // Remove fully processed openEntity from open entity list. # if XML_GE == 1 entityTrackingOnClose(parser, entity, __LINE__); # endif // openEntity is m_openValueEntities' head, since we set it at the // start of this function and because we skipped storeEntityValue call // with hasMore set to false. This means we can directly remove the head // of m_openValueEntities assert(parser->m_openValueEntities == openEntity); entity->open = XML_FALSE; parser->m_openValueEntities = parser->m_openValueEntities->next; /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeValueEntities; parser->m_freeValueEntities = openEntity; } // Break if an error occurred or there is nothing left to process if (result || (parser->m_openValueEntities == NULL && entityTextEnd == next)) { break; } } return result; } #else /* XML_GE == 0 */ static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity) { // This will store "&entity123;" in entity->textPtr // to end up as "&entity123;" in the handler. const char *const entity_start = "&"; const char *const entity_end = ";"; STRING_POOL *const pool = &(parser->m_dtd->entityValuePool); if (! poolAppendString(pool, entity_start) || ! poolAppendString(pool, entity->name) || ! poolAppendString(pool, entity_end)) { poolDiscard(pool); return XML_ERROR_NO_MEMORY; } entity->textPtr = poolStart(pool); entity->textLen = (int)(poolLength(pool)); poolFinish(pool); return XML_ERROR_NONE; } #endif /* XML_GE == 0 */ static void FASTCALL normalizeLines(XML_Char *s) { XML_Char *p; for (;; s++) { if (*s == XML_T('\0')) return; if (*s == 0xD) break; } p = s; do { if (*s == 0xD) { *p++ = 0xA; if (*++s == 0xA) s++; } else *p++ = *s++; } while (*s); *p = XML_T('\0'); } static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { const XML_Char *target; XML_Char *data; const char *tem; if (! parser->m_processingInstructionHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); target = poolStoreString(&parser->m_tempPool, enc, start, tem); if (! target) return 0; poolFinish(&parser->m_tempPool); data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), end - enc->minBytesPerChar * 2); if (! data) return 0; normalizeLines(data); parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); poolClear(&parser->m_tempPool); return 1; } static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { XML_Char *data; if (! parser->m_commentHandler) { if (parser->m_defaultHandler) reportDefault(parser, enc, start, end); return 1; } data = poolStoreString(&parser->m_tempPool, enc, start + enc->minBytesPerChar * 4, end - enc->minBytesPerChar * 3); if (! data) return 0; normalizeLines(data); parser->m_commentHandler(parser->m_handlerArg, data); poolClear(&parser->m_tempPool); return 1; } static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) { if (MUST_CONVERT(enc, s)) { enum XML_Convert_Result convert_res; const char **eventPP; const char **eventEndPP; if (enc == parser->m_encoding) { eventPP = &parser->m_eventPtr; eventEndPP = &parser->m_eventEndPtr; } else { /* To get here, two things must be true; the parser must be * using a character encoding that is not the same as the * encoding passed in, and the encoding passed in must need * conversion to the internal format (UTF-8 unless XML_UNICODE * is defined). The only occasions on which the encoding passed * in is not the same as the parser's encoding are when it is * the internal encoding (e.g. a previously defined parameter * entity, already converted to internal format). This by * definition doesn't need conversion, so the whole branch never * gets executed. * * For safety's sake we don't delete these lines and merely * exclude them from coverage statistics. * * LCOV_EXCL_START */ eventPP = &(parser->m_openInternalEntities->internalEventPtr); eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); /* LCOV_EXCL_STOP */ } do { ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); *eventEndPP = s; parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); *eventPP = s; } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); } else parser->m_defaultHandler( parser->m_handlerArg, (const XML_Char *)s, (int)((const XML_Char *)end - (const XML_Char *)s)); } static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, XML_Bool isId, const XML_Char *value, XML_Parser parser) { DEFAULT_ATTRIBUTE *att; if (value || isId) { /* The handling of default attributes gets messed up if we have a default which duplicates a non-default. */ int i; for (i = 0; i < type->nDefaultAtts; i++) if (attId == type->defaultAtts[i].id) return 1; if (isId && ! type->idAtt && ! attId->xmlns) type->idAtt = attId; } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; type->defaultAtts = MALLOC(parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (! type->defaultAtts) { type->allocDefaultAtts = 0; return 0; } } else { DEFAULT_ATTRIBUTE *temp; /* Detect and prevent integer overflow */ if (type->allocDefaultAtts > INT_MAX / 2) { return 0; } int count = type->allocDefaultAtts * 2; /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((unsigned)count > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) { return 0; } #endif temp = REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) return 0; type->allocDefaultAtts = count; type->defaultAtts = temp; } } att = type->defaultAtts + type->nDefaultAtts; att->id = attId; att->value = value; att->isCdata = isCdata; if (! isCdata) attId->maybeTokenized = XML_TRUE; type->nDefaultAtts += 1; return 1; } static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name; for (name = elementType->name; *name; name++) { if (*name == XML_T(ASCII_COLON)) { PREFIX *prefix; const XML_Char *s; for (s = elementType->name; s != name; s++) { if (! poolAppendChar(&dtd->pool, *s)) return 0; } if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return 0; prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); if (! prefix) return 0; if (prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); elementType->prefix = prefix; break; } } return 1; } static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ ATTRIBUTE_ID *id; const XML_Char *name; if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; name = poolStoreString(&dtd->pool, enc, start, end); if (! name) return NULL; /* skip quotation mark - its storage will be reused (like in name[-1]) */ ++name; id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); if (! id) return NULL; if (id->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); if (! parser->m_ns) ; else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) && name[4] == XML_T(ASCII_s) && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { if (name[5] == XML_T('\0')) id->prefix = &dtd->defaultPrefix; else id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX)); id->xmlns = XML_TRUE; } else { int i; for (i = 0; name[i]; i++) { /* attributes without prefix are *not* in the default namespace */ if (name[i] == XML_T(ASCII_COLON)) { int j; for (j = 0; j < i; j++) { if (! poolAppendChar(&dtd->pool, name[j])) return NULL; } if (! poolAppendChar(&dtd->pool, XML_T('\0'))) return NULL; id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); if (! id->prefix) return NULL; if (id->prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); break; } } } } return id; } #define CONTEXT_SEP XML_T(ASCII_FF) static const XML_Char * getContext(XML_Parser parser) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ HASH_TABLE_ITER iter; XML_Bool needSep = XML_FALSE; if (dtd->defaultPrefix.binding) { int i; int len; if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = dtd->defaultPrefix.binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) { if (! poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) { /* Because of memory caching, I don't believe this line can be * executed. * * This is part of a loop copying the default prefix binding * URI into the parser's temporary string pool. Previously, * that URI was copied into the same string pool, with a * terminating NUL character, as part of setContext(). When * the pool was cleared, that leaves a block definitely big * enough to hold the URI on the free block list of the pool. * The URI copy in getContext() therefore cannot run out of * memory. * * If the pool is used between the setContext() and * getContext() calls, the worst it can do is leave a bigger * block on the front of the free list. Given that this is * all somewhat inobvious and program logic can be changed, we * don't delete the line but we do exclude it from the test * coverage statistics. */ return NULL; /* LCOV_EXCL_LINE */ } } needSep = XML_TRUE; } hashTableIterInit(&iter, &(dtd->prefixes)); for (;;) { int i; int len; const XML_Char *s; PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); if (! prefix) break; if (! prefix->binding) { /* This test appears to be (justifiable) paranoia. There does * not seem to be a way of injecting a prefix without a binding * that doesn't get errored long before this function is called. * The test should remain for safety's sake, so we instead * exclude the following line from the coverage statistics. */ continue; /* LCOV_EXCL_LINE */ } if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = prefix->name; *s; s++) if (! poolAppendChar(&parser->m_tempPool, *s)) return NULL; if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) return NULL; len = prefix->binding->uriLen; if (parser->m_namespaceSeparator) len--; for (i = 0; i < len; i++) if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) return NULL; needSep = XML_TRUE; } hashTableIterInit(&iter, &(dtd->generalEntities)); for (;;) { const XML_Char *s; ENTITY *e = (ENTITY *)hashTableIterNext(&iter); if (! e) break; if (! e->open) continue; if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) return NULL; for (s = e->name; *s; s++) if (! poolAppendChar(&parser->m_tempPool, *s)) return 0; needSep = XML_TRUE; } if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return NULL; return parser->m_tempPool.start; } static XML_Bool setContext(XML_Parser parser, const XML_Char *context) { if (context == NULL) { return XML_FALSE; } DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *s = context; while (*context != XML_T('\0')) { if (*s == CONTEXT_SEP || *s == XML_T('\0')) { ENTITY *e; if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0); if (e) e->open = XML_TRUE; if (*s != XML_T('\0')) s++; context = s; poolDiscard(&parser->m_tempPool); } else if (*s == XML_T(ASCII_EQUALS)) { PREFIX *prefix; if (poolLength(&parser->m_tempPool) == 0) prefix = &dtd->defaultPrefix; else { if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; const XML_Char *const prefixName = poolCopyStringNoFinish( &dtd->pool, poolStart(&parser->m_tempPool)); if (! prefixName) { return XML_FALSE; } prefix = (PREFIX *)lookup(parser, &dtd->prefixes, prefixName, sizeof(PREFIX)); const bool prefixNameUsed = prefix && prefix->name == prefixName; if (prefixNameUsed) poolFinish(&dtd->pool); else poolDiscard(&dtd->pool); if (! prefix) return XML_FALSE; poolDiscard(&parser->m_tempPool); } for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) if (! poolAppendChar(&parser->m_tempPool, *context)) return XML_FALSE; if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) return XML_FALSE; if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), &parser->m_inheritedBindings) != XML_ERROR_NONE) return XML_FALSE; poolDiscard(&parser->m_tempPool); if (*context != XML_T('\0')) ++context; s = context; } else { if (! poolAppendChar(&parser->m_tempPool, *s)) return XML_FALSE; s++; } } return XML_TRUE; } static void FASTCALL normalizePublicId(XML_Char *publicId) { XML_Char *p = publicId; XML_Char *s; for (s = publicId; *s; s++) { switch (*s) { case 0x20: case 0xD: case 0xA: if (p != publicId && p[-1] != 0x20) *p++ = 0x20; break; default: *p++ = *s; } } if (p != publicId && p[-1] == 0x20) --p; *p = XML_T('\0'); } static DTD * dtdCreate(XML_Parser parser) { DTD *p = MALLOC(parser, sizeof(DTD)); if (p == NULL) return p; poolInit(&(p->pool), parser); poolInit(&(p->entityValuePool), parser); hashTableInit(&(p->generalEntities), parser); hashTableInit(&(p->elementTypes), parser); hashTableInit(&(p->attributeIds), parser); hashTableInit(&(p->prefixes), parser); #ifdef XML_DTD p->paramEntityRead = XML_FALSE; hashTableInit(&(p->paramEntities), parser); #endif /* XML_DTD */ p->defaultPrefix.name = NULL; p->defaultPrefix.binding = NULL; p->in_eldecl = XML_FALSE; p->scaffIndex = NULL; p->scaffold = NULL; p->scaffLevel = 0; p->scaffSize = 0; p->scaffCount = 0; p->contentStringLen = 0; p->keepProcessing = XML_TRUE; p->hasParamEntityRefs = XML_FALSE; p->standalone = XML_FALSE; return p; } static void dtdReset(DTD *p, XML_Parser parser) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! e) break; if (e->allocDefaultAtts != 0) FREE(parser, e->defaultAtts); } hashTableClear(&(p->generalEntities)); #ifdef XML_DTD p->paramEntityRead = XML_FALSE; hashTableClear(&(p->paramEntities)); #endif /* XML_DTD */ hashTableClear(&(p->elementTypes)); hashTableClear(&(p->attributeIds)); hashTableClear(&(p->prefixes)); poolClear(&(p->pool)); poolClear(&(p->entityValuePool)); p->defaultPrefix.name = NULL; p->defaultPrefix.binding = NULL; p->in_eldecl = XML_FALSE; FREE(parser, p->scaffIndex); p->scaffIndex = NULL; FREE(parser, p->scaffold); p->scaffold = NULL; p->scaffLevel = 0; p->scaffSize = 0; p->scaffCount = 0; p->contentStringLen = 0; p->keepProcessing = XML_TRUE; p->hasParamEntityRefs = XML_FALSE; p->standalone = XML_FALSE; } static void dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! e) break; if (e->allocDefaultAtts != 0) FREE(parser, e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); #ifdef XML_DTD hashTableDestroy(&(p->paramEntities)); #endif /* XML_DTD */ hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); poolDestroy(&(p->pool)); poolDestroy(&(p->entityValuePool)); if (isDocEntity) { FREE(parser, p->scaffIndex); FREE(parser, p->scaffold); } FREE(parser, p); } /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. The new DTD has already been initialized. */ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, XML_Parser parser) { HASH_TABLE_ITER iter; /* Copy the prefix table. */ hashTableIterInit(&iter, &(oldDtd->prefixes)); for (;;) { const XML_Char *name; const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); if (! oldP) break; name = poolCopyString(&(newDtd->pool), oldP->name); if (! name) return 0; if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) return 0; } hashTableIterInit(&iter, &(oldDtd->attributeIds)); /* Copy the attribute id table. */ for (;;) { ATTRIBUTE_ID *newA; const XML_Char *name; const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); if (! oldA) break; /* Remember to allocate the scratch byte before the name. */ if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) return 0; name = poolCopyString(&(newDtd->pool), oldA->name); if (! name) return 0; ++name; newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); if (! newA) return 0; newA->maybeTokenized = oldA->maybeTokenized; if (oldA->prefix) { newA->xmlns = oldA->xmlns; if (oldA->prefix == &oldDtd->defaultPrefix) newA->prefix = &newDtd->defaultPrefix; else newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), oldA->prefix->name, 0); } } /* Copy the element type table. */ hashTableIterInit(&iter, &(oldDtd->elementTypes)); for (;;) { int i; ELEMENT_TYPE *newE; const XML_Char *name; const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (! oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (! name) return 0; newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); if (! newE) return 0; if (oldE->nDefaultAtts) { /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if ((size_t)oldE->nDefaultAtts > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) { return 0; } #endif newE->defaultAtts = MALLOC(parser, oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (! newE->defaultAtts) { return 0; } } if (oldE->idAtt) newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; if (oldE->prefix) newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), oldE->prefix->name, 0); for (i = 0; i < newE->nDefaultAtts; i++) { newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; if (oldE->defaultAtts[i].value) { newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); if (! newE->defaultAtts[i].value) return 0; } else newE->defaultAtts[i].value = NULL; } } /* Copy the entity tables. */ if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), &(oldDtd->generalEntities))) return 0; #ifdef XML_DTD if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), &(oldDtd->paramEntities))) return 0; newDtd->paramEntityRead = oldDtd->paramEntityRead; #endif /* XML_DTD */ newDtd->keepProcessing = oldDtd->keepProcessing; newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; newDtd->standalone = oldDtd->standalone; /* Don't want deep copying for scaffolding */ newDtd->in_eldecl = oldDtd->in_eldecl; newDtd->scaffold = oldDtd->scaffold; newDtd->contentStringLen = oldDtd->contentStringLen; newDtd->scaffSize = oldDtd->scaffSize; newDtd->scaffLevel = oldDtd->scaffLevel; newDtd->scaffIndex = oldDtd->scaffIndex; return 1; } /* End dtdCopy */ static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, STRING_POOL *newPool, const HASH_TABLE *oldTable) { HASH_TABLE_ITER iter; const XML_Char *cachedOldBase = NULL; const XML_Char *cachedNewBase = NULL; hashTableIterInit(&iter, oldTable); for (;;) { ENTITY *newE; const XML_Char *name; const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (! oldE) break; name = poolCopyString(newPool, oldE->name); if (! name) return 0; newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); if (! newE) return 0; if (oldE->systemId) { const XML_Char *tem = poolCopyString(newPool, oldE->systemId); if (! tem) return 0; newE->systemId = tem; if (oldE->base) { if (oldE->base == cachedOldBase) newE->base = cachedNewBase; else { cachedOldBase = oldE->base; tem = poolCopyString(newPool, cachedOldBase); if (! tem) return 0; cachedNewBase = newE->base = tem; } } if (oldE->publicId) { tem = poolCopyString(newPool, oldE->publicId); if (! tem) return 0; newE->publicId = tem; } } else { const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); if (! tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { const XML_Char *tem = poolCopyString(newPool, oldE->notation); if (! tem) return 0; newE->notation = tem; } newE->is_param = oldE->is_param; newE->is_internal = oldE->is_internal; } return 1; } #define INIT_POWER 6 static XML_Bool FASTCALL keyeq(KEY s1, KEY s2) { for (; *s1 == *s2; s1++, s2++) if (*s1 == 0) return XML_TRUE; return XML_FALSE; } static size_t keylen(KEY s) { size_t len = 0; for (; *s; s++, len++) ; return len; } static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { key->k[0] = 0; key->k[1] = get_hash_secret_salt(parser); } static unsigned long FASTCALL hash(XML_Parser parser, KEY s) { struct siphash state; struct sipkey key; (void)sip24_valid; copy_salt_to_sipkey(parser, &key); sip24_init(&state, &key); sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); return (unsigned long)sip24_final(&state); } static NAMED * lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { size_t i; if (table->size == 0) { size_t tsize; if (! createSize) return NULL; table->power = INIT_POWER; /* table->size is a power of 2 */ table->size = (size_t)1 << INIT_POWER; tsize = table->size * sizeof(NAMED *); table->v = MALLOC(table->parser, tsize); if (! table->v) { table->size = 0; return NULL; } memset(table->v, 0, tsize); i = hash(parser, name) & ((unsigned long)table->size - 1); } else { unsigned long h = hash(parser, name); unsigned long mask = (unsigned long)table->size - 1; unsigned char step = 0; i = h & mask; while (table->v[i]) { if (keyeq(name, table->v[i]->name)) return table->v[i]; if (! step) step = PROBE_STEP(h, mask, table->power); i < step ? (i += table->size - step) : (i -= step); } if (! createSize) return NULL; /* check for overflow (table is half full) */ if (table->used >> (table->power - 1)) { unsigned char newPower = table->power + 1; /* Detect and prevent invalid shift */ if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { return NULL; } size_t newSize = (size_t)1 << newPower; unsigned long newMask = (unsigned long)newSize - 1; /* Detect and prevent integer overflow */ if (newSize > SIZE_MAX / sizeof(NAMED *)) { return NULL; } size_t tsize = newSize * sizeof(NAMED *); NAMED **newV = MALLOC(table->parser, tsize); if (! newV) return NULL; memset(newV, 0, tsize); for (i = 0; i < table->size; i++) if (table->v[i]) { unsigned long newHash = hash(parser, table->v[i]->name); size_t j = newHash & newMask; step = 0; while (newV[j]) { if (! step) step = PROBE_STEP(newHash, newMask, newPower); j < step ? (j += newSize - step) : (j -= step); } newV[j] = table->v[i]; } FREE(table->parser, table->v); table->v = newV; table->power = newPower; table->size = newSize; i = h & newMask; step = 0; while (table->v[i]) { if (! step) step = PROBE_STEP(h, newMask, newPower); i < step ? (i += newSize - step) : (i -= step); } } } table->v[i] = MALLOC(table->parser, createSize); if (! table->v[i]) return NULL; memset(table->v[i], 0, createSize); table->v[i]->name = name; (table->used)++; return table->v[i]; } static void FASTCALL hashTableClear(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) { FREE(table->parser, table->v[i]); table->v[i] = NULL; } table->used = 0; } static void FASTCALL hashTableDestroy(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) FREE(table->parser, table->v[i]); FREE(table->parser, table->v); } static void FASTCALL hashTableInit(HASH_TABLE *p, XML_Parser parser) { p->power = 0; p->size = 0; p->used = 0; p->v = NULL; p->parser = parser; } static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { iter->p = table->v; iter->end = iter->p ? iter->p + table->size : NULL; } static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter) { while (iter->p != iter->end) { NAMED *tem = *(iter->p)++; if (tem) return tem; } return NULL; } static void FASTCALL poolInit(STRING_POOL *pool, XML_Parser parser) { pool->blocks = NULL; pool->freeBlocks = NULL; pool->start = NULL; pool->ptr = NULL; pool->end = NULL; pool->parser = parser; } static void FASTCALL poolClear(STRING_POOL *pool) { if (! pool->freeBlocks) pool->freeBlocks = pool->blocks; else { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; p->next = pool->freeBlocks; pool->freeBlocks = p; p = tem; } } pool->blocks = NULL; pool->start = NULL; pool->ptr = NULL; pool->end = NULL; } static void FASTCALL poolDestroy(STRING_POOL *pool) { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; FREE(pool->parser, p); p = tem; } p = pool->freeBlocks; while (p) { BLOCK *tem = p->next; FREE(pool->parser, p); p = tem; } } static XML_Char * poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (! pool->ptr && ! poolGrow(pool)) return NULL; for (;;) { const enum XML_Convert_Result convert_res = XmlConvert( enc, &ptr, end, (ICHAR **)&(pool->ptr), (const ICHAR *)pool->end); if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; if (! poolGrow(pool)) return NULL; } return pool->start; } static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, const XML_Char *s) { do { if (! poolAppendChar(pool, *s)) return NULL; } while (*s++); s = pool->start; poolFinish(pool); return s; } // A version of `poolCopyString` that does not call `poolFinish` // and reverts any partial advancement upon failure. static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) { const XML_Char *const original = s; do { if (! poolAppendChar(pool, *s)) { // Revert any previously successful advancement const ptrdiff_t advancedBy = s - original; if (advancedBy > 0) pool->ptr -= advancedBy; return NULL; } } while (*s++); return pool->start; } static const XML_Char * poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { if (! pool->ptr && ! poolGrow(pool)) { /* The following line is unreachable given the current usage of * poolCopyStringN(). Currently it is called from exactly one * place to copy the text of a simple general entity. By that * point, the name of the entity is already stored in the pool, so * pool->ptr cannot be NULL. * * If poolCopyStringN() is used elsewhere as it well might be, * this line may well become executable again. Regardless, this * sort of check shouldn't be removed lightly, so we just exclude * it from the coverage statistics. */ return NULL; /* LCOV_EXCL_LINE */ } for (; n > 0; --n, s++) { if (! poolAppendChar(pool, *s)) return NULL; } s = pool->start; poolFinish(pool); return s; } static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, const XML_Char *s) { while (*s) { if (! poolAppendChar(pool, *s)) return NULL; s++; } return pool->start; } static XML_Char * poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (! poolAppend(pool, enc, ptr, end)) return NULL; if (pool->ptr == pool->end && ! poolGrow(pool)) return NULL; *(pool->ptr)++ = 0; return pool->start; } static size_t poolBytesToAllocateFor(int blockSize) { /* Unprotected math would be: ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); ** ** Detect overflow, avoiding _signed_ overflow undefined behavior ** For a + b * c we check b * c in isolation first, so that addition of a ** on top has no chance of making us accept a small non-negative number */ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ if (blockSize <= 0) return 0; if (blockSize > (int)(INT_MAX / stretch)) return 0; { const int stretchedBlockSize = blockSize * (int)stretch; const int bytesToAllocate = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); if (bytesToAllocate < 0) return 0; return (size_t)bytesToAllocate; } } static XML_Bool FASTCALL poolGrow(STRING_POOL *pool) { if (pool->freeBlocks) { if (pool->start == NULL) { pool->blocks = pool->freeBlocks; pool->freeBlocks = pool->freeBlocks->next; pool->blocks->next = NULL; pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; pool->ptr = pool->start; return XML_TRUE; } if (pool->end - pool->start < pool->freeBlocks->size) { BLOCK *tem = pool->freeBlocks->next; pool->freeBlocks->next = pool->blocks; pool->blocks = pool->freeBlocks; pool->freeBlocks = tem; memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char)); pool->ptr = pool->blocks->s + (pool->ptr - pool->start); pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; return XML_TRUE; } } if (pool->blocks && pool->start == pool->blocks->s) { BLOCK *temp; int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); size_t bytesToAllocate; /* NOTE: Needs to be calculated prior to calling `realloc` to avoid dangling pointers: */ const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; if (blockSize < 0) { /* This condition traps a situation where either more than * INT_MAX/2 bytes have already been allocated. This isn't * readily testable, since it is unlikely that an average * machine will have that much memory, so we exclude it from the * coverage statistics. */ return XML_FALSE; /* LCOV_EXCL_LINE */ } bytesToAllocate = poolBytesToAllocateFor(blockSize); if (bytesToAllocate == 0) return XML_FALSE; temp = REALLOC(pool->parser, pool->blocks, bytesToAllocate); if (temp == NULL) return XML_FALSE; pool->blocks = temp; pool->blocks->size = blockSize; pool->ptr = pool->blocks->s + offsetInsideBlock; pool->start = pool->blocks->s; pool->end = pool->start + blockSize; } else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); size_t bytesToAllocate; if (blockSize < 0) { /* This condition traps a situation where either more than * INT_MAX bytes have already been allocated (which is prevented * by various pieces of program logic, not least this one, never * mind the unlikelihood of actually having that much memory) or * the pool control fields have been corrupted (which could * conceivably happen in an extremely buggy user handler * function). Either way it isn't readily testable, so we * exclude it from the coverage statistics. */ return XML_FALSE; /* LCOV_EXCL_LINE */ } if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; else { /* Detect overflow, avoiding _signed_ overflow undefined behavior */ if ((int)((unsigned)blockSize * 2U) < 0) { return XML_FALSE; } blockSize *= 2; } bytesToAllocate = poolBytesToAllocateFor(blockSize); if (bytesToAllocate == 0) return XML_FALSE; tem = MALLOC(pool->parser, bytesToAllocate); if (! tem) return XML_FALSE; tem->size = blockSize; tem->next = pool->blocks; pool->blocks = tem; if (pool->ptr != pool->start) memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); pool->ptr = tem->s + (pool->ptr - pool->start); pool->start = tem->s; pool->end = tem->s + blockSize; } return XML_TRUE; } static int FASTCALL nextScaffoldPart(XML_Parser parser) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ CONTENT_SCAFFOLD *me; int next; if (! dtd->scaffIndex) { /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if (parser->m_groupSize > SIZE_MAX / sizeof(int)) { return -1; } #endif dtd->scaffIndex = MALLOC(parser, parser->m_groupSize * sizeof(int)); if (! dtd->scaffIndex) return -1; dtd->scaffIndex[0] = 0; } // Will casting to int be safe further down? if (dtd->scaffCount > INT_MAX) { return -1; } if (dtd->scaffCount >= dtd->scaffSize) { CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { /* Detect and prevent integer overflow */ if (dtd->scaffSize > UINT_MAX / 2u) { return -1; } /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if (dtd->scaffSize > SIZE_MAX / 2u / sizeof(CONTENT_SCAFFOLD)) { return -1; } #endif temp = REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize *= 2; } else { temp = MALLOC(parser, INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) return -1; dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; } dtd->scaffold = temp; } next = (int)dtd->scaffCount++; me = &dtd->scaffold[next]; if (dtd->scaffLevel) { CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; if (parent->lastchild) { dtd->scaffold[parent->lastchild].nextsib = next; } if (! parent->childcnt) parent->firstchild = next; parent->lastchild = next; parent->childcnt++; } me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; return next; } static XML_Content * build_model(XML_Parser parser) { /* Function build_model transforms the existing parser->m_dtd->scaffold * array of CONTENT_SCAFFOLD tree nodes into a new array of * XML_Content tree nodes followed by a gapless list of zero-terminated * strings. */ DTD *const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; XML_Char *str; /* the current string writing location */ /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX if (dtd->scaffCount > SIZE_MAX / sizeof(XML_Content)) { return NULL; } if (dtd->contentStringLen > SIZE_MAX / sizeof(XML_Char)) { return NULL; } #endif if (dtd->scaffCount * sizeof(XML_Content) > SIZE_MAX - dtd->contentStringLen * sizeof(XML_Char)) { return NULL; } const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) + (dtd->contentStringLen * sizeof(XML_Char))); // NOTE: We are avoiding MALLOC(..) here to so that // applications that are not using XML_FreeContentModel but plain // free(..) or .free_fcn() to free the content model's memory are safe. ret = parser->m_mem.malloc_fcn(allocsize); if (! ret) return NULL; /* What follows is an iterative implementation (of what was previously done * recursively in a dedicated function called "build_node". The old recursive * build_node could be forced into stack exhaustion from input as small as a * few megabyte, and so that was a security issue. Hence, a function call * stack is avoided now by resolving recursion.) * * The iterative approach works as follows: * * - We have two writing pointers, both walking up the result array; one does * the work, the other creates "jobs" for its colleague to do, and leads * the way: * * - The faster one, pointer jobDest, always leads and writes "what job * to do" by the other, once they reach that place in the * array: leader "jobDest" stores the source node array index (relative * to array dtd->scaffold) in field "numchildren". * * - The slower one, pointer dest, looks at the value stored in the * "numchildren" field (which actually holds a source node array index * at that time) and puts the real data from dtd->scaffold in. * * - Before the loop starts, jobDest writes source array index 0 * (where the root node is located) so that dest will have something to do * when it starts operation. * * - Whenever nodes with children are encountered, jobDest appends * them as new jobs, in order. As a result, tree node siblings are * adjacent in the resulting array, for example: * * [0] root, has two children * [1] first child of 0, has three children * [3] first child of 1, does not have children * [4] second child of 1, does not have children * [5] third child of 1, does not have children * [2] second child of 0, does not have children * * Or (the same data) presented in flat array view: * * [0] root, has two children * * [1] first child of 0, has three children * [2] second child of 0, does not have children * * [3] first child of 1, does not have children * [4] second child of 1, does not have children * [5] third child of 1, does not have children * * - The algorithm repeats until all target array indices have been processed. */ XML_Content *dest = ret; /* tree node writing location, moves upwards */ XML_Content *const destLimit = &ret[dtd->scaffCount]; XML_Content *jobDest = ret; /* next free writing location in target array */ str = (XML_Char *)&ret[dtd->scaffCount]; /* Add the starting job, the root node (index 0) of the source tree */ (jobDest++)->numchildren = 0; for (; dest < destLimit; dest++) { /* Retrieve source tree array index from job storage */ const int src_node = (int)dest->numchildren; /* Convert item */ dest->type = dtd->scaffold[src_node].type; dest->quant = dtd->scaffold[src_node].quant; if (dest->type == XML_CTYPE_NAME) { const XML_Char *src; dest->name = str; src = dtd->scaffold[src_node].name; for (;;) { *str++ = *src; if (! *src) break; src++; } dest->numchildren = 0; dest->children = NULL; } else { unsigned int i; int cn; dest->name = NULL; dest->numchildren = dtd->scaffold[src_node].childcnt; dest->children = jobDest; /* Append scaffold indices of children to array */ for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) (jobDest++)->numchildren = (unsigned int)cn; } } return ret; } static ELEMENT_TYPE * getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, const char *end) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); ELEMENT_TYPE *ret; if (! name) return NULL; ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (! ret) return NULL; if (ret->name != name) poolDiscard(&dtd->pool); else { poolFinish(&dtd->pool); if (! setElementTypePrefix(parser, ret)) return NULL; } return ret; } static XML_Char * copyString(const XML_Char *s, XML_Parser parser) { size_t charsRequired = 0; XML_Char *result; /* First determine how long the string is */ while (s[charsRequired] != 0) { charsRequired++; } /* Include the terminator */ charsRequired++; /* Now allocate space for the copy */ result = MALLOC(parser, charsRequired * sizeof(XML_Char)); if (result == NULL) return NULL; /* Copy the original into place */ memcpy(result, s, charsRequired * sizeof(XML_Char)); return result; } #if XML_GE == 1 static float accountingGetCurrentAmplification(XML_Parser rootParser) { // 1.........1.........12 => 22 const size_t lenOfShortestInclude = sizeof("") - 1; const XmlBigCount countBytesOutput = rootParser->m_accounting.countBytesDirect + rootParser->m_accounting.countBytesIndirect; const float amplificationFactor = rootParser->m_accounting.countBytesDirect ? ((float)countBytesOutput / (float)(rootParser->m_accounting.countBytesDirect)) : ((float)(lenOfShortestInclude + rootParser->m_accounting.countBytesIndirect) / (float)lenOfShortestInclude); assert(! rootParser->m_parentParser); return amplificationFactor; } static void accountingReportStats(XML_Parser originParser, const char *epilog) { const XML_Parser rootParser = getRootParserOf(originParser, NULL); assert(! rootParser->m_parentParser); if (rootParser->m_accounting.debugLevel == 0u) { return; } const float amplificationFactor = accountingGetCurrentAmplification(rootParser); fprintf(stderr, "expat: Accounting(%p): Direct " EXPAT_FMT_ULL( "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s", (void *)rootParser, rootParser->m_accounting.countBytesDirect, rootParser->m_accounting.countBytesIndirect, (double)amplificationFactor, epilog); } static void accountingOnAbort(XML_Parser originParser) { accountingReportStats(originParser, " ABORTING\n"); } static void accountingReportDiff(XML_Parser rootParser, unsigned int levelsAwayFromRootParser, const char *before, const char *after, ptrdiff_t bytesMore, int source_line, enum XML_Account account) { assert(! rootParser->m_parentParser); fprintf(stderr, " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%u, xmlparse.c:%d) %*s\"", bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", levelsAwayFromRootParser, source_line, 10, ""); const char ellipis[] = "[..]"; const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1; const unsigned int contextLength = 10; /* Note: Performance is of no concern here */ const char *walker = before; if ((rootParser->m_accounting.debugLevel >= 3u) || (after - before) <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) { for (; walker < after; walker++) { fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); } } else { for (; walker < before + contextLength; walker++) { fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); } fprintf(stderr, ellipis); walker = after - contextLength; for (; walker < after; walker++) { fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); } } fprintf(stderr, "\"\n"); } static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, const char *before, const char *after, int source_line, enum XML_Account account) { /* Note: We need to check the token type *first* to be sure that * we can even access variable , safely. * E.g. for XML_TOK_NONE may hold an invalid pointer. */ switch (tok) { case XML_TOK_INVALID: case XML_TOK_PARTIAL: case XML_TOK_PARTIAL_CHAR: case XML_TOK_NONE: return XML_TRUE; } if (account == XML_ACCOUNT_NONE) return XML_TRUE; /* because these bytes have been accounted for, already */ unsigned int levelsAwayFromRootParser; const XML_Parser rootParser = getRootParserOf(originParser, &levelsAwayFromRootParser); assert(! rootParser->m_parentParser); const int isDirect = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser); const ptrdiff_t bytesMore = after - before; XmlBigCount *const additionTarget = isDirect ? &rootParser->m_accounting.countBytesDirect : &rootParser->m_accounting.countBytesIndirect; /* Detect and avoid integer overflow */ if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore) return XML_FALSE; *additionTarget += bytesMore; const XmlBigCount countBytesOutput = rootParser->m_accounting.countBytesDirect + rootParser->m_accounting.countBytesIndirect; const float amplificationFactor = accountingGetCurrentAmplification(rootParser); const XML_Bool tolerated = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes) || (amplificationFactor <= rootParser->m_accounting.maximumAmplificationFactor); if (rootParser->m_accounting.debugLevel >= 2u) { accountingReportStats(rootParser, ""); accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after, bytesMore, source_line, account); } return tolerated; } unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser) { if (! parser) return 0; return parser->m_accounting.countBytesDirect; } unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser) { if (! parser) return 0; return parser->m_accounting.countBytesIndirect; } static void entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, const char *action, int sourceLine) { assert(! rootParser->m_parentParser); if (rootParser->m_entity_stats.debugLevel == 0u) return; # if defined(XML_UNICODE) const char *const entityName = "[..]"; # else const char *const entityName = entity->name; # endif fprintf( stderr, "expat: Entities(%p): Count %9u, depth %2u/%2u %*s%s%s; %s length %d (xmlparse.c:%d)\n", (void *)rootParser, rootParser->m_entity_stats.countEverOpened, rootParser->m_entity_stats.currentDepth, rootParser->m_entity_stats.maximumDepthSeen, ((int)rootParser->m_entity_stats.currentDepth - 1) * 2, "", entity->is_param ? "%" : "&", entityName, action, entity->textLen, sourceLine); } static void entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) { const XML_Parser rootParser = getRootParserOf(originParser, NULL); assert(! rootParser->m_parentParser); rootParser->m_entity_stats.countEverOpened++; rootParser->m_entity_stats.currentDepth++; if (rootParser->m_entity_stats.currentDepth > rootParser->m_entity_stats.maximumDepthSeen) { rootParser->m_entity_stats.maximumDepthSeen++; } entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine); } static void entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) { const XML_Parser rootParser = getRootParserOf(originParser, NULL); assert(! rootParser->m_parentParser); entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine); rootParser->m_entity_stats.currentDepth--; } #endif /* XML_GE == 1 */ static XML_Parser getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) { XML_Parser rootParser = parser; unsigned int stepsTakenUpwards = 0; while (rootParser->m_parentParser) { rootParser = rootParser->m_parentParser; stepsTakenUpwards++; } assert(! rootParser->m_parentParser); if (outLevelDiff != NULL) { *outLevelDiff = stepsTakenUpwards; } return rootParser; } #if XML_GE == 1 const char * unsignedCharToPrintable(unsigned char c) { switch (c) { case 0: return "\\0"; case 1: return "\\x1"; case 2: return "\\x2"; case 3: return "\\x3"; case 4: return "\\x4"; case 5: return "\\x5"; case 6: return "\\x6"; case 7: return "\\x7"; case 8: return "\\x8"; case 9: return "\\t"; case 10: return "\\n"; case 11: return "\\xB"; case 12: return "\\xC"; case 13: return "\\r"; case 14: return "\\xE"; case 15: return "\\xF"; case 16: return "\\x10"; case 17: return "\\x11"; case 18: return "\\x12"; case 19: return "\\x13"; case 20: return "\\x14"; case 21: return "\\x15"; case 22: return "\\x16"; case 23: return "\\x17"; case 24: return "\\x18"; case 25: return "\\x19"; case 26: return "\\x1A"; case 27: return "\\x1B"; case 28: return "\\x1C"; case 29: return "\\x1D"; case 30: return "\\x1E"; case 31: return "\\x1F"; case 32: return " "; case 33: return "!"; case 34: return "\\\""; case 35: return "#"; case 36: return "$"; case 37: return "%"; case 38: return "&"; case 39: return "'"; case 40: return "("; case 41: return ")"; case 42: return "*"; case 43: return "+"; case 44: return ","; case 45: return "-"; case 46: return "."; case 47: return "/"; case 48: return "0"; case 49: return "1"; case 50: return "2"; case 51: return "3"; case 52: return "4"; case 53: return "5"; case 54: return "6"; case 55: return "7"; case 56: return "8"; case 57: return "9"; case 58: return ":"; case 59: return ";"; case 60: return "<"; case 61: return "="; case 62: return ">"; case 63: return "?"; case 64: return "@"; case 65: return "A"; case 66: return "B"; case 67: return "C"; case 68: return "D"; case 69: return "E"; case 70: return "F"; case 71: return "G"; case 72: return "H"; case 73: return "I"; case 74: return "J"; case 75: return "K"; case 76: return "L"; case 77: return "M"; case 78: return "N"; case 79: return "O"; case 80: return "P"; case 81: return "Q"; case 82: return "R"; case 83: return "S"; case 84: return "T"; case 85: return "U"; case 86: return "V"; case 87: return "W"; case 88: return "X"; case 89: return "Y"; case 90: return "Z"; case 91: return "["; case 92: return "\\\\"; case 93: return "]"; case 94: return "^"; case 95: return "_"; case 96: return "`"; case 97: return "a"; case 98: return "b"; case 99: return "c"; case 100: return "d"; case 101: return "e"; case 102: return "f"; case 103: return "g"; case 104: return "h"; case 105: return "i"; case 106: return "j"; case 107: return "k"; case 108: return "l"; case 109: return "m"; case 110: return "n"; case 111: return "o"; case 112: return "p"; case 113: return "q"; case 114: return "r"; case 115: return "s"; case 116: return "t"; case 117: return "u"; case 118: return "v"; case 119: return "w"; case 120: return "x"; case 121: return "y"; case 122: return "z"; case 123: return "{"; case 124: return "|"; case 125: return "}"; case 126: return "~"; case 127: return "\\x7F"; case 128: return "\\x80"; case 129: return "\\x81"; case 130: return "\\x82"; case 131: return "\\x83"; case 132: return "\\x84"; case 133: return "\\x85"; case 134: return "\\x86"; case 135: return "\\x87"; case 136: return "\\x88"; case 137: return "\\x89"; case 138: return "\\x8A"; case 139: return "\\x8B"; case 140: return "\\x8C"; case 141: return "\\x8D"; case 142: return "\\x8E"; case 143: return "\\x8F"; case 144: return "\\x90"; case 145: return "\\x91"; case 146: return "\\x92"; case 147: return "\\x93"; case 148: return "\\x94"; case 149: return "\\x95"; case 150: return "\\x96"; case 151: return "\\x97"; case 152: return "\\x98"; case 153: return "\\x99"; case 154: return "\\x9A"; case 155: return "\\x9B"; case 156: return "\\x9C"; case 157: return "\\x9D"; case 158: return "\\x9E"; case 159: return "\\x9F"; case 160: return "\\xA0"; case 161: return "\\xA1"; case 162: return "\\xA2"; case 163: return "\\xA3"; case 164: return "\\xA4"; case 165: return "\\xA5"; case 166: return "\\xA6"; case 167: return "\\xA7"; case 168: return "\\xA8"; case 169: return "\\xA9"; case 170: return "\\xAA"; case 171: return "\\xAB"; case 172: return "\\xAC"; case 173: return "\\xAD"; case 174: return "\\xAE"; case 175: return "\\xAF"; case 176: return "\\xB0"; case 177: return "\\xB1"; case 178: return "\\xB2"; case 179: return "\\xB3"; case 180: return "\\xB4"; case 181: return "\\xB5"; case 182: return "\\xB6"; case 183: return "\\xB7"; case 184: return "\\xB8"; case 185: return "\\xB9"; case 186: return "\\xBA"; case 187: return "\\xBB"; case 188: return "\\xBC"; case 189: return "\\xBD"; case 190: return "\\xBE"; case 191: return "\\xBF"; case 192: return "\\xC0"; case 193: return "\\xC1"; case 194: return "\\xC2"; case 195: return "\\xC3"; case 196: return "\\xC4"; case 197: return "\\xC5"; case 198: return "\\xC6"; case 199: return "\\xC7"; case 200: return "\\xC8"; case 201: return "\\xC9"; case 202: return "\\xCA"; case 203: return "\\xCB"; case 204: return "\\xCC"; case 205: return "\\xCD"; case 206: return "\\xCE"; case 207: return "\\xCF"; case 208: return "\\xD0"; case 209: return "\\xD1"; case 210: return "\\xD2"; case 211: return "\\xD3"; case 212: return "\\xD4"; case 213: return "\\xD5"; case 214: return "\\xD6"; case 215: return "\\xD7"; case 216: return "\\xD8"; case 217: return "\\xD9"; case 218: return "\\xDA"; case 219: return "\\xDB"; case 220: return "\\xDC"; case 221: return "\\xDD"; case 222: return "\\xDE"; case 223: return "\\xDF"; case 224: return "\\xE0"; case 225: return "\\xE1"; case 226: return "\\xE2"; case 227: return "\\xE3"; case 228: return "\\xE4"; case 229: return "\\xE5"; case 230: return "\\xE6"; case 231: return "\\xE7"; case 232: return "\\xE8"; case 233: return "\\xE9"; case 234: return "\\xEA"; case 235: return "\\xEB"; case 236: return "\\xEC"; case 237: return "\\xED"; case 238: return "\\xEE"; case 239: return "\\xEF"; case 240: return "\\xF0"; case 241: return "\\xF1"; case 242: return "\\xF2"; case 243: return "\\xF3"; case 244: return "\\xF4"; case 245: return "\\xF5"; case 246: return "\\xF6"; case 247: return "\\xF7"; case 248: return "\\xF8"; case 249: return "\\xF9"; case 250: return "\\xFA"; case 251: return "\\xFB"; case 252: return "\\xFC"; case 253: return "\\xFD"; case 254: return "\\xFE"; case 255: return "\\xFF"; // LCOV_EXCL_START default: assert(0); /* never gets here */ return "dead code"; } assert(0); /* never gets here */ // LCOV_EXCL_STOP } #endif /* XML_GE == 1 */ static unsigned long getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) { const char *const valueOrNull = getenv(variableName); if (valueOrNull == NULL) { return defaultDebugLevel; } const char *const value = valueOrNull; errno = 0; char *afterValue = NULL; unsigned long debugLevel = strtoul(value, &afterValue, 10); if ((errno != 0) || (afterValue == value) || (afterValue[0] != '\0')) { errno = 0; return defaultDebugLevel; } return debugLevel; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmlrole.c000066400000000000000000001052701516712004000261460ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Greg Stein Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2002-2003 Fred L. Drake, Jr. Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2019 David Loffredo Copyright (c) 2021 Donghee Na Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "expat_config.h" #include #ifdef _WIN32 # include "winconfig.h" #endif #include "internal.h" #include "xmlrole.h" #include "ascii.h" /* Doesn't check: that ,| are not mixed in a model group content of literals */ static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'}; static const char KW_ATTLIST[] = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'}; static const char KW_CDATA[] = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_DOCTYPE[] = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'}; static const char KW_ELEMENT[] = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'}; static const char KW_EMPTY[] = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'}; static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0'}; static const char KW_ENTITY[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; static const char KW_FIXED[] = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'}; static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'}; static const char KW_IDREF[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; static const char KW_IDREFS[] = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; #ifdef XML_DTD static const char KW_IGNORE[] = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'}; #endif static const char KW_IMPLIED[] = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'}; #ifdef XML_DTD static const char KW_INCLUDE[] = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'}; #endif static const char KW_NDATA[] = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_NMTOKEN[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0'}; static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0'}; static const char KW_PCDATA[] = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; static const char KW_PUBLIC[] = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'}; static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0'}; static const char KW_SYSTEM[] = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'}; #ifndef MIN_BYTES_PER_CHAR # define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif #ifdef XML_DTD # define setTopLevel(state) \ ((state)->handler \ = ((state)->documentEntity ? internalSubset : externalSubset1)) #else /* not XML_DTD */ # define setTopLevel(state) ((state)->handler = internalSubset) #endif /* not XML_DTD */ typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc); static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10, notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, attlist9, element0, element1, element2, element3, element4, element5, element6, element7, #ifdef XML_DTD externalSubset0, externalSubset1, condSect0, condSect1, condSect2, #endif /* XML_DTD */ declClose, error; static int FASTCALL common(PROLOG_STATE *state, int tok); static int PTRCALL prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: state->handler = prolog1; return XML_ROLE_NONE; case XML_TOK_XML_DECL: state->handler = prolog1; return XML_ROLE_XML_DECL; case XML_TOK_PI: state->handler = prolog1; return XML_ROLE_PI; case XML_TOK_COMMENT: state->handler = prolog1; return XML_ROLE_COMMENT; case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_BOM: /* This case can never arise. To reach this role function, the * parse must have passed through prolog0 and therefore have had * some form of input, even if only a space. At that point, a * byte order mark is no longer a valid character (though * technically it should be interpreted as a non-breaking space), * so will be rejected by the tokenizing stages. */ return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ case XML_TOK_DECL_OPEN: if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_DOCTYPE)) break; state->handler = doctype0; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return common(state, tok); } static int PTRCALL doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = doctype1; return XML_ROLE_DOCTYPE_NAME; } return common(state, tok); } static int PTRCALL doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = doctype3; return XML_ROLE_DOCTYPE_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = doctype2; return XML_ROLE_DOCTYPE_NONE; } break; } return common(state, tok); } static int PTRCALL doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_LITERAL: state->handler = doctype3; return XML_ROLE_DOCTYPE_PUBLIC_ID; } return common(state, tok); } static int PTRCALL doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_LITERAL: state->handler = doctype4; return XML_ROLE_DOCTYPE_SYSTEM_ID; } return common(state, tok); } static int PTRCALL doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return common(state, tok); } static int PTRCALL doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_DOCTYPE_NONE; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return common(state, tok); } static int PTRCALL internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ENTITY)) { state->handler = entity0; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ATTLIST)) { state->handler = attlist0; return XML_ROLE_ATTLIST_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_ELEMENT)) { state->handler = element0; return XML_ROLE_ELEMENT_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, KW_NOTATION)) { state->handler = notation0; return XML_ROLE_NOTATION_NONE; } break; case XML_TOK_PI: return XML_ROLE_PI; case XML_TOK_COMMENT: return XML_ROLE_COMMENT; case XML_TOK_PARAM_ENTITY_REF: return XML_ROLE_PARAM_ENTITY_REF; case XML_TOK_CLOSE_BRACKET: state->handler = doctype5; return XML_ROLE_DOCTYPE_NONE; case XML_TOK_NONE: return XML_ROLE_NONE; } return common(state, tok); } #ifdef XML_DTD static int PTRCALL externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { state->handler = externalSubset1; if (tok == XML_TOK_XML_DECL) return XML_ROLE_TEXT_DECL; return externalSubset1(state, tok, ptr, end, enc); } static int PTRCALL externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_COND_SECT_OPEN: state->handler = condSect0; return XML_ROLE_NONE; case XML_TOK_COND_SECT_CLOSE: if (state->includeLevel == 0) break; state->includeLevel -= 1; return XML_ROLE_NONE; case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_BRACKET: break; case XML_TOK_NONE: if (state->includeLevel) break; return XML_ROLE_NONE; default: return internalSubset(state, tok, ptr, end, enc); } return common(state, tok); } #endif /* XML_DTD */ static int PTRCALL entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_PERCENT: state->handler = entity1; return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = entity2; return XML_ROLE_GENERAL_ENTITY_NAME; } return common(state, tok); } static int PTRCALL entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = entity7; return XML_ROLE_PARAM_ENTITY_NAME; } return common(state, tok); } static int PTRCALL entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = entity4; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = entity3; return XML_ROLE_ENTITY_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_VALUE; } return common(state, tok); } static int PTRCALL entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity4; return XML_ROLE_ENTITY_PUBLIC_ID; } return common(state, tok); } static int PTRCALL entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity5; return XML_ROLE_ENTITY_SYSTEM_ID; } return common(state, tok); } static int PTRCALL entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ENTITY_COMPLETE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { state->handler = entity6; return XML_ROLE_ENTITY_NONE; } break; } return common(state, tok); } static int PTRCALL entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_NOTATION_NAME; } return common(state, tok); } static int PTRCALL entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = entity9; return XML_ROLE_ENTITY_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = entity8; return XML_ROLE_ENTITY_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_ENTITY_NONE; return XML_ROLE_ENTITY_VALUE; } return common(state, tok); } static int PTRCALL entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity9; return XML_ROLE_ENTITY_PUBLIC_ID; } return common(state, tok); } static int PTRCALL entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_LITERAL: state->handler = entity10; return XML_ROLE_ENTITY_SYSTEM_ID; } return common(state, tok); } static int PTRCALL entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ENTITY_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ENTITY_COMPLETE; } return common(state, tok); } static int PTRCALL notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_NAME: state->handler = notation1; return XML_ROLE_NOTATION_NAME; } return common(state, tok); } static int PTRCALL notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { state->handler = notation3; return XML_ROLE_NOTATION_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { state->handler = notation2; return XML_ROLE_NOTATION_NONE; } break; } return common(state, tok); } static int PTRCALL notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = notation4; return XML_ROLE_NOTATION_PUBLIC_ID; } return common(state, tok); } static int PTRCALL notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_NOTATION_NONE; return XML_ROLE_NOTATION_SYSTEM_ID; } return common(state, tok); } static int PTRCALL notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NOTATION_NONE; case XML_TOK_LITERAL: state->handler = declClose; state->role_none = XML_ROLE_NOTATION_NONE; return XML_ROLE_NOTATION_SYSTEM_ID; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_NOTATION_NO_SYSTEM_ID; } return common(state, tok); } static int PTRCALL attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist1; return XML_ROLE_ATTLIST_ELEMENT_NAME; } return common(state, tok); } static int PTRCALL attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_DECL_CLOSE: setTopLevel(state); return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist2; return XML_ROLE_ATTRIBUTE_NAME; } return common(state, tok); } static int PTRCALL attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: { static const char *const types[] = { KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS, KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS, }; int i; for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { state->handler = attlist8; return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; } } if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { state->handler = attlist5; return XML_ROLE_ATTLIST_NONE; } break; case XML_TOK_OPEN_PAREN: state->handler = attlist3; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NMTOKEN: case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist4; return XML_ROLE_ATTRIBUTE_ENUM_VALUE; } return common(state, tok); } static int PTRCALL attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_ATTLIST_NONE; case XML_TOK_OR: state->handler = attlist3; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_OPEN_PAREN: state->handler = attlist6; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } static int PTRCALL attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_NAME: state->handler = attlist7; return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; } return common(state, tok); } static int PTRCALL attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_ATTLIST_NONE; case XML_TOK_OR: state->handler = attlist6; return XML_ROLE_ATTLIST_NONE; } return common(state, tok); } /* default value */ static int PTRCALL attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_IMPLIED)) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_REQUIRED)) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_FIXED)) { state->handler = attlist9; return XML_ROLE_ATTLIST_NONE; } break; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; } return common(state, tok); } static int PTRCALL attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ATTLIST_NONE; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_FIXED_ATTRIBUTE_VALUE; } return common(state, tok); } static int PTRCALL element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element1; return XML_ROLE_ELEMENT_NAME; } return common(state, tok); } static int PTRCALL element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_CONTENT_EMPTY; } if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_CONTENT_ANY; } break; case XML_TOK_OPEN_PAREN: state->handler = element2; state->level = 1; return XML_ROLE_GROUP_OPEN; } return common(state, tok); } static int PTRCALL element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, KW_PCDATA)) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; } break; case XML_TOK_OPEN_PAREN: state->level = 2; state->handler = element6; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return common(state, tok); } static int PTRCALL element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_ELEMENT_NONE; } return common(state, tok); } static int PTRCALL element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element5; return XML_ROLE_CONTENT_ELEMENT; } return common(state, tok); } static int PTRCALL element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_ELEMENT_NONE; } return common(state, tok); } static int PTRCALL element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_OPEN_PAREN: state->level += 1; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return common(state, tok); } static int PTRCALL element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_ELEMENT_NONE; case XML_TOK_CLOSE_PAREN: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_CLOSE_PAREN_QUESTION: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_OPT; case XML_TOK_CLOSE_PAREN_PLUS: state->level -= 1; if (state->level == 0) { state->handler = declClose; state->role_none = XML_ROLE_ELEMENT_NONE; } return XML_ROLE_GROUP_CLOSE_PLUS; case XML_TOK_COMMA: state->handler = element6; return XML_ROLE_GROUP_SEQUENCE; case XML_TOK_OR: state->handler = element6; return XML_ROLE_GROUP_CHOICE; } return common(state, tok); } #ifdef XML_DTD static int PTRCALL condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { state->handler = condSect1; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { state->handler = condSect2; return XML_ROLE_NONE; } break; } return common(state, tok); } static int PTRCALL condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = externalSubset1; state->includeLevel += 1; return XML_ROLE_NONE; } return common(state, tok); } static int PTRCALL condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = externalSubset1; return XML_ROLE_IGNORE_SECT; } return common(state, tok); } #endif /* XML_DTD */ static int PTRCALL declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); switch (tok) { case XML_TOK_PROLOG_S: return state->role_none; case XML_TOK_DECL_CLOSE: setTopLevel(state); return state->role_none; } return common(state, tok); } /* This function will only be invoked if the internal logic of the * parser has broken down. It is used in two cases: * * 1: When the XML prolog has been finished. At this point the * processor (the parser level above these role handlers) should * switch from prologProcessor to contentProcessor and reinitialise * the handler function. * * 2: When an error has been detected (via common() below). At this * point again the processor should be switched to errorProcessor, * which will never call a handler. * * The result of this is that error() can only be called if the * processor switch failed to happen, which is an internal error and * therefore we shouldn't be able to provoke it simply by using the * library. It is a necessary backstop, however, so we merely exclude * it from the coverage statistics. * * LCOV_EXCL_START */ static int PTRCALL error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { UNUSED_P(state); UNUSED_P(tok); UNUSED_P(ptr); UNUSED_P(end); UNUSED_P(enc); return XML_ROLE_NONE; } /* LCOV_EXCL_STOP */ static int FASTCALL common(PROLOG_STATE *state, int tok) { #ifdef XML_DTD if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) return XML_ROLE_INNER_PARAM_ENTITY_REF; #else UNUSED_P(tok); #endif state->handler = error; return XML_ROLE_ERROR; } void XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; #ifdef XML_DTD state->documentEntity = 1; state->includeLevel = 0; state->inEntityValue = 0; #endif /* XML_DTD */ } #ifdef XML_DTD void XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { state->handler = externalSubset0; state->documentEntity = 0; state->includeLevel = 0; } #endif /* XML_DTD */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmlrole.h000066400000000000000000000105511516712004000261500ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Karl Waclawek Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2017-2025 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef XmlRole_INCLUDED # define XmlRole_INCLUDED 1 # include "xmltok.h" # ifdef __cplusplus extern "C" { # endif enum { XML_ROLE_ERROR = -1, XML_ROLE_NONE = 0, XML_ROLE_XML_DECL, XML_ROLE_INSTANCE_START, XML_ROLE_DOCTYPE_NONE, XML_ROLE_DOCTYPE_NAME, XML_ROLE_DOCTYPE_SYSTEM_ID, XML_ROLE_DOCTYPE_PUBLIC_ID, XML_ROLE_DOCTYPE_INTERNAL_SUBSET, XML_ROLE_DOCTYPE_CLOSE, XML_ROLE_GENERAL_ENTITY_NAME, XML_ROLE_PARAM_ENTITY_NAME, XML_ROLE_ENTITY_NONE, XML_ROLE_ENTITY_VALUE, XML_ROLE_ENTITY_SYSTEM_ID, XML_ROLE_ENTITY_PUBLIC_ID, XML_ROLE_ENTITY_COMPLETE, XML_ROLE_ENTITY_NOTATION_NAME, XML_ROLE_NOTATION_NONE, XML_ROLE_NOTATION_NAME, XML_ROLE_NOTATION_SYSTEM_ID, XML_ROLE_NOTATION_NO_SYSTEM_ID, XML_ROLE_NOTATION_PUBLIC_ID, XML_ROLE_ATTRIBUTE_NAME, XML_ROLE_ATTRIBUTE_TYPE_CDATA, XML_ROLE_ATTRIBUTE_TYPE_ID, XML_ROLE_ATTRIBUTE_TYPE_IDREF, XML_ROLE_ATTRIBUTE_TYPE_IDREFS, XML_ROLE_ATTRIBUTE_TYPE_ENTITY, XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, XML_ROLE_ATTRIBUTE_ENUM_VALUE, XML_ROLE_ATTRIBUTE_NOTATION_VALUE, XML_ROLE_ATTLIST_NONE, XML_ROLE_ATTLIST_ELEMENT_NAME, XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, XML_ROLE_FIXED_ATTRIBUTE_VALUE, XML_ROLE_ELEMENT_NONE, XML_ROLE_ELEMENT_NAME, XML_ROLE_CONTENT_ANY, XML_ROLE_CONTENT_EMPTY, XML_ROLE_CONTENT_PCDATA, XML_ROLE_GROUP_OPEN, XML_ROLE_GROUP_CLOSE, XML_ROLE_GROUP_CLOSE_REP, XML_ROLE_GROUP_CLOSE_OPT, XML_ROLE_GROUP_CLOSE_PLUS, XML_ROLE_GROUP_CHOICE, XML_ROLE_GROUP_SEQUENCE, XML_ROLE_CONTENT_ELEMENT, XML_ROLE_CONTENT_ELEMENT_REP, XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, XML_ROLE_PI, XML_ROLE_COMMENT, # ifdef XML_DTD XML_ROLE_TEXT_DECL, XML_ROLE_IGNORE_SECT, XML_ROLE_INNER_PARAM_ENTITY_REF, # endif /* XML_DTD */ XML_ROLE_PARAM_ENTITY_REF }; typedef struct prolog_state { int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr, const char *end, const ENCODING *enc); unsigned level; int role_none; # ifdef XML_DTD unsigned includeLevel; int documentEntity; int inEntityValue; # endif /* XML_DTD */ } PROLOG_STATE; void XmlPrologStateInit(PROLOG_STATE *state); # ifdef XML_DTD void XmlPrologStateInitExternalEntity(PROLOG_STATE *state); # endif /* XML_DTD */ # define XmlTokenRole(state, tok, ptr, end, enc) \ (((state)->handler)(state, tok, ptr, end, enc)) # ifdef __cplusplus } # endif #endif /* not XmlRole_INCLUDED */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmltok.c000066400000000000000000001521731516712004000260060ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2001-2003 Fred L. Drake, Jr. Copyright (c) 2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Don Lewis Copyright (c) 2017 Rhodri James Copyright (c) 2017 Alexander Bluhm Copyright (c) 2017 Benbuck Nason Copyright (c) 2017 José Gutiérrez de la Concha Copyright (c) 2019 David Loffredo Copyright (c) 2021 Donghee Na Copyright (c) 2022 Martin Ettl Copyright (c) 2022 Sean McBride Copyright (c) 2023 Hanno Böck Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "expat_config.h" #include #include /* memcpy */ #include #ifdef _WIN32 # include "winconfig.h" #endif #include "internal.h" #include "xmltok.h" #include "nametab.h" #ifdef XML_DTD # define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) #else # define IGNORE_SECTION_TOK_VTABLE /* as nothing */ #endif #define VTABLE1 \ {PREFIX(prologTok), PREFIX(contentTok), \ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \ PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \ PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \ PREFIX(updatePosition), PREFIX(isPublicId) #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING2(pages, byte) \ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ & (1u << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING3(pages, byte) \ (namingBitmap \ [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ << 3) \ + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ & (1u << (((byte)[2]) & 0x1F))) /* Detection of invalid UTF-8 sequences is based on Table 3.1B of Unicode 3.2: https://www.unicode.org/unicode/reports/tr28/ with the additional restriction of not allowing the Unicode code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). Implementation details: (A & 0x80) == 0 means A < 0x80 and (A & 0xC0) == 0xC0 means A > 0xBF */ #define UTF8_INVALID2(p) \ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) #define UTF8_INVALID3(p) \ (((p)[2] & 0x80) == 0 \ || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ : ((p)[2] & 0xC0) == 0xC0) \ || ((*p) == 0xE0 \ ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ : ((p)[1] & 0x80) == 0 \ || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) #define UTF8_INVALID4(p) \ (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ || ((p)[2] & 0xC0) == 0xC0 \ || ((*p) == 0xF0 \ ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ : ((p)[1] & 0x80) == 0 \ || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL isNever(const ENCODING *enc, const char *p) { UNUSED_P(enc); UNUSED_P(p); return 0; } static int PTRFASTCALL utf8_isName2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL utf8_isName3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); } #define utf8_isName4 isNever static int PTRFASTCALL utf8_isNmstrt2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL utf8_isNmstrt3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); } #define utf8_isNmstrt4 isNever static int PTRFASTCALL utf8_isInvalid2(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL utf8_isInvalid3(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL utf8_isInvalid4(const ENCODING *enc, const char *p) { UNUSED_P(enc); return UTF8_INVALID4((const unsigned char *)p); } struct normal_encoding { ENCODING enc; unsigned char type[256]; #ifdef XML_MIN_SIZE int(PTRFASTCALL *byteType)(const ENCODING *, const char *); int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); int(PTRCALL *charMatches)(const ENCODING *, const char *, int); #endif /* XML_MIN_SIZE */ int(PTRFASTCALL *isName2)(const ENCODING *, const char *); int(PTRFASTCALL *isName3)(const ENCODING *, const char *); int(PTRFASTCALL *isName4)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); }; #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) #ifdef XML_MIN_SIZE # define STANDARD_VTABLE(E) \ E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, #else # define STANDARD_VTABLE(E) /* as nothing */ #endif #define NORMAL_VTABLE(E) \ E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 #define NULL_VTABLE \ /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL static int FASTCALL checkCharRefNumber(int result); #include "xmltok_impl.h" #include "ascii.h" #ifdef XML_MIN_SIZE # define sb_isNameMin isNever # define sb_isNmstrtMin isNever #endif #ifdef XML_MIN_SIZE # define MINBPC(enc) ((enc)->minBytesPerChar) #else /* minimum bytes per character */ # define MINBPC(enc) 1 #endif #define SB_BYTE_TYPE(enc, p) \ (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) #ifdef XML_MIN_SIZE static int PTRFASTCALL sb_byteType(const ENCODING *enc, const char *p) { return SB_BYTE_TYPE(enc, p); } # define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) #else # define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) #endif #ifdef XML_MIN_SIZE # define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) static int PTRFASTCALL sb_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return *p; } #else # define BYTE_TO_ASCII(enc, p) (*(p)) #endif #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) #ifdef XML_MIN_SIZE # define IS_INVALID_CHAR(enc, p, n) \ (AS_NORMAL_ENCODING(enc)->isInvalid##n \ && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) #else # define IS_INVALID_CHAR(enc, p, n) \ (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) #endif #ifdef XML_MIN_SIZE # define IS_NAME_CHAR_MINBPC(enc, p) \ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) # define IS_NMSTRT_CHAR_MINBPC(enc, p) \ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) #else # define IS_NAME_CHAR_MINBPC(enc, p) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) #endif #ifdef XML_MIN_SIZE # define CHAR_MATCHES(enc, p, c) \ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) static int PTRCALL sb_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return *p == c; } #else /* c is an ASCII character */ # define CHAR_MATCHES(enc, p, c) (*(p) == (c)) #endif #define PREFIX(ident) normal_##ident #define XML_TOK_IMPL_C #include "xmltok_impl.c" #undef XML_TOK_IMPL_C #undef MINBPC #undef BYTE_TYPE #undef BYTE_TO_ASCII #undef CHAR_MATCHES #undef IS_NAME_CHAR #undef IS_NAME_CHAR_MINBPC #undef IS_NMSTRT_CHAR #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ UTF8_cval1 = 0x00, UTF8_cval2 = 0xc0, UTF8_cval3 = 0xe0, UTF8_cval4 = 0xf0 }; void _INTERNAL_trim_to_complete_utf8_characters(const char *from, const char **fromLimRef) { const char *fromLim = *fromLimRef; size_t walked = 0; for (; fromLim > from; fromLim--, walked++) { const unsigned char prev = (unsigned char)fromLim[-1]; if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ if (walked + 1 >= 4) { fromLim += 4 - 1; break; } else { walked = 0; } } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ if (walked + 1 >= 3) { fromLim += 3 - 1; break; } else { walked = 0; } } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ if (walked + 1 >= 2) { fromLim += 2 - 1; break; } else { walked = 0; } } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ break; } } *fromLimRef = fromLim; } static enum XML_Convert_Result PTRCALL utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { bool input_incomplete = false; bool output_exhausted = false; /* Avoid copying partial characters (due to limited space). */ const ptrdiff_t bytesAvailable = fromLim - *fromP; const ptrdiff_t bytesStorable = toLim - *toP; UNUSED_P(enc); if (bytesAvailable > bytesStorable) { fromLim = *fromP + bytesStorable; output_exhausted = true; } /* Avoid copying partial characters (from incomplete input). */ { const char *const fromLimBefore = fromLim; _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); if (fromLim < fromLimBefore) { input_incomplete = true; } } { const ptrdiff_t bytesToCopy = fromLim - *fromP; memcpy(*toP, *fromP, bytesToCopy); *fromP += bytesToCopy; *toP += bytesToCopy; } if (output_exhausted) /* needs to go first */ return XML_CONVERT_OUTPUT_EXHAUSTED; else if (input_incomplete) return XML_CONVERT_INPUT_INCOMPLETE; else return XML_CONVERT_COMPLETED; } static enum XML_Convert_Result PTRCALL utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { enum XML_Convert_Result res = XML_CONVERT_COMPLETED; unsigned short *to = *toP; const char *from = *fromP; while (from < fromLim && to < toLim) { switch (SB_BYTE_TYPE(enc, from)) { case BT_LEAD2: if (fromLim - from < 2) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; break; case BT_LEAD3: if (fromLim - from < 3) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); from += 3; break; case BT_LEAD4: { unsigned long n; if (toLim - to < 2) { res = XML_CONVERT_OUTPUT_EXHAUSTED; goto after; } if (fromLim - from < 4) { res = XML_CONVERT_INPUT_INCOMPLETE; goto after; } n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000; to[0] = (unsigned short)((n >> 10) | 0xD800); to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); to += 2; from += 4; } break; default: *to++ = *from++; break; } } if (from < fromLim) res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to; return res; } #ifdef XML_NS static const struct normal_encoding utf8_encoding_ns = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { # include "asciitab.h" # include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif static const struct normal_encoding utf8_encoding = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #ifdef XML_NS static const struct normal_encoding internal_utf8_encoding_ns = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { # include "iasciitab.h" # include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; #endif static const struct normal_encoding internal_utf8_encoding = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; static enum XML_Convert_Result PTRCALL latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { UNUSED_P(enc); for (;;) { unsigned char c; if (*fromP == fromLim) return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2) return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim) return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; } } } static enum XML_Convert_Result PTRCALL latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = (unsigned char)*(*fromP)++; if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } #ifdef XML_NS static const struct normal_encoding latin1_encoding_ns = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif static const struct normal_encoding latin1_encoding = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(sb_) NULL_VTABLE}; static enum XML_Convert_Result PTRCALL ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { UNUSED_P(enc); while (*fromP < fromLim && *toP < toLim) *(*toP)++ = *(*fromP)++; if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } #ifdef XML_NS static const struct normal_encoding ascii_encoding_ns = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, { # include "asciitab.h" /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) NULL_VTABLE}; #endif static const struct normal_encoding ascii_encoding = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) NULL_VTABLE}; static int PTRFASTCALL unicode_byte_type(char hi, char lo) { switch ((unsigned char)hi) { /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */ case 0xD8: case 0xD9: case 0xDA: case 0xDB: return BT_LEAD4; /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */ case 0xDC: case 0xDD: case 0xDE: case 0xDF: return BT_TRAIL; case 0xFF: switch ((unsigned char)lo) { case 0xFF: /* noncharacter-FFFF */ case 0xFE: /* noncharacter-FFFE */ return BT_NONXML; } break; } return BT_NONASCII; } #define DEFINE_UTF16_TO_UTF8(E) \ static enum XML_Convert_Result PTRCALL E##toUtf8( \ const ENCODING *enc, const char **fromP, const char *fromLim, \ char **toP, const char *toLim) { \ const char *from = *fromP; \ UNUSED_P(enc); \ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ for (; from < fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \ unsigned char hi = GET_HI(from); \ switch (hi) { \ case 0: \ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = lo; \ break; \ } \ /* fall through */ \ case 0x1: \ case 0x2: \ case 0x3: \ case 0x4: \ case 0x5: \ case 0x6: \ case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ default: \ if (toLim - *toP < 3) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ case 0xD8: \ case 0xD9: \ case 0xDA: \ case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ if (fromLim - from < 4) { \ *fromP = from; \ return XML_CONVERT_INPUT_INCOMPLETE; \ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ from += 2; \ lo2 = GET_LO(from); \ *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ | (lo2 >> 6) | 0x80); \ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ break; \ } \ } \ *fromP = from; \ if (from < fromLim) \ return XML_CONVERT_INPUT_INCOMPLETE; \ else \ return XML_CONVERT_COMPLETED; \ } #define DEFINE_UTF16_TO_UTF16(E) \ static enum XML_Convert_Result PTRCALL E##toUtf16( \ const ENCODING *enc, const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) { \ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ UNUSED_P(enc); \ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ fromLim -= 2; \ res = XML_CONVERT_INPUT_INCOMPLETE; \ } \ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ if ((*toP == toLim) && (*fromP < fromLim)) \ return XML_CONVERT_OUTPUT_EXHAUSTED; \ else \ return res; \ } #define GET_LO(ptr) ((unsigned char)(ptr)[0]) #define GET_HI(ptr) ((unsigned char)(ptr)[1]) DEFINE_UTF16_TO_UTF8(little2_) DEFINE_UTF16_TO_UTF16(little2_) #undef GET_LO #undef GET_HI #define GET_LO(ptr) ((unsigned char)(ptr)[1]) #define GET_HI(ptr) ((unsigned char)(ptr)[0]) DEFINE_UTF16_TO_UTF8(big2_) DEFINE_UTF16_TO_UTF16(big2_) #undef GET_LO #undef GET_HI #define LITTLE2_BYTE_TYPE(enc, p) \ ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0])) #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) #ifdef XML_MIN_SIZE static int PTRFASTCALL little2_byteType(const ENCODING *enc, const char *p) { return LITTLE2_BYTE_TYPE(enc, p); } static int PTRFASTCALL little2_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_BYTE_TO_ASCII(p); } static int PTRCALL little2_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return LITTLE2_CHAR_MATCHES(p, c); } static int PTRFASTCALL little2_isNameMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL little2_isNmstrtMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); } # undef VTABLE # define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 #else /* not XML_MIN_SIZE */ # undef PREFIX # define PREFIX(ident) little2_##ident # define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ # define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) # define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) # define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) # define IS_NAME_CHAR(enc, p, n) 0 # define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) # define IS_NMSTRT_CHAR(enc, p, n) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) # define XML_TOK_IMPL_C # include "xmltok_impl.c" # undef XML_TOK_IMPL_C # undef MINBPC # undef BYTE_TYPE # undef BYTE_TO_ASCII # undef CHAR_MATCHES # undef IS_NAME_CHAR # undef IS_NAME_CHAR_MINBPC # undef IS_NMSTRT_CHAR # undef IS_NMSTRT_CHAR_MINBPC # undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding little2_encoding_ns = {{VTABLE, 2, 0, # if BYTEORDER == 1234 1 # else 0 # endif }, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif static const struct normal_encoding little2_encoding = {{VTABLE, 2, 0, #if BYTEORDER == 1234 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #if BYTEORDER != 4321 # ifdef XML_NS static const struct normal_encoding internal_little2_encoding_ns = {{VTABLE, 2, 0, 1}, { # include "iasciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; # endif static const struct normal_encoding internal_little2_encoding = {{VTABLE, 2, 0, 1}, { # define BT_COLON BT_NMSTRT # include "iasciitab.h" # undef BT_COLON # include "latin1tab.h" }, STANDARD_VTABLE(little2_) NULL_VTABLE}; #endif #define BIG2_BYTE_TYPE(enc, p) \ ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1])) #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) #define BIG2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) #ifdef XML_MIN_SIZE static int PTRFASTCALL big2_byteType(const ENCODING *enc, const char *p) { return BIG2_BYTE_TYPE(enc, p); } static int PTRFASTCALL big2_byteToAscii(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_BYTE_TO_ASCII(p); } static int PTRCALL big2_charMatches(const ENCODING *enc, const char *p, int c) { UNUSED_P(enc); return BIG2_CHAR_MATCHES(p, c); } static int PTRFASTCALL big2_isNameMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_IS_NAME_CHAR_MINBPC(p); } static int PTRFASTCALL big2_isNmstrtMin(const ENCODING *enc, const char *p) { UNUSED_P(enc); return BIG2_IS_NMSTRT_CHAR_MINBPC(p); } # undef VTABLE # define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 #else /* not XML_MIN_SIZE */ # undef PREFIX # define PREFIX(ident) big2_##ident # define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ # define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) # define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) # define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) # define IS_NAME_CHAR(enc, p, n) 0 # define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) # define IS_NMSTRT_CHAR(enc, p, n) (0) # define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) # define XML_TOK_IMPL_C # include "xmltok_impl.c" # undef XML_TOK_IMPL_C # undef MINBPC # undef BYTE_TYPE # undef BYTE_TO_ASCII # undef CHAR_MATCHES # undef IS_NAME_CHAR # undef IS_NAME_CHAR_MINBPC # undef IS_NMSTRT_CHAR # undef IS_NMSTRT_CHAR_MINBPC # undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding big2_encoding_ns = {{VTABLE, 2, 0, # if BYTEORDER == 4321 1 # else 0 # endif }, { # include "asciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif static const struct normal_encoding big2_encoding = {{VTABLE, 2, 0, #if BYTEORDER == 4321 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #if BYTEORDER != 1234 # ifdef XML_NS static const struct normal_encoding internal_big2_encoding_ns = {{VTABLE, 2, 0, 1}, { # include "iasciitab.h" # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; # endif static const struct normal_encoding internal_big2_encoding = {{VTABLE, 2, 0, 1}, { # define BT_COLON BT_NMSTRT # include "iasciitab.h" # undef BT_COLON # include "latin1tab.h" }, STANDARD_VTABLE(big2_) NULL_VTABLE}; #endif #undef PREFIX static int FASTCALL streqci(const char *s1, const char *s2) { for (;;) { char c1 = *s1++; char c2 = *s2++; if (ASCII_a <= c1 && c1 <= ASCII_z) c1 += ASCII_A - ASCII_a; if (ASCII_a <= c2 && c2 <= ASCII_z) /* The following line will never get executed. streqci() is * only called from two places, both of which guarantee to put * upper-case strings into s2. */ c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ if (c1 != c2) return 0; if (! c1) break; } return 1; } static void PTRCALL initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { UNUSED_P(enc); normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); } static int toAscii(const ENCODING *enc, const char *ptr, const char *end) { char buf[1]; char *p = buf; XmlUtf8Convert(enc, &ptr, end, &p, p + 1); if (p == buf) return -1; else return buf[0]; } static int FASTCALL isSpace(int c) { switch (c) { case 0x20: case 0xD: case 0xA: case 0x9: return 1; } return 0; } /* Return 1 if there's just optional white space or there's an S followed by name=val. */ static int parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, const char **namePtr, const char **nameEndPtr, const char **valPtr, const char **nextTokPtr) { int c; char open; if (ptr == end) { *namePtr = NULL; return 1; } if (! isSpace(toAscii(enc, ptr, end))) { *nextTokPtr = ptr; return 0; } do { ptr += enc->minBytesPerChar; } while (isSpace(toAscii(enc, ptr, end))); if (ptr == end) { *namePtr = NULL; return 1; } *namePtr = ptr; for (;;) { c = toAscii(enc, ptr, end); if (c == -1) { *nextTokPtr = ptr; return 0; } if (c == ASCII_EQUALS) { *nameEndPtr = ptr; break; } if (isSpace(c)) { *nameEndPtr = ptr; do { ptr += enc->minBytesPerChar; } while (isSpace(c = toAscii(enc, ptr, end))); if (c != ASCII_EQUALS) { *nextTokPtr = ptr; return 0; } break; } ptr += enc->minBytesPerChar; } if (ptr == *namePtr) { *nextTokPtr = ptr; return 0; } ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); while (isSpace(c)) { ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); } if (c != ASCII_QUOT && c != ASCII_APOS) { *nextTokPtr = ptr; return 0; } open = (char)c; ptr += enc->minBytesPerChar; *valPtr = ptr; for (;; ptr += enc->minBytesPerChar) { c = toAscii(enc, ptr, end); if (c == open) break; if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { *nextTokPtr = ptr; return 0; } } *nextTokPtr = ptr + enc->minBytesPerChar; return 1; } static const char KW_version[] = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'}; static const char KW_standalone[] = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; static int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, const char *), int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { const char *val = NULL; const char *name = NULL; const char *nameEnd = NULL; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || ! name) { *badPtr = ptr; return 0; } if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { if (! isGeneralTextEntity) { *badPtr = name; return 0; } } else { if (versionPtr) *versionPtr = val; if (versionEndPtr) *versionEndPtr = ptr; if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (! name) { if (isGeneralTextEntity) { /* a TextDecl must have an EncodingDecl */ *badPtr = ptr; return 0; } return 1; } } if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { int c = toAscii(enc, val, end); if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { *badPtr = val; return 0; } if (encodingName) *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { *badPtr = ptr; return 0; } if (! name) return 1; } if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) { *badPtr = name; return 0; } if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { if (standalone) *standalone = 1; } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { if (standalone) *standalone = 0; } else { *badPtr = val; return 0; } while (isSpace(toAscii(enc, ptr, end))) ptr += enc->minBytesPerChar; if (ptr != end) { *badPtr = ptr; return 0; } return 1; } static int FASTCALL checkCharRefNumber(int result) { switch (result >> 8) { case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: return -1; case 0: if (latin1_encoding.type[result] == BT_NONXML) return -1; break; case 0xFF: if (result == 0xFFFE || result == 0xFFFF) return -1; break; } return result; } int FASTCALL XmlUtf8Encode(int c, char *buf) { enum { /* minN is minimum legal resulting value for N byte sequence */ min2 = 0x80, min3 = 0x800, min4 = 0x10000 }; if (c < 0) return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ if (c < min2) { buf[0] = (char)(c | UTF8_cval1); return 1; } if (c < min3) { buf[0] = (char)((c >> 6) | UTF8_cval2); buf[1] = (char)((c & 0x3f) | 0x80); return 2; } if (c < min4) { buf[0] = (char)((c >> 12) | UTF8_cval3); buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); buf[2] = (char)((c & 0x3f) | 0x80); return 3; } if (c < 0x110000) { buf[0] = (char)((c >> 18) | UTF8_cval4); buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); buf[3] = (char)((c & 0x3f) | 0x80); return 4; } return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ } int FASTCALL XmlUtf16Encode(int charNum, unsigned short *buf) { if (charNum < 0) return 0; if (charNum < 0x10000) { buf[0] = (unsigned short)charNum; return 1; } if (charNum < 0x110000) { charNum -= 0x10000; buf[0] = (unsigned short)((charNum >> 10) + 0xD800); buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); return 2; } return 0; } struct unknown_encoding { struct normal_encoding normal; CONVERTER convert; void *userData; unsigned short utf16[256]; char utf8[256][4]; }; #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) int XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } static int PTRFASTCALL unknown_isName(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); } static int PTRFASTCALL unknown_isNmstrt(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); } static int PTRFASTCALL unknown_isInvalid(const ENCODING *enc, const char *p) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); int c = uenc->convert(uenc->userData, p); return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); char buf[XML_UTF8_ENCODE_MAX]; for (;;) { const char *utf8; int n; if (*fromP == fromLim) return XML_CONVERT_COMPLETED; utf8 = uenc->utf8[(unsigned char)**fromP]; n = *utf8++; if (n == 0) { int c = uenc->convert(uenc->userData, *fromP); n = XmlUtf8Encode(c, buf); if (n > toLim - *toP) return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else { if (n > toLim - *toP) return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } memcpy(*toP, utf8, n); *toP += n; } } static enum XML_Convert_Result PTRCALL unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short)uenc->convert(uenc->userData, *fromP); *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else (*fromP)++; *(*toP)++ = c; } if ((*toP == toLim) && (*fromP < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else return XML_CONVERT_COMPLETED; } ENCODING * XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert, void *userData) { int i; struct unknown_encoding *e = (struct unknown_encoding *)mem; memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); for (i = 0; i < 128; i++) if (latin1_encoding.type[i] != BT_OTHER && latin1_encoding.type[i] != BT_NONXML && table[i] != i) return 0; for (i = 0; i < 256; i++) { int c = table[i]; if (c == -1) { e->normal.type[i] = BT_MALFORM; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else if (c < 0) { if (c < -4) return 0; /* Multi-byte sequences need a converter function */ if (! convert) return 0; e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); e->utf8[i][0] = 0; e->utf16[i] = 0; } else if (c < 0x80) { if (latin1_encoding.type[c] != BT_OTHER && latin1_encoding.type[c] != BT_NONXML && c != i) return 0; e->normal.type[i] = latin1_encoding.type[c]; e->utf8[i][0] = 1; e->utf8[i][1] = (char)c; e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); } else if (checkCharRefNumber(c) < 0) { e->normal.type[i] = BT_NONXML; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else { if (c > 0xFFFF) return 0; if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NMSTRT; else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NAME; else e->normal.type[i] = BT_OTHER; e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); e->utf16[i] = (unsigned short)c; } } e->userData = userData; e->convert = convert; if (convert) { e->normal.isName2 = unknown_isName; e->normal.isName3 = unknown_isName; e->normal.isName4 = unknown_isName; e->normal.isNmstrt2 = unknown_isNmstrt; e->normal.isNmstrt3 = unknown_isNmstrt; e->normal.isNmstrt4 = unknown_isNmstrt; e->normal.isInvalid2 = unknown_isInvalid; e->normal.isInvalid3 = unknown_isInvalid; e->normal.isInvalid4 = unknown_isInvalid; } e->normal.enc.utf8Convert = unknown_toUtf8; e->normal.enc.utf16Convert = unknown_toUtf16; return &(e->normal.enc); } /* If this enumeration is changed, getEncodingIndex and encodings must also be changed. */ enum { UNKNOWN_ENC = -1, ISO_8859_1_ENC = 0, US_ASCII_ENC, UTF_8_ENC, UTF_16_ENC, UTF_16BE_ENC, UTF_16LE_ENC, /* must match encodingNames up to here */ NO_ENC }; static const char KW_ISO_8859_1[] = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; static const char KW_US_ASCII[] = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'}; static const char KW_UTF_8[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; static const char KW_UTF_16[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; static const char KW_UTF_16BE[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'}; static const char KW_UTF_16LE[] = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'}; static int FASTCALL getEncodingIndex(const char *name) { static const char *const encodingNames[] = { KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, }; int i; if (name == NULL) return NO_ENC; for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) if (streqci(name, encodingNames[i])) return i; return UNKNOWN_ENC; } /* For binary compatibility, we store the index of the encoding specified at initialization in the isUtf16 member. */ #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) /* This is what detects the encoding. encodingTable maps from encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding; state is XML_CONTENT_STATE if we're parsing an external text entity, and XML_PROLOG_STATE otherwise. */ static int initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, int state, const char *ptr, const char *end, const char **nextTokPtr) { const ENCODING **encPtr; if (ptr >= end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) { /* only a single byte available for auto-detection */ #ifndef XML_DTD /* FIXME */ /* a well-formed document entity must have more than one byte */ if (state != XML_CONTENT_STATE) return XML_TOK_PARTIAL; #endif /* so we're parsing an external text entity... */ /* if UTF-16 was externally specified, then we need at least 2 bytes */ switch (INIT_ENC_INDEX(enc)) { case UTF_16_ENC: case UTF_16LE_ENC: case UTF_16BE_ENC: return XML_TOK_PARTIAL; } switch ((unsigned char)*ptr) { case 0xFE: case 0xFF: case 0xEF: /* possibly first byte of UTF-8 BOM */ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; /* fall through */ case 0x00: case 0x3C: return XML_TOK_PARTIAL; } } else { switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { case 0xFEFF: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16BE_ENC]; return XML_TOK_BOM; /* 00 3C is handled in the default case */ case 0x3C00: if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC || INIT_ENC_INDEX(enc) == UTF_16_ENC) && state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); case 0xFFFE: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16LE_ENC]; return XML_TOK_BOM; case 0xEFBB: /* Maybe a UTF-8 BOM (EF BB BF) */ /* If there's an explicitly specified (external) encoding of ISO-8859-1 or some flavour of UTF-16 and this is an external text entity, don't look for the BOM, because it might be a legal data. */ if (state == XML_CONTENT_STATE) { int e = INIT_ENC_INDEX(enc); if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC) break; } if (ptr + 2 == end) return XML_TOK_PARTIAL; if ((unsigned char)ptr[2] == 0xBF) { *nextTokPtr = ptr + 3; *encPtr = encodingTable[UTF_8_ENC]; return XML_TOK_BOM; } break; default: if (ptr[0] == '\0') { /* 0 isn't a legal data character. Furthermore a document entity can only start with ASCII characters. So the only way this can fail to be big-endian UTF-16 if it it's an external parsed general entity that's labelled as UTF-16LE. */ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) break; *encPtr = encodingTable[UTF_16BE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } else if (ptr[1] == '\0') { /* We could recover here in the case: - parsing an external entity - second byte is 0 - no externally specified encoding - no encoding declaration by assuming UTF-16LE. But we don't, because this would mean when presented just with a single byte, we couldn't reliably determine whether we needed further bytes. */ if (state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } break; } } *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } #define NS(x) x #define ns(x) x #define XML_TOK_NS_C #include "xmltok_ns.c" #undef XML_TOK_NS_C #undef NS #undef ns #ifdef XML_NS # define NS(x) x##NS # define ns(x) x##_ns # define XML_TOK_NS_C # include "xmltok_ns.c" # undef XML_TOK_NS_C # undef NS # undef ns ENCODING * XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert, void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); if (enc) ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; return enc; } #endif /* XML_NS */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmltok.h000066400000000000000000000314401516712004000260040ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2005 Karl Waclawek Copyright (c) 2016-2024 Sebastian Pipping Copyright (c) 2017 Rhodri James Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef XmlTok_INCLUDED # define XmlTok_INCLUDED 1 # ifdef __cplusplus extern "C" { # endif /* The following token may be returned by XmlContentTok */ # define XML_TOK_TRAILING_RSQB \ -5 /* ] or ]] at the end of the scan; might be \ start of illegal ]]> sequence */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ # define XML_TOK_NONE -4 /* The string to be scanned is empty */ # define XML_TOK_TRAILING_CR \ -3 /* A CR at the end of the scan; \ might be part of CRLF sequence */ # define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ # define XML_TOK_PARTIAL -1 /* only part of a token */ # define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. */ # define XML_TOK_START_TAG_WITH_ATTS 1 # define XML_TOK_START_TAG_NO_ATTS 2 # define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ # define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 # define XML_TOK_END_TAG 5 # define XML_TOK_DATA_CHARS 6 # define XML_TOK_DATA_NEWLINE 7 # define XML_TOK_CDATA_SECT_OPEN 8 # define XML_TOK_ENTITY_REF 9 # define XML_TOK_CHAR_REF 10 /* numeric character reference */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok. */ # define XML_TOK_PI 11 /* processing instruction */ # define XML_TOK_XML_DECL 12 /* XML decl or text decl */ # define XML_TOK_COMMENT 13 # define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ # define XML_TOK_PROLOG_S 15 # define XML_TOK_DECL_OPEN 16 /* */ # define XML_TOK_NAME 18 # define XML_TOK_NMTOKEN 19 # define XML_TOK_POUND_NAME 20 /* #name */ # define XML_TOK_OR 21 /* | */ # define XML_TOK_PERCENT 22 # define XML_TOK_OPEN_PAREN 23 # define XML_TOK_CLOSE_PAREN 24 # define XML_TOK_OPEN_BRACKET 25 # define XML_TOK_CLOSE_BRACKET 26 # define XML_TOK_LITERAL 27 # define XML_TOK_PARAM_ENTITY_REF 28 # define XML_TOK_INSTANCE_START 29 /* The following occur only in element type declarations */ # define XML_TOK_NAME_QUESTION 30 /* name? */ # define XML_TOK_NAME_ASTERISK 31 /* name* */ # define XML_TOK_NAME_PLUS 32 /* name+ */ # define XML_TOK_COND_SECT_OPEN 33 /* */ # define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ # define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ # define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ # define XML_TOK_COMMA 38 /* The following token is returned only by XmlAttributeValueTok */ # define XML_TOK_ATTRIBUTE_VALUE_S 39 /* The following token is returned only by XmlCdataSectionTok */ # define XML_TOK_CDATA_SECT_CLOSE 40 /* With namespace processing this is returned by XmlPrologTok for a name with a colon. */ # define XML_TOK_PREFIXED_NAME 41 # ifdef XML_DTD # define XML_TOK_IGNORE_SECT 42 # endif /* XML_DTD */ # ifdef XML_DTD # define XML_N_STATES 4 # else /* not XML_DTD */ # define XML_N_STATES 3 # endif /* not XML_DTD */ # define XML_PROLOG_STATE 0 # define XML_CONTENT_STATE 1 # define XML_CDATA_SECTION_STATE 2 # ifdef XML_DTD # define XML_IGNORE_SECTION_STATE 3 # endif /* XML_DTD */ # define XML_N_LITERAL_TYPES 2 # define XML_ATTRIBUTE_VALUE_LITERAL 0 # define XML_ENTITY_VALUE_LITERAL 1 /* The size of the buffer passed to XmlUtf8Encode must be at least this. */ # define XML_UTF8_ENCODE_MAX 4 /* The size of the buffer passed to XmlUtf16Encode must be at least this. */ # define XML_UTF16_ENCODE_MAX 2 typedef struct position { /* first line and first column are 0 not 1 */ XML_Size lineNumber; XML_Size columnNumber; } POSITION; typedef struct { const char *name; const char *valuePtr; const char *valueEnd; char normalized; } ATTRIBUTE; struct encoding; typedef struct encoding ENCODING; typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *, const char **); enum XML_Convert_Result { XML_CONVERT_COMPLETED = 0, XML_CONVERT_INPUT_INCOMPLETE = 1, XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */ }; struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES]; int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, const char *); int(PTRFASTCALL *nameLength)(const ENCODING *, const char *); const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts); int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *, const char *); void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr, const char *end, POSITION *); int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr); enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim); enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim); int minBytesPerChar; char isUtf8; char isUtf16; }; /* Scan the string starting at ptr until the end of the next complete token, but do not scan past eptr. Return an integer giving the type of token. Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. Return XML_TOK_PARTIAL when the string does not contain a complete token; nextTokPtr will not be set. Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr will be set to point to the character which made the token invalid. Otherwise the string starts with a valid token; nextTokPtr will be set to point to the character following the end of that token. Each data character counts as a single token, but adjacent data characters may be returned together. Similarly for characters in the prolog outside literals, comments and processing instructions. */ # define XmlTok(enc, state, ptr, end, nextTokPtr) \ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) # define XmlPrologTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) # define XmlContentTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) # define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) # ifdef XML_DTD # define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) # endif /* XML_DTD */ /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ # define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) # define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) # define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) # define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) # define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr)) # define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr)) # define XmlGetAttributes(enc, ptr, attsMax, atts) \ (((enc)->getAtts)(enc, ptr, attsMax, atts)) # define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr)) # define XmlPredefinedEntityName(enc, ptr, end) \ (((enc)->predefinedEntityName)(enc, ptr, end)) # define XmlUpdatePosition(enc, ptr, end, pos) \ (((enc)->updatePosition)(enc, ptr, end, pos)) # define XmlIsPublicId(enc, ptr, end, badPtr) \ (((enc)->isPublicId)(enc, ptr, end, badPtr)) # define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) # define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) typedef struct { ENCODING initEnc; const ENCODING **encPtr; } INIT_ENCODING; int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr, const char *name); const ENCODING *XmlGetUtf8InternalEncoding(void); const ENCODING *XmlGetUtf16InternalEncoding(void); int FASTCALL XmlUtf8Encode(int charNumber, char *buf); int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); int XmlSizeOfUnknownEncoding(void); typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); ENCODING *XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert, void *userData); int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr, const char *name); const ENCODING *XmlGetUtf8InternalEncodingNS(void); const ENCODING *XmlGetUtf16InternalEncodingNS(void); ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert, void *userData); # ifdef __cplusplus } # endif #endif /* not XmlTok_INCLUDED */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmltok_impl.c000066400000000000000000001507301516712004000270240ustar00rootroot00000000000000/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)! __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2016 Karl Waclawek Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2018 Benjamin Peterson Copyright (c) 2018 Anton Maklakov Copyright (c) 2019 David Loffredo Copyright (c) 2020 Boris Kolpackov Copyright (c) 2022 Martin Ettl Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef XML_TOK_IMPL_C # ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined # define IS_INVALID_CHAR(enc, ptr, n) (0) # endif # define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define INVALID_CASES(ptr, nextTokPtr) \ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ case BT_NONXML: \ case BT_MALFORM: \ case BT_TRAIL: \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; # define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ /* fall through */ \ case BT_NMSTRT: \ case BT_HEX: \ case BT_DIGIT: \ case BT_NAME: \ case BT_MINUS: \ ptr += MINBPC(enc); \ break; \ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) # define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ if ((end) - (ptr) < (n)) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; # define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ /* fall through */ \ case BT_NMSTRT: \ case BT_HEX: \ ptr += MINBPC(enc); \ break; \ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) # ifndef PREFIX # define PREFIX(ident) ident # endif # define HAS_CHARS(enc, ptr, end, count) \ ((end) - (ptr) >= ((count) * MINBPC(enc))) # define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) # define REQUIRE_CHARS(enc, ptr, end, count) \ { \ if (! HAS_CHARS(enc, ptr, end, count)) { \ return XML_TOK_PARTIAL; \ } \ } # define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1) /* ptr points to character following " */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_INVALID; } /* fall through */ case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; case BT_NMSTRT: case BT_HEX: ptr += MINBPC(enc); break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr) { int upper = 0; UNUSED_P(enc); *tokPtr = XML_TOK_PI; if (end - ptr != MINBPC(enc) * 3) return 1; switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_x: break; case ASCII_X: upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_m: break; case ASCII_M: upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: break; case ASCII_L: upper = 1; break; default: return 1; } if (upper) return 0; *tokPtr = XML_TOK_XML_DECL; return 1; } /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: case BT_RSQB: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_LT: return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_AMP: return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr; return XML_TOK_INVALID; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_RSQB: if (HAS_CHARS(enc, ptr, end, 2)) { if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { ptr += MINBPC(enc); break; } if (HAS_CHARS(enc, ptr, end, 3)) { if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) { ptr += MINBPC(enc); break; } *nextTokPtr = ptr + 2 * MINBPC(enc); return XML_TOK_INVALID; } } /* fall through */ case BT_AMP: case BT_LT: case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "%" */ static int PTRCALL PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; return XML_TOK_POUND_NAME; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return -XML_TOK_POUND_NAME; } static int PTRCALL PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr) case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) break; if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: return XML_TOK_LITERAL; default: return XML_TOK_INVALID; } default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; } static int PTRCALL PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int tok; if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_QUOT: return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_QUEST: return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_NMSTRT: case BT_HEX: case BT_NONASCII: case BT_LEAD2: case BT_LEAD3: case BT_LEAD4: *nextTokPtr = ptr - MINBPC(enc); return XML_TOK_INSTANCE_START; } *nextTokPtr = ptr; return XML_TOK_INVALID; } case BT_CR: if (ptr + MINBPC(enc) == end) { *nextTokPtr = end; /* indicate that this might be part of a CR/LF pair */ return -XML_TOK_PROLOG_S; } /* fall through */ case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: break; case BT_CR: /* don't split CR/LF pair */ if (ptr + MINBPC(enc) != end) break; /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; return XML_TOK_PROLOG_S; case BT_PERCNT: return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_COMMA: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_COMMA; case BT_LSQB: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { *nextTokPtr = ptr + 2 * MINBPC(enc); return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; return XML_TOK_CLOSE_BRACKET; case BT_LPAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_ASTERISK; case BT_QUEST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_QUESTION; case BT_PLUS: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_PLUS; case BT_CR: case BT_LF: case BT_S: case BT_GT: case BT_COMMA: case BT_VERBAR: case BT_RPAR: *nextTokPtr = ptr; return XML_TOK_CLOSE_PAREN; } *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_VERBAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OR; case BT_GT: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); # define LEAD_CASE(n) \ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NAME; \ break; \ } \ if (IS_NAME_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NMTOKEN; \ break; \ } \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NMSTRT: case BT_HEX: tok = XML_TOK_NAME; ptr += MINBPC(enc); break; case BT_DIGIT: case BT_NAME: case BT_MINUS: # ifdef XML_NS case BT_COLON: # endif tok = XML_TOK_NMTOKEN; ptr += MINBPC(enc); break; case BT_NONASCII: if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NAME; break; } if (IS_NAME_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NMTOKEN; break; } /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA: case BT_VERBAR: case BT_LSQB: case BT_PERCNT: case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return tok; # ifdef XML_NS case BT_COLON: ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME: REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) default: tok = XML_TOK_NMTOKEN; break; } break; case XML_TOK_PREFIXED_NAME: tok = XML_TOK_NMTOKEN; break; } break; # endif case BT_PLUS: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_PLUS; case BT_AST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_ASTERISK; case BT_QUEST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_QUESTION; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return -tok; } static int PTRCALL PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; else if (! HAS_CHAR(enc, ptr, end)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the paranoia * check is still valuable, however. */ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ } start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: /* this is for inside entity references */ *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } static int PTRCALL PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr >= end) return XML_TOK_NONE; else if (! HAS_CHAR(enc, ptr, end)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the paranoia * check is still valuable, however. */ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ } start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) { int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } # ifdef XML_DTD static int PTRCALL PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); end = ptr + n; } } while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_LT: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { ++level; ptr += MINBPC(enc); } } break; case BT_RSQB: ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { ptr += MINBPC(enc); REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr += MINBPC(enc); if (level == 0) { *nextTokPtr = ptr; return XML_TOK_IGNORE_SECT; } --level; } } break; default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; } # endif /* XML_DTD */ static int PTRCALL PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: case BT_MINUS: case BT_APOS: case BT_LPAR: case BT_RPAR: case BT_PLUS: case BT_COMMA: case BT_SOL: case BT_EQUALS: case BT_QUEST: case BT_CR: case BT_LF: case BT_SEMI: case BT_EXCL: case BT_AST: case BT_PERCNT: case BT_NUM: # ifdef XML_NS case BT_COLON: # endif break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { *badPtr = ptr; return 0; } break; case BT_NAME: case BT_NMSTRT: if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f)) break; /* fall through */ default: switch (BYTE_TO_ASCII(enc, ptr)) { case 0x24: /* $ */ case 0x40: /* @ */ break; default: *badPtr = ptr; return 0; } break; } } return 1; } /* This must only be called for a well-formed start-tag or empty element tag. Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PTRCALL PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { # define START_NAME \ if (state == other) { \ if (nAtts < attsMax) { \ atts[nAtts].name = ptr; \ atts[nAtts].normalized = 1; \ } \ state = inName; \ } # define LEAD_CASE(n) \ case BT_LEAD##n: /* NOTE: The encoding has already been validated. */ \ START_NAME ptr += (n - MINBPC(enc)); \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: case BT_HEX: START_NAME break; # undef START_NAME case BT_QUOT: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_APOS: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_AMP: if (nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized && (ptr == atts[nAtts].valuePtr || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted Apart from that we could just change state on the quote. */ if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) return nAtts; break; default: break; } } /* not reached */ } static int PTRFASTCALL PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) { int result = 0; /* skip &# */ UNUSED_P(enc); ptr += 2 * MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_x)) { for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); switch (c) { case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: result <<= 4; result |= (c - ASCII_0); break; case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: result <<= 4; result += 10 + (c - ASCII_A); break; case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: result <<= 4; result += 10 + (c - ASCII_a); break; } if (result >= 0x110000) return -1; } } else { for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); result *= 10; result += (c - ASCII_0); if (result >= 0x110000) return -1; } } return checkCharRefNumber(result); } static int PTRCALL PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end) { UNUSED_P(enc); switch ((end - ptr) / MINBPC(enc)) { case 2: if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: return ASCII_LT; case ASCII_g: return ASCII_GT; } } break; case 3: if (CHAR_MATCHES(enc, ptr, ASCII_a)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_m)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) return ASCII_AMP; } } break; case 4: switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_q: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_u)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_o)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_t)) return ASCII_QUOT; } } break; case ASCII_a: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_o)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_s)) return ASCII_APOS; } } break; } } return 0; } static int PTRCALL PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *end1, const char *ptr2) { UNUSED_P(enc); for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { if (end1 - ptr1 < MINBPC(enc)) { /* This line cannot be executed. The incoming data has already * been tokenized once, so incomplete characters like this have * already been eliminated from the input. Retaining the * paranoia check is still valuable, however. */ return 0; /* LCOV_EXCL_LINE */ } if (! CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } return ptr1 == end1; } static int PTRFASTCALL PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { const char *start = ptr; for (;;) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: # ifdef XML_NS case BT_COLON: # endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: ptr += MINBPC(enc); break; default: return (int)(ptr - start); } } } static const char *PTRFASTCALL PREFIX(skipS)(const ENCODING *enc, const char *ptr) { for (;;) { switch (BYTE_TYPE(enc, ptr)) { case BT_LF: case BT_CR: case BT_S: ptr += MINBPC(enc); break; default: return ptr; } } } static void PTRCALL PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ ptr += n; /* NOTE: The encoding has already been validated. */ \ pos->columnNumber++; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) # undef LEAD_CASE case BT_LF: pos->columnNumber = 0; pos->lineNumber++; ptr += MINBPC(enc); break; case BT_CR: pos->lineNumber++; ptr += MINBPC(enc); if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = 0; break; default: ptr += MINBPC(enc); pos->columnNumber++; break; } } } # undef DO_LEAD_CASE # undef MULTIBYTE_CASES # undef INVALID_CASES # undef CHECK_NAME_CASE # undef CHECK_NAME_CASES # undef CHECK_NMSTRT_CASE # undef CHECK_NMSTRT_CASES #endif /* XML_TOK_IMPL_C */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmltok_impl.h000066400000000000000000000065461516712004000270360ustar00rootroot00000000000000/* __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2017-2019 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ enum { BT_NONXML, /* e.g. noncharacter-FFFF */ BT_MALFORM, /* illegal, with regard to encoding */ BT_LT, /* less than = "<" */ BT_AMP, /* ampersand = "&" */ BT_RSQB, /* right square bracket = "[" */ BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */ BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */ BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */ BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */ BT_CR, /* carriage return = "\r" */ BT_LF, /* line feed = "\n" */ BT_GT, /* greater than = ">" */ BT_QUOT, /* quotation character = "\"" */ BT_APOS, /* apostrophe = "'" */ BT_EQUALS, /* equal sign = "=" */ BT_QUEST, /* question mark = "?" */ BT_EXCL, /* exclamation mark = "!" */ BT_SOL, /* solidus, slash = "/" */ BT_SEMI, /* semicolon = ";" */ BT_NUM, /* number sign = "#" */ BT_LSQB, /* left square bracket = "[" */ BT_S, /* white space, e.g. "\t", " "[, "\r"] */ BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */ BT_COLON, /* colon = ":" */ BT_HEX, /* hex letter = "A".."F" + "a".."f" */ BT_DIGIT, /* digit = "0".."9" */ BT_NAME, /* dot and middle dot = "." + chr(0xb7) */ BT_MINUS, /* minus = "-" */ BT_OTHER, /* known not to be a name or name start character */ BT_NONASCII, /* might be a name or name start character */ BT_PERCNT, /* percent sign = "%" */ BT_LPAR, /* left parenthesis = "(" */ BT_RPAR, /* right parenthesis = "(" */ BT_AST, /* asterisk = "*" */ BT_PLUS, /* plus sign = "+" */ BT_COMMA, /* comma = "," */ BT_VERBAR /* vertical bar = "|" */ }; #include boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/expat/xmltok_ns.c000066400000000000000000000111471516712004000265010ustar00rootroot00000000000000/* This file is included! __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Greg Stein Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2017-2026 Sebastian Pipping Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef XML_TOK_NS_C const ENCODING * NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } const ENCODING * NS(XmlGetUtf16InternalEncoding)(void) { # if BYTEORDER == 1234 return &ns(internal_little2_encoding).enc; # elif BYTEORDER == 4321 return &ns(internal_big2_encoding).enc; # else const short n = 1; return (*(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc); # endif } static const ENCODING *const NS(encodings)[] = { &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, &ns(utf8_encoding).enc, &ns(big2_encoding).enc, &ns(big2_encoding).enc, &ns(little2_encoding).enc, &ns(utf8_encoding).enc /* NO_ENC */ }; static int PTRCALL NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); } static int PTRCALL NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); } int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name) { int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; SET_INIT_ENC_INDEX(p, i); p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); p->initEnc.updatePosition = initUpdatePosition; p->encPtr = encPtr; *encPtr = &(p->initEnc); return 1; } static const ENCODING * NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { # define ENCODING_MAX 128 char buf[ENCODING_MAX] = ""; char *p = buf; int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); if (ptr != end) return NULL; *p = 0; if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) return enc; i = getEncodingIndex(buf); if (i == UNKNOWN_ENC) return NULL; return NS(encodings)[i]; } int NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **versionEndPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, badPtr, versionPtr, versionEndPtr, encodingName, encoding, standalone); } #endif /* XML_TOK_NS_C */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/000077500000000000000000000000001516712004000252065ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/Makefile000066400000000000000000000010601516712004000266430ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = UriCommon.o UriCompare.o UriEscape.o UriFile.o UriIp4.o UriIp4Base.o UriMemory.o UriNormalize.o UriNormalizeBase.o UriParse.o UriParseBase.o UriQuery.o UriRecompose.o UriResolve.o UriShorten.o TARGET = liburiparser.a CCOPTS = -I"$(SRCDIR)"/.. AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/Uri.h000066400000000000000000002502351516712004000261250ustar00rootroot00000000000000/* 5abed1007be99942f49ffe603a894d277066b79b9cb824547af0f3b9481cb9ca (1.0.0+) * * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file Uri.h * Holds the RFC 3986 %URI parser interface. * NOTE: This header includes itself twice. */ #if (defined(URI_PASS_ANSI) && !defined(URI_H_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_H_UNICODE)) \ || (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* What encodings are enabled? */ # include "UriDefsConfig.h" # if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "Uri.h" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "Uri.h" # undef URI_PASS_UNICODE # endif /* Only one pass for each encoding */ # elif (defined(URI_PASS_ANSI) && !defined(URI_H_ANSI) && defined(URI_ENABLE_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_H_UNICODE) \ && defined(URI_ENABLE_UNICODE)) # ifdef URI_PASS_ANSI # define URI_H_ANSI 1 # include "UriDefsAnsi.h" # else # define URI_H_UNICODE 1 # include "UriDefsUnicode.h" # endif # ifdef __cplusplus extern "C" { # endif # ifndef URI_DOXYGEN # include "UriBase.h" # endif /** * Specifies a range of characters within a string. * The range includes all characters from first * to one before afterLast. So if both are * non-NULL the difference is the length of the text range. * * @see UriUriA * @see UriPathSegmentA * @see UriHostDataA * @since 0.3.0 */ typedef struct URI_TYPE(TextRangeStruct) { const URI_CHAR * first; /**< Pointer to first character */ const URI_CHAR * afterLast; /**< Pointer to character after the last one still in */ } URI_TYPE(TextRange); /**< @copydoc UriTextRangeStructA */ /** * Represents a path segment within a %URI path. * More precisely it is a node in a linked * list of path segments. * * @see UriUriA * @since 0.3.0 */ typedef struct URI_TYPE(PathSegmentStruct) { URI_TYPE(TextRange) text; /**< Path segment name */ struct URI_TYPE(PathSegmentStruct) * next; /**< Pointer to the next path segment in the list, can be NULL if last already */ void * reserved; /**< Reserved to the parser */ } URI_TYPE(PathSegment); /**< @copydoc UriPathSegmentStructA */ /** * Holds structured host information. * This is either a IPv4, IPv6, plain * text for IPvFuture or all zero for * a registered name. * * @see UriUriA * @since 0.3.0 */ typedef struct URI_TYPE(HostDataStruct) { UriIp4 * ip4; /**< IPv4 address */ UriIp6 * ip6; /**< IPv6 address */ URI_TYPE(TextRange) ipFuture; /**< IPvFuture address @note With non-NULL members in UriUriStructA.hostData context, this text range's pointers must be identical to those of UriUriStructA.hostText at all times. */ } URI_TYPE(HostData); /**< @copydoc UriHostDataStructA */ /** * Represents an RFC 3986 %URI. * Missing components can be {NULL, NULL} ranges. * * @see uriFreeUriMembersA * @see uriFreeUriMembersMmA * @see UriParserStateA * @since 0.3.0 */ typedef struct URI_TYPE(UriStruct) { URI_TYPE(TextRange) scheme; /**< Scheme (e.g. "http") */ URI_TYPE(TextRange) userInfo; /**< User info (e.g. "user:pass") */ URI_TYPE(TextRange) hostText; /**< Host text (set for all hosts, excluding square brackets) */ URI_TYPE(HostData) hostData; /**< Structured host type specific data */ URI_TYPE(TextRange) portText; /**< Port (e.g. "80") */ URI_TYPE(PathSegment) * pathHead; /**< Head of a linked list of path segments */ URI_TYPE(PathSegment) * pathTail; /**< Tail of the list behind pathHead */ URI_TYPE(TextRange) query; /**< Query without leading "?" */ URI_TYPE(TextRange) fragment; /**< Query without leading "#" */ UriBool absolutePath; /**< Absolute path flag, distincting "a" and "/a"; always URI_FALSE for URIs with host */ UriBool owner; /**< Memory owner flag */ void * reserved; /**< Reserved to the parser */ } URI_TYPE(Uri); /**< @copydoc UriUriStructA */ /** * Represents a state of the %URI parser. * Missing components can be NULL to reflect * a components absence. * * @see uriFreeUriMembersA * @see uriFreeUriMembersMmA * @since 0.3.0 */ typedef struct URI_TYPE(ParserStateStruct) { URI_TYPE(Uri) *uri; /**< Plug in the %URI structure to be filled while parsing here */ int errorCode; /**< Code identifying the error which occurred */ const URI_CHAR * errorPos; /**< Pointer to position in case of a syntax error */ void * reserved; /**< Reserved to the parser */ } URI_TYPE(ParserState); /**< @copydoc UriParserStateStructA */ /** * Represents a query element. * More precisely it is a node in a linked * list of query elements. * * @since 0.7.0 */ typedef struct URI_TYPE(QueryListStruct) { const URI_CHAR * key; /**< Key of the query element */ const URI_CHAR * value; /**< Value of the query element, can be NULL */ struct URI_TYPE(QueryListStruct) * next; /**< Pointer to the next key/value pair in the list, can be NULL if last already */ } URI_TYPE(QueryList); /**< @copydoc UriQueryListStructA */ /** * Checks if a URI has the host component set. * * @param uri IN: %URI to check * @return URI_TRUE when host is set, URI_FALSE otherwise * * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri); /** * Converts an IPv6 text representation into 16 bytes. * * Uses default libc-based memory manager. * * @param output OUT: Output destination, can be NULL * @param first IN: First character of IPv6 text to parse * @param afterLast IN: Position to stop parsing at * @return Error code or URI_SUCCESS on success * * @see uriParseIpFourAddressA * @see uriParseIpSixAddressMmA * @see uriIsWellFormedHostIp6A * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(ParseIpSixAddress)(UriIp6 * output, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Converts an IPv6 text representation into 16 bytes. * * @param output OUT: Output destination, can be NULL * @param first IN: First character of IPv6 text to parse * @param afterLast IN: Position to stop parsing at * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or URI_SUCCESS on success * * @see uriParseIpFourAddressA * @see uriParseIpSixAddressA * @see uriIsWellFormedHostIp6MmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Parses a RFC 3986 %URI. * Uses default libc-based memory manager. * * @param state INOUT: Parser state with set output %URI, must not be NULL * @param first IN: Pointer to the first character to parse, must not be NULL * @param afterLast IN: Pointer to the character after the last to parse, must * not be NULL * @return 0 on success, error code otherwise * * @see uriParseUriA * @see uriParseSingleUriA * @see uriParseSingleUriExA * @see uriToStringA * @since 0.3.0 * @deprecated Deprecated since 0.9.0, please migrate to uriParseSingleUriExA (with * "Single"). */ URI_PUBLIC int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Parses a RFC 3986 %URI. * Uses default libc-based memory manager. * * @param state INOUT: Parser state with set output %URI, must not be NULL * @param text IN: Text to parse, must not be NULL * @return 0 on success, error code otherwise * * @see uriParseUriExA * @see uriParseSingleUriA * @see uriParseSingleUriExA * @see uriToStringA * @since 0.3.0 * @deprecated Deprecated since 0.9.0, please migrate to uriParseSingleUriA (with * "Single"). */ URI_PUBLIC int URI_FUNC(ParseUri)(URI_TYPE(ParserState) * state, const URI_CHAR * text); /** * Parses a single RFC 3986 %URI. * Uses default libc-based memory manager. * * @param uri OUT: Output %URI, must not be NULL * @param text IN: Pointer to the first character to parse, * must not be NULL * @param errorPos OUT: Pointer to a pointer to the first character * causing a syntax error, can be NULL; * only set when URI_ERROR_SYNTAX was returned * @return 0 on success, error code otherwise * * @see uriParseSingleUriExA * @see uriParseSingleUriExMmA * @see uriToStringA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(ParseSingleUri)(URI_TYPE(Uri) * uri, const URI_CHAR * text, const URI_CHAR ** errorPos); /** * Parses a single RFC 3986 %URI. * Uses default libc-based memory manager. * * @param uri OUT: Output %URI, must not be NULL * @param first IN: Pointer to the first character to parse, * must not be NULL * @param afterLast IN: Pointer to the character after the last to * parse, can be NULL * (to use first + strlen(first)) * @param errorPos OUT: Pointer to a pointer to the first character * causing a syntax error, can be NULL; * only set when URI_ERROR_SYNTAX was returned * @return 0 on success, error code otherwise * * @see uriParseSingleUriA * @see uriParseSingleUriExMmA * @see uriToStringA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(ParseSingleUriEx)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, const URI_CHAR ** errorPos); /** * Parses a single RFC 3986 %URI. * * @param uri OUT: Output %URI, must not be NULL * @param first IN: Pointer to the first character to parse, * must not be NULL * @param afterLast IN: Pointer to the character after the last to * parse, can be NULL * (to use first + strlen(first)) * @param errorPos OUT: Pointer to a pointer to the first character * causing a syntax error, can be NULL; * only set when URI_ERROR_SYNTAX was returned * @param memory IN: Memory manager to use, NULL for default libc * @return 0 on success, error code otherwise * * @see uriParseSingleUriA * @see uriParseSingleUriExA * @see uriToStringA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(ParseSingleUriExMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, const URI_CHAR ** errorPos, UriMemoryManager * memory); /** * Frees all memory associated with the members * of the %URI structure. Note that the structure * itself is not freed, only its members. * Uses default libc-based memory manager. * * @remarks * Calling on an all-zeros structure (e.g. through memset or calloc) is * safe.
Calling on an uninitialized structure is not safe. * * @param uri INOUT: %URI structure whose members should be freed * * @see uriFreeUriMembersMmA * @since 0.3.0 */ URI_PUBLIC void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri); /** * Frees all memory associated with the members * of the %URI structure. Note that the structure * itself is not freed, only its members. * * @remarks * Calling on an all-zeros structure (e.g. through memset or calloc) is * safe.
Calling on an uninitialized structure is not safe. * * @param uri INOUT: %URI structure whose members should be freed * @param memory IN: Memory manager to use, NULL for default libc * @return 0 on success, error code otherwise * * @see uriFreeUriMembersA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(FreeUriMembersMm)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); /** * Percent-encodes all but unreserved characters from the input string and * writes the encoded version to the output string. * * NOTE: Be sure to allocate 3 times the space of the input buffer for * the output buffer for normalizeBreaks == URI_FALSE and 6 times * the space for normalizeBreaks == URI_TRUE * (since e.g. "\x0d" becomes "%0D%0A" in that case). * * NOTE: The implementation treats (both char and) wchar_t units * as code point integers, which works well for code points U+0001 to U+00ff * in host-native endianness but nothing more; * in particular, using uriEscapeExW with arbitrary Unicode input will * not produce healthy results. * Passing UTF-8 input to uriEscapeExA may be useful in some scenarios. * Keep in mind that uriparser is about %URI (RFC 3986) not %IRI (RFC 3987). * * @param inFirst IN: Pointer to first character of the input text * @param inAfterLast IN: Pointer after the last character of the input text * @param out OUT: Encoded text destination * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @return Position of terminator in output string * * @see uriEscapeA * @see uriUnescapeInPlaceExA * @since 0.5.2 */ URI_PUBLIC URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst, const URI_CHAR * inAfterLast, URI_CHAR * out, UriBool spaceToPlus, UriBool normalizeBreaks); /** * Percent-encodes all but unreserved characters from the input string and * writes the encoded version to the output string. * * NOTE: Be sure to allocate 3 times the space of the input buffer for * the output buffer for normalizeBreaks == URI_FALSE and 6 times * the space for normalizeBreaks == URI_TRUE * (since e.g. "\x0d" becomes "%0D%0A" in that case). * * NOTE: The implementation treats (both char and) wchar_t units * as code point integers, which works well for code points U+0001 to U+00ff * in host-native endianness but nothing more; * in particular, using uriEscapeW with arbitrary Unicode input will * not produce healthy results. * Passing UTF-8 input to uriEscapeA may be useful in some scenarios. * Keep in mind that uriparser is about %URI (RFC 3986) not %IRI (RFC 3987). * * @param in IN: Text source * @param out OUT: Encoded text destination * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @return Position of terminator in output string * * @see uriEscapeExA * @see uriUnescapeInPlaceA * @since 0.5.0 */ URI_PUBLIC URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out, UriBool spaceToPlus, UriBool normalizeBreaks); /** * Unescapes percent-encoded groups in a given string. * E.g. "%20" will become " ". Unescaping is done in place. * The return value will be point to the new position * of the terminating zero. Use this value to get the new * length of the string. NULL is only returned if inout * is NULL. * * @param inout INOUT: Text to unescape/decode * @param plusToSpace IN: Whether to convert '+' to ' ' or not * @param breakConversion IN: Line break conversion mode * @return Pointer to new position of the terminating zero * * @see uriUnescapeInPlaceA * @see uriEscapeExA * @since 0.5.0 */ URI_PUBLIC const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout, UriBool plusToSpace, UriBreakConversion breakConversion); /** * Unescapes percent-encoded groups in a given string. * E.g. "%20" will become " ". Unescaping is done in place. * The return value will be point to the new position * of the terminating zero. Use this value to get the new * length of the string. NULL is only returned if inout * is NULL. * * NOTE: '+' is not decoded to ' ' and line breaks are not converted. * Use the more advanced UnescapeInPlaceEx for that features instead. * * @param inout INOUT: Text to unescape/decode * @return Pointer to new position of the terminating zero * * @see uriUnescapeInPlaceExA * @see uriEscapeA * @since 0.3.0 */ URI_PUBLIC const URI_CHAR * URI_FUNC(UnescapeInPlace)(URI_CHAR * inout); /** * Performs reference resolution as described in * section 5.2.2 of * RFC 3986. Uses default libc-based memory manager. NOTE: On success you have to call * uriFreeUriMembersA on \p absoluteDest manually later. * * @param absoluteDest OUT: Result %URI * @param relativeSource IN: Reference to resolve * @param absoluteBase IN: Base %URI to apply * @return Error code or 0 on success * * @see uriRemoveBaseUriA * @see uriRemoveBaseUriMmA * @see uriAddBaseUriExA * @see uriAddBaseUriExMmA * @since 0.4.0 */ URI_PUBLIC int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absoluteDest, const URI_TYPE(Uri) * relativeSource, const URI_TYPE(Uri) * absoluteBase); /** * Performs reference resolution as described in * section 5.2.2 of * RFC 3986. Uses default libc-based memory manager. NOTE: On success you have to call * uriFreeUriMembersA on \p absoluteDest manually later. * * @param absoluteDest OUT: Result %URI * @param relativeSource IN: Reference to resolve * @param absoluteBase IN: Base %URI to apply * @param options IN: Configuration to apply * @return Error code or 0 on success * * @see uriRemoveBaseUriA * @see uriAddBaseUriA * @see uriAddBaseUriExMmA * @since 0.8.1 */ URI_PUBLIC int URI_FUNC(AddBaseUriEx)(URI_TYPE(Uri) * absoluteDest, const URI_TYPE(Uri) * relativeSource, const URI_TYPE(Uri) * absoluteBase, UriResolutionOptions options); /** * Performs reference resolution as described in * section 5.2.2 of * RFC 3986. NOTE: On success you have to call uriFreeUriMembersMmA on \p absoluteDest * manually later. * * @param absoluteDest OUT: Result %URI * @param relativeSource IN: Reference to resolve * @param absoluteBase IN: Base %URI to apply * @param options IN: Configuration to apply * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriRemoveBaseUriA * @see uriRemoveBaseUriMmA * @see uriAddBaseUriA * @see uriAddBaseUriExA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(AddBaseUriExMm)(URI_TYPE(Uri) * absoluteDest, const URI_TYPE(Uri) * relativeSource, const URI_TYPE(Uri) * absoluteBase, UriResolutionOptions options, UriMemoryManager * memory); /** * Tries to make a relative %URI (a reference) from an * absolute %URI and a given base %URI. The resulting %URI is going to be * relative if the absolute %URI and base %UI share both scheme and authority. * If that is not the case, the result will still be * an absolute URI (with scheme part if necessary). * Uses default libc-based memory manager. * NOTE: On success you have to call uriFreeUriMembersA on * \p dest manually later. * * @param dest OUT: Result %URI * @param absoluteSource IN: Absolute %URI to make relative * @param absoluteBase IN: Base %URI * @param domainRootMode IN: Create %URI with path relative to domain root * @return Error code or 0 on success * * @see uriRemoveBaseUriMmA * @see uriAddBaseUriA * @see uriAddBaseUriExA * @see uriAddBaseUriExMmA * @since 0.5.2 */ URI_PUBLIC int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absoluteSource, const URI_TYPE(Uri) * absoluteBase, UriBool domainRootMode); /** * Tries to make a relative %URI (a reference) from an * absolute %URI and a given base %URI. The resulting %URI is going to be * relative if the absolute %URI and base %UI share both scheme and authority. * If that is not the case, the result will still be * an absolute URI (with scheme part if necessary). * NOTE: On success you have to call uriFreeUriMembersMmA on * \p dest manually later. * * @param dest OUT: Result %URI * @param absoluteSource IN: Absolute %URI to make relative * @param absoluteBase IN: Base %URI * @param domainRootMode IN: Create %URI with path relative to domain root * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriRemoveBaseUriA * @see uriAddBaseUriA * @see uriAddBaseUriExA * @see uriAddBaseUriExMmA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(RemoveBaseUriMm)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absoluteSource, const URI_TYPE(Uri) * absoluteBase, UriBool domainRootMode, UriMemoryManager * memory); /** * Checks two URIs for equivalence. Comparison is done * the naive way, without prior normalization. * NOTE: Two NULL URIs are equal as well. * * @param a IN: First %URI * @param b IN: Second %URI * @return URI_TRUE when equal, URI_FAlSE else * * @since 0.4.0 */ URI_PUBLIC UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b); /** * Calculates the number of characters needed to store the * string representation of the given %URI excluding the * terminator. * * @param uri IN: %URI to measure * @param charsRequired OUT: Length of the string representation in characters * excluding terminator * @return Error code or 0 on success * * @see uriToStringA * @since 0.5.0 */ URI_PUBLIC int URI_FUNC(ToStringCharsRequired)(const URI_TYPE(Uri) * uri, int * charsRequired); /** * Converts a %URI structure back to text as described in * section 5.3 of RFC * 3986. * * NOTE: Scheme-based normalization * (section 6.2.3 of * RFC 3986) is not applied and is considered a responsibility of the application * using uriparser. * * @param dest OUT: Output destination * @param uri IN: %URI to convert * @param maxChars IN: Maximum number of characters to copy including * terminator * @param charsWritten OUT: Number of characters written, can be lower than * maxChars even if the %URI is too long! * @return Error code or 0 on success * * @see uriToStringCharsRequiredA * @since 0.4.0 */ URI_PUBLIC int URI_FUNC(ToString)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars, int * charsWritten); /** * Copies a %URI structure. * * @param destUri OUT: Output destination * @param sourceUri IN: %URI to copy * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriCopyUriA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory); /** * Copies a %URI structure. * * @param destUri OUT: Output destination * @param sourceUri IN: %URI to copy * @return Error code or 0 on success * * @see uriCopyUriMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri); /** * Determines the components of a %URI that are not normalized. * * @param uri IN: %URI to check * @return Normalization job mask * * @see uriNormalizeSyntaxA * @see uriNormalizeSyntaxExA * @see uriNormalizeSyntaxExMmA * @see uriNormalizeSyntaxMaskRequiredExA * @since 0.5.0 * @deprecated Deprecated since 0.9.0, please migrate to uriNormalizeSyntaxMaskRequiredExA * (with "Ex"). */ URI_PUBLIC unsigned int URI_FUNC(NormalizeSyntaxMaskRequired)(const URI_TYPE(Uri) * uri); /** * Determines the components of a %URI that are not normalized. * * @param uri IN: %URI to check * @param outMask OUT: Normalization job mask * @return Error code or 0 on success * * @see uriNormalizeSyntaxA * @see uriNormalizeSyntaxExA * @see uriNormalizeSyntaxExMmA * @see uriNormalizeSyntaxMaskRequiredA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(NormalizeSyntaxMaskRequiredEx)(const URI_TYPE(Uri) * uri, unsigned int * outMask); /** * Normalizes a %URI using a normalization mask. * The normalization mask decides what components are normalized. * * NOTE: If necessary the %URI becomes owner of all memory * behind the text pointed to. Text is duplicated in that case. * Uses default libc-based memory manager. * * @param uri INOUT: %URI to normalize * @param mask IN: Normalization mask * @return Error code or 0 on success * * @see uriNormalizeSyntaxA * @see uriNormalizeSyntaxExMmA * @see uriNormalizeSyntaxMaskRequiredA * @since 0.5.0 */ URI_PUBLIC int URI_FUNC(NormalizeSyntaxEx)(URI_TYPE(Uri) * uri, unsigned int mask); /** * Normalizes a %URI using a normalization mask. * The normalization mask decides what components are normalized. * * NOTE: If necessary the %URI becomes owner of all memory * behind the text pointed to. Text is duplicated in that case. * * @param uri INOUT: %URI to normalize * @param mask IN: Normalization mask * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriNormalizeSyntaxA * @see uriNormalizeSyntaxExA * @see uriNormalizeSyntaxMaskRequiredA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(NormalizeSyntaxExMm)(URI_TYPE(Uri) * uri, unsigned int mask, UriMemoryManager * memory); /** * Normalizes all components of a %URI. * * NOTE: If necessary the %URI becomes owner of all memory * behind the text pointed to. Text is duplicated in that case. * Uses default libc-based memory manager. * * @param uri INOUT: %URI to normalize * @return Error code or 0 on success * * @see uriNormalizeSyntaxExA * @see uriNormalizeSyntaxExMmA * @see uriNormalizeSyntaxMaskRequiredA * @since 0.5.0 */ URI_PUBLIC int URI_FUNC(NormalizeSyntax)(URI_TYPE(Uri) * uri); /** * Converts a Unix filename to a %URI string. * The destination buffer must be large enough to hold 7 + 3 * len(filename) + 1 * characters in case of an absolute filename or 3 * len(filename) + 1 in case * of a relative filename. * * EXAMPLE * Input: "/bin/bash" * Output: "file:///bin/bash" * * @param filename IN: Unix filename to convert * @param uriString OUT: Destination to write %URI string to * @return Error code or 0 on success * * @see uriUriStringToUnixFilenameA * @see uriWindowsFilenameToUriStringA * @since 0.5.2 */ URI_PUBLIC int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString); /** * Converts a Windows filename to a %URI string. * The destination buffer must be large enough to hold 8 + 3 * len(filename) + 1 * characters in case of an absolute filename or 3 * len(filename) + 1 in case * of a relative filename. * * EXAMPLE * Input: "E:\\Documents and Settings" * Output: "file:///E:/Documents%20and%20Settings" * * @param filename IN: Windows filename to convert * @param uriString OUT: Destination to write %URI string to * @return Error code or 0 on success * * @see uriUriStringToWindowsFilenameA * @see uriUnixFilenameToUriStringA * @since 0.5.2 */ URI_PUBLIC int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString); /** * Extracts a Unix filename from a %URI string. * The destination buffer must be large enough to hold len(uriString) + 1 - 5 * characters in case of an absolute %URI or len(uriString) + 1 in case * of a relative %URI. * * @param uriString IN: %URI string to convert * @param filename OUT: Destination to write filename to * @return Error code or 0 on success * * @see uriUnixFilenameToUriStringA * @see uriUriStringToWindowsFilenameA * @since 0.5.2 */ URI_PUBLIC int URI_FUNC(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename); /** * Extracts a Windows filename from a %URI string. * The destination buffer must be large enough to hold len(uriString) + 1 - 5 * characters in case of an absolute %URI or len(uriString) + 1 in case * of a relative %URI. * * @param uriString IN: %URI string to convert * @param filename OUT: Destination to write filename to * @return Error code or 0 on success * * @see uriWindowsFilenameToUriStringA * @see uriUriStringToUnixFilenameA * @since 0.5.2 */ URI_PUBLIC int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString, URI_CHAR * filename); /** * Calculates the number of characters needed to store the * string representation of the given query list excluding the * terminator. It is assumed that line breaks are will be * normalized to "%0D%0A". * * @param queryList IN: Query list to measure * @param charsRequired OUT: Length of the string representation in characters * excluding terminator * @return Error code or 0 on success * * @see uriComposeQueryCharsRequiredExA * @see uriComposeQueryA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryCharsRequired)(const URI_TYPE(QueryList) * queryList, int * charsRequired); /** * Calculates the number of characters needed to store the * string representation of the given query list excluding the * terminator. * * @param queryList IN: Query list to measure * @param charsRequired OUT: Length of the string representation in characters * excluding terminator * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @return Error code or 0 on success * * @see uriComposeQueryCharsRequiredA * @see uriComposeQueryExA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryCharsRequiredEx)(const URI_TYPE(QueryList) * queryList, int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks); /** * Converts a query list structure back to a query string. * The composed string does not start with '?', * on the way ' ' is converted to '+' and line breaks are * normalized to "%0D%0A". * * @param dest OUT: Output destination * @param queryList IN: Query list to convert * @param maxChars IN: Maximum number of characters to copy * including terminator * @param charsWritten OUT: Number of characters written, can be lower than * maxChars even if the query list is too long! * @return Error code or 0 on success * * @see uriComposeQueryExA * @see uriComposeQueryMallocA * @see uriComposeQueryMallocExA * @see uriComposeQueryMallocExMmA * @see uriComposeQueryCharsRequiredA * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQuery)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten); /** * Converts a query list structure back to a query string. * The composed string does not start with '?'. * * @param dest OUT: Output destination * @param queryList IN: Query list to convert * @param maxChars IN: Maximum number of characters to copy * including terminator * @param charsWritten OUT: Number of characters written, can be lower than * maxChars even if the query list is too long! * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @return Error code or 0 on success * * @see uriComposeQueryA * @see uriComposeQueryMallocA * @see uriComposeQueryMallocExA * @see uriComposeQueryMallocExMmA * @see uriComposeQueryCharsRequiredExA * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryEx)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten, UriBool spaceToPlus, UriBool normalizeBreaks); /** * Converts a query list structure back to a query string. * Memory for this string is allocated internally. * The composed string does not start with '?', * on the way ' ' is converted to '+' and line breaks are * normalized to "%0D%0A". * Uses default libc-based memory manager. * * @param dest OUT: Output destination * @param queryList IN: Query list to convert * @return Error code or 0 on success * * @see uriComposeQueryMallocExA * @see uriComposeQueryMallocExMmA * @see uriComposeQueryA * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryMalloc)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList); /** * Converts a query list structure back to a query string. * Memory for this string is allocated internally. * The composed string does not start with '?'. * Uses default libc-based memory manager. * * @param dest OUT: Output destination * @param queryList IN: Query list to convert * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @return Error code or 0 on success * * @see uriComposeQueryMallocA * @see uriComposeQueryMallocExMmA * @see uriComposeQueryExA * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList, UriBool spaceToPlus, UriBool normalizeBreaks); /** * Converts a query list structure back to a query string. * Memory for this string is allocated internally. * The composed string does not start with '?'. * * @param dest OUT: Output destination * @param queryList IN: Query list to convert * @param spaceToPlus IN: Whether to convert ' ' to '+' or not * @param normalizeBreaks IN: Whether to convert CR and LF to CR-LF or not. * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriComposeQueryMallocA * @see uriComposeQueryMallocExA * @see uriComposeQueryExA * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(ComposeQueryMallocExMm)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList, UriBool spaceToPlus, UriBool normalizeBreaks, UriMemoryManager * memory); /** * Constructs a query list from the raw query string of a given URI. * On the way '+' is converted back to ' ', line breaks are not modified. * Uses default libc-based memory manager. * * @param dest OUT: Output destination * @param itemCount OUT: Number of items found, can be NULL * @param first IN: Pointer to first character after '?' * @param afterLast IN: Pointer to character after the last one still in * @return Error code or 0 on success * * @see uriDissectQueryMallocExA * @see uriDissectQueryMallocExMmA * @see uriComposeQueryA * @see uriFreeQueryListA * @see uriFreeQueryListMmA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Constructs a query list from the raw query string of a given URI. * Uses default libc-based memory manager. * * @param dest OUT: Output destination * @param itemCount OUT: Number of items found, can be NULL * @param first IN: Pointer to first character after '?' * @param afterLast IN: Pointer to character after the last one still in * @param plusToSpace IN: Whether to convert '+' to ' ' or not * @param breakConversion IN: Line break conversion mode * @return Error code or 0 on success * * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExMmA * @see uriComposeQueryExA * @see uriFreeQueryListA * @since 0.7.0 */ URI_PUBLIC int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast, UriBool plusToSpace, UriBreakConversion breakConversion); /** * Constructs a query list from the raw query string of a given URI. * * @param dest OUT: Output destination * @param itemCount OUT: Number of items found, can be NULL * @param first IN: Pointer to first character after '?' * @param afterLast IN: Pointer to character after the last one still in * @param plusToSpace IN: Whether to convert '+' to ' ' or not * @param breakConversion IN: Line break conversion mode * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriDissectQueryMallocA * @see uriDissectQueryMallocExA * @see uriComposeQueryExA * @see uriFreeQueryListA * @see uriFreeQueryListMmA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(DissectQueryMallocExMm)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast, UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory); /** * Frees all memory associated with the given query list. * The structure itself is freed as well. * * @param queryList INOUT: Query list to free * * @see uriFreeQueryListMmA * @since 0.7.0 */ URI_PUBLIC void URI_FUNC(FreeQueryList)(URI_TYPE(QueryList) * queryList); /** * Frees all memory associated with the given query list. * The structure itself is freed as well. * * @param queryList INOUT: Query list to free * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriFreeQueryListA * @since 0.9.0 */ URI_PUBLIC int URI_FUNC(FreeQueryListMm)(URI_TYPE(QueryList) * queryList, UriMemoryManager * memory); /** * Makes the %URI hold copies of strings so that it no longer depends * on the original %URI string. If the %URI is already owner of copies, * this function returns URI_TRUE and does not modify the %URI further. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to make independent * @return Error code or 0 on success * * @see uriMakeOwnerMmA * @since 0.9.4 */ URI_PUBLIC int URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri); /** * Makes the %URI hold copies of strings so that it no longer depends * on the original %URI string. If the %URI is already owner of copies, * this function returns URI_TRUE and does not modify the %URI further. * * @param uri INOUT: %URI to make independent * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriMakeOwnerA * @since 0.9.4 */ URI_PUBLIC int URI_FUNC(MakeOwnerMm)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); /** * Determines if the given text range contains a well-formed fragment * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetFragmentA * @see uriSetFragmentMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed IPv4 address * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetHostIp4A * @see uriSetHostIp4MmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedHostIp4)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed IPv6 address * according to RFC 3986 or not. * * Uses default libc-based memory manager. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_SUCCESS if non-NULL and well-formed, else an error * code * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6MmA * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriParseIpSixAddressA * @see uriParseIpSixAddressMmA * @since 0.9.9 */ int URI_FUNC(IsWellFormedHostIp6)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed IPv6 address * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @param memory IN: Memory manager to use, NULL for default libc * @return URI_SUCCESS if non-NULL and well-formed, else an error * code * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureMmA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @since 0.9.9 */ int URI_FUNC(IsWellFormedHostIp6Mm)(const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Determines if the given text range contains a well-formed IPvFuture address * according to RFC 3986 or not. * * Uses default libc-based memory manager. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_SUCCESS if non-NULL and well-formed, else an error * code * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureMmA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetHostIpFutureA * @see uriSetHostIpFutureMmA * @since 0.9.9 */ int URI_FUNC(IsWellFormedHostIpFuture)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed IPvFuture address * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @param memory IN: Memory manager to use, NULL for default libc * @return URI_SUCCESS if non-NULL and well-formed, else an error * code * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetHostIpFutureA * @see uriSetHostIpFutureMmA * @since 0.9.9 */ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Determines if the given text range contains a well-formed registered host name * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetHostRegNameA * @see uriSetHostRegNameMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed path * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @param hasHost IN: Whether the target %URI has a non-NULL host set or * not * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetPathA * @see uriSetPathMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afterLast, UriBool hasHost); /** * Determines if the given text range contains a well-formed port text * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetPortTextA * @see uriSetPortTextMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedPort)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed query * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetQueryA * @see uriSetQueryMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed scheme * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriIsWellFormedUserInfoA * @see uriSetSchemeA * @see uriSetSchemeMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedScheme)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Determines if the given text range contains a well-formed user info * according to RFC 3986 or not. * * @param first IN: Pointer to first character * @param afterLast IN: Pointer to character after the last one still in * @return URI_TRUE if non-NULL and well-formed, else * URI_FALSE * * @see uriIsWellFormedFragmentA * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostRegNameA * @see uriIsWellFormedPathA * @see uriIsWellFormedPortA * @see uriIsWellFormedQueryA * @see uriIsWellFormedSchemeA * @see uriSetUserInfoA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the fragment of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedFragmentA * @see uriSetFragmentMmA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetFragment)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the fragment of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedFragmentA * @see uriSetFragmentA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetFragmentMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIp6MmA * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostIpFutureMmA * @see uriIsWellFormedHostRegNameA * @see uriSetFragmentA * @see uriSetHostAutoMmA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostAuto)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriIsWellFormedHostIp6A * @see uriIsWellFormedHostIp6MmA * @see uriIsWellFormedHostIpFutureA * @see uriIsWellFormedHostIpFutureMmA * @see uriIsWellFormedHostRegNameA * @see uriSetFragmentMmA * @see uriSetHostAutoA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostAutoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedHostRegNameA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameMmA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostRegName)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedHostRegNameA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostRegNameMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4MmA * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIp4)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4A * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIp4Mm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedHostIp6A * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6MmA * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIp6)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedHostIp6A * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6A * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIp6Mm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIpFuture)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the host of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedHostIp4A * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetHostIpFutureMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the path of the given %URI to the given value. * * Non-NULL values must start with a leading slash for %URIs that have a host. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedPathA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPathMmA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetPath)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the path of the given %URI to the given value. * * Non-NULL values must start with a leading slash for %URIs that have a host. * * The %URI must have a non-NULL host set. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedPathA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPathA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the port text of the given %URI to the given value. * * The %URI must have a non-NULL host set. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedPortA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextMmA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetPortText)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the port text of the given %URI to the given value. * * The %URI must have a non-NULL host set. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedPortA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetPortTextMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the query of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedQueryA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryMmA * @see uriSetSchemeA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetQuery)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the query of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedQueryA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryA * @see uriSetSchemeMmA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetQueryMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the scheme of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedSchemeA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeMmA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetScheme)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the scheme of the given %URI to the given value. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedSchemeA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetSchemeMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Sets the user info of the given %URI to the given value. * * The %URI must have a non-NULL host set. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * Uses default libc-based memory manager. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @return Error code or 0 on success * * @see uriIsWellFormedUserInfoA * @see uriSetFragmentA * @see uriSetHostAutoA * @see uriSetHostIp4A * @see uriSetHostIp6A * @see uriSetHostIpFutureA * @see uriSetHostRegNameA * @see uriSetPortTextA * @see uriSetQueryA * @see uriSetSchemeA * @see uriSetUserInfoMmA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetUserInfo)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast); /** * Sets the user info of the given %URI to the given value. * * The %URI must have a non-NULL host set. * * Parameters first and afterLast must both be NULL * or non-NULL at the same time. * * The function may make the %URI own its memory if needed (if it is not already owned). * * For all return values but URI_ERROR_MALLOC, all-or-nothing behavior * can be expected, e.g. trying to apply a malformed value will leave the * %URI unchanged. * * @param uri INOUT: %URI to modify * @param first IN: Pointer to first character, can be NULL * @param afterLast IN: Pointer to character after the last one still in, can be * NULL * @param memory IN: Memory manager to use, NULL for default libc * @return Error code or 0 on success * * @see uriIsWellFormedUserInfoA * @see uriSetFragmentMmA * @see uriSetHostAutoMmA * @see uriSetHostIp4MmA * @see uriSetHostIp6MmA * @see uriSetHostIpFutureMmA * @see uriSetHostRegNameMmA * @see uriSetPortTextMmA * @see uriSetQueryMmA * @see uriSetSchemeMmA * @see uriSetUserInfoA * @since 0.9.9 */ URI_PUBLIC int URI_FUNC(SetUserInfoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); /** * Obtain the base runtime version of uriparser. * * The string returned is based on the compile time version * of uriparser. * * @note Distributors may have applied backports of security * fixes (potentially with adjusting packaging version but often * without adjusting runtime version) * or even fully custom patches. As a result, the version string * returned serves as nothing more than "based on that version", * it does not guarantee equivalence to vanilla upstream releases * or absence of additional downstream patches. * It is nothing more than "a hint" and MUST NEVER be used to * make decisions on in application code at runtime. * * @return Pointer to a read-only zero terminated version string * * @since 0.9.9 */ URI_PUBLIC const URI_CHAR * URI_FUNC(BaseRuntimeVersion)(void); # ifdef __cplusplus } # endif # endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriBase.h000066400000000000000000000355021516712004000267160ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriBase.h * Holds definitions independent of the encoding pass. */ #ifndef URI_BASE_H # define URI_BASE_H 1 /* Version helper macro */ # define URI_ANSI_TO_UNICODE_HELPER(x) L##x # define URI_ANSI_TO_UNICODE(x) URI_ANSI_TO_UNICODE_HELPER(x) /* Version */ # define URI_VER_MAJOR 1 # define URI_VER_MINOR 0 # define URI_VER_RELEASE 0 # define URI_VER_SUFFIX_ANSI "" # define URI_VER_SUFFIX_UNICODE URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI) /* More version helper macros */ # define URI_INT_TO_ANSI_HELPER(x) #x # define URI_INT_TO_ANSI(x) URI_INT_TO_ANSI_HELPER(x) # define URI_INT_TO_UNICODE_HELPER(x) URI_ANSI_TO_UNICODE(#x) # define URI_INT_TO_UNICODE(x) URI_INT_TO_UNICODE_HELPER(x) # define URI_VER_ANSI_HELPER(ma, mi, r, s) \ URI_INT_TO_ANSI(ma) "." URI_INT_TO_ANSI(mi) "." URI_INT_TO_ANSI(r) s # define URI_VER_UNICODE_HELPER(ma, mi, r, s) \ URI_INT_TO_UNICODE(ma) L"." URI_INT_TO_UNICODE(mi) L"." URI_INT_TO_UNICODE(r) s /* Full version strings */ # define URI_VER_ANSI \ URI_VER_ANSI_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, \ URI_VER_SUFFIX_ANSI) # define URI_VER_UNICODE \ URI_VER_UNICODE_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, \ URI_VER_SUFFIX_UNICODE) /* Unused parameter macro */ # ifdef __GNUC__ # define URI_UNUSED(x) unused_##x __attribute__((unused)) # else # define URI_UNUSED(x) x # endif /* Import/export decorator */ # if defined(_MSC_VER) # if defined(URI_STATIC_BUILD) # define URI_PUBLIC # elif defined(URI_LIBRARY_BUILD) # define URI_PUBLIC __declspec(dllexport) # else # define URI_PUBLIC __declspec(dllimport) # endif # else # if !defined(URI_LIBRARY_BUILD) || !defined(URI_VISIBILITY) # define URI_PUBLIC # else # define URI_PUBLIC __attribute__((visibility("default"))) # endif # endif typedef int UriBool; /**< Boolean type */ # define URI_TRUE 1 # define URI_FALSE 0 /* Shared errors */ # define URI_SUCCESS 0 # define URI_ERROR_SYNTAX 1 /* Parsed text violates expected format */ # define URI_ERROR_NULL \ 2 /* One of the params passed was NULL although it mustn't be \ */ # define URI_ERROR_MALLOC 3 /* Requested memory could not be allocated */ # define URI_ERROR_OUTPUT_TOO_LARGE \ 4 /* Some output is to large for the receiving buffer */ # define URI_ERROR_NOT_IMPLEMENTED 8 /* The called function is not implemented yet */ # define URI_ERROR_RANGE_INVALID 9 /* The parameters passed contained invalid ranges */ # define URI_ERROR_MEMORY_MANAGER_INCOMPLETE \ 10 /* [>=0.9.0] The UriMemoryManager passed does not implement all needed \ functions */ /* Errors specific to ToString */ # define URI_ERROR_TOSTRING_TOO_LONG \ URI_ERROR_OUTPUT_TOO_LARGE /* Deprecated, test for URI_ERROR_OUTPUT_TOO_LARGE \ instead */ /* Errors specific to AddBaseUri */ # define URI_ERROR_ADDBASE_REL_BASE 5 /* Given base is not absolute */ /* Errors specific to RemoveBaseUri */ # define URI_ERROR_REMOVEBASE_REL_BASE 6 /* Given base is not absolute */ # define URI_ERROR_REMOVEBASE_REL_SOURCE 7 /* Given base is not absolute */ /* Error specific to uriTestMemoryManager */ # define URI_ERROR_MEMORY_MANAGER_FAULTY \ 11 /* [>=0.9.0] The UriMemoryManager given did not pass the test suite */ /* Error specific to uriSetUserInfo */ # define URI_ERROR_SETUSERINFO_HOST_NOT_SET \ 12 /* [>=0.9.9] The %URI given does not have the host set */ /* Error specific to uriSetPort */ # define URI_ERROR_SETPORT_HOST_NOT_SET \ 13 /* [>=0.9.9] The %URI given does not have the host set */ /* Error specific to uriSetHost* */ # define URI_ERROR_SETHOST_USERINFO_SET \ 14 /* [>=0.9.9] The %URI given does have user info set */ # define URI_ERROR_SETHOST_PORT_SET \ 15 /* [>=0.9.9] The %URI given does have a port set */ # ifndef URI_DOXYGEN # include /* For NULL, snprintf */ # include /* For wchar_t */ # include /* For strlen, memset, memcpy */ # include /* For malloc */ # endif /* URI_DOXYGEN */ /** * Holds an IPv4 address. */ typedef struct UriIp4Struct { unsigned char data[4]; /**< Each octet in one byte */ } UriIp4; /**< @copydoc UriIp4Struct */ /** * Holds an IPv6 address. */ typedef struct UriIp6Struct { unsigned char data[16]; /**< Each quad in two bytes */ } UriIp6; /**< @copydoc UriIp6Struct */ struct UriMemoryManagerStruct; /* forward declaration to break loop */ /** * Function signature that custom malloc(3) functions must conform to * * @since 0.9.0 */ typedef void * (*UriFuncMalloc)(struct UriMemoryManagerStruct *, size_t); /** * Function signature that custom calloc(3) functions must conform to * * @since 0.9.0 */ typedef void * (*UriFuncCalloc)(struct UriMemoryManagerStruct *, size_t, size_t); /** * Function signature that custom realloc(3) functions must conform to * * @since 0.9.0 */ typedef void * (*UriFuncRealloc)(struct UriMemoryManagerStruct *, void *, size_t); /** * Function signature that custom reallocarray(3) functions must conform to * * @since 0.9.0 */ typedef void * (*UriFuncReallocarray)(struct UriMemoryManagerStruct *, void *, size_t, size_t); /** * Function signature that custom free(3) functions must conform to * * @since 0.9.0 */ typedef void (*UriFuncFree)(struct UriMemoryManagerStruct *, void *); /** * Class-like interface of custom memory managers * * @see uriCompleteMemoryManager * @see uriEmulateCalloc * @see uriEmulateReallocarray * @see uriTestMemoryManager * @since 0.9.0 */ typedef struct UriMemoryManagerStruct { UriFuncMalloc malloc; /**< Pointer to custom malloc(3) */ UriFuncCalloc calloc; /**< Pointer to custom calloc(3); to emulate using malloc and memset see uriEmulateCalloc */ UriFuncRealloc realloc; /**< Pointer to custom realloc(3) */ UriFuncReallocarray reallocarray; /**< Pointer to custom reallocarray(3); to emulate using realloc see uriEmulateReallocarray */ UriFuncFree free; /**< Pointer to custom free(3) */ void * userData; /**< Pointer to data that the other function members need access to */ } UriMemoryManager; /**< @copydoc UriMemoryManagerStruct */ /** * Specifies a line break conversion mode. */ typedef enum UriBreakConversionEnum { URI_BR_TO_LF, /**< Convert to Unix line breaks ("\\x0a") */ URI_BR_TO_CRLF, /**< Convert to Windows line breaks ("\\x0d\\x0a") */ URI_BR_TO_CR, /**< Convert to Macintosh line breaks ("\\x0d") */ URI_BR_TO_UNIX = URI_BR_TO_LF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_LF */ URI_BR_TO_WINDOWS = URI_BR_TO_CRLF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CRLF */ URI_BR_TO_MAC = URI_BR_TO_CR, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CR */ URI_BR_DONT_TOUCH /**< Copy line breaks unmodified */ } UriBreakConversion; /**< @copydoc UriBreakConversionEnum */ /** * Specifies which component of a %URI has to be normalized. */ typedef enum UriNormalizationMaskEnum { URI_NORMALIZED = 0, /**< Do not normalize anything */ URI_NORMALIZE_SCHEME = 1 << 0, /**< Normalize scheme (fix uppercase letters) */ URI_NORMALIZE_USER_INFO = 1 << 1, /**< Normalize user info (fix uppercase percent-encodings) */ URI_NORMALIZE_HOST = 1 << 2, /**< Normalize host (fix uppercase letters) */ URI_NORMALIZE_PATH = 1 << 3, /**< Normalize path (fix uppercase percent-encodings and redundant dot segments) */ URI_NORMALIZE_QUERY = 1 << 4, /**< Normalize query (fix uppercase percent-encodings) */ URI_NORMALIZE_FRAGMENT = 1 << 5, /**< Normalize fragment (fix uppercase percent-encodings) */ URI_NORMALIZE_PORT = 1 << 6 /**< Normalize port (drop leading zeros) @since 0.9.9 */ } UriNormalizationMask; /**< @copydoc UriNormalizationMaskEnum */ /** * Specifies how to resolve %URI references. */ typedef enum UriResolutionOptionsEnum { URI_RESOLVE_STRICTLY = 0, /**< Full RFC conformance */ URI_RESOLVE_IDENTICAL_SCHEME_COMPAT = 1 << 0 /**< Treat %URI to resolve with identical scheme as having no scheme */ } UriResolutionOptions; /**< @copydoc UriResolutionOptionsEnum */ /** * Wraps a memory manager backend that only provides malloc(3) and * free(3) to make a complete memory manager ready to be used. * * The core feature of this wrapper is that you don't need to implement * realloc(3) if you don't want to. The wrapped memory manager uses * backend->malloc, memcpy(3), and backend->free and * (at least) sizeof(size_t) extra bytes per allocation to emulate * fallback realloc(3) for you. * *
    *
  • memory->calloc is uriEmulateCalloc.
  • *
  • memory->free uses backend->free, * and handles the size header.
  • *
  • memory->malloc uses backend->malloc, * and adds a size header.
  • *
  • memory->realloc uses memory->malloc, * memcpy(3) and memory->free, * and reads the size header.
  • *
  • memory->reallocarray is uriEmulateReallocarray.
  • *
* * The internal workings behind memory->free, memory->malloc, * and memory->realloc may change, and the functions exposed by these * function pointers should be considered internal and not public API. * * @param memory OUT: Where to write the wrapped memory manager to * @param backend IN: Memory manager to use as a backend * @return Error code or 0 on success * * @see uriEmulateCalloc * @see uriEmulateReallocarray * @see UriMemoryManager * @since 0.9.0 */ URI_PUBLIC int uriCompleteMemoryManager(UriMemoryManager * memory, UriMemoryManager * backend); /** * Offers emulation of calloc(3) based on memory->malloc and memset. * See "man 3 calloc" as well. * * @param memory IN: Memory manager to use, should not be NULL * @param nmemb IN: Number of elements to allocate * @param size IN: Size in bytes per element * @return Pointer to allocated memory or NULL * * @see uriCompleteMemoryManager * @see uriEmulateReallocarray * @see UriMemoryManager * @since 0.9.0 */ URI_PUBLIC void * uriEmulateCalloc(UriMemoryManager * memory, size_t nmemb, size_t size); /** * Offers emulation of reallocarray(3) based on memory->realloc. * See "man 3 reallocarray" as well. * * @param memory IN: Memory manager to use, should not be NULL * @param ptr IN: Pointer allocated using memory->malloc/... or NULL * @param nmemb IN: Number of elements to allocate * @param size IN: Size in bytes per element * @return Pointer to allocated memory or NULL * * @see uriCompleteMemoryManager * @see uriEmulateCalloc * @see UriMemoryManager * @since 0.9.0 */ URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size); /** * Run multiple tests against a given memory manager. * For example, one test * 1. allocates a small amount of memory, * 2. writes some magic bytes to it, * 3. reallocates it, * 4. checks that previous values are still present, * 5. and frees that memory. * * It is recommended to compile with AddressSanitizer enabled * to take full advantage of uriTestMemoryManager. * * For backwards-compatibility, uriTestMemoryManager * does not challenge pointer alignment; please see * uriTestMemoryManagerEx for that feature. * * @param memory IN: Memory manager to use, should not be NULL * @return Error code or 0 on success * * @see uriEmulateCalloc * @see uriEmulateReallocarray * @see UriMemoryManager * @see uriTestMemoryManagerEx * @since 0.9.0 */ URI_PUBLIC int uriTestMemoryManager(UriMemoryManager * memory); /** * Run multiple tests against a given memory manager. * For example, one test * 1. allocates a small amount of memory, * 2. writes some magic bytes to it, * 3. reallocates it, * 4. checks that previous values are still present, * 5. and frees that memory. * * It is recommended to compile with both AddressSanitizer and * UndefinedBehaviorSanitizer enabled to take full advantage of * uriTestMemoryManagerEx. Note that environment variable * UBSAN_OPTIONS may need adjustment to make UndefinedBehaviorSanitizer * fatal (which by default it is not). * * @param memory IN: Memory manager to use, should not be NULL * @param challengeAlignment IN: Whether to challenge pointer alignment * @return Error code or 0 on success * * @see uriEmulateCalloc * @see uriEmulateReallocarray * @see UriMemoryManager * @see uriTestMemoryManager * @since 1.0.0 */ URI_PUBLIC int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment); #endif /* URI_BASE_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriCommon.c000066400000000000000000000737661516712004000273050ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriCommon.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriCommon.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # include "UriSets.h" # endif # include /*extern*/ const URI_CHAR * const URI_FUNC(SafeToPointTo) = _UT("X"); /*extern*/ const URI_CHAR * const URI_FUNC(ConstPwd) = _UT("."); /*extern*/ const URI_CHAR * const URI_FUNC(ConstParent) = _UT(".."); void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) { if (uri == NULL) { return; } memset(uri, 0, sizeof(URI_TYPE(Uri))); } int URI_FUNC(FreeUriPath)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { assert(uri != NULL); assert(memory != NULL); if (uri->pathHead != NULL) { URI_TYPE(PathSegment) * segWalk = uri->pathHead; while (segWalk != NULL) { URI_TYPE(PathSegment) * const next = segWalk->next; if ((uri->owner == URI_TRUE) && (segWalk->text.first != segWalk->text.afterLast)) { memory->free(memory, (URI_CHAR *)segWalk->text.first); } segWalk->text.first = NULL; segWalk->text.afterLast = NULL; segWalk->next = NULL; memory->free(memory, segWalk); segWalk = next; } uri->pathHead = NULL; uri->pathTail = NULL; } return URI_SUCCESS; } /* Compares two text ranges for equal text content */ int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b) { int diff; /* NOTE: Both NULL means equal! */ if ((a == NULL) || (b == NULL)) { return ((a == NULL) ? 0 : 1) - ((b == NULL) ? 0 : 1); } /* NOTE: Both NULL means equal! */ if ((a->first == NULL) || (b->first == NULL)) { return ((a->first == NULL) ? 0 : 1) - ((b->first == NULL) ? 0 : 1); } diff = ((int)(a->afterLast - a->first) - (int)(b->afterLast - b->first)); if (diff > 0) { return 1; } else if (diff < 0) { return -1; } diff = URI_STRNCMP(a->first, b->first, (a->afterLast - a->first)); if (diff > 0) { return 1; } else if (diff < 0) { return -1; } return diff; } UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) { const int lenInChars = (int)(sourceRange->afterLast - sourceRange->first); const int lenInBytes = lenInChars * sizeof(URI_CHAR); URI_CHAR * dup = memory->malloc(memory, lenInBytes); if (dup == NULL) { return URI_FALSE; } memcpy(dup, sourceRange->first, lenInBytes); destRange->first = dup; destRange->afterLast = dup + lenInChars; return URI_TRUE; } UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) { if (sourceRange->first == NULL) { destRange->first = NULL; destRange->afterLast = NULL; } else if (sourceRange->first == sourceRange->afterLast) { destRange->first = URI_FUNC(SafeToPointTo); destRange->afterLast = URI_FUNC(SafeToPointTo); } else { return URI_FUNC(CopyRange)(destRange, sourceRange, memory); } return URI_TRUE; } UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, UriBool relative, UriBool pathOwned, UriMemoryManager * memory) { URI_TYPE(PathSegment) * walker; if ((uri == NULL) || (uri->pathHead == NULL)) { return URI_TRUE; } walker = uri->pathHead; walker->reserved = NULL; /* Prev pointer */ do { UriBool removeSegment = URI_FALSE; int len = (int)(walker->text.afterLast - walker->text.first); switch (len) { case 1: if ((walker->text.first)[0] == _UT('.')) { /* "." segment -> remove if not essential */ URI_TYPE(PathSegment) * const prev = walker->reserved; URI_TYPE(PathSegment) * const nextBackup = walker->next; /* * Is this dot segment essential, * i.e. is there a chance of changing semantics by dropping this dot * segment? * * For example, changing "./http://foo" into "http://foo" would change * semantics and hence the dot segment is essential to that case and * cannot be removed. * * Other examples that would change semantics are: * - cutting "/.//" down to "//" * - cutting "scheme:/.//" down to "scheme://". */ removeSegment = URI_TRUE; if ((walker == uri->pathHead) && (walker->next != NULL)) { /* Detect case "/.//" (with or without scheme) */ if ((walker->next->text.first == walker->next->text.afterLast) && (URI_FUNC(HasHost)(uri) == URI_FALSE)) { removeSegment = URI_FALSE; /* Detect case "./withcolon:" */ } else if (relative) { const URI_CHAR * ch = walker->next->text.first; for (; ch < walker->next->text.afterLast; ch++) { if (*ch == _UT(':')) { removeSegment = URI_FALSE; break; } } } } if (removeSegment) { /* .. then let's go remove that segment. */ /* Last segment? */ if (walker->next != NULL) { /* Not last segment, i.e. first or middle segment * OLD: (prev|NULL) <- walker <- next * NEW: (prev|NULL) <----------- next */ walker->next->reserved = prev; if (prev == NULL) { /* First but not last segment * OLD: head -> walker -> next * NEW: head -----------> next */ uri->pathHead = walker->next; } else { /* Middle segment * OLD: prev -> walker -> next * NEW: prev -----------> next */ prev->next = walker->next; } if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); } else { /* Last segment */ if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } if (prev == NULL) { /* Last and first */ if (URI_FUNC(HasHost)(uri)) { /* Replace "." with empty segment to represent trailing * slash */ walker->text.first = URI_FUNC(SafeToPointTo); walker->text.afterLast = URI_FUNC(SafeToPointTo); } else { memory->free(memory, walker); uri->pathHead = NULL; uri->pathTail = NULL; } } else { /* Last but not first, replace "." with empty segment to * represent trailing slash */ walker->text.first = URI_FUNC(SafeToPointTo); walker->text.afterLast = URI_FUNC(SafeToPointTo); } } walker = nextBackup; } } break; case 2: if (((walker->text.first)[0] == _UT('.')) && ((walker->text.first)[1] == _UT('.'))) { /* Path ".." -> remove this and the previous segment */ URI_TYPE(PathSegment) * const prev = walker->reserved; URI_TYPE(PathSegment) * prevPrev; URI_TYPE(PathSegment) * const nextBackup = walker->next; removeSegment = URI_TRUE; if (relative) { if (prev == NULL) { /* We cannot remove traversal beyond because the * URI is relative and may be resolved later. * So we can simplify "a/../b/d" to "b/d" but * we cannot simplify "../b/d" (outside of reference resolution). */ removeSegment = URI_FALSE; } else if ((prev != NULL) && ((prev->text.afterLast - prev->text.first) == 2) && ((prev->text.first)[0] == _UT('.')) && ((prev->text.first)[1] == _UT('.'))) { /* We need to protect against mis-simplifying "a/../../b" to * "a/b". */ removeSegment = URI_FALSE; } } if (removeSegment) { if (prev != NULL) { /* Not first segment */ prevPrev = prev->reserved; if (prevPrev != NULL) { /* Not even prev is the first one * OLD: prevPrev -> prev -> walker -> (next|NULL) * NEW: prevPrev -------------------> (next|NULL) */ prevPrev->next = walker->next; if (walker->next != NULL) { /* Update parent relationship as well * OLD: prevPrev <- prev <- walker <- next * NEW: prevPrev <------------------- next */ walker->next->reserved = prevPrev; } else { /* Last segment -> insert "" segment to represent trailing * slash, update tail */ URI_TYPE(PathSegment) * const segment = memory->calloc( memory, 1, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); if (pathOwned && (prev->text.first != prev->text.afterLast)) { memory->free(memory, (URI_CHAR *)prev->text.first); } memory->free(memory, prev); return URI_FALSE; /* Raises malloc error */ } segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); prevPrev->next = segment; uri->pathTail = segment; } if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); if (pathOwned && (prev->text.first != prev->text.afterLast)) { memory->free(memory, (URI_CHAR *)prev->text.first); } memory->free(memory, prev); walker = nextBackup; } else { /* Prev is the first segment */ if (walker->next != NULL) { uri->pathHead = walker->next; walker->next->reserved = NULL; if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); } else { /* Reuse segment for "" path segment to represent trailing * slash, update tail */ URI_TYPE(PathSegment) * const segment = walker; if (pathOwned && (segment->text.first != segment->text.afterLast)) { memory->free(memory, (URI_CHAR *)segment->text.first); } segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); uri->pathHead = segment; uri->pathTail = segment; } if (pathOwned && (prev->text.first != prev->text.afterLast)) { memory->free(memory, (URI_CHAR *)prev->text.first); } memory->free(memory, prev); walker = nextBackup; } } else { URI_TYPE(PathSegment) * const anotherNextBackup = walker->next; int freeWalker = URI_TRUE; /* First segment */ if (walker->next != NULL) { /* First segment of multiple -> update head * OLD: head -> walker -> next * NEW: head -----------> next */ uri->pathHead = walker->next; /* Update parent link as well * OLD: head <- walker <- next * NEW: head <----------- next */ walker->next->reserved = NULL; } else { if (uri->absolutePath) { /* First and only segment -> update head * OLD: head -> walker -> NULL * NEW: head -----------> NULL */ uri->pathHead = NULL; /* Last segment -> update tail * OLD: tail -> walker * NEW: tail -> NULL */ uri->pathTail = NULL; } else { /* Reuse segment for "" path segment to represent trailing * slash, then update head and tail */ if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } walker->text.first = URI_FUNC(SafeToPointTo); walker->text.afterLast = URI_FUNC(SafeToPointTo); freeWalker = URI_FALSE; } } if (freeWalker) { if (pathOwned && (walker->text.first != walker->text.afterLast)) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); } walker = anotherNextBackup; } } } break; } /* end of switch */ if (!removeSegment) { /* .. then let's move to the next element, and start again. */ if (walker->next != NULL) { walker->next->reserved = walker; } else { /* Last segment -> update tail */ uri->pathTail = walker; } walker = walker->next; } } while (walker != NULL); return URI_TRUE; } /* Properly removes "." and ".." path segments */ UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { const UriBool ABSOLUTE = URI_FALSE; if (uri == NULL) { return URI_TRUE; } return URI_FUNC(RemoveDotSegmentsEx)(uri, ABSOLUTE, uri->owner, memory); } unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig) { switch (hexdig) { case URI_SET_DIGIT(_UT): return (unsigned char)(9 + hexdig - _UT('9')); case URI_SET_HEX_LETTER_LOWER(_UT): return (unsigned char)(15 + hexdig - _UT('f')); case URI_SET_HEX_LETTER_UPPER(_UT): return (unsigned char)(15 + hexdig - _UT('F')); default: return 0; } } URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase) { switch (value) { case 0: return _UT('0'); case 1: return _UT('1'); case 2: return _UT('2'); case 3: return _UT('3'); case 4: return _UT('4'); case 5: return _UT('5'); case 6: return _UT('6'); case 7: return _UT('7'); case 8: return _UT('8'); case 9: return _UT('9'); case 10: return (uppercase == URI_TRUE) ? _UT('A') : _UT('a'); case 11: return (uppercase == URI_TRUE) ? _UT('B') : _UT('b'); case 12: return (uppercase == URI_TRUE) ? _UT('C') : _UT('c'); case 13: return (uppercase == URI_TRUE) ? _UT('D') : _UT('d'); case 14: return (uppercase == URI_TRUE) ? _UT('E') : _UT('e'); default: return (uppercase == URI_TRUE) ? _UT('F') : _UT('f'); } } /* Checks if a URI has the host component set. */ UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri) { /* NOTE: .hostData.ipFuture.first is not being checked, * * because we do check .hostText.first and * * .hostData.ipFuture.first has to be identical to * * .hostText.first if set, and hence there is * * no more information to be gained. */ return (uri != NULL) && ((uri->hostText.first != NULL) || (uri->hostData.ip4 != NULL) || (uri->hostData.ip6 != NULL)); } /* Copies the path segment list from one URI to another. */ UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source, UriMemoryManager * memory) { if (source->pathHead == NULL) { /* No path component */ dest->pathHead = NULL; dest->pathTail = NULL; } else { /* Copy list but not the text contained */ URI_TYPE(PathSegment) * sourceWalker = source->pathHead; URI_TYPE(PathSegment) * destPrev = NULL; do { URI_TYPE(PathSegment) * cur = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (cur == NULL) { /* Fix broken list */ if (destPrev != NULL) { destPrev->next = NULL; } return URI_FALSE; /* Raises malloc error */ } /* From this functions usage we know that * * the dest URI cannot be uri->owner */ cur->text = sourceWalker->text; if (destPrev == NULL) { /* First segment ever */ dest->pathHead = cur; } else { destPrev->next = cur; } destPrev = cur; sourceWalker = sourceWalker->next; } while (sourceWalker != NULL); dest->pathTail = destPrev; dest->pathTail->next = NULL; } dest->absolutePath = source->absolutePath; return URI_TRUE; } /* Copies the authority part of an URI over to another. */ UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source, UriMemoryManager * memory) { /* From this functions usage we know that * * the dest URI cannot be uri->owner */ /* Copy userInfo */ dest->userInfo = source->userInfo; /* Copy hostText */ dest->hostText = source->hostText; /* Copy hostData */ if (source->hostData.ip4 != NULL) { dest->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4)); if (dest->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } *(dest->hostData.ip4) = *(source->hostData.ip4); dest->hostData.ip6 = NULL; dest->hostData.ipFuture.first = NULL; dest->hostData.ipFuture.afterLast = NULL; } else if (source->hostData.ip6 != NULL) { dest->hostData.ip4 = NULL; dest->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6)); if (dest->hostData.ip6 == NULL) { return URI_FALSE; /* Raises malloc error */ } *(dest->hostData.ip6) = *(source->hostData.ip6); dest->hostData.ipFuture.first = NULL; dest->hostData.ipFuture.afterLast = NULL; } else { dest->hostData.ip4 = NULL; dest->hostData.ip6 = NULL; dest->hostData.ipFuture = source->hostData.ipFuture; } /* Copy portText */ dest->portText = source->portText; return URI_TRUE; } UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { URI_TYPE(PathSegment) * segment; if (/* Case 1: absolute path, empty first segment */ (uri->absolutePath && (uri->pathHead != NULL) && (uri->pathHead->text.afterLast == uri->pathHead->text.first)) /* Case 2: relative path, empty first and second segment */ || (!uri->absolutePath && (uri->pathHead != NULL) && (uri->pathHead->next != NULL) && (uri->pathHead->text.afterLast == uri->pathHead->text.first) && (uri->pathHead->next->text.afterLast == uri->pathHead->next->text.first))) { /* NOOP */ } else { return URI_TRUE; } segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } /* Insert "." segment in front */ segment->next = uri->pathHead; segment->text.first = URI_FUNC(ConstPwd); segment->text.afterLast = URI_FUNC(ConstPwd) + 1; uri->pathHead = segment; return URI_TRUE; } static UriBool URI_FUNC(PrependNewDotSegment)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { assert(uri != NULL); assert(memory != NULL); URI_TYPE(PathSegment) * const segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* i.e. raise malloc error */ } segment->next = uri->pathHead; URI_TYPE(TextRange) dotRange; dotRange.first = URI_FUNC(ConstPwd); dotRange.afterLast = URI_FUNC(ConstPwd) + 1; if (uri->owner == URI_TRUE) { if (URI_FUNC(CopyRange)(&(segment->text), &dotRange, memory) == URI_FALSE) { memory->free(memory, segment); return URI_FALSE; /* i.e. raise malloc error */ } } else { segment->text = dotRange; /* copies all members */ } uri->pathHead = segment; return URI_TRUE; } /* When dropping a scheme from a URI without a host and with a colon (":") * in the first path segment, a consecutive reparse would rightfully * mis-classify the first path segment as a scheme due to the colon. * To protect against this case, we prepend an artificial "." segment * to the path in here; the function is called after the scheme has * just been dropped. * * 0. We start with parsed URI "scheme:path1:/path2/path3". * 1. We drop the scheme naively and yield "path1:/path2/path3". * 2. We prepend "." and yield unambiguous "./path1:/path2/path3". * * From the view of the RFC 3986 grammar, this is replacing rule path-rootless * by path-noscheme content. * * Returns URI_TRUE for (a) nothing to do or (b) successful changes. * Returns URI_FALSE to signal out-of-memory. */ UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { assert(uri != NULL); assert(memory != NULL); if ((uri->absolutePath == URI_TRUE) || (uri->pathHead == NULL) || (uri->scheme.first != NULL) || URI_FUNC(HasHost)(uri)) { return URI_TRUE; /* i.e. nothing to do */ } /* Check for troublesome first path segment containing a colon */ UriBool colonFound = URI_FALSE; const URI_CHAR * walker = uri->pathHead->text.first; while (walker < uri->pathHead->text.afterLast) { if (walker[0] == _UT(':')) { colonFound = URI_TRUE; break; } walker++; } assert((walker == uri->pathHead->text.afterLast) || (colonFound == URI_TRUE)); if (colonFound == URI_FALSE) { return URI_TRUE; /* i.e. nothing to do */ } /* Insert "." segment in front */ return URI_FUNC(PrependNewDotSegment)(uri, memory); } /* When dropping a host from a URI without a scheme, an absolute path * and and empty first path segment, a consecutive reparse would rightfully * mis-classify the first path segment as a host marker due to the "//". * To protect against this case, we prepend an artificial "." segment * to the path in here; the function is called after the host has * just been dropped. * * 0. We start with parsed URI "//host//path1/path2". * 1. We drop the host naively and yield "//path1/path2". * 2. We insert "./" and yield unambiguous "/.//path1/path2". * * Returns URI_TRUE for (a) nothing to do or (b) successful changes. * Returns URI_FALSE to signal out-of-memory. */ UriBool URI_FUNC(EnsureThatPathIsNotMistakenForHost)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { assert(uri != NULL); assert(memory != NULL); if ((URI_FUNC(HasHost)(uri) == URI_TRUE) || (uri->absolutePath == URI_FALSE) || (uri->pathHead == NULL) || (uri->pathHead == uri->pathTail) /* i.e. no second slash */ || (uri->pathHead->text.first != uri->pathHead->text.afterLast)) { return URI_TRUE; /* i.e. nothing to do */ } /* Insert "." segment in front */ return URI_FUNC(PrependNewDotSegment)(uri, memory); } void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { /* Fix path if only one empty segment */ if (!uri->absolutePath && !URI_FUNC(HasHost)(uri) && (uri->pathHead != NULL) && (uri->pathHead->next == NULL) && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) { memory->free(memory, uri->pathHead); uri->pathHead = NULL; uri->pathTail = NULL; } } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriCommon.h000066400000000000000000000115001516712004000272640ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #if (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE)) \ || (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* What encodings are enabled? */ # include # if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriCommon.h" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriCommon.h" # undef URI_PASS_UNICODE # endif /* Only one pass for each encoding */ # elif (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI) \ && defined(URI_ENABLE_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE) \ && defined(URI_ENABLE_UNICODE)) # ifdef URI_PASS_ANSI # define URI_COMMON_H_ANSI 1 # include # else # define URI_COMMON_H_UNICODE 1 # include # endif /* Used to point to from empty path segments. * X.first and X.afterLast must be the same non-NULL value then. */ extern const URI_CHAR * const URI_FUNC(SafeToPointTo); extern const URI_CHAR * const URI_FUNC(ConstPwd); extern const URI_CHAR * const URI_FUNC(ConstParent); void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri); int URI_FUNC(FreeUriPath)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b); UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory); UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory); UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, UriBool relative, UriBool pathOwned, UriMemoryManager * memory); unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig); URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase); UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source, UriMemoryManager * memory); UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source, UriMemoryManager * memory); UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); UriBool URI_FUNC(EnsureThatPathIsNotMistakenForHost)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); # endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriCompare.c000066400000000000000000000117531516712004000274270ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriCompare.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriCompare.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include # include "UriCommon.h" # endif UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) { /* NOTE: Both NULL means equal! */ if ((a == NULL) || (b == NULL)) { return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE; } /* scheme */ if (URI_FUNC(CompareRange)(&(a->scheme), &(b->scheme))) { return URI_FALSE; } /* absolutePath */ if ((a->scheme.first == NULL) && (a->absolutePath != b->absolutePath)) { return URI_FALSE; } /* userInfo */ if (URI_FUNC(CompareRange)(&(a->userInfo), &(b->userInfo))) { return URI_FALSE; } /* Host */ if (((a->hostData.ip4 == NULL) != (b->hostData.ip4 == NULL)) || ((a->hostData.ip6 == NULL) != (b->hostData.ip6 == NULL)) || ((a->hostData.ipFuture.first == NULL) != (b->hostData.ipFuture.first == NULL))) { return URI_FALSE; } if (a->hostData.ip4 != NULL) { if (memcmp(a->hostData.ip4->data, b->hostData.ip4->data, 4)) { return URI_FALSE; } } if (a->hostData.ip6 != NULL) { if (memcmp(a->hostData.ip6->data, b->hostData.ip6->data, 16)) { return URI_FALSE; } } if (a->hostData.ipFuture.first != NULL) { if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) { return URI_FALSE; } } if ((a->hostData.ip4 == NULL) && (a->hostData.ip6 == NULL) && (a->hostData.ipFuture.first == NULL)) { if (URI_FUNC(CompareRange)(&(a->hostText), &(b->hostText))) { return URI_FALSE; } } /* portText */ if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) { return URI_FALSE; } /* Path */ if ((a->pathHead == NULL) != (b->pathHead == NULL)) { return URI_FALSE; } if (a->pathHead != NULL) { URI_TYPE(PathSegment) * walkA = a->pathHead; URI_TYPE(PathSegment) * walkB = b->pathHead; do { if (URI_FUNC(CompareRange)(&(walkA->text), &(walkB->text))) { return URI_FALSE; } if ((walkA->next == NULL) != (walkB->next == NULL)) { return URI_FALSE; } walkA = walkA->next; walkB = walkB->next; } while (walkA != NULL); } /* query */ if (URI_FUNC(CompareRange)(&(a->query), &(b->query))) { return URI_FALSE; } /* fragment */ if (URI_FUNC(CompareRange)(&(a->fragment), &(b->fragment))) { return URI_FALSE; } return URI_TRUE; /* Equal*/ } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriConfig.h000066400000000000000000000036451516712004000272540ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2018, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(URI_CONFIG_H) # define URI_CONFIG_H 1 # define PACKAGE_VERSION "1.0.0" #undef HAVE_WPRINTF #undef HAVE_REALLOCARRAY #endif /* !defined(URI_CONFIG_H) */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriDefsAnsi.h000066400000000000000000000050231516712004000275330ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriDefsAnsi.h * Holds definitions for the ANSI pass. * NOTE: This header is included N times, not once. */ /* Allow multi inclusion */ #include "UriDefsConfig.h" #undef URI_CHAR #define URI_CHAR char #undef _UT #define _UT(x) x #undef URI_FUNC #define URI_FUNC(x) uri##x##A #undef URI_TYPE #define URI_TYPE(x) Uri##x##A #undef URI_STRLEN #define URI_STRLEN strlen #undef URI_STRCPY #define URI_STRCPY strcpy #undef URI_STRCMP #define URI_STRCMP strcmp #undef URI_STRNCMP #define URI_STRNCMP strncmp /* TODO Remove on next source-compatibility break */ #undef URI_SNPRINTF #if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) # define URI_SNPRINTF _snprintf #else # define URI_SNPRINTF snprintf #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriDefsConfig.h000066400000000000000000000064441516712004000300560ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriDefsConfig.h * Adjusts the internal configuration after processing external definitions. */ #ifndef URI_DEFS_CONFIG_H # define URI_DEFS_CONFIG_H 1 /* Deny external overriding */ # undef URI_ENABLE_ANSI /* Internal for !URI_NO_ANSI */ # undef URI_ENABLE_UNICODE /* Internal for !URI_NO_UNICODE */ /* Encoding */ # ifdef URI_NO_ANSI # ifdef URI_NO_UNICODE /* No encoding at all */ # error URI_NO_ANSI and URI_NO_UNICODE cannot go together. # else /* Wide strings only */ # define URI_ENABLE_UNICODE 1 # endif # else # ifdef URI_NO_UNICODE /* Narrow strings only */ # define URI_ENABLE_ANSI 1 # else /* Both narrow and wide strings */ # define URI_ENABLE_ANSI 1 # define URI_ENABLE_UNICODE 1 # endif # endif /* Function inlining, not ANSI/ISO C! */ # if defined(URI_DOXYGEN) # define URI_INLINE # elif defined(__INTEL_COMPILER) /* Intel C/C++ */ /* http://predef.sourceforge.net/precomp.html#sec20 */ /* http://www.intel.com/support/performancetools/c/windows/sb/CS-007751.htm#2 */ # define URI_INLINE __forceinline # elif defined(_MSC_VER) /* Microsoft Visual C++ */ /* http://predef.sourceforge.net/precomp.html#sec32 */ /* http://msdn2.microsoft.com/en-us/library/ms882281.aspx */ # define URI_INLINE __forceinline # elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99, "inline" is a keyword */ # define URI_INLINE inline # else /* No inlining */ # define URI_INLINE # endif #endif /* URI_DEFS_CONFIG_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriDefsUnicode.h000066400000000000000000000050441516712004000302320ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriDefsUnicode.h * Holds definitions for the wide string pass. * NOTE: This header is included N times, not once. */ /* Allow multi inclusion */ #include "UriDefsConfig.h" #undef URI_CHAR #define URI_CHAR wchar_t #undef _UT #define _UT(x) L##x #undef URI_FUNC #define URI_FUNC(x) uri##x##W #undef URI_TYPE #define URI_TYPE(x) Uri##x##W #undef URI_STRLEN #define URI_STRLEN wcslen #undef URI_STRCPY #define URI_STRCPY wcscpy #undef URI_STRCMP #define URI_STRCMP wcscmp #undef URI_STRNCMP #define URI_STRNCMP wcsncmp /* TODO Remove on next source-compatibility break */ #undef URI_SNPRINTF #if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) # define URI_SNPRINTF _snwprintf #else # define URI_SNPRINTF swprintf #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriEscape.c000066400000000000000000000247351516712004000272450ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriEscape.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriEscape.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # include "UriSets.h" # endif URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out, UriBool spaceToPlus, UriBool normalizeBreaks) { return URI_FUNC(EscapeEx)(in, NULL, out, spaceToPlus, normalizeBreaks); } URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst, const URI_CHAR * inAfterLast, URI_CHAR * out, UriBool spaceToPlus, UriBool normalizeBreaks) { const URI_CHAR * read = inFirst; URI_CHAR * write = out; UriBool prevWasCr = URI_FALSE; if ((out == NULL) || (inFirst == out)) { return NULL; } else if (inFirst == NULL) { if (out != NULL) { out[0] = _UT('\0'); } return out; } for (;;) { if ((inAfterLast != NULL) && (read >= inAfterLast)) { write[0] = _UT('\0'); return write; } switch (read[0]) { case _UT('\0'): write[0] = _UT('\0'); return write; case _UT(' '): if (spaceToPlus) { write[0] = _UT('+'); write++; } else { write[0] = _UT('%'); write[1] = _UT('2'); write[2] = _UT('0'); write += 3; } prevWasCr = URI_FALSE; break; case URI_SET_UNRESERVED(_UT): /* Copy unmodified */ write[0] = read[0]; write++; prevWasCr = URI_FALSE; break; case _UT('\x0a'): if (normalizeBreaks) { if (!prevWasCr) { write[0] = _UT('%'); write[1] = _UT('0'); write[2] = _UT('D'); write[3] = _UT('%'); write[4] = _UT('0'); write[5] = _UT('A'); write += 6; } } else { write[0] = _UT('%'); write[1] = _UT('0'); write[2] = _UT('A'); write += 3; } prevWasCr = URI_FALSE; break; case _UT('\x0d'): if (normalizeBreaks) { write[0] = _UT('%'); write[1] = _UT('0'); write[2] = _UT('D'); write[3] = _UT('%'); write[4] = _UT('0'); write[5] = _UT('A'); write += 6; } else { write[0] = _UT('%'); write[1] = _UT('0'); write[2] = _UT('D'); write += 3; } prevWasCr = URI_TRUE; break; default: /* Percent encode */ { const unsigned char code = (unsigned char)read[0]; /* Uppercase recommended in (last sentence of) section 2.1 * * of RFC 3986: * * https://datatracker.ietf.org/doc/html/rfc3986#section-2.1 */ write[0] = _UT('%'); write[1] = URI_FUNC(HexToLetterEx)(code >> 4, URI_TRUE); write[2] = URI_FUNC(HexToLetterEx)(code & 0x0f, URI_TRUE); write += 3; } prevWasCr = URI_FALSE; break; } read++; } } const URI_CHAR * URI_FUNC(UnescapeInPlace)(URI_CHAR * inout) { return URI_FUNC(UnescapeInPlaceEx)(inout, URI_FALSE, URI_BR_DONT_TOUCH); } const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout, UriBool plusToSpace, UriBreakConversion breakConversion) { URI_CHAR * read = inout; URI_CHAR * write = inout; UriBool prevWasCr = URI_FALSE; if (inout == NULL) { return NULL; } for (;;) { switch (read[0]) { case _UT('\0'): if (read > write) { write[0] = _UT('\0'); } return write; case _UT('%'): switch (read[1]) { case URI_SET_HEXDIG(_UT): switch (read[2]) { case URI_SET_HEXDIG(_UT): { /* Percent group found */ const unsigned char left = URI_FUNC(HexdigToInt)(read[1]); const unsigned char right = URI_FUNC(HexdigToInt)(read[2]); const int code = 16 * left + right; switch (code) { case 10: switch (breakConversion) { case URI_BR_TO_LF: if (!prevWasCr) { write[0] = (URI_CHAR)10; write++; } break; case URI_BR_TO_CRLF: if (!prevWasCr) { write[0] = (URI_CHAR)13; write[1] = (URI_CHAR)10; write += 2; } break; case URI_BR_TO_CR: if (!prevWasCr) { write[0] = (URI_CHAR)13; write++; } break; case URI_BR_DONT_TOUCH: default: write[0] = (URI_CHAR)10; write++; } prevWasCr = URI_FALSE; break; case 13: switch (breakConversion) { case URI_BR_TO_LF: write[0] = (URI_CHAR)10; write++; break; case URI_BR_TO_CRLF: write[0] = (URI_CHAR)13; write[1] = (URI_CHAR)10; write += 2; break; case URI_BR_TO_CR: write[0] = (URI_CHAR)13; write++; break; case URI_BR_DONT_TOUCH: default: write[0] = (URI_CHAR)13; write++; } prevWasCr = URI_TRUE; break; default: write[0] = (URI_CHAR)(code); write++; prevWasCr = URI_FALSE; } read += 3; } break; default: /* Copy two chars unmodified and */ /* look at this char again */ if (read > write) { write[0] = read[0]; write[1] = read[1]; } read += 2; write += 2; prevWasCr = URI_FALSE; } break; default: /* Copy one char unmodified and */ /* look at this char again */ if (read > write) { write[0] = read[0]; } read++; write++; prevWasCr = URI_FALSE; } break; case _UT('+'): if (plusToSpace) { /* Convert '+' to ' ' */ write[0] = _UT(' '); } else { /* Copy one char unmodified */ if (read > write) { write[0] = read[0]; } } read++; write++; prevWasCr = URI_FALSE; break; default: /* Copy one char unmodified */ if (read > write) { write[0] = read[0]; } read++; write++; prevWasCr = URI_FALSE; } } } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriFile.c000066400000000000000000000211061516712004000267110ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriFile.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriFile.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # endif # include /* for size_t, avoiding stddef.h for older MSVCs */ static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString, UriBool fromUnix) { const URI_CHAR * input = filename; const URI_CHAR * lastSep = input - 1; UriBool firstSegment = URI_TRUE; URI_CHAR * output = uriString; UriBool absolute; UriBool is_windows_network; if ((filename == NULL) || (uriString == NULL)) { return URI_ERROR_NULL; } is_windows_network = (filename[0] == _UT('\\')) && (filename[1] == _UT('\\')); absolute = fromUnix ? (filename[0] == _UT('/')) : (((filename[0] != _UT('\0')) && (filename[1] == _UT(':'))) || is_windows_network); if (absolute) { const URI_CHAR * const prefix = fromUnix ? _UT("file://") : is_windows_network ? _UT("file:") : _UT("file:///"); const size_t prefixLen = URI_STRLEN(prefix); /* Copy prefix */ memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR)); output += prefixLen; } /* Copy and escape on the fly */ for (;;) { if ((input[0] == _UT('\0')) || (fromUnix && input[0] == _UT('/')) || (!fromUnix && input[0] == _UT('\\'))) { /* Copy text after last separator */ if (lastSep + 1 < input) { if (!fromUnix && absolute && (firstSegment == URI_TRUE)) { /* Quick hack to not convert "C:" to "C%3A" */ const int charsToCopy = (int)(input - (lastSep + 1)); memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR)); output += charsToCopy; } else { output = URI_FUNC(EscapeEx)(lastSep + 1, input, output, URI_FALSE, URI_FALSE); } } firstSegment = URI_FALSE; } if (input[0] == _UT('\0')) { output[0] = _UT('\0'); break; } else if (fromUnix && (input[0] == _UT('/'))) { /* Copy separators unmodified */ output[0] = _UT('/'); output++; lastSep = input; } else if (!fromUnix && (input[0] == _UT('\\'))) { /* Convert backslashes to forward slashes */ output[0] = _UT('/'); output++; lastSep = input; } input++; } return URI_SUCCESS; } static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString, URI_CHAR * filename, UriBool toUnix) { if ((uriString == NULL) || (filename == NULL)) { return URI_ERROR_NULL; } const UriBool file_unknown_slashes = URI_STRNCMP(uriString, _UT("file:"), URI_STRLEN(_UT("file:"))) == 0; const UriBool file_one_or_more_slashes = file_unknown_slashes && (URI_STRNCMP(uriString, _UT("file:/"), URI_STRLEN(_UT("file:/"))) == 0); const UriBool file_two_or_more_slashes = file_one_or_more_slashes && (URI_STRNCMP(uriString, _UT("file://"), URI_STRLEN(_UT("file://"))) == 0); const UriBool file_three_or_more_slashes = file_two_or_more_slashes && (URI_STRNCMP(uriString, _UT("file:///"), URI_STRLEN(_UT("file:///"))) == 0); const size_t charsToSkip = file_two_or_more_slashes ? file_three_or_more_slashes ? toUnix /* file:///bin/bash */ ? URI_STRLEN(_UT("file://")) /* file:///E:/Documents%20and%20Settings */ : URI_STRLEN(_UT("file:///")) /* file://Server01/Letter.txt */ : URI_STRLEN(_UT("file://")) : ((file_one_or_more_slashes && toUnix) /* file:/bin/bash */ /* https://tools.ietf.org/html/rfc8089#appendix-B */ ? URI_STRLEN(_UT("file:")) : ((!toUnix && file_unknown_slashes && !file_one_or_more_slashes) /* file:c:/path/to/file */ /* https://tools.ietf.org/html/rfc8089#appendix-E.2 */ ? URI_STRLEN(_UT("file:")) : 0)); const size_t charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1; const UriBool is_windows_network_with_authority = (toUnix == URI_FALSE) && file_two_or_more_slashes && !file_three_or_more_slashes; URI_CHAR * const unescape_target = is_windows_network_with_authority ? (filename + 2) : filename; if (is_windows_network_with_authority) { filename[0] = '\\'; filename[1] = '\\'; } memcpy(unescape_target, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR)); URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH); /* Convert forward slashes to backslashes */ if (!toUnix) { URI_CHAR * walker = filename; while (walker[0] != _UT('\0')) { if (walker[0] == _UT('/')) { walker[0] = _UT('\\'); } walker++; } } return URI_SUCCESS; } int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) { return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE); } int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) { return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE); } int URI_FUNC(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename) { return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE); } int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString, URI_CHAR * filename) { return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE); } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriIp4.c000066400000000000000000000231341516712004000264710ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriIp4.c * Holds the IPv4 parser implementation. * NOTE: This source file includes itself twice. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriIp4.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriIp4.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # endif # ifndef URI_DOXYGEN # include # include "UriIp4Base.h" # include # include "UriSets.h" # endif /* Prototypes */ static const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast); /* * [ipFourAddress]->[decOctet]<.>[decOctet]<.>[decOctet]<.>[decOctet] */ int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput, const URI_CHAR * first, const URI_CHAR * afterLast) { const URI_CHAR * after; UriIp4Parser parser; /* Essential checks */ if ((octetOutput == NULL) || (first == NULL) || (afterLast <= first)) { return URI_ERROR_SYNTAX; } /* Reset parser */ parser.stackCount = 0; /* Octet #1 */ after = URI_FUNC(ParseDecOctet)(&parser, first, afterLast); if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) { return URI_ERROR_SYNTAX; } uriStackToOctet(&parser, octetOutput); /* Octet #2 */ after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast); if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) { return URI_ERROR_SYNTAX; } uriStackToOctet(&parser, octetOutput + 1); /* Octet #3 */ after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast); if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) { return URI_ERROR_SYNTAX; } uriStackToOctet(&parser, octetOutput + 2); /* Octet #4 */ after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast); if (after != afterLast) { return URI_ERROR_SYNTAX; } uriStackToOctet(&parser, octetOutput + 3); return URI_SUCCESS; } /* * [decOctet]-><0> * [decOctet]-><1>[decOctetOne] * [decOctet]-><2>[decOctetTwo] * [decOctet]-><3>[decOctetThree] * [decOctet]-><4>[decOctetThree] * [decOctet]-><5>[decOctetThree] * [decOctet]-><6>[decOctetThree] * [decOctet]-><7>[decOctetThree] * [decOctet]-><8>[decOctetThree] * [decOctet]-><9>[decOctetThree] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return NULL; } switch (*first) { case _UT('0'): uriPushToStack(parser, 0); return first + 1; case _UT('1'): uriPushToStack(parser, 1); return (const URI_CHAR *)URI_FUNC(ParseDecOctetOne)(parser, first + 1, afterLast); case _UT('2'): uriPushToStack(parser, 2); return (const URI_CHAR *)URI_FUNC(ParseDecOctetTwo)(parser, first + 1, afterLast); case _UT('3'): case _UT('4'): case _UT('5'): case _UT('6'): case _UT('7'): case _UT('8'): case _UT('9'): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast); default: return NULL; } } /* * [decOctetOne]-> * [decOctetOne]->[DIGIT][decOctetThree] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_DIGIT(_UT): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast); default: return first; } } /* * [decOctetTwo]-> * [decOctetTwo]-><0>[decOctetThree] * [decOctetTwo]-><1>[decOctetThree] * [decOctetTwo]-><2>[decOctetThree] * [decOctetTwo]-><3>[decOctetThree] * [decOctetTwo]-><4>[decOctetThree] * [decOctetTwo]-><5>[decOctetFour] * [decOctetTwo]-><6> * [decOctetTwo]-><7> * [decOctetTwo]-><8> * [decOctetTwo]-><9> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('0'): case _UT('1'): case _UT('2'): case _UT('3'): case _UT('4'): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast); case _UT('5'): uriPushToStack(parser, 5); return (const URI_CHAR *)URI_FUNC(ParseDecOctetFour)(parser, first + 1, afterLast); case _UT('6'): case _UT('7'): case _UT('8'): case _UT('9'): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return first + 1; default: return first; } } /* * [decOctetThree]-> * [decOctetThree]->[DIGIT] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_DIGIT(_UT): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return first + 1; default: return first; } } /* * [decOctetFour]-> * [decOctetFour]-><0> * [decOctetFour]-><1> * [decOctetFour]-><2> * [decOctetFour]-><3> * [decOctetFour]-><4> * [decOctetFour]-><5> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('0'): case _UT('1'): case _UT('2'): case _UT('3'): case _UT('4'): case _UT('5'): uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9'))); return first + 1; default: return first; } } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriIp4.h000066400000000000000000000072271516712004000265030ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriIp4.h * Holds the IPv4 parser interface. * NOTE: This header includes itself twice. */ #if (defined(URI_PASS_ANSI) && !defined(URI_IP4_TWICE_H_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_IP4_TWICE_H_UNICODE)) \ || (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* What encodings are enabled? */ # include "UriDefsConfig.h" # if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriIp4.h" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriIp4.h" # undef URI_PASS_UNICODE # endif /* Only one pass for each encoding */ # elif (defined(URI_PASS_ANSI) && !defined(URI_IP4_TWICE_H_ANSI) \ && defined(URI_ENABLE_ANSI)) \ || (defined(URI_PASS_UNICODE) && !defined(URI_IP4_TWICE_H_UNICODE) \ && defined(URI_ENABLE_UNICODE)) # ifdef URI_PASS_ANSI # define URI_IP4_TWICE_H_ANSI 1 # include "UriDefsAnsi.h" # else # define URI_IP4_TWICE_H_UNICODE 1 # include "UriDefsUnicode.h" # include # endif # ifdef __cplusplus extern "C" { # endif # ifndef URI_DOXYGEN # include "UriBase.h" # endif /** * Converts an IPv4 text representation into four bytes. * * @param octetOutput Output destination * @param first First character of IPv4 text to parse * @param afterLast Position to stop parsing at * @return Error code or 0 on success * * @see uriParseIpSixAddressA * @see uriParseIpSixAddressMmA */ URI_PUBLIC int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput, const URI_CHAR * first, const URI_CHAR * afterLast); # ifdef __cplusplus } # endif # endif #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriIp4Base.c000066400000000000000000000053611516712004000272660ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriIp4Base.c * Holds code independent of the encoding pass. */ #ifndef URI_DOXYGEN # include "UriIp4Base.h" #endif void uriStackToOctet(UriIp4Parser * parser, unsigned char * octet) { switch (parser->stackCount) { case 1: *octet = parser->stackOne; break; case 2: *octet = parser->stackOne * 10 + parser->stackTwo; break; case 3: *octet = parser->stackOne * 100 + parser->stackTwo * 10 + parser->stackThree; break; default:; } parser->stackCount = 0; } void uriPushToStack(UriIp4Parser * parser, unsigned char digit) { switch (parser->stackCount) { case 0: parser->stackOne = digit; parser->stackCount = 1; break; case 1: parser->stackTwo = digit; parser->stackCount = 2; break; case 2: parser->stackThree = digit; parser->stackCount = 3; break; default:; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriIp4Base.h000066400000000000000000000042621516712004000272720ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_IP4_BASE_H # define URI_IP4_BASE_H 1 typedef struct UriIp4ParserStruct { unsigned char stackCount; unsigned char stackOne; unsigned char stackTwo; unsigned char stackThree; } UriIp4Parser; void uriPushToStack(UriIp4Parser * parser, unsigned char digit); void uriStackToOctet(UriIp4Parser * parser, unsigned char * octet); #endif /* URI_IP4_BASE_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriMemory.c000066400000000000000000000331731516712004000273110ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2018, Weijia Song * Copyright (C) 2018, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriMemory.c * Holds memory manager implementation. */ #include "UriConfig.h" /* for HAVE_REALLOCARRAY */ #ifdef HAVE_REALLOCARRAY # ifndef _GNU_SOURCE # define _GNU_SOURCE 1 # endif # ifdef __NetBSD__ # define _OPENBSD_SOURCE 1 # endif #endif #include #include #ifndef URI_DOXYGEN # include "UriMemory.h" #endif #define URI_MAX(a, b) (((a) > (b)) ? (a) : (b)) /* NOTE: This intends to mimic MALLOC_ALIGNMENT of glibc */ #define URI_MALLOC_ALIGNMENT URI_MAX(2 * sizeof(size_t), sizeof(long double)) #define URI_MALLOC_PADDING (URI_MALLOC_ALIGNMENT - sizeof(size_t)) #define URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size) \ do { \ /* check for unsigned overflow */ \ if ((nmemb != 0) && (total_size / nmemb != size)) { \ errno = ENOMEM; \ return NULL; \ } \ } while (0) static void * uriDefaultMalloc(UriMemoryManager * URI_UNUSED(memory), size_t size) { return malloc(size); } static void * uriDefaultCalloc(UriMemoryManager * URI_UNUSED(memory), size_t nmemb, size_t size) { return calloc(nmemb, size); } static void * uriDefaultRealloc(UriMemoryManager * URI_UNUSED(memory), void * ptr, size_t size) { return realloc(ptr, size); } static void * uriDefaultReallocarray(UriMemoryManager * URI_UNUSED(memory), void * ptr, size_t nmemb, size_t size) { #ifdef HAVE_REALLOCARRAY return reallocarray(ptr, nmemb, size); #else const size_t total_size = nmemb * size; URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ return realloc(ptr, total_size); #endif } static void uriDefaultFree(UriMemoryManager * URI_UNUSED(memory), void * ptr) { free(ptr); } UriBool uriMemoryManagerIsComplete(const UriMemoryManager * memory) { return (memory && memory->malloc && memory->calloc && memory->realloc && memory->reallocarray && memory->free) ? URI_TRUE : URI_FALSE; } void * uriEmulateCalloc(UriMemoryManager * memory, size_t nmemb, size_t size) { void * buffer; const size_t total_size = nmemb * size; if (memory == NULL) { errno = EINVAL; return NULL; } URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ buffer = memory->malloc(memory, total_size); if (buffer == NULL) { /* errno set by malloc */ return NULL; } memset(buffer, 0, total_size); return buffer; } void * uriEmulateReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size) { const size_t total_size = nmemb * size; if (memory == NULL) { errno = EINVAL; return NULL; } URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ return memory->realloc(memory, ptr, total_size); } static void * uriDecorateMalloc(UriMemoryManager * memory, size_t size) { UriMemoryManager * backend; const size_t extraBytes = sizeof(size_t) + URI_MALLOC_PADDING; void * buffer; if (memory == NULL) { errno = EINVAL; return NULL; } /* check for unsigned overflow */ if (size > ((size_t)-1) - extraBytes) { errno = ENOMEM; return NULL; } backend = (UriMemoryManager *)memory->userData; if (backend == NULL) { errno = EINVAL; return NULL; } buffer = backend->malloc(backend, extraBytes + size); if (buffer == NULL) { return NULL; } *(size_t *)buffer = size; return (char *)buffer + extraBytes; } static void * uriDecorateRealloc(UriMemoryManager * memory, void * ptr, size_t size) { void * newBuffer; size_t prevSize; if (memory == NULL) { errno = EINVAL; return NULL; } /* man realloc: "If ptr is NULL, then the call is equivalent to * malloc(size), for *all* values of size" */ if (ptr == NULL) { return memory->malloc(memory, size); } /* man realloc: "If size is equal to zero, and ptr is *not* NULL, * then the call is equivalent to free(ptr)." */ if (size == 0) { memory->free(memory, ptr); return NULL; } prevSize = *((size_t *)((char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING)); /* Anything to do? */ /* mull-ignore-next cxx_le_to_lt */ if (size <= prevSize) { return ptr; } newBuffer = memory->malloc(memory, size); if (newBuffer == NULL) { /* errno set by malloc */ return NULL; } memcpy(newBuffer, ptr, prevSize); memory->free(memory, ptr); return newBuffer; } static void uriDecorateFree(UriMemoryManager * memory, void * ptr) { UriMemoryManager * backend; if ((ptr == NULL) || (memory == NULL)) { return; } backend = (UriMemoryManager *)memory->userData; if (backend == NULL) { return; } backend->free(backend, (char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING); } int uriCompleteMemoryManager(UriMemoryManager * memory, UriMemoryManager * backend) { if ((memory == NULL) || (backend == NULL)) { return URI_ERROR_NULL; } if ((backend->malloc == NULL) || (backend->free == NULL)) { return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; } memory->calloc = uriEmulateCalloc; memory->reallocarray = uriEmulateReallocarray; memory->malloc = uriDecorateMalloc; memory->realloc = uriDecorateRealloc; memory->free = uriDecorateFree; memory->userData = backend; return URI_SUCCESS; } /* mull-off */ int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment) { const size_t mallocSize = 7; const size_t callocNmemb = 3; const size_t callocSize = 5; const size_t callocTotalSize = callocNmemb * callocSize; const size_t reallocSize = 11; const size_t reallocarrayNmemb = 5; const size_t reallocarraySize = 7; const size_t reallocarrayTotal = reallocarrayNmemb * reallocarraySize; size_t index; char * buffer; if (memory == NULL) { return URI_ERROR_NULL; } if (uriMemoryManagerIsComplete(memory) != URI_TRUE) { return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; } /* malloc + free*/ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xF1'; memory->free(memory, buffer); buffer = NULL; /* calloc + free */ buffer = memory->calloc(memory, callocNmemb, callocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } for (index = 0; index < callocTotalSize; index++) { /* all zeros? */ if (buffer[index] != '\0') { return URI_ERROR_MEMORY_MANAGER_FAULTY; } } buffer[callocTotalSize - 1] = '\xF2'; memory->free(memory, buffer); buffer = NULL; /* malloc + realloc + free */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } for (index = 0; index < mallocSize; index++) { buffer[index] = '\xF3'; } buffer = memory->realloc(memory, buffer, reallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } for (index = 0; index < mallocSize; index++) { /* previous content? */ if (buffer[index] != '\xF3') { return URI_ERROR_MEMORY_MANAGER_FAULTY; } } buffer[reallocSize - 1] = '\xF4'; memory->free(memory, buffer); buffer = NULL; /* malloc + realloc ptr!=NULL size==0 (equals free) */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xF5'; memory->realloc(memory, buffer, 0); buffer = NULL; /* realloc ptr==NULL size!=0 (equals malloc) + free */ buffer = memory->realloc(memory, NULL, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xF6'; memory->free(memory, buffer); buffer = NULL; /* realloc ptr==NULL size==0 (equals malloc) + free */ buffer = memory->realloc(memory, NULL, 0); if (buffer != NULL) { memory->free(memory, buffer); buffer = NULL; } /* malloc + reallocarray + free */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } for (index = 0; index < mallocSize; index++) { buffer[index] = '\xF7'; } buffer = memory->reallocarray(memory, buffer, reallocarrayNmemb, reallocarraySize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } for (index = 0; index < mallocSize; index++) { /* previous content? */ if (buffer[index] != '\xF7') { return URI_ERROR_MEMORY_MANAGER_FAULTY; } } buffer[reallocarrayTotal - 1] = '\xF8'; memory->free(memory, buffer); buffer = NULL; /* malloc + reallocarray ptr!=NULL nmemb==0 size!=0 (equals free) */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xF9'; memory->reallocarray(memory, buffer, 0, reallocarraySize); buffer = NULL; /* malloc + reallocarray ptr!=NULL nmemb!=0 size==0 (equals free) */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xFA'; memory->reallocarray(memory, buffer, reallocarrayNmemb, 0); buffer = NULL; /* malloc + reallocarray ptr!=NULL nmemb==0 size==0 (equals free) */ buffer = memory->malloc(memory, mallocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[mallocSize - 1] = '\xFB'; memory->reallocarray(memory, buffer, 0, 0); buffer = NULL; /* reallocarray ptr==NULL nmemb!=0 size!=0 (equals malloc) + free */ buffer = memory->reallocarray(memory, NULL, callocNmemb, callocSize); if (buffer == NULL) { return URI_ERROR_MEMORY_MANAGER_FAULTY; } buffer[callocTotalSize - 1] = '\xFC'; memory->free(memory, buffer); buffer = NULL; /* reallocarray ptr==NULL nmemb==0 size!=0 (equals malloc) + free */ buffer = memory->reallocarray(memory, NULL, 0, callocSize); if (buffer != NULL) { memory->free(memory, buffer); buffer = NULL; } /* reallocarray ptr==NULL nmemb!=0 size==0 (equals malloc) + free */ buffer = memory->reallocarray(memory, NULL, callocNmemb, 0); if (buffer != NULL) { memory->free(memory, buffer); buffer = NULL; } /* reallocarray ptr==NULL nmemb==0 size==0 (equals malloc) + free */ buffer = memory->reallocarray(memory, NULL, 0, 0); if (buffer != NULL) { memory->free(memory, buffer); buffer = NULL; } /* challenge pointer alignment */ if (challengeAlignment == URI_TRUE) { long double * ptr = memory->malloc(memory, 4 * sizeof(long double)); if (ptr != NULL) { ptr[0] = 0.0L; ptr[1] = 1.1L; ptr[2] = 2.2L; ptr[3] = 3.3L; long double * const ptrNew = memory->realloc(memory, ptr, 8 * sizeof(long double)); if (ptrNew != NULL) { ptr = ptrNew; ptr[4] = 4.4L; ptr[5] = 5.5L; ptr[6] = 6.6L; ptr[7] = 7.7L; } memory->free(memory, ptr); } } return URI_SUCCESS; } /* mull-on */ int uriTestMemoryManager(UriMemoryManager * memory) { return uriTestMemoryManagerEx(memory, /*challengeAlignment=*/URI_FALSE); } /*extern*/ UriMemoryManager defaultMemoryManager = { uriDefaultMalloc, uriDefaultCalloc, uriDefaultRealloc, uriDefaultReallocarray, uriDefaultFree, NULL /* userData */ }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriMemory.h000066400000000000000000000047731516712004000273220ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2018, Weijia Song * Copyright (C) 2018, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_MEMORY_H # define URI_MEMORY_H 1 # ifndef URI_DOXYGEN # include # endif # define URI_CHECK_MEMORY_MANAGER(memory) \ do { \ if (memory == NULL) { \ memory = &defaultMemoryManager; \ } else if (uriMemoryManagerIsComplete(memory) != URI_TRUE) { \ return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; \ } \ } while (0) # ifdef __cplusplus # define URIPARSER_EXTERN extern "C" # else # define URIPARSER_EXTERN extern # endif URIPARSER_EXTERN UriMemoryManager defaultMemoryManager; # undef URIPARSER_EXTERN UriBool uriMemoryManagerIsComplete(const UriMemoryManager * memory); #endif /* URI_MEMORY_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriNormalize.c000066400000000000000000001007471516712004000300030ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriNormalize.c * Holds the RFC 3986 %URI normalization implementation. * NOTE: This source file includes itself twice. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriNormalize.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriNormalize.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriNormalizeBase.h" # include "UriCommon.h" # include "UriMemory.h" # endif # include static int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask, UriMemoryManager * memory); static UriBool URI_FUNC(MakeRangeOwner)(unsigned int * revertMask, unsigned int maskTest, URI_TYPE(TextRange) * range, UriMemoryManager * memory); static UriBool URI_FUNC(MakeOwnerEngine)(URI_TYPE(Uri) * uri, unsigned int * revertMask, UriMemoryManager * memory); static void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first, const URI_CHAR ** afterLast); static UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory); static void URI_FUNC(FixPercentEncodingEngine)(const URI_CHAR * inFirst, const URI_CHAR * inAfterLast, const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast); static UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first, const URI_CHAR * afterLast); static UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first, const URI_CHAR * afterLast); static void URI_FUNC(LowercaseInplace)(const URI_CHAR * first, const URI_CHAR * afterLast); static void URI_FUNC(LowercaseInplaceExceptPercentEncoding)(const URI_CHAR * first, const URI_CHAR * afterLast); static UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory); void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, unsigned int revertMask, UriMemoryManager * memory) { if (revertMask & URI_NORMALIZE_SCHEME) { /* NOTE: A scheme cannot be the empty string * so no need to compare .first with .afterLast, here. */ memory->free(memory, (URI_CHAR *)uri->scheme.first); uri->scheme.first = NULL; uri->scheme.afterLast = NULL; } if (revertMask & URI_NORMALIZE_USER_INFO) { if (uri->userInfo.first != uri->userInfo.afterLast) { memory->free(memory, (URI_CHAR *)uri->userInfo.first); } uri->userInfo.first = NULL; uri->userInfo.afterLast = NULL; } if (revertMask & URI_NORMALIZE_HOST) { if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ /* NOTE: An IPvFuture address cannot be the empty string * so no need to compare .first with .afterLast, here. */ memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first); uri->hostData.ipFuture.first = NULL; uri->hostData.ipFuture.afterLast = NULL; uri->hostText.first = NULL; uri->hostText.afterLast = NULL; } else if (uri->hostText.first != NULL) { /* Regname */ if (uri->hostText.first != uri->hostText.afterLast) { memory->free(memory, (URI_CHAR *)uri->hostText.first); } uri->hostText.first = NULL; uri->hostText.afterLast = NULL; } } /* NOTE: Port cannot happen! */ if (revertMask & URI_NORMALIZE_PATH) { URI_TYPE(PathSegment) * walker = uri->pathHead; while (walker != NULL) { URI_TYPE(PathSegment) * const next = walker->next; if (walker->text.afterLast > walker->text.first) { memory->free(memory, (URI_CHAR *)walker->text.first); } memory->free(memory, walker); walker = next; } uri->pathHead = NULL; uri->pathTail = NULL; } if (revertMask & URI_NORMALIZE_QUERY) { if (uri->query.first != uri->query.afterLast) { memory->free(memory, (URI_CHAR *)uri->query.first); } uri->query.first = NULL; uri->query.afterLast = NULL; } if (revertMask & URI_NORMALIZE_FRAGMENT) { if (uri->fragment.first != uri->fragment.afterLast) { memory->free(memory, (URI_CHAR *)uri->fragment.first); } uri->fragment.first = NULL; uri->fragment.afterLast = NULL; } } static URI_INLINE UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first, const URI_CHAR * afterLast) { if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) { const URI_CHAR * i = first; for (; i < afterLast; i++) { /* 6.2.2.1 Case Normalization: uppercase letters in scheme or host */ if ((*i >= _UT('A')) && (*i <= _UT('Z'))) { return URI_TRUE; } } } return URI_FALSE; } static URI_INLINE UriBool URI_FUNC(ContainsUglyPercentEncoding)( const URI_CHAR * first, const URI_CHAR * afterLast) { if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) { const URI_CHAR * i = first; for (; i + 2 < afterLast; i++) { if (i[0] == _UT('%')) { /* 6.2.2.1 Case Normalization: * * lowercase percent-encodings */ if (((i[1] >= _UT('a')) && (i[1] <= _UT('f'))) || ((i[2] >= _UT('a')) && (i[2] <= _UT('f')))) { return URI_TRUE; } else { /* 6.2.2.2 Percent-Encoding Normalization: * * percent-encoded unreserved characters */ const unsigned char left = URI_FUNC(HexdigToInt)(i[1]); const unsigned char right = URI_FUNC(HexdigToInt)(i[2]); const int code = 16 * left + right; if (uriIsUnreserved(code)) { return URI_TRUE; } } } } } return URI_FALSE; } static URI_INLINE void URI_FUNC(LowercaseInplace)(const URI_CHAR * first, const URI_CHAR * afterLast) { if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) { URI_CHAR * i = (URI_CHAR *)first; const int lowerUpperDiff = (_UT('a') - _UT('A')); for (; i < afterLast; i++) { if ((*i >= _UT('A')) && (*i <= _UT('Z'))) { *i = (URI_CHAR)(*i + lowerUpperDiff); } } } } static URI_INLINE void URI_FUNC(LowercaseInplaceExceptPercentEncoding)(const URI_CHAR * first, const URI_CHAR * afterLast) { if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) { URI_CHAR * i = (URI_CHAR *)first; const int lowerUpperDiff = (_UT('a') - _UT('A')); for (; i < afterLast; i++) { if ((*i >= _UT('A')) && (*i <= _UT('Z'))) { *i = (URI_CHAR)(*i + lowerUpperDiff); } else if (*i == _UT('%')) { if (i + 3 >= afterLast) { return; } i += 2; } } } } static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory) { int lenInChars; const int lowerUpperDiff = (_UT('a') - _UT('A')); URI_CHAR * buffer; int i = 0; if ((first == NULL) || (afterLast == NULL) || (*first == NULL) || (*afterLast == NULL)) { return URI_FALSE; } lenInChars = (int)(*afterLast - *first); if (lenInChars == 0) { return URI_TRUE; } else if (lenInChars < 0) { return URI_FALSE; } buffer = memory->malloc(memory, lenInChars * sizeof(URI_CHAR)); if (buffer == NULL) { return URI_FALSE; } for (; i < lenInChars; i++) { if (((*first)[i] >= _UT('A')) && ((*first)[i] <= _UT('Z'))) { buffer[i] = (URI_CHAR)((*first)[i] + lowerUpperDiff); } else { buffer[i] = (*first)[i]; } } *first = buffer; *afterLast = buffer + lenInChars; return URI_TRUE; } /* NOTE: Implementation must stay inplace-compatible */ static URI_INLINE void URI_FUNC(FixPercentEncodingEngine)(const URI_CHAR * inFirst, const URI_CHAR * inAfterLast, const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast) { URI_CHAR * write = (URI_CHAR *)outFirst; const int lenInChars = (int)(inAfterLast - inFirst); int i = 0; /* All but last two */ for (; i + 2 < lenInChars; i++) { if (inFirst[i] != _UT('%')) { write[0] = inFirst[i]; write++; } else { /* 6.2.2.2 Percent-Encoding Normalization: * * percent-encoded unreserved characters */ const URI_CHAR one = inFirst[i + 1]; const URI_CHAR two = inFirst[i + 2]; const unsigned char left = URI_FUNC(HexdigToInt)(one); const unsigned char right = URI_FUNC(HexdigToInt)(two); const int code = 16 * left + right; if (uriIsUnreserved(code)) { write[0] = (URI_CHAR)(code); write++; } else { /* 6.2.2.1 Case Normalization: * * uppercase percent-encodings */ write[0] = _UT('%'); write[1] = URI_FUNC(HexToLetterEx)(left, URI_TRUE); write[2] = URI_FUNC(HexToLetterEx)(right, URI_TRUE); write += 3; } i += 2; /* For the two chars of the percent group we just ate */ } } /* Last two */ for (; i < lenInChars; i++) { write[0] = inFirst[i]; write++; } *outAfterLast = write; } static URI_INLINE void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first, const URI_CHAR ** afterLast) { /* Death checks */ if ((first == NULL) || (afterLast == NULL) || (*afterLast == NULL)) { return; } /* Fix inplace */ URI_FUNC(FixPercentEncodingEngine)(first, *afterLast, first, afterLast); } static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory) { int lenInChars; URI_CHAR * buffer; /* Death checks */ if ((first == NULL) || (afterLast == NULL) || (*first == NULL) || (*afterLast == NULL)) { return URI_FALSE; } /* Old text length */ lenInChars = (int)(*afterLast - *first); if (lenInChars == 0) { return URI_TRUE; } else if (lenInChars < 0) { return URI_FALSE; } /* New buffer */ buffer = memory->malloc(memory, lenInChars * sizeof(URI_CHAR)); if (buffer == NULL) { return URI_FALSE; } /* Fix on copy */ URI_FUNC(FixPercentEncodingEngine)(*first, *afterLast, buffer, afterLast); *first = buffer; return URI_TRUE; } static URI_INLINE UriBool URI_FUNC(MakeRangeOwner)(unsigned int * revertMask, unsigned int maskTest, URI_TYPE(TextRange) * range, UriMemoryManager * memory) { if (((*revertMask & maskTest) == 0) && (range->first != NULL) && (range->afterLast != NULL) && (range->afterLast > range->first)) { if (URI_FUNC(CopyRange)(range, range, memory) == URI_FALSE) { return URI_FALSE; } *revertMask |= maskTest; } return URI_TRUE; } static URI_INLINE UriBool URI_FUNC(MakeOwnerEngine)(URI_TYPE(Uri) * uri, unsigned int * revertMask, UriMemoryManager * memory) { URI_TYPE(PathSegment) * walker = uri->pathHead; if (!URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_SCHEME, &(uri->scheme), memory) || !URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_USER_INFO, &(uri->userInfo), memory) || !URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_QUERY, &(uri->query), memory) || !URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_FRAGMENT, &(uri->fragment), memory)) { return URI_FALSE; /* Raises malloc error */ } /* Host */ if ((*revertMask & URI_NORMALIZE_HOST) == 0) { if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ if (!URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_HOST, &(uri->hostData.ipFuture), memory)) { return URI_FALSE; /* Raises malloc error */ } uri->hostText.first = uri->hostData.ipFuture.first; uri->hostText.afterLast = uri->hostData.ipFuture.afterLast; } else if (uri->hostText.first != NULL) { /* Regname */ if (!URI_FUNC(MakeRangeOwner)(revertMask, URI_NORMALIZE_HOST, &(uri->hostText), memory)) { return URI_FALSE; /* Raises malloc error */ } } } /* Path */ if ((*revertMask & URI_NORMALIZE_PATH) == 0) { while (walker != NULL) { if (!URI_FUNC(MakeRangeOwner)(revertMask, 0, &(walker->text), memory)) { /* Free allocations done so far and kill path */ /* Kill path to one before walker (if any) */ URI_TYPE(PathSegment) * ranger = uri->pathHead; while (ranger != walker) { URI_TYPE(PathSegment) * const next = ranger->next; if ((ranger->text.first != NULL) && (ranger->text.afterLast != NULL) && (ranger->text.afterLast > ranger->text.first)) { memory->free(memory, (URI_CHAR *)ranger->text.first); } memory->free(memory, ranger); ranger = next; } /* Kill path from walker */ while (walker != NULL) { URI_TYPE(PathSegment) * const next = walker->next; memory->free(memory, walker); walker = next; } uri->pathHead = NULL; uri->pathTail = NULL; return URI_FALSE; /* Raises malloc error */ } walker = walker->next; } *revertMask |= URI_NORMALIZE_PATH; } /* Port text, must come last so we don't have to undo that one if it fails. * * Otherwise we would need and extra enum flag for it although the port * * cannot go unnormalized... */ if (!URI_FUNC(MakeRangeOwner)(revertMask, 0, &(uri->portText), memory)) { return URI_FALSE; /* Raises malloc error */ } return URI_TRUE; } unsigned int URI_FUNC(NormalizeSyntaxMaskRequired)(const URI_TYPE(Uri) * uri) { unsigned int outMask = URI_NORMALIZED; /* for NULL uri */ URI_FUNC(NormalizeSyntaxMaskRequiredEx)(uri, &outMask); return outMask; } int URI_FUNC(NormalizeSyntaxMaskRequiredEx)(const URI_TYPE(Uri) * uri, unsigned int * outMask) { UriMemoryManager * const memory = NULL; /* no use of memory manager */ # if defined(__GNUC__) \ && ((__GNUC__ > 4) \ || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2))) /* Slower code that fixes a warning, not sure if this is a smart idea */ URI_TYPE(Uri) writeableClone; # endif if ((uri == NULL) || (outMask == NULL)) { return URI_ERROR_NULL; } # if defined(__GNUC__) \ && ((__GNUC__ > 4) \ || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2))) /* Slower code that fixes a warning, not sure if this is a smart idea */ memcpy(&writeableClone, uri, 1 * sizeof(URI_TYPE(Uri))); URI_FUNC(NormalizeSyntaxEngine)(&writeableClone, 0, outMask, memory); # else URI_FUNC(NormalizeSyntaxEngine)((URI_TYPE(Uri) *)uri, 0, outMask, memory); # endif return URI_SUCCESS; } int URI_FUNC(NormalizeSyntaxEx)(URI_TYPE(Uri) * uri, unsigned int mask) { return URI_FUNC(NormalizeSyntaxExMm)(uri, mask, NULL); } int URI_FUNC(NormalizeSyntaxExMm)(URI_TYPE(Uri) * uri, unsigned int mask, UriMemoryManager * memory) { URI_CHECK_MEMORY_MANAGER(memory); /* may return */ return URI_FUNC(NormalizeSyntaxEngine)(uri, mask, NULL, memory); } int URI_FUNC(NormalizeSyntax)(URI_TYPE(Uri) * uri) { return URI_FUNC(NormalizeSyntaxEx)(uri, (unsigned int)-1); } static const URI_CHAR * URI_FUNC(PastLeadingZeros)(const URI_CHAR * first, const URI_CHAR * afterLast) { assert(first != NULL); assert(afterLast != NULL); assert(first != afterLast); /* Find the first non-zero character */ const URI_CHAR * remainderFirst = first; while ((remainderFirst < afterLast) && (remainderFirst[0] == _UT('0'))) { remainderFirst++; } /* Is the string /all/ zeros? */ if (remainderFirst == afterLast) { /* Yes, and length is >=1 because we ruled out the empty string earlier; * pull back onto rightmost zero */ assert(remainderFirst > first); remainderFirst--; assert(remainderFirst[0] == _UT('0')); } return remainderFirst; } static void URI_FUNC(DropLeadingZerosInplace)(URI_CHAR * first, const URI_CHAR ** afterLast) { assert(first != NULL); assert(afterLast != NULL); assert(*afterLast != NULL); if (first == *afterLast) { return; } const URI_CHAR * const remainderFirst = URI_FUNC(PastLeadingZeros)(first, *afterLast); if (remainderFirst > first) { const size_t remainderLen = *afterLast - remainderFirst; memmove(first, remainderFirst, remainderLen * sizeof(URI_CHAR)); first[remainderLen] = _UT('\0'); *afterLast = first + remainderLen; } } static void URI_FUNC(AdvancePastLeadingZeros)(const URI_CHAR ** first, const URI_CHAR * afterLast) { assert(first != NULL); assert(*first != NULL); assert(afterLast != NULL); if (*first == afterLast) { return; } const URI_CHAR * const remainderFirst = URI_FUNC(PastLeadingZeros)(*first, afterLast); /* Cut off leading zeros */ *first = remainderFirst; } static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask, UriMemoryManager * memory) { unsigned int revertMask = URI_NORMALIZED; /* Not just doing inspection? -> memory manager required! */ if (outMask == NULL) { assert(memory != NULL); } if (uri == NULL) { if (outMask != NULL) { *outMask = URI_NORMALIZED; return URI_SUCCESS; } else { return URI_ERROR_NULL; } } if (outMask != NULL) { /* Reset mask */ *outMask = URI_NORMALIZED; } else if (inMask == URI_NORMALIZED) { /* Nothing to do */ return URI_SUCCESS; } /* Scheme, host */ if (outMask != NULL) { const UriBool normalizeScheme = URI_FUNC(ContainsUppercaseLetters)(uri->scheme.first, uri->scheme.afterLast); const UriBool normalizeHostCase = URI_FUNC(ContainsUppercaseLetters)( uri->hostText.first, uri->hostText.afterLast); if (normalizeScheme) { *outMask |= URI_NORMALIZE_SCHEME; } if (normalizeHostCase) { *outMask |= URI_NORMALIZE_HOST; } else { const UriBool normalizeHostPrecent = URI_FUNC(ContainsUglyPercentEncoding)( uri->hostText.first, uri->hostText.afterLast); if (normalizeHostPrecent) { *outMask |= URI_NORMALIZE_HOST; } } } else { /* Scheme */ if ((inMask & URI_NORMALIZE_SCHEME) && (uri->scheme.first != NULL)) { if (uri->owner) { URI_FUNC(LowercaseInplace)(uri->scheme.first, uri->scheme.afterLast); } else { if (!URI_FUNC(LowercaseMalloc)(&(uri->scheme.first), &(uri->scheme.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_SCHEME; } } /* Host */ if (inMask & URI_NORMALIZE_HOST) { if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ if (uri->owner) { URI_FUNC(LowercaseInplace)(uri->hostData.ipFuture.first, uri->hostData.ipFuture.afterLast); } else { if (!URI_FUNC(LowercaseMalloc)(&(uri->hostData.ipFuture.first), &(uri->hostData.ipFuture.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_HOST; } uri->hostText.first = uri->hostData.ipFuture.first; uri->hostText.afterLast = uri->hostData.ipFuture.afterLast; } else if ((uri->hostText.first != NULL) && (uri->hostData.ip4 == NULL)) { /* Regname or IPv6 */ if (uri->owner) { URI_FUNC(FixPercentEncodingInplace)(uri->hostText.first, &(uri->hostText.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)( &(uri->hostText.first), &(uri->hostText.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_HOST; } URI_FUNC(LowercaseInplaceExceptPercentEncoding)(uri->hostText.first, uri->hostText.afterLast); } } } /* Port */ if (outMask != NULL) { /* Is there a port even? */ if (uri->portText.first != NULL) { /* Determine whether the port is already normalized, i.e. either "", "0" or no * leading zeros */ const size_t portLen = uri->portText.afterLast - uri->portText.first; if ((portLen > 1) && (uri->portText.first[0] == _UT('0'))) { *outMask |= URI_NORMALIZE_PORT; } } } else { /* Normalize the port, i.e. drop leading zeros (except for string "0") */ if ((inMask & URI_NORMALIZE_PORT) && (uri->portText.first != NULL)) { if (uri->owner) { URI_FUNC(DropLeadingZerosInplace)((URI_CHAR *)uri->portText.first, &(uri->portText.afterLast)); } else { URI_FUNC(AdvancePastLeadingZeros)(&(uri->portText.first), uri->portText.afterLast); } } } /* User info */ if (outMask != NULL) { const UriBool normalizeUserInfo = URI_FUNC(ContainsUglyPercentEncoding)( uri->userInfo.first, uri->userInfo.afterLast); if (normalizeUserInfo) { *outMask |= URI_NORMALIZE_USER_INFO; } } else { if ((inMask & URI_NORMALIZE_USER_INFO) && (uri->userInfo.first != NULL)) { if (uri->owner) { URI_FUNC(FixPercentEncodingInplace)(uri->userInfo.first, &(uri->userInfo.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)( &(uri->userInfo.first), &(uri->userInfo.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_USER_INFO; } } } /* Path */ if (outMask != NULL) { const URI_TYPE(PathSegment) * walker = uri->pathHead; while (walker != NULL) { const URI_CHAR * const first = walker->text.first; const URI_CHAR * const afterLast = walker->text.afterLast; if ((first != NULL) && (afterLast != NULL) && (afterLast > first) && ((((afterLast - first) == 1) && (first[0] == _UT('.'))) || (((afterLast - first) == 2) && (first[0] == _UT('.')) && (first[1] == _UT('.'))) || URI_FUNC(ContainsUglyPercentEncoding)(first, afterLast))) { *outMask |= URI_NORMALIZE_PATH; break; } walker = walker->next; } } else if (inMask & URI_NORMALIZE_PATH) { URI_TYPE(PathSegment) * walker; const UriBool relative = ((uri->scheme.first == NULL) && !uri->absolutePath) ? URI_TRUE : URI_FALSE; /* Fix percent-encoding for each segment */ walker = uri->pathHead; if (uri->owner) { while (walker != NULL) { URI_FUNC(FixPercentEncodingInplace)(walker->text.first, &(walker->text.afterLast)); walker = walker->next; } } else { while (walker != NULL) { if (!URI_FUNC(FixPercentEncodingMalloc)( &(walker->text.first), &(walker->text.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } walker = walker->next; } revertMask |= URI_NORMALIZE_PATH; } /* 6.2.2.3 Path Segment Normalization */ if (!URI_FUNC(RemoveDotSegmentsEx)( uri, relative, (uri->owner == URI_TRUE) || ((revertMask & URI_NORMALIZE_PATH) != 0), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } URI_FUNC(FixEmptyTrailSegment)(uri, memory); } /* Query, fragment */ if (outMask != NULL) { const UriBool normalizeQuery = URI_FUNC(ContainsUglyPercentEncoding)(uri->query.first, uri->query.afterLast); const UriBool normalizeFragment = URI_FUNC(ContainsUglyPercentEncoding)( uri->fragment.first, uri->fragment.afterLast); if (normalizeQuery) { *outMask |= URI_NORMALIZE_QUERY; } if (normalizeFragment) { *outMask |= URI_NORMALIZE_FRAGMENT; } } else { /* Query */ if ((inMask & URI_NORMALIZE_QUERY) && (uri->query.first != NULL)) { if (uri->owner) { URI_FUNC(FixPercentEncodingInplace)(uri->query.first, &(uri->query.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)( &(uri->query.first), &(uri->query.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_QUERY; } } /* Fragment */ if ((inMask & URI_NORMALIZE_FRAGMENT) && (uri->fragment.first != NULL)) { if (uri->owner) { URI_FUNC(FixPercentEncodingInplace)(uri->fragment.first, &(uri->fragment.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)( &(uri->fragment.first), &(uri->fragment.afterLast), memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } revertMask |= URI_NORMALIZE_FRAGMENT; } } } /* Dup all not duped yet */ if ((outMask == NULL) && !uri->owner) { if (!URI_FUNC(MakeOwnerEngine)(uri, &revertMask, memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } uri->owner = URI_TRUE; } return URI_SUCCESS; } int URI_FUNC(MakeOwnerMm)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { unsigned int revertMask = URI_NORMALIZED; URI_CHECK_MEMORY_MANAGER(memory); /* may return */ if (uri == NULL) { return URI_ERROR_NULL; } if (uri->owner == URI_TRUE) { return URI_SUCCESS; } if (!URI_FUNC(MakeOwnerEngine)(uri, &revertMask, memory)) { URI_FUNC(PreventLeakage)(uri, revertMask, memory); return URI_ERROR_MALLOC; } uri->owner = URI_TRUE; return URI_SUCCESS; } int URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri) { return URI_FUNC(MakeOwnerMm)(uri, NULL); } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriNormalizeBase.c000066400000000000000000000060031516712004000305640ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_DOXYGEN # include "UriNormalizeBase.h" #endif UriBool uriIsUnreserved(int code) { switch (code) { case L'a': /* ALPHA */ case L'A': case L'b': case L'B': case L'c': case L'C': case L'd': case L'D': case L'e': case L'E': case L'f': case L'F': case L'g': case L'G': case L'h': case L'H': case L'i': case L'I': case L'j': case L'J': case L'k': case L'K': case L'l': case L'L': case L'm': case L'M': case L'n': case L'N': case L'o': case L'O': case L'p': case L'P': case L'q': case L'Q': case L'r': case L'R': case L's': case L'S': case L't': case L'T': case L'u': case L'U': case L'v': case L'V': case L'w': case L'W': case L'x': case L'X': case L'y': case L'Y': case L'z': case L'Z': case L'0': /* DIGIT */ case L'1': case L'2': case L'3': case L'4': case L'5': case L'6': case L'7': case L'8': case L'9': case L'-': /* "-" / "." / "_" / "~" */ case L'.': case L'_': case L'~': return URI_TRUE; default: return URI_FALSE; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriNormalizeBase.h000066400000000000000000000037331516712004000306000ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_NORMALIZE_BASE_H # define URI_NORMALIZE_BASE_H 1 # include UriBool uriIsUnreserved(int code); #endif /* URI_NORMALIZE_BASE_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriParse.c000066400000000000000000002276061516712004000271210ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriParse.c * Holds the RFC 3986 %URI parsing implementation. * NOTE: This source file includes itself twice. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriParse.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriParse.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include # include "UriCommon.h" # include "UriMemory.h" # include "UriParseBase.h" # include "UriSets.h" # endif static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseHexZero)(const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePort)(const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); static UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); static UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); static UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); static void URI_FUNC(OnExitPartHelperTwo)(URI_TYPE(ParserState) * state); static void URI_FUNC(ResetParserStateExceptUri)(URI_TYPE(ParserState) * state); static UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, const URI_CHAR * errorPos, UriMemoryManager * memory); static void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state, UriMemoryManager * memory); static int URI_FUNC(ParseUriExMm)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static URI_INLINE void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, const URI_CHAR * errorPos, UriMemoryManager * memory) { URI_FUNC(FreeUriMembersMm)(state->uri, memory); state->errorPos = errorPos; state->errorCode = URI_ERROR_SYNTAX; } static URI_INLINE void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state, UriMemoryManager * memory) { URI_FUNC(FreeUriMembersMm)(state->uri, memory); state->errorPos = NULL; state->errorCode = URI_ERROR_MALLOC; } /* * [authority]-><[>[ipLit2][authorityTwo] * [authority]->[ownHostUserInfoNz] * [authority]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { /* "" regname host */ state->uri->hostText.first = URI_FUNC(SafeToPointTo); state->uri->hostText.afterLast = URI_FUNC(SafeToPointTo); return afterLast; } switch (*first) { case _UT('['): { const URI_CHAR * const afterIpLit2 = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast, memory); if (afterIpLit2 == NULL) { return NULL; } state->uri->hostText.first = first + 1; /* HOST BEGIN */ return URI_FUNC(ParseAuthorityTwo)(state, afterIpLit2, afterLast); } case URI_SET_PCHAR(_UT): state->uri->userInfo.first = first; /* USERINFO BEGIN */ return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast, memory); default: /* "" regname host */ state->uri->hostText.first = URI_FUNC(SafeToPointTo); state->uri->hostText.afterLast = URI_FUNC(SafeToPointTo); return first; } } /* * [authorityTwo]-><:>[port] * [authorityTwo]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { if (first >= afterLast) { return afterLast; } switch (*first) { case _UT(':'): { const URI_CHAR * const afterPort = URI_FUNC(ParsePort)(first + 1, afterLast); if (afterPort == NULL) { return NULL; } state->uri->portText.first = first + 1; /* PORT BEGIN */ state->uri->portText.afterLast = afterPort; /* PORT END */ return afterPort; } default: return first; } } /* * [hexZero]->[HEXDIG][hexZero] * [hexZero]-> */ static const URI_CHAR * URI_FUNC(ParseHexZero)(const URI_CHAR * first, const URI_CHAR * afterLast) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_HEXDIG(_UT): first += 1; goto tail_call; default: return first; } } /* * [hierPart]->[pathRootless] * [hierPart]->[partHelperTwo] * [hierPart]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_PCHAR(_UT): return URI_FUNC(ParsePathRootless)(state, first, afterLast, memory); case _UT('/'): return URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast, memory); default: return first; } } /* * [ipFutLoop]->[subDelims][ipFutStopGo] * [ipFutLoop]->[unreserved][ipFutStopGo] * [ipFutLoop]-><:>[ipFutStopGo] * * [ipFutStopGo]->[ipFutLoop] * [ipFutStopGo]-> */ static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * const originalFirst = first; while (first < afterLast) { switch (*first) { case _UT(':'): case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): first += 1; break; default: goto done_looping; break; } } done_looping: if (first == originalFirst) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } return first; } /* * [ipFuture]->[HEXDIG][hexZero]<.>[ipFutLoop] */ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } /* First character has already been checked before entering this rule. switch (*first) { case _UT('v'): case _UT('V'): */ if (afterLast - first < 2) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (first[1]) { case URI_SET_HEXDIG(_UT): { const URI_CHAR * afterIpFutLoop; const URI_CHAR * const afterHexZero = URI_FUNC(ParseHexZero)(first + 2, afterLast); if (afterHexZero == NULL) { return NULL; } if (afterHexZero >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } if (*afterHexZero != _UT('.')) { URI_FUNC(StopSyntax)(state, afterHexZero, memory); return NULL; } state->uri->hostText.first = first; /* HOST BEGIN */ state->uri->hostData.ipFuture.first = first; /* IPFUTURE BEGIN */ afterIpFutLoop = URI_FUNC(ParseIpFutLoop)(state, afterHexZero + 1, afterLast, memory); if (afterIpFutLoop == NULL) { return NULL; } state->uri->hostText.afterLast = afterIpFutLoop; /* HOST END */ state->uri->hostData.ipFuture.afterLast = afterIpFutLoop; /* IPFUTURE END */ return afterIpFutLoop; } default: URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } /* default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } */ } /* * [ipLit2]->[ipFuture]<]> * [ipLit2]->[IPv6address2] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (*first) { /* The leading "v" of IPvFuture is case-insensitive. */ case _UT('v'): case _UT('V'): { const URI_CHAR * const afterIpFuture = URI_FUNC(ParseIpFuture)(state, first, afterLast, memory); if (afterIpFuture == NULL) { return NULL; } if (afterIpFuture >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } if (*afterIpFuture != _UT(']')) { URI_FUNC(StopSyntax)(state, afterIpFuture, memory); return NULL; } return afterIpFuture + 1; } case _UT(':'): case _UT(']'): case URI_SET_HEXDIG(_UT): state->uri->hostData.ip6 = memory->malloc( memory, 1 * sizeof(UriIp6)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip6 == NULL) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return URI_FUNC(ParseIPv6address2)(state, first, afterLast, memory); default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } /* * [IPv6address2]->..<]> */ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { int zipperEver = 0; int quadsDone = 0; int digitCount = 0; unsigned char digitHistory[4]; int ip4OctetsDone = 0; unsigned char quadsAfterZipper[14]; int quadsAfterZipperCount = 0; for (;;) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } /* Inside IPv4 part? */ if (ip4OctetsDone > 0) { /* Eat rest of IPv4 address */ for (;;) { switch (*first) { case URI_SET_DIGIT(_UT): if (digitCount == 4) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount++] = (unsigned char)(9 + *first - _UT('9')); break; case _UT('.'): if ((ip4OctetsDone == 4) /* NOTE! */ || (digitCount == 0) || (digitCount == 4)) { /* Invalid digit or octet count */ URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] + 10 * digitHistory[1] + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { URI_FUNC(StopSyntax)(state, first - 2, memory); } else { URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } /* Copy IPv4 octet */ state->uri->hostData.ip6->data[16 - 4 + ip4OctetsDone] = uriGetOctetValue(digitHistory, digitCount); digitCount = 0; ip4OctetsDone++; break; case _UT(']'): if ((ip4OctetsDone != 3) /* NOTE! */ || (digitCount == 0) || (digitCount == 4)) { /* Invalid digit or octet count */ URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] + 10 * digitHistory[1] + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { URI_FUNC(StopSyntax)(state, first - 2, memory); } else { URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } state->uri->hostText.afterLast = first; /* HOST END */ /* Copy missing quads right before IPv4 */ memcpy(state->uri->hostData.ip6->data + 16 - 4 - 2 * quadsAfterZipperCount, quadsAfterZipper, 2 * quadsAfterZipperCount); /* Copy last IPv4 octet */ state->uri->hostData.ip6->data[16 - 4 + 3] = uriGetOctetValue(digitHistory, digitCount); return first + 1; default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } first++; if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } } } else { /* Eat while no dot in sight */ int letterAmong = 0; int walking = 1; do { switch (*first) { case URI_SET_HEX_LETTER_LOWER(_UT): letterAmong = 1; if (digitCount == 4) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('f')); digitCount++; break; case URI_SET_HEX_LETTER_UPPER(_UT): letterAmong = 1; if (digitCount == 4) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('F')); digitCount++; break; case URI_SET_DIGIT(_UT): if (digitCount == 4) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(9 + *first - _UT('9')); digitCount++; break; case _UT(':'): { int setZipper = 0; if (digitCount > 0) { if (zipperEver) { uriWriteQuadToDoubleByte(digitHistory, digitCount, quadsAfterZipper + 2 * quadsAfterZipperCount); quadsAfterZipperCount++; } else { uriWriteQuadToDoubleByte(digitHistory, digitCount, state->uri->hostData.ip6->data + 2 * quadsDone); } quadsDone++; digitCount = 0; } letterAmong = 0; /* Too many quads? */ if (quadsDone >= 8 - zipperEver) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } /* "::"? */ if (afterLast - first < 2) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } if (first[1] == _UT(':')) { const int resetOffset = 2 * (quadsDone + (digitCount > 0)); first++; if (zipperEver) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; /* "::.+::" */ } /* Zero everything after zipper */ memset(state->uri->hostData.ip6->data + resetOffset, 0, 16 - resetOffset); setZipper = 1; /* ":::+"? */ if (afterLast - first < 2) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; /* No ']' yet */ } if (first[1] == _UT(':')) { URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; /* ":::+ "*/ } } else if (quadsDone == 0 || first[1] == _UT(']')) { /* Single leading or trailing ":" */ URI_FUNC(StopSyntax)(state, first, memory); return NULL; } if (setZipper) { zipperEver = 1; } } break; case _UT('.'): if ((quadsDone + zipperEver > 6) /* NOTE */ || (!zipperEver && (quadsDone < 6)) || letterAmong || (digitCount == 0) || (digitCount == 4)) { /* Invalid octet before */ URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] + 10 * digitHistory[1] + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { URI_FUNC(StopSyntax)(state, first - 2, memory); } else { URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } /* Copy first IPv4 octet */ state->uri->hostData.ip6->data[16 - 4] = uriGetOctetValue(digitHistory, digitCount); digitCount = 0; /* Switch over to IPv4 loop */ ip4OctetsDone = 1; walking = 0; break; case _UT(']'): /* Too little quads? */ if (!zipperEver && !((quadsDone == 7) && (digitCount > 0))) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } if (digitCount > 0) { if (zipperEver) { /* Too many quads? */ if (quadsDone >= 7) { URI_FUNC(StopSyntax)(state, first, memory); return NULL; } uriWriteQuadToDoubleByte(digitHistory, digitCount, quadsAfterZipper + 2 * quadsAfterZipperCount); quadsAfterZipperCount++; } else { uriWriteQuadToDoubleByte(digitHistory, digitCount, state->uri->hostData.ip6->data + 2 * quadsDone); } /* quadsDone++; digitCount = 0; */ } /* Copy missing quads to the end */ memcpy(state->uri->hostData.ip6->data + 16 - 2 * quadsAfterZipperCount, quadsAfterZipper, 2 * quadsAfterZipperCount); state->uri->hostText.afterLast = first; /* HOST END */ return first + 1; /* Fine */ default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } first++; if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; /* No ']' yet */ } } while (walking); } } } /* * [mustBeSegmentNzNc]->[pctEncoded][mustBeSegmentNzNc] * [mustBeSegmentNzNc]->[subDelims][mustBeSegmentNzNc] * [mustBeSegmentNzNc]->[unreserved][mustBeSegmentNzNc] * [mustBeSegmentNzNc]->[uriTail] // can take * [mustBeSegmentNzNc]->[segment][zeroMoreSlashSegs][uriTail] * [mustBeSegmentNzNc]-><@>[mustBeSegmentNzNc] */ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ return afterLast; } switch (*first) { case _UT('%'): { const URI_CHAR * const afterPctEncoded = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } first = afterPctEncoded; goto tail_call; } case _UT('@'): case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): first += 1; goto tail_call; case _UT('/'): { const URI_CHAR * afterZeroMoreSlashSegs; const URI_CHAR * afterSegment; if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } afterZeroMoreSlashSegs = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory); if (afterZeroMoreSlashSegs == NULL) { return NULL; } return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast, memory); } default: if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } /* * [ownHost]-><[>[ipLit2][authorityTwo] * [ownHost]->[ownHost2] // can take */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { state->uri->hostText.afterLast = afterLast; /* HOST END */ return afterLast; } switch (*first) { case _UT('['): { const URI_CHAR * const afterIpLit2 = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast, memory); if (afterIpLit2 == NULL) { return NULL; } state->uri->hostText.first = first + 1; /* HOST BEGIN */ return URI_FUNC(ParseAuthorityTwo)(state, afterIpLit2, afterLast); } default: return URI_FUNC(ParseOwnHost2)(state, first, afterLast, memory); } } static URI_INLINE UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory) { state->uri->hostText.afterLast = first; /* HOST END */ /* Valid IPv4 or just a regname? */ state->uri->hostData.ip4 = memory->malloc( memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ } /* * [ownHost2]->[authorityTwo] // can take * [ownHost2]->[pctSubUnres][ownHost2] */ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { if (!URI_FUNC(OnExitOwnHost2)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; } switch (*first) { case _UT('%'): case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): { const URI_CHAR * const afterPctSubUnres = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } first = afterPctSubUnres; goto tail_call; } default: if (!URI_FUNC(OnExitOwnHost2)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return URI_FUNC(ParseAuthorityTwo)(state, first, afterLast); } } static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory) { state->uri->hostText.first = state->uri->userInfo.first; /* Host instead of userInfo, update */ state->uri->userInfo.first = NULL; /* Not a userInfo, reset */ state->uri->hostText.afterLast = first; /* HOST END */ /* Valid IPv4 or just a regname? */ state->uri->hostData.ip4 = memory->malloc( memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ } /* * [ownHostUserInfoNz]->[pctSubUnres][ownHostUserInfo] * [ownHostUserInfoNz]-><:>[ownPortUserInfo] * [ownHostUserInfoNz]-><@>[ownHost] * * [ownHostUserInfo]->[ownHostUserInfoNz] * [ownHostUserInfo]-> */ static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * const originalFirst = first; while (first < afterLast) { switch (*first) { case _UT('%'): case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): { const URI_CHAR * const afterPctSubUnres = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } first = afterPctSubUnres; break; } default: goto done_looping; break; } } done_looping: if (first < afterLast) { switch (*first) { case _UT(':'): state->uri->hostText.afterLast = first; /* HOST END */ state->uri->portText.first = first + 1; /* PORT BEGIN */ return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory); case _UT('@'): state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: break; } } if (first == originalFirst) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return first; } static URI_INLINE UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory) { state->uri->hostText.first = state->uri->userInfo.first; /* Host instead of userInfo, update */ state->uri->userInfo.first = NULL; /* Not a userInfo, reset */ state->uri->portText.afterLast = first; /* PORT END */ /* Valid IPv4 or just a regname? */ state->uri->hostData.ip4 = memory->malloc( memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ } /* * [ownPortUserInfo]->[ALPHA][ownUserInfo] * [ownPortUserInfo]->[DIGIT][ownPortUserInfo] * [ownPortUserInfo]-><.>[ownUserInfo] * [ownPortUserInfo]-><_>[ownUserInfo] * [ownPortUserInfo]-><~>[ownUserInfo] * [ownPortUserInfo]-><->[ownUserInfo] * [ownPortUserInfo]->[subDelims][ownUserInfo] * [ownPortUserInfo]->[pctEncoded][ownUserInfo] * [ownPortUserInfo]-><:>[ownUserInfo] * [ownPortUserInfo]-><@>[ownHost] * [ownPortUserInfo]-> */ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; } switch (*first) { case URI_SET_SUB_DELIMS(_UT): /* begin unreserved (except alpha and digit) */ case _UT('-'): case _UT('.'): case _UT('_'): case _UT('~'): /* end unreserved (except alpha and digit) */ case _UT(':'): case URI_SET_ALPHA(_UT): state->uri->hostText.afterLast = NULL; /* Not a host, reset */ state->uri->portText.first = NULL; /* Not a port, reset */ return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast, memory); case URI_SET_DIGIT(_UT): first += 1; goto tail_call; case _UT('%'): state->uri->portText.first = NULL; /* Not a port, reset */ const URI_CHAR * const afterPct = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPct == NULL) { return NULL; } return URI_FUNC(ParseOwnUserInfo)(state, afterPct, afterLast, memory); case _UT('@'): state->uri->hostText.afterLast = NULL; /* Not a host, reset */ state->uri->portText.first = NULL; /* Not a port, reset */ state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return first; } } /* * [ownUserInfo]->[pctSubUnres][ownUserInfo] * [ownUserInfo]-><:>[ownUserInfo] * [ownUserInfo]-><@>[ownHost] */ static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (*first) { case _UT('%'): case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): { const URI_CHAR * const afterPctSubUnres = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } first = afterPctSubUnres; goto tail_call; } case _UT(':'): first += 1; goto tail_call; case _UT('@'): /* SURE */ state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } static URI_INLINE void URI_FUNC(OnExitPartHelperTwo)(URI_TYPE(ParserState) * state) { state->uri->absolutePath = URI_TRUE; } /* * [partHelperTwo]->[pathAbsNoLeadSlash] // can take * [partHelperTwo]->[authority][pathAbsEmpty] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(OnExitPartHelperTwo)(state); return afterLast; } switch (*first) { case _UT('/'): { const URI_CHAR * const afterAuthority = URI_FUNC(ParseAuthority)(state, first + 1, afterLast, memory); const URI_CHAR * afterPathAbsEmpty; if (afterAuthority == NULL) { return NULL; } afterPathAbsEmpty = URI_FUNC(ParsePathAbsEmpty)(state, afterAuthority, afterLast, memory); URI_FUNC(FixEmptyTrailSegment)(state->uri, memory); return afterPathAbsEmpty; } default: URI_FUNC(OnExitPartHelperTwo)(state); return URI_FUNC(ParsePathAbsNoLeadSlash)(state, first, afterLast, memory); } } /* * [pathAbsEmpty]->[segment][pathAbsEmpty] * [pathAbsEmpty]-> */ static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('/'): { const URI_CHAR * const afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } first = afterSegment; goto tail_call; } default: return first; } } /* * [pathAbsNoLeadSlash]->[segmentNz][zeroMoreSlashSegs] * [pathAbsNoLeadSlash]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_PCHAR(_UT): { const URI_CHAR * const afterSegmentNz = URI_FUNC(ParseSegmentNz)(state, first, afterLast, memory); if (afterSegmentNz == NULL) { return NULL; } if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast, memory); } default: return first; } } /* * [pathRootless]->[segmentNz][zeroMoreSlashSegs] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * const afterSegmentNz = URI_FUNC(ParseSegmentNz)(state, first, afterLast, memory); if (afterSegmentNz == NULL) { return NULL; } else { if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } } return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast, memory); } /* * [pchar]->[pctEncoded] * [pchar]->[subDelims] * [pchar]->[unreserved] * [pchar]-><:> * [pchar]-><@> */ static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (*first) { case _UT('%'): return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); case URI_SET_PCHAR_WITHOUT_PERCENT(_UT): return first + 1; default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } /* * [pctEncoded]-><%>[HEXDIG][HEXDIG] */ static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } /* First character has already been checked before entering this rule. switch (*first) { case _UT('%'): */ if (afterLast - first < 2) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (first[1]) { case URI_SET_HEXDIG(_UT): if (afterLast - first < 3) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (first[2]) { case URI_SET_HEXDIG(_UT): return first + 3; default: URI_FUNC(StopSyntax)(state, first + 2, memory); return NULL; } default: URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } /* default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } */ } /* * [pctSubUnres]->[pctEncoded] * [pctSubUnres]->[subDelims] * [pctSubUnres]->[unreserved] */ static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(StopSyntax)(state, afterLast, memory); return NULL; } switch (*first) { case _UT('%'): return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); case URI_SET_SUB_DELIMS(_UT): case URI_SET_UNRESERVED(_UT): return first + 1; default: URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } /* * [port]->[DIGIT][port] * [port]-> */ static const URI_CHAR * URI_FUNC(ParsePort)(const URI_CHAR * first, const URI_CHAR * afterLast) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_DIGIT(_UT): first += 1; goto tail_call; default: return first; } } /* * [queryFrag]->[pchar][queryFrag] * [queryFrag]->[queryFrag] * [queryFrag]->[queryFrag] * [queryFrag]-> */ static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_PCHAR(_UT): { const URI_CHAR * const afterPchar = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } first = afterPchar; goto tail_call; } case _UT('/'): case _UT('?'): first += 1; goto tail_call; default: return first; } } /* * [segment]->[pchar][segment] * [segment]-> */ static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_PCHAR(_UT): { const URI_CHAR * const afterPchar = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } first = afterPchar; goto tail_call; } default: return first; } } /* * [segmentNz]->[pchar][segment] */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * const afterPchar = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } return URI_FUNC(ParseSegment)(state, afterPchar, afterLast, memory); } static URI_INLINE UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)( URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory) { if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ return URI_FALSE; /* Raises malloc error*/ } state->uri->scheme.first = NULL; /* Not a scheme, reset */ return URI_TRUE; /* Success */ } /* * [segmentNzNcOrScheme2]->[ALPHA][segmentNzNcOrScheme2] * [segmentNzNcOrScheme2]->[DIGIT][segmentNzNcOrScheme2] * [segmentNzNcOrScheme2]->[pctEncoded][mustBeSegmentNzNc] * [segmentNzNcOrScheme2]->[uriTail] // can take * [segmentNzNcOrScheme2]->[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><$>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><&>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><(>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><)>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><*>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><,>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><.>[segmentNzNcOrScheme2] * [segmentNzNcOrScheme2]->[segment][zeroMoreSlashSegs][uriTail] * [segmentNzNcOrScheme2]-><:>[hierPart][uriTail] * [segmentNzNcOrScheme2]-><;>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><@>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><_>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><~>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><+>[segmentNzNcOrScheme2] * [segmentNzNcOrScheme2]-><=>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><'>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><->[segmentNzNcOrScheme2] */ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; } switch (*first) { case _UT('.'): case _UT('+'): case _UT('-'): case URI_SET_ALPHA(_UT): case URI_SET_DIGIT(_UT): first += 1; goto tail_call; case _UT('%'): { const URI_CHAR * const afterPctEncoded = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast, memory); } case _UT('!'): case _UT('$'): case _UT('&'): case _UT('('): case _UT(')'): case _UT('*'): case _UT(','): case _UT(';'): case _UT('@'): case _UT('_'): case _UT('~'): case _UT('='): case _UT('\''): return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory); case _UT('/'): { const URI_CHAR * afterZeroMoreSlashSegs; const URI_CHAR * const afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } afterZeroMoreSlashSegs = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory); if (afterZeroMoreSlashSegs == NULL) { return NULL; } return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast, memory); } case _UT(':'): { const URI_CHAR * const afterHierPart = URI_FUNC(ParseHierPart)(state, first + 1, afterLast, memory); state->uri->scheme.afterLast = first; /* SCHEME END */ if (afterHierPart == NULL) { return NULL; } return URI_FUNC(ParseUriTail)(state, afterHierPart, afterLast, memory); } default: if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first, memory)) { URI_FUNC(StopMalloc)(state, memory); return NULL; } return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } /* * [uriReference]->[ALPHA][segmentNzNcOrScheme2] * [uriReference]->[DIGIT][mustBeSegmentNzNc] * [uriReference]->[pctEncoded][mustBeSegmentNzNc] * [uriReference]->[subDelims][mustBeSegmentNzNc] * [uriReference]->[uriTail] // can take * [uriReference]-><.>[mustBeSegmentNzNc] * [uriReference]->[partHelperTwo][uriTail] * [uriReference]-><@>[mustBeSegmentNzNc] * [uriReference]-><_>[mustBeSegmentNzNc] * [uriReference]-><~>[mustBeSegmentNzNc] * [uriReference]-><->[mustBeSegmentNzNc] */ static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } switch (*first) { case URI_SET_ALPHA(_UT): state->uri->scheme.first = first; /* SCHEME BEGIN */ return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast, memory); case URI_SET_DIGIT(_UT): case URI_SET_SUB_DELIMS(_UT): case _UT('.'): case _UT('_'): case _UT('~'): case _UT('-'): case _UT('@'): state->uri->scheme.first = first; /* SEGMENT BEGIN, ABUSE SCHEME POINTER */ return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory); case _UT('%'): { const URI_CHAR * const afterPctEncoded = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } state->uri->scheme.first = first; /* SEGMENT BEGIN, ABUSE SCHEME POINTER */ return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast, memory); } case _UT('/'): { const URI_CHAR * const afterPartHelperTwo = URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast, memory); if (afterPartHelperTwo == NULL) { return NULL; } return URI_FUNC(ParseUriTail)(state, afterPartHelperTwo, afterLast, memory); } default: return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } /* * [uriTail]-><#>[queryFrag] * [uriTail]->[queryFrag][uriTailTwo] * [uriTail]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('#'): { const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } state->uri->fragment.first = first + 1; /* FRAGMENT BEGIN */ state->uri->fragment.afterLast = afterQueryFrag; /* FRAGMENT END */ return afterQueryFrag; } case _UT('?'): { const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } state->uri->query.first = first + 1; /* QUERY BEGIN */ state->uri->query.afterLast = afterQueryFrag; /* QUERY END */ return URI_FUNC(ParseUriTailTwo)(state, afterQueryFrag, afterLast, memory); } default: return first; } } /* * [uriTailTwo]-><#>[queryFrag] * [uriTailTwo]-> */ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('#'): { const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } state->uri->fragment.first = first + 1; /* FRAGMENT BEGIN */ state->uri->fragment.afterLast = afterQueryFrag; /* FRAGMENT END */ return afterQueryFrag; } default: return first; } } /* * [zeroMoreSlashSegs]->[segment][zeroMoreSlashSegs] * [zeroMoreSlashSegs]-> */ static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { tail_call: if (first >= afterLast) { return afterLast; } switch (*first) { case _UT('/'): { const URI_CHAR * const afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ URI_FUNC(StopMalloc)(state, memory); return NULL; } first = afterSegment; goto tail_call; } default: return first; } } static URI_INLINE void URI_FUNC(ResetParserStateExceptUri)(URI_TYPE(ParserState) * state) { URI_TYPE(Uri) * const uriBackup = state->uri; memset(state, 0, sizeof(URI_TYPE(ParserState))); state->uri = uriBackup; } static URI_INLINE UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { URI_TYPE(PathSegment) * segment = memory->calloc(memory, 1, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } if (first == afterLast) { segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); } else { segment->text.first = first; segment->text.afterLast = afterLast; } /* First segment ever? */ if (state->uri->pathHead == NULL) { /* First segment ever, set head and tail */ state->uri->pathHead = segment; state->uri->pathTail = segment; } else { /* Append, update tail */ state->uri->pathTail->next = segment; state->uri->pathTail = segment; } return URI_TRUE; /* Success */ } int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { return URI_FUNC(ParseUriExMm)(state, first, afterLast, NULL); } static int URI_FUNC(ParseUriExMm)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * afterUriReference; URI_TYPE(Uri) * uri; /* Check params */ if ((state == NULL) || (first == NULL) || (afterLast == NULL)) { return URI_ERROR_NULL; } URI_CHECK_MEMORY_MANAGER(memory); /* may return */ uri = state->uri; /* Init parser */ URI_FUNC(ResetParserStateExceptUri)(state); URI_FUNC(ResetUri)(uri); /* Parse */ afterUriReference = URI_FUNC(ParseUriReference)(state, first, afterLast, memory); if (afterUriReference == NULL) { /* Waterproof errorPos <= afterLast */ if (state->errorPos && (state->errorPos > afterLast)) { state->errorPos = afterLast; } return state->errorCode; } if (afterUriReference != afterLast) { if (afterUriReference < afterLast) { URI_FUNC(StopSyntax)(state, afterUriReference, memory); } else { URI_FUNC(StopSyntax)(state, afterLast, memory); } return state->errorCode; } return URI_SUCCESS; } int URI_FUNC(ParseUri)(URI_TYPE(ParserState) * state, const URI_CHAR * text) { if ((state == NULL) || (text == NULL)) { return URI_ERROR_NULL; } return URI_FUNC(ParseUriEx)(state, text, text + URI_STRLEN(text)); } int URI_FUNC(ParseSingleUri)(URI_TYPE(Uri) * uri, const URI_CHAR * text, const URI_CHAR ** errorPos) { return URI_FUNC(ParseSingleUriEx)(uri, text, NULL, errorPos); } int URI_FUNC(ParseSingleUriEx)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, const URI_CHAR ** errorPos) { if ((afterLast == NULL) && (first != NULL)) { afterLast = first + URI_STRLEN(first); } return URI_FUNC(ParseSingleUriExMm)(uri, first, afterLast, errorPos, NULL); } int URI_FUNC(ParseSingleUriExMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, const URI_CHAR ** errorPos, UriMemoryManager * memory) { URI_TYPE(ParserState) state; int res; /* Check params */ if ((uri == NULL) || (first == NULL) || (afterLast == NULL)) { return URI_ERROR_NULL; } URI_CHECK_MEMORY_MANAGER(memory); /* may return */ state.uri = uri; res = URI_FUNC(ParseUriExMm)(&state, first, afterLast, memory); if (res != URI_SUCCESS) { if (errorPos != NULL) { *errorPos = state.errorPos; } URI_FUNC(FreeUriMembersMm)(uri, memory); } return res; } void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { URI_FUNC(FreeUriMembersMm)(uri, NULL); } int URI_FUNC(FreeUriMembersMm)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { if (uri == NULL) { return URI_ERROR_NULL; } URI_CHECK_MEMORY_MANAGER(memory); /* may return */ if (uri->owner) { /* Scheme */ if (uri->scheme.first != NULL) { if (uri->scheme.first != uri->scheme.afterLast) { memory->free(memory, (URI_CHAR *)uri->scheme.first); } uri->scheme.first = NULL; uri->scheme.afterLast = NULL; } /* User info */ if (uri->userInfo.first != NULL) { if (uri->userInfo.first != uri->userInfo.afterLast) { memory->free(memory, (URI_CHAR *)uri->userInfo.first); } uri->userInfo.first = NULL; uri->userInfo.afterLast = NULL; } /* Host data - IPvFuture (may affect host text) */ if (uri->hostData.ipFuture.first != NULL) { /* NOTE: .hostData.ipFuture holds the very same range pointers * as .hostText; we must not free memory twice. */ uri->hostText.first = NULL; uri->hostText.afterLast = NULL; if (uri->hostData.ipFuture.first != uri->hostData.ipFuture.afterLast) { memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first); } uri->hostData.ipFuture.first = NULL; uri->hostData.ipFuture.afterLast = NULL; } /* Host text (after IPvFuture, see above) */ if (uri->hostText.first != NULL) { if (uri->hostText.first != uri->hostText.afterLast) { memory->free(memory, (URI_CHAR *)uri->hostText.first); } uri->hostText.first = NULL; uri->hostText.afterLast = NULL; } } /* Host data - IPv4 */ if (uri->hostData.ip4 != NULL) { memory->free(memory, uri->hostData.ip4); uri->hostData.ip4 = NULL; } /* Host data - IPv6 */ if (uri->hostData.ip6 != NULL) { memory->free(memory, uri->hostData.ip6); uri->hostData.ip6 = NULL; } /* Port text */ if (uri->owner && (uri->portText.first != NULL)) { if (uri->portText.first != uri->portText.afterLast) { memory->free(memory, (URI_CHAR *)uri->portText.first); } uri->portText.first = NULL; uri->portText.afterLast = NULL; } /* Path */ URI_FUNC(FreeUriPath)(uri, memory); if (uri->owner) { /* Query */ if (uri->query.first != NULL) { if (uri->query.first != uri->query.afterLast) { memory->free(memory, (URI_CHAR *)uri->query.first); } uri->query.first = NULL; uri->query.afterLast = NULL; } /* Fragment */ if (uri->fragment.first != NULL) { if (uri->fragment.first != uri->fragment.afterLast) { memory->free(memory, (URI_CHAR *)uri->fragment.first); } uri->fragment.first = NULL; uri->fragment.afterLast = NULL; } } return URI_SUCCESS; } UriBool URI_FUNC(_TESTING_ONLY_ParseIpSix)(const URI_CHAR * text) { UriMemoryManager * const memory = &defaultMemoryManager; URI_TYPE(Uri) uri; URI_TYPE(ParserState) parser; const URI_CHAR * const afterIpSix = text + URI_STRLEN(text); const URI_CHAR * res; URI_FUNC(ResetUri)(&uri); parser.uri = &uri; URI_FUNC(ResetParserStateExceptUri)(&parser); parser.uri->hostData.ip6 = memory->malloc(memory, 1 * sizeof(UriIp6)); res = URI_FUNC(ParseIPv6address2)(&parser, text, afterIpSix, memory); URI_FUNC(FreeUriMembersMm)(&uri, memory); return res == afterIpSix ? URI_TRUE : URI_FALSE; } UriBool URI_FUNC(_TESTING_ONLY_ParseIpFour)(const URI_CHAR * text) { unsigned char octets[4]; int res = URI_FUNC(ParseIpFourAddress)(octets, text, text + URI_STRLEN(text)); return (res == URI_SUCCESS) ? URI_TRUE : URI_FALSE; } # undef URI_SET_DIGIT # undef URI_SET_HEX_LETTER_UPPER # undef URI_SET_HEX_LETTER_LOWER # undef URI_SET_HEXDIG # undef URI_SET_ALPHA #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriParseBase.c000066400000000000000000000055751516712004000277130ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_DOXYGEN # include "UriParseBase.h" #endif void uriWriteQuadToDoubleByte(const unsigned char * hexDigits, int digitCount, unsigned char * output) { switch (digitCount) { case 1: /* 0x___? -> \x00 \x0? */ output[0] = 0; output[1] = hexDigits[0]; break; case 2: /* 0x__?? -> \0xx \x?? */ output[0] = 0; output[1] = 16 * hexDigits[0] + hexDigits[1]; break; case 3: /* 0x_??? -> \0x? \x?? */ output[0] = hexDigits[0]; output[1] = 16 * hexDigits[1] + hexDigits[2]; break; case 4: /* 0x???? -> \0?? \x?? */ output[0] = 16 * hexDigits[0] + hexDigits[1]; output[1] = 16 * hexDigits[2] + hexDigits[3]; break; } } unsigned char uriGetOctetValue(const unsigned char * digits, int digitCount) { switch (digitCount) { case 1: return digits[0]; case 2: return 10 * digits[0] + digits[1]; case 3: default: return 100 * digits[0] + 10 * digits[1] + digits[2]; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriParseBase.h000066400000000000000000000042001516712004000277000ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef URI_PARSE_BASE_H # define URI_PARSE_BASE_H 1 # include void uriWriteQuadToDoubleByte(const unsigned char * hexDigits, int digitCount, unsigned char * output); unsigned char uriGetOctetValue(const unsigned char * digits, int digitCount); #endif /* URI_PARSE_BASE_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriQuery.c000066400000000000000000000405721516712004000271470ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriQuery.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriQuery.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # include "UriMemory.h" # endif # include # include /* size_t */ static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten, int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks); static UriBool URI_FUNC(AppendQueryItem)( URI_TYPE(QueryList) * *prevNext, int * itemCount, const URI_CHAR * keyFirst, const URI_CHAR * keyAfter, const URI_CHAR * valueFirst, const URI_CHAR * valueAfter, UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory); int URI_FUNC(ComposeQueryCharsRequired)(const URI_TYPE(QueryList) * queryList, int * charsRequired) { const UriBool spaceToPlus = URI_TRUE; const UriBool normalizeBreaks = URI_TRUE; return URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, charsRequired, spaceToPlus, normalizeBreaks); } int URI_FUNC(ComposeQueryCharsRequiredEx)(const URI_TYPE(QueryList) * queryList, int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks) { if ((queryList == NULL) || (charsRequired == NULL)) { return URI_ERROR_NULL; } return URI_FUNC(ComposeQueryEngine)(NULL, queryList, 0, NULL, charsRequired, spaceToPlus, normalizeBreaks); } int URI_FUNC(ComposeQuery)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten) { const UriBool spaceToPlus = URI_TRUE; const UriBool normalizeBreaks = URI_TRUE; return URI_FUNC(ComposeQueryEx)(dest, queryList, maxChars, charsWritten, spaceToPlus, normalizeBreaks); } int URI_FUNC(ComposeQueryEx)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten, UriBool spaceToPlus, UriBool normalizeBreaks) { if ((dest == NULL) || (queryList == NULL)) { return URI_ERROR_NULL; } if (maxChars < 1) { return URI_ERROR_OUTPUT_TOO_LARGE; } return URI_FUNC(ComposeQueryEngine)(dest, queryList, maxChars, charsWritten, NULL, spaceToPlus, normalizeBreaks); } int URI_FUNC(ComposeQueryMalloc)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList) { const UriBool spaceToPlus = URI_TRUE; const UriBool normalizeBreaks = URI_TRUE; return URI_FUNC(ComposeQueryMallocEx)(dest, queryList, spaceToPlus, normalizeBreaks); } int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList, UriBool spaceToPlus, UriBool normalizeBreaks) { return URI_FUNC(ComposeQueryMallocExMm)(dest, queryList, spaceToPlus, normalizeBreaks, NULL); } int URI_FUNC(ComposeQueryMallocExMm)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList, UriBool spaceToPlus, UriBool normalizeBreaks, UriMemoryManager * memory) { int charsRequired; int res; URI_CHAR * queryString; if (dest == NULL) { return URI_ERROR_NULL; } URI_CHECK_MEMORY_MANAGER(memory); /* may return */ /* Calculate space */ res = URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, &charsRequired, spaceToPlus, normalizeBreaks); if (res != URI_SUCCESS) { return res; } if (charsRequired == INT_MAX) { return URI_ERROR_MALLOC; } charsRequired++; /* Allocate space */ queryString = memory->calloc(memory, charsRequired, sizeof(URI_CHAR)); if (queryString == NULL) { return URI_ERROR_MALLOC; } /* Put query in */ res = URI_FUNC(ComposeQueryEx)(queryString, queryList, charsRequired, NULL, spaceToPlus, normalizeBreaks); if (res != URI_SUCCESS) { memory->free(memory, queryString); return res; } *dest = queryString; return URI_SUCCESS; } int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten, int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks) { UriBool firstItem = URI_TRUE; int ampersandLen = 0; /* increased to 1 from second item on */ URI_CHAR * write = dest; /* Subtract terminator */ if (dest == NULL) { *charsRequired = 0; } else { maxChars--; } while (queryList != NULL) { const URI_CHAR * const key = queryList->key; const URI_CHAR * const value = queryList->value; const int worstCase = (normalizeBreaks == URI_TRUE ? 6 : 3); const size_t keyLen = (key == NULL) ? 0 : URI_STRLEN(key); int keyRequiredChars; const size_t valueLen = (value == NULL) ? 0 : URI_STRLEN(value); int valueRequiredChars; if ((keyLen >= (size_t)INT_MAX / worstCase) || (valueLen >= (size_t)INT_MAX / worstCase)) { return URI_ERROR_OUTPUT_TOO_LARGE; } keyRequiredChars = worstCase * (int)keyLen; valueRequiredChars = worstCase * (int)valueLen; if (dest == NULL) { (*charsRequired) += ampersandLen + keyRequiredChars + ((value == NULL) ? 0 : 1 + valueRequiredChars); if (firstItem == URI_TRUE) { ampersandLen = 1; firstItem = URI_FALSE; } } else { if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) { return URI_ERROR_OUTPUT_TOO_LARGE; } /* Copy key */ if (firstItem == URI_TRUE) { ampersandLen = 1; firstItem = URI_FALSE; } else { write[0] = _UT('&'); write++; } write = URI_FUNC(EscapeEx)(key, key + keyLen, write, spaceToPlus, normalizeBreaks); if (value != NULL) { if ((write - dest) + 1 + valueRequiredChars > maxChars) { return URI_ERROR_OUTPUT_TOO_LARGE; } /* Copy value */ write[0] = _UT('='); write++; write = URI_FUNC(EscapeEx)(value, value + valueLen, write, spaceToPlus, normalizeBreaks); } } queryList = queryList->next; } if (dest != NULL) { write[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = (int)(write - dest) + 1; /* .. for terminator */ } } return URI_SUCCESS; } UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) * *prevNext, int * itemCount, const URI_CHAR * keyFirst, const URI_CHAR * keyAfter, const URI_CHAR * valueFirst, const URI_CHAR * valueAfter, UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory) { const int keyLen = (int)(keyAfter - keyFirst); const int valueLen = (int)(valueAfter - valueFirst); URI_CHAR * key; URI_CHAR * value; if ((prevNext == NULL) || (itemCount == NULL) || (keyFirst == NULL) || (keyAfter == NULL) || (keyFirst > keyAfter) || (valueFirst > valueAfter) || ((keyFirst == keyAfter) && (valueFirst == NULL) && (valueAfter == NULL))) { return URI_TRUE; } /* Append new empty item */ *prevNext = memory->malloc(memory, 1 * sizeof(URI_TYPE(QueryList))); if (*prevNext == NULL) { return URI_FALSE; /* Raises malloc error */ } (*prevNext)->next = NULL; /* Fill key */ key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR)); if (key == NULL) { memory->free(memory, *prevNext); *prevNext = NULL; return URI_FALSE; /* Raises malloc error */ } key[keyLen] = _UT('\0'); if (keyLen > 0) { /* Copy 1:1 */ memcpy(key, keyFirst, keyLen * sizeof(URI_CHAR)); /* Unescape */ URI_FUNC(UnescapeInPlaceEx)(key, plusToSpace, breakConversion); } (*prevNext)->key = key; /* Fill value */ if (valueFirst != NULL) { value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR)); if (value == NULL) { memory->free(memory, key); memory->free(memory, *prevNext); *prevNext = NULL; return URI_FALSE; /* Raises malloc error */ } value[valueLen] = _UT('\0'); if (valueLen > 0) { /* Copy 1:1 */ memcpy(value, valueFirst, valueLen * sizeof(URI_CHAR)); /* Unescape */ URI_FUNC(UnescapeInPlaceEx)(value, plusToSpace, breakConversion); } (*prevNext)->value = value; } else { value = NULL; } (*prevNext)->value = value; (*itemCount)++; return URI_TRUE; } void URI_FUNC(FreeQueryList)(URI_TYPE(QueryList) * queryList) { URI_FUNC(FreeQueryListMm)(queryList, NULL); } int URI_FUNC(FreeQueryListMm)(URI_TYPE(QueryList) * queryList, UriMemoryManager * memory) { URI_CHECK_MEMORY_MANAGER(memory); /* may return */ while (queryList != NULL) { URI_TYPE(QueryList) * nextBackup = queryList->next; memory->free(memory, (URI_CHAR *)queryList->key); /* const cast */ memory->free(memory, (URI_CHAR *)queryList->value); /* const cast */ memory->free(memory, queryList); queryList = nextBackup; } return URI_SUCCESS; } int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast) { const UriBool plusToSpace = URI_TRUE; const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH; return URI_FUNC(DissectQueryMallocEx)(dest, itemCount, first, afterLast, plusToSpace, breakConversion); } int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast, UriBool plusToSpace, UriBreakConversion breakConversion) { return URI_FUNC(DissectQueryMallocExMm)(dest, itemCount, first, afterLast, plusToSpace, breakConversion, NULL); } int URI_FUNC(DissectQueryMallocExMm)(URI_TYPE(QueryList) * *dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast, UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory) { const URI_CHAR * walk = first; const URI_CHAR * keyFirst = first; const URI_CHAR * keyAfter = NULL; const URI_CHAR * valueFirst = NULL; const URI_CHAR * valueAfter = NULL; URI_TYPE(QueryList) ** prevNext = dest; int nullCounter; int * itemsAppended = (itemCount == NULL) ? &nullCounter : itemCount; if ((dest == NULL) || (first == NULL) || (afterLast == NULL)) { return URI_ERROR_NULL; } if (first > afterLast) { return URI_ERROR_RANGE_INVALID; } URI_CHECK_MEMORY_MANAGER(memory); /* may return */ *dest = NULL; *itemsAppended = 0; /* Parse query string */ for (; walk < afterLast; walk++) { switch (*walk) { case _UT('&'): if (valueFirst != NULL) { valueAfter = walk; } else { keyAfter = walk; } if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, valueFirst, valueAfter, plusToSpace, breakConversion, memory) == URI_FALSE) { /* Free list we built */ *itemsAppended = 0; URI_FUNC(FreeQueryListMm)(*dest, memory); return URI_ERROR_MALLOC; } /* Make future items children of the current */ if ((prevNext != NULL) && (*prevNext != NULL)) { prevNext = &((*prevNext)->next); } if (walk + 1 < afterLast) { keyFirst = walk + 1; } else { keyFirst = NULL; } keyAfter = NULL; valueFirst = NULL; valueAfter = NULL; break; case _UT('='): /* NOTE: WE treat the first '=' as a separator, */ /* all following go into the value part */ if (keyAfter == NULL) { keyAfter = walk; if (walk + 1 <= afterLast) { valueFirst = walk + 1; valueAfter = walk + 1; } } break; default: break; } } if (valueFirst != NULL) { /* Must be key/value pair */ valueAfter = walk; } else { /* Must be key only */ keyAfter = walk; } if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, valueFirst, valueAfter, plusToSpace, breakConversion, memory) == URI_FALSE) { /* Free list we built */ *itemsAppended = 0; URI_FUNC(FreeQueryListMm)(*dest, memory); return URI_ERROR_MALLOC; } return URI_SUCCESS; } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriRecompose.c000066400000000000000000000660761516712004000300050ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriRecompose.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriRecompose.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # endif static int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars, int * charsWritten, int * charsRequired); int URI_FUNC(ToStringCharsRequired)(const URI_TYPE(Uri) * uri, int * charsRequired) { const int MAX_CHARS = ((unsigned int)-1) >> 1; return URI_FUNC(ToStringEngine)(NULL, uri, MAX_CHARS, NULL, charsRequired); } int URI_FUNC(ToString)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars, int * charsWritten) { return URI_FUNC(ToStringEngine)(dest, uri, maxChars, charsWritten, NULL); } static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars, int * charsWritten, int * charsRequired) { int written = 0; if ((uri == NULL) || ((dest == NULL) && (charsRequired == NULL))) { if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_NULL; } if (maxChars < 1) { if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } maxChars--; /* So we don't have to subtract 1 for '\0' all the time */ /* NOTE: The curly brackets here force deeper indent (and that's all) */ { { { /* clang-format off */ /* [01/19] result = "" */ /* clang-format on */ if (dest != NULL) { dest[0] = _UT('\0'); } else { (*charsRequired) = 0; } /* clang-format off */ /* [02/19] if defined(scheme) then */ /* clang-format on */ if (uri->scheme.first != NULL) { /* clang-format off */ /* [03/19] append scheme to result; */ /* clang-format on */ const int charsToWrite = (int)(uri->scheme.afterLast - uri->scheme.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->scheme.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite; } /* clang-format off */ /* [04/19] append ":" to result; */ /* clang-format on */ if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } /* clang-format off */ /* [05/19] endif; */ /* clang-format on */ } /* clang-format off */ /* [06/19] if defined(authority) then */ /* clang-format on */ if (URI_FUNC(HasHost)(uri)) { /* clang-format off */ /* [07/19] append "//" to result; */ /* clang-format on */ if (dest != NULL) { if (written + 2 <= maxChars) { memcpy(dest + written, _UT("//"), 2 * sizeof(URI_CHAR)); written += 2; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 2; } /* clang-format off */ /* [08/19] append authority to result; */ /* clang-format on */ /* UserInfo */ if (uri->userInfo.first != NULL) { const int charsToWrite = (int)(uri->userInfo.afterLast - uri->userInfo.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->userInfo.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } if (written + 1 <= maxChars) { memcpy(dest + written, _UT("@"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite + 1; } } /* Host */ if (uri->hostData.ip4 != NULL) { /* IPv4 */ int i = 0; for (; i < 4; i++) { const unsigned char value = uri->hostData.ip4->data[i]; const int charsToWrite = (value > 99) ? 3 : ((value > 9) ? 2 : 1); if (dest != NULL) { if (written + charsToWrite <= maxChars) { URI_CHAR text[4]; if (value > 99) { text[0] = _UT('0') + (value / 100); text[1] = _UT('0') + ((value % 100) / 10); text[2] = _UT('0') + (value % 10); } else if (value > 9) { text[0] = _UT('0') + (value / 10); text[1] = _UT('0') + (value % 10); } else { text[0] = _UT('0') + value; } text[charsToWrite] = _UT('\0'); memcpy(dest + written, text, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } if (i < 3) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("."), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } } else { (*charsRequired) += charsToWrite + ((i == 3) ? 0 : 1); } } } else if (uri->hostData.ip6 != NULL) { /* IPv6 */ int i = 0; if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } for (; i < 16; i++) { const unsigned char value = uri->hostData.ip6->data[i]; if (dest != NULL) { if (written + 2 <= maxChars) { URI_CHAR text[3]; text[0] = URI_FUNC(HexToLetterEx)(value / 16, URI_FALSE); text[1] = URI_FUNC(HexToLetterEx)(value % 16, URI_FALSE); text[2] = _UT('\0'); memcpy(dest + written, text, 2 * sizeof(URI_CHAR)); written += 2; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 2; } if (((i & 1) == 1) && (i < 15)) { if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } } } if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("]"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } } else if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ const int charsToWrite = (int)(uri->hostData.ipFuture.afterLast - uri->hostData.ipFuture.first); if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->hostData.ipFuture.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } if (written + 1 <= maxChars) { memcpy(dest + written, _UT("]"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1 + charsToWrite + 1; } } else if (uri->hostText.first != NULL) { /* Regname */ const int charsToWrite = (int)(uri->hostText.afterLast - uri->hostText.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->hostText.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite; } } /* Port */ if (uri->portText.first != NULL) { const int charsToWrite = (int)(uri->portText.afterLast - uri->portText.first); if (dest != NULL) { /* Leading ':' */ if (written + 1 <= maxChars) { memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } /* Port number */ if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->portText.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1 + charsToWrite; } } /* clang-format off */ /* [09/19] endif; */ /* clang-format on */ } /* clang-format off */ /* [10/19] append path to result; */ /* clang-format on */ /* Slash needed here? */ if (uri->absolutePath || ((uri->pathHead != NULL) && URI_FUNC(HasHost)(uri))) { if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("/"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } } if (uri->pathHead != NULL) { URI_TYPE(PathSegment) * walker = uri->pathHead; do { const int charsToWrite = (int)(walker->text.afterLast - walker->text.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, walker->text.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite; } /* Not last segment -> append slash */ if (walker->next != NULL) { if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("/"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } } walker = walker->next; } while (walker != NULL); } /* clang-format off */ /* [11/19] if defined(query) then */ /* clang-format on */ if (uri->query.first != NULL) { /* clang-format off */ /* [12/19] append "?" to result; */ /* clang-format on */ if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("?"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } /* clang-format off */ /* [13/19] append query to result; */ /* clang-format on */ const int charsToWrite = (int)(uri->query.afterLast - uri->query.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->query.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite; } /* clang-format off */ /* [14/19] endif; */ /* clang-format on */ } /* clang-format off */ /* [15/19] if defined(fragment) then */ /* clang-format on */ if (uri->fragment.first != NULL) { /* clang-format off */ /* [16/19] append "#" to result; */ /* clang-format on */ if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("#"), 1 * sizeof(URI_CHAR)); written += 1; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += 1; } /* clang-format off */ /* [17/19] append fragment to result; */ /* clang-format on */ const int charsToWrite = (int)(uri->fragment.afterLast - uri->fragment.first); if (dest != NULL) { if (written + charsToWrite <= maxChars) { memcpy(dest + written, uri->fragment.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; } else { dest[0] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = 0; } return URI_ERROR_TOSTRING_TOO_LONG; } } else { (*charsRequired) += charsToWrite; } /* clang-format off */ /* [18/19] endif; */ /* clang-format on */ } /* clang-format off */ /* [19/19] return result; */ /* clang-format on */ if (dest != NULL) { dest[written++] = _UT('\0'); if (charsWritten != NULL) { *charsWritten = written; } } return URI_SUCCESS; } } } } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriResolve.c000066400000000000000000000403551516712004000274600ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriResolve.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriResolve.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # include "UriMemory.h" # endif /* Appends a relative URI to an absolute. The last path segment of * the absolute URI is replaced. */ static URI_INLINE UriBool URI_FUNC(MergePath)(URI_TYPE(Uri) * absWork, const URI_TYPE(Uri) * relAppend, UriMemoryManager * memory) { URI_TYPE(PathSegment) * sourceWalker; URI_TYPE(PathSegment) * destPrev; if (relAppend->pathHead == NULL) { return URI_TRUE; } /* Replace last segment ("" if trailing slash) with first of append chain */ if (absWork->pathHead == NULL) { URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (dup == NULL) { return URI_FALSE; /* Raises malloc error */ } dup->next = NULL; absWork->pathHead = dup; absWork->pathTail = dup; } absWork->pathTail->text.first = relAppend->pathHead->text.first; absWork->pathTail->text.afterLast = relAppend->pathHead->text.afterLast; /* Append all the others */ sourceWalker = relAppend->pathHead->next; if (sourceWalker == NULL) { return URI_TRUE; } destPrev = absWork->pathTail; for (;;) { URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (dup == NULL) { destPrev->next = NULL; absWork->pathTail = destPrev; return URI_FALSE; /* Raises malloc error */ } dup->text = sourceWalker->text; destPrev->next = dup; if (sourceWalker->next == NULL) { absWork->pathTail = dup; absWork->pathTail->next = NULL; break; } destPrev = dup; sourceWalker = sourceWalker->next; } return URI_TRUE; } static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork, UriMemoryManager * memory) { if (absWork == NULL) { return URI_ERROR_NULL; } if (URI_FUNC(HasHost)(absWork) && absWork->absolutePath) { /* Empty segment needed, instead? */ if (absWork->pathHead == NULL) { URI_TYPE(PathSegment) * const segment = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_ERROR_MALLOC; } segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); segment->next = NULL; absWork->pathHead = segment; absWork->pathTail = segment; } absWork->absolutePath = URI_FALSE; } return URI_SUCCESS; } static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, UriResolutionOptions options, UriMemoryManager * memory) { UriBool relSourceHasScheme; if (absDest == NULL) { return URI_ERROR_NULL; } URI_FUNC(ResetUri)(absDest); if ((relSource == NULL) || (absBase == NULL)) { return URI_ERROR_NULL; } /* absBase absolute? */ if (absBase->scheme.first == NULL) { return URI_ERROR_ADDBASE_REL_BASE; } /* NOTE: The curly brackets here force deeper indent (and that's all) */ { { { /* clang-format off */ /* [00/32] -- A non-strict parser may ignore a scheme in the reference */ /* [00/32] -- if it is identical to the base URI's scheme. */ /* [00/32] if ((not strict) and (R.scheme == Base.scheme)) then */ /* clang-format on */ relSourceHasScheme = (relSource->scheme.first != NULL) ? URI_TRUE : URI_FALSE; if ((options & URI_RESOLVE_IDENTICAL_SCHEME_COMPAT) && (absBase->scheme.first != NULL) && (relSource->scheme.first != NULL) && (0 == URI_FUNC(CompareRange)(&(absBase->scheme), &(relSource->scheme)))) { /* clang-format off */ /* [00/32] undefine(R.scheme); */ /* clang-format on */ relSourceHasScheme = URI_FALSE; /* clang-format off */ /* [00/32] endif; */ /* clang-format on */ } /* clang-format off */ /* [01/32] if defined(R.scheme) then */ /* clang-format on */ if (relSourceHasScheme) { /* clang-format off */ /* [02/32] T.scheme = R.scheme; */ /* clang-format on */ absDest->scheme = relSource->scheme; /* clang-format off */ /* [03/32] T.authority = R.authority; */ /* clang-format on */ if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [04/32] T.path = remove_dot_segments(R.path); */ /* clang-format on */ if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [05/32] T.query = R.query; */ /* clang-format on */ absDest->query = relSource->query; /* clang-format off */ /* [06/32] else */ /* clang-format on */ } else { /* clang-format off */ /* [07/32] if defined(R.authority) then */ /* clang-format on */ if (URI_FUNC(HasHost)(relSource)) { /* clang-format off */ /* [08/32] T.authority = R.authority; */ /* clang-format on */ if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [09/32] T.path = remove_dot_segments(R.path); */ /* clang-format on */ if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [10/32] T.query = R.query; */ /* clang-format on */ absDest->query = relSource->query; /* clang-format off */ /* [11/32] else */ /* clang-format on */ } else { /* clang-format off */ /* [28/32] T.authority = Base.authority; */ /* clang-format on */ if (!URI_FUNC(CopyAuthority)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [12/32] if (R.path == "") then */ /* clang-format on */ if (relSource->pathHead == NULL && !relSource->absolutePath) { /* clang-format off */ /* [13/32] T.path = Base.path; */ /* clang-format on */ if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [14/32] if defined(R.query) then */ /* clang-format on */ if (relSource->query.first != NULL) { /* clang-format off */ /* [15/32] T.query = R.query; */ /* clang-format on */ absDest->query = relSource->query; /* clang-format off */ /* [16/32] else */ /* clang-format on */ } else { /* clang-format off */ /* [17/32] T.query = Base.query; */ /* clang-format on */ absDest->query = absBase->query; /* clang-format off */ /* [18/32] endif; */ /* clang-format on */ } /* clang-format off */ /* [19/32] else */ /* clang-format on */ } else { /* clang-format off */ /* [20/32] if (R.path starts-with "/") then */ /* clang-format on */ if (relSource->absolutePath) { int res; /* clang-format off */ /* [21/32] T.path = remove_dot_segments(R.path); */ /* clang-format on */ if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } res = URI_FUNC(ResolveAbsolutePathFlag)(absDest, memory); if (res != URI_SUCCESS) { return res; } if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [22/32] else */ /* clang-format on */ } else { /* clang-format off */ /* [23/32] T.path = merge(Base.path, R.path); */ /* clang-format on */ if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } if (!URI_FUNC(MergePath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [24/32] T.path = remove_dot_segments(T.path); */ /* clang-format on */ if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } if (!URI_FUNC(FixAmbiguity)(absDest, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [25/32] endif; */ } /* clang-format off */ /* [26/32] T.query = R.query; */ /* clang-format on */ absDest->query = relSource->query; /* clang-format off */ /* [27/32] endif; */ /* clang-format on */ } URI_FUNC(FixEmptyTrailSegment)(absDest, memory); /* clang-format off */ /* [29/32] endif; */ /* clang-format on */ } /* clang-format off */ /* [30/32] T.scheme = Base.scheme; */ /* clang-format on */ absDest->scheme = absBase->scheme; /* clang-format off */ /* [31/32] endif; */ /* clang-format on */ } /* clang-format off */ /* [32/32] T.fragment = R.fragment; */ /* clang-format on */ absDest->fragment = relSource->fragment; } } } return URI_SUCCESS; } int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase) { const UriResolutionOptions options = URI_RESOLVE_STRICTLY; return URI_FUNC(AddBaseUriEx)(absDest, relSource, absBase, options); } int URI_FUNC(AddBaseUriEx)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, UriResolutionOptions options) { return URI_FUNC(AddBaseUriExMm)(absDest, relSource, absBase, options, NULL); } int URI_FUNC(AddBaseUriExMm)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, UriResolutionOptions options, UriMemoryManager * memory) { int res; URI_CHECK_MEMORY_MANAGER(memory); /* may return */ res = URI_FUNC(AddBaseUriImpl)(absDest, relSource, absBase, options, memory); if ((res != URI_SUCCESS) && (absDest != NULL)) { URI_FUNC(FreeUriMembersMm)(absDest, memory); } return res; } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriSets.h000066400000000000000000000107231516712004000267600ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2025, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file UriSets.h * Holds character set definitions. */ // NOTE: We cannot use a regular include-once guard here because the // file must support being included twice, e.g. from file UriParse.c. #if !defined(URI_SET_DIGIT) // clang-format off # define URI_SET_DIGIT(ut) \ ut('0'): \ case ut('1'): \ /* clang-format on */ \ case ut('2'): \ case ut('3'): \ case ut('4'): \ case ut('5'): \ case ut('6'): \ case ut('7'): \ case ut('8'): \ case ut('9') // clang-format off # define URI_SET_HEX_LETTER_LOWER(ut) \ ut('a'): \ case ut('b'): \ /* clang-format on */ \ case ut('c'): \ case ut('d'): \ case ut('e'): \ case ut('f') // clang-format off # define URI_SET_HEX_LETTER_UPPER(ut) \ ut('A'): \ case ut('B'): \ /* clang-format on */ \ case ut('C'): \ case ut('D'): \ case ut('E'): \ case ut('F') // clang-format off # define URI_SET_HEXDIG(ut) \ URI_SET_DIGIT(ut): \ case URI_SET_HEX_LETTER_LOWER(ut): \ /* clang-format on */ \ case URI_SET_HEX_LETTER_UPPER(ut) // clang-format off # define URI_SET_ALPHA(ut) \ URI_SET_HEX_LETTER_UPPER(ut): \ case URI_SET_HEX_LETTER_LOWER(ut): \ /* clang-format on */ \ case ut('g'): \ case ut('G'): \ case ut('h'): \ case ut('H'): \ case ut('i'): \ case ut('I'): \ case ut('j'): \ case ut('J'): \ case ut('k'): \ case ut('K'): \ case ut('l'): \ case ut('L'): \ case ut('m'): \ case ut('M'): \ case ut('n'): \ case ut('N'): \ case ut('o'): \ case ut('O'): \ case ut('p'): \ case ut('P'): \ case ut('q'): \ case ut('Q'): \ case ut('r'): \ case ut('R'): \ case ut('s'): \ case ut('S'): \ case ut('t'): \ case ut('T'): \ case ut('u'): \ case ut('U'): \ case ut('v'): \ case ut('V'): \ case ut('w'): \ case ut('W'): \ case ut('x'): \ case ut('X'): \ case ut('y'): \ case ut('Y'): \ case ut('z'): \ case ut('Z') // clang-format off # define URI_SET_SUB_DELIMS(ut) \ ut('!'): \ case ut('$'): \ /* clang-format on */ \ case ut('&'): \ case ut('\''): \ case ut('('): \ case ut(')'): \ case ut('*'): \ case ut('+'): \ case ut(','): \ case ut(';'): \ case ut('=') // clang-format off # define URI_SET_UNRESERVED(ut) \ URI_SET_ALPHA(ut): \ case URI_SET_DIGIT(ut): \ /* clang-format on */ \ case ut('-'): \ case ut('.'): \ case ut('_'): \ case ut('~') // clang-format off # define URI_SET_PCHAR_WITHOUT_PERCENT(ut) \ URI_SET_UNRESERVED(ut): \ case URI_SET_SUB_DELIMS(ut): \ /* clang-format on */ \ case ut(':'): \ case ut('@') // clang-format off # define URI_SET_PCHAR(ut) \ URI_SET_PCHAR_WITHOUT_PERCENT(ut): \ case ut('%') /* clang-format on */ #endif // ! defined(URI_SET_DIGIT) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/uriparser/UriShorten.c000066400000000000000000000451711516712004000274640ustar00rootroot00000000000000/* * uriparser - RFC 3986 URI parsing library * * Copyright (C) 2007, Weijia Song * Copyright (C) 2007, Sebastian Pipping * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* What encodings are enabled? */ #include #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) /* Include SELF twice */ # ifdef URI_ENABLE_ANSI # define URI_PASS_ANSI 1 # include "UriShorten.c" # undef URI_PASS_ANSI # endif # ifdef URI_ENABLE_UNICODE # define URI_PASS_UNICODE 1 # include "UriShorten.c" # undef URI_PASS_UNICODE # endif #else # ifdef URI_PASS_ANSI # include # else # include # include # endif # ifndef URI_DOXYGEN # include # include "UriCommon.h" # include "UriMemory.h" # endif static URI_INLINE UriBool URI_FUNC(AppendSegment)(URI_TYPE(Uri) * uri, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) { /* Create segment */ URI_TYPE(PathSegment) * segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } segment->next = NULL; segment->text.first = first; segment->text.afterLast = afterLast; /* Put into chain */ if (uri->pathTail == NULL) { uri->pathHead = segment; } else { uri->pathTail->next = segment; } uri->pathTail = segment; return URI_TRUE; } static URI_INLINE UriBool URI_FUNC(EqualsAuthority)(const URI_TYPE(Uri) * first, const URI_TYPE(Uri) * second) { /* IPv4 */ if (first->hostData.ip4 != NULL) { return ((second->hostData.ip4 != NULL) && !memcmp(first->hostData.ip4->data, second->hostData.ip4->data, 4)) ? URI_TRUE : URI_FALSE; } /* IPv6 */ if (first->hostData.ip6 != NULL) { return ((second->hostData.ip6 != NULL) && !memcmp(first->hostData.ip6->data, second->hostData.ip6->data, 16)) ? URI_TRUE : URI_FALSE; } /* IPvFuture */ if (first->hostData.ipFuture.first != NULL) { return ((second->hostData.ipFuture.first != NULL) && !URI_FUNC(CompareRange)(&first->hostData.ipFuture, &second->hostData.ipFuture)) ? URI_TRUE : URI_FALSE; } return !URI_FUNC(CompareRange)(&first->hostText, &second->hostText) ? URI_TRUE : URI_FALSE; } static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource, const URI_TYPE(Uri) * absBase, UriBool domainRootMode, UriMemoryManager * memory) { if (dest == NULL) { return URI_ERROR_NULL; } URI_FUNC(ResetUri)(dest); if ((absSource == NULL) || (absBase == NULL)) { return URI_ERROR_NULL; } /* absBase absolute? */ if (absBase->scheme.first == NULL) { return URI_ERROR_REMOVEBASE_REL_BASE; } /* absSource absolute? */ if (absSource->scheme.first == NULL) { return URI_ERROR_REMOVEBASE_REL_SOURCE; } /* NOTE: The curly brackets here force deeper indent (and that's all) */ { { { /* clang-format off */ /* [01/50] if (A.scheme != Base.scheme) then */ /* clang-format on */ if (URI_FUNC(CompareRange)(&absSource->scheme, &absBase->scheme)) { /* clang-format off */ /* [02/50] T.scheme = A.scheme; */ /* clang-format on */ dest->scheme = absSource->scheme; /* clang-format off */ /* [03/50] T.authority = A.authority; */ /* clang-format on */ if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [04/50] T.path = A.path; */ /* clang-format on */ if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [05/50] else */ /* clang-format on */ } else { /* clang-format off */ /* [06/50] undef(T.scheme); */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [07/50] if (A.authority != Base.authority) then */ /* clang-format on */ if (!URI_FUNC(EqualsAuthority)(absSource, absBase)) { /* clang-format off */ /* [08/50] T.authority = A.authority; */ /* clang-format on */ if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [09/50] T.path = A.path; */ /* clang-format on */ if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [10/50] else */ /* clang-format on */ } else { /* clang-format off */ /* [11/50] if domainRootMode then */ /* clang-format on */ if (domainRootMode == URI_TRUE) { /* clang-format off */ /* [12/50] undef(T.authority); */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [13/50] if (first(A.path) == "") then */ /* clang-format on */ /* GROUPED */ /* clang-format off */ /* [14/50] T.path = "/." + A.path; */ /* clang-format on */ /* GROUPED */ /* clang-format off */ /* [15/50] else */ /* clang-format on */ /* GROUPED */ /* clang-format off */ /* [16/50] T.path = A.path; */ /* clang-format on */ /* GROUPED */ /* clang-format off */ /* [17/50] endif; */ /* clang-format on */ if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } dest->absolutePath = URI_TRUE; if (!URI_FUNC(FixAmbiguity)(dest, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [18/50] else */ /* clang-format on */ } else { const URI_TYPE(PathSegment) * sourceSeg = absSource->pathHead; const URI_TYPE(PathSegment) * baseSeg = absBase->pathHead; /* clang-format off */ /* [19/50] bool pathNaked = true; */ /* clang-format on */ UriBool pathNaked = URI_TRUE; /* clang-format off */ /* [20/50] undef(last(Base.path)); */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [21/50] T.path = ""; */ /* clang-format on */ dest->absolutePath = URI_FALSE; /* clang-format off */ /* [22/50] while (first(A.path) == first(Base.path)) do */ /* clang-format on */ while ( (sourceSeg != NULL) && (baseSeg != NULL) && !URI_FUNC(CompareRange)(&sourceSeg->text, &baseSeg->text) && !((sourceSeg->text.first == sourceSeg->text.afterLast) && ((sourceSeg->next == NULL) != (baseSeg->next == NULL)))) { /* clang-format off */ /* [23/50] A.path++; */ /* clang-format on */ sourceSeg = sourceSeg->next; /* clang-format off */ /* [24/50] Base.path++; */ /* clang-format on */ baseSeg = baseSeg->next; /* clang-format off */ /* [25/50] endwhile; */ /* clang-format on */ } /* clang-format off */ /* [26/50] while defined(first(Base.path)) do */ /* clang-format on */ while ((baseSeg != NULL) && (baseSeg->next != NULL)) { /* clang-format off */ /* [27/50] Base.path++; */ /* clang-format on */ baseSeg = baseSeg->next; /* clang-format off */ /* [28/50] T.path += "../"; */ /* clang-format on */ if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstParent), URI_FUNC(ConstParent) + 2, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [29/50] pathNaked = false; */ /* clang-format on */ pathNaked = URI_FALSE; /* clang-format off */ /* [30/50] endwhile; */ /* clang-format on */ } /* clang-format off */ /* [31/50] while defined(first(A.path)) do */ /* clang-format on */ while (sourceSeg != NULL) { /* clang-format off */ /* [32/50] if pathNaked then */ /* clang-format on */ if (pathNaked == URI_TRUE) { /* clang-format off */ /* [33/50] if (first(A.path) contains ":") then */ /* clang-format on */ UriBool containsColon = URI_FALSE; const URI_CHAR * ch = sourceSeg->text.first; for (; ch < sourceSeg->text.afterLast; ch++) { if (*ch == _UT(':')) { containsColon = URI_TRUE; break; } } if (containsColon) { /* clang-format off */ /* [34/50] T.path += "./"; */ /* clang-format on */ if (!URI_FUNC(AppendSegment)( dest, URI_FUNC(ConstPwd), URI_FUNC(ConstPwd) + 1, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [35/50] elseif (first(A.path) == "") then */ /* clang-format on */ } else if (sourceSeg->text.first == sourceSeg->text.afterLast) { /* clang-format off */ /* [36/50] T.path += "/."; */ /* clang-format on */ if (!URI_FUNC(AppendSegment)( dest, URI_FUNC(ConstPwd), URI_FUNC(ConstPwd) + 1, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [37/50] endif; */ /* clang-format on */ } /* clang-format off */ /* [38/50] endif; */ /* clang-format on */ } /* clang-format off */ /* [39/50] T.path += first(A.path); */ /* clang-format on */ if (!URI_FUNC(AppendSegment)(dest, sourceSeg->text.first, sourceSeg->text.afterLast, memory)) { return URI_ERROR_MALLOC; } /* clang-format off */ /* [40/50] pathNaked = false; */ /* clang-format on */ pathNaked = URI_FALSE; /* clang-format off */ /* [41/50] A.path++; */ /* clang-format on */ sourceSeg = sourceSeg->next; /* clang-format off */ /* [42/50] if defined(first(A.path)) then */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [43/50] T.path += + "/"; */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [44/50] endif; */ /* clang-format on */ /* NOOP */ /* clang-format off */ /* [45/50] endwhile; */ /* clang-format on */ } /* clang-format off */ /* [46/50] endif; */ /* clang-format on */ } /* clang-format off */ /* [47/50] endif; */ /* clang-format on */ } /* clang-format off */ /* [48/50] endif; */ /* clang-format on */ } /* clang-format off */ /* [49/50] T.query = A.query; */ /* clang-format on */ dest->query = absSource->query; /* clang-format off */ /* [50/50] T.fragment = A.fragment; */ /* clang-format on */ dest->fragment = absSource->fragment; } } } return URI_SUCCESS; } int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource, const URI_TYPE(Uri) * absBase, UriBool domainRootMode) { return URI_FUNC(RemoveBaseUriMm)(dest, absSource, absBase, domainRootMode, NULL); } int URI_FUNC(RemoveBaseUriMm)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource, const URI_TYPE(Uri) * absBase, UriBool domainRootMode, UriMemoryManager * memory) { int res; URI_CHECK_MEMORY_MANAGER(memory); /* may return */ res = URI_FUNC(RemoveBaseUriImpl)(dest, absSource, absBase, domainRootMode, memory); if ((res != URI_SUCCESS) && (dest != NULL)) { URI_FUNC(FreeUriMembersMm)(dest, memory); } return res; } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf.cpp000066400000000000000000000123131516712004000246560ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "xspf.h" using namespace Xspf; using namespace smooth::IO; const String &BoCA::PlaylistXSPF::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ XSPF Playlist \ 1.0 \ xspf-playlist \ playlist \ \ XSPF Playlist \ xspf \ \ \ \ "; return componentSpecs; } namespace BoCA { class PlaylistXSPFCallback : public XspfReaderCallback { private: PlaylistXSPF *playlist; public: PlaylistXSPFCallback(PlaylistXSPF *); void addTrack(XspfTrack *); }; }; BoCA::PlaylistXSPF::PlaylistXSPF() { } BoCA::PlaylistXSPF::~PlaylistXSPF() { } Bool BoCA::PlaylistXSPF::CanOpenFile(const String &file) { return file.ToLower().EndsWith(".xspf"); } const Array &BoCA::PlaylistXSPF::ReadPlaylist(const String &file) { InStream in(STREAM_FILE, file, IS_READ); /* Create XSPF reader. */ XspfReader reader; PlaylistXSPFCallback callback(this); int numBytes = in.Size() + 1; char *memory = new char [numBytes]; in.InputData(memory, numBytes - 1); memory[numBytes - 1] = 0; reader.parseMemory(memory, numBytes, &callback, String("file://").Append(Encoding::URLEncode::Encode(file.Replace("\\", "/")).Replace("%2F", "/").Replace("%3A", ":"))); delete [] memory; /* Complete relative filenames. */ for (Int i = 0; i < trackList.Length(); i++) { Track &track = trackList.GetNthReference(i); /* Get file name. */ String &fileName = track.fileName; /* Handle relative paths. */ if (Utilities::IsRelativePath(fileName)) fileName = File(file).GetFilePath().Append(Directory::GetDirectoryDelimiter()).Append(fileName); } in.Close(); return trackList; } Error BoCA::PlaylistXSPF::WritePlaylist(const String &file) { if (trackList.Length() == 0) return Error(); String::OutputFormat outputFormat("UTF-8"); String actualFile = Utilities::CreateDirectoryForFile(file); OutStream out(STREAM_FILE, actualFile, OS_REPLACE); /* Create XSPF writer. */ XspfIndentFormatter formatter; XspfWriter *writer = XspfWriter::makeWriter(formatter, NIL, false); /* Add tracks. */ foreach (const Track &track, trackList) { /* Special handling for CD tracks on Windows. */ String fileName = Utilities::GetRelativeFileName(Utilities::GetCDTrackFileName(track), actualFile); fileName = Encoding::URLEncode::Encode(fileName.Replace("\\", "/")).Replace("%2F", "/").Replace("%3A", ":"); /* Handle absolute paths. */ #ifdef __WIN32__ if (fileName[1] == ':') fileName = String("/").Append(fileName); #endif if (fileName[0] == '/') fileName = String("file://").Append(fileName); /* Add info to XSPF. */ const Info &info = track.GetInfo(); XspfTrack xspfTrack; if (info.artist != NIL) xspfTrack.lendCreator(info.artist); if (info.album != NIL) xspfTrack.lendAlbum(info.album); if (info.title != NIL) xspfTrack.lendTitle(info.title); if (info.track > 0) xspfTrack.setTrackNum(info.track); if (track.length >= 0) xspfTrack.setDuration(Math::Round((Float) track.length / track.GetFormat().rate * 1000.0)); xspfTrack.lendAppendLocation(fileName); writer->addTrack(xspfTrack); } /* Write file and clean up. */ char *memory = NIL; int numBytes = 0; if (writer->writeMemory(memory, numBytes) == XSPF_WRITER_SUCCESS) { /* Replace tabs with double spaces in output XSPF. */ String xml; xml.ImportFrom("UTF-8", memory); xml.Replace("\t", " "); out.OutputString(xml); delete [] memory; } delete writer; out.Close(); return Success(); } BoCA::PlaylistXSPFCallback::PlaylistXSPFCallback(PlaylistXSPF *playlist) { this->playlist = playlist; } void BoCA::PlaylistXSPFCallback::addTrack(XspfTrack *xspfTrack) { String::InputFormat inputFormat("UTF-8"); /* Get title info. */ Track track; Info info; info.artist = xspfTrack->getCreator(); info.album = xspfTrack->getAlbum(); info.title = xspfTrack->getTitle(); info.track = xspfTrack->getTrackNum(); track.SetInfo(info); /* Decode file name. */ String fileName = Encoding::URLEncode::Decode(String(xspfTrack->getLocation(0)).Replace("file://", NIL)).Replace("/", Directory::GetDirectoryDelimiter()); #ifdef __WIN32__ if (fileName.StartsWith(Directory::GetDirectoryDelimiter()) && fileName[2] == ':') fileName = fileName.Tail(fileName.Length() - 1); #endif track.fileName = fileName; /* Add track to playlist. */ playlist->trackList.Add(track); delete xspfTrack; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf.h000066400000000000000000000020601516712004000243210ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(PlaylistXSPF) namespace BoCA { class PlaylistXSPF : public CS::PlaylistComponent { friend class PlaylistXSPFCallback; public: static const String &GetComponentSpecs(); PlaylistXSPF(); ~PlaylistXSPF(); Bool CanOpenFile(const String &); const Array &ReadPlaylist(const String &); Error WritePlaylist(const String &); }; }; BoCA_DEFINE_PLAYLIST_COMPONENT(PlaylistXSPF) BoCA_END_COMPONENT(PlaylistXSPF) boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/000077500000000000000000000000001516712004000241525ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/Makefile000066400000000000000000000015071516712004000256150ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = XspfChunkCallback.o XspfData.o XspfDataWriter.o XspfDateTime.o XspfExtension.o XspfExtensionReader.o XspfExtensionReaderFactory.o XspfExtensionWriter.o XspfIndentFormatter.o XspfProps.o XspfPropsWriter.o XspfReader.o XspfReaderCallback.o XspfSeamlessFormatter.o XspfSkipExtensionReader.o XspfStrictReaderCallback.o XspfToolbox.o XspfTrack.o XspfTrackWriter.o XspfWriter.o XspfXmlFormatter.o TARGET = libxspf.a CPPOPTS = -I"$(SRCDIR)"/.. AR = ar ifeq ($(USE_BUNDLED_LIBEXPAT),True) CPPOPTS += -I"$(SRCDIR)"/../expat endif ifneq ($(BUILD_WIN32),True) CPPOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .cpp.o: $(CXX) $(CPPOPTS) $(CXXFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/Xspf.h000066400000000000000000000051741516712004000252520ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file Xspf.h * Include-everything header for lazy people with fast machines. */ #ifndef XSPF_H #define XSPF_H /** * @namespace Xspf * Provides reading and writing functionality * for both XSPF-0 and XSPF-1. */ // #include "Xspf.h" #include "XspfChunkCallback.h" // #include "XspfData.h" #include "XspfDateTime.h" // #include "XspfDefines.h" #include "XspfExtension.h" // #include "XspfExtensionReader.h" #include "XspfExtensionReaderFactory.h" #include "XspfExtensionWriter.h" #include "XspfIndentFormatter.h" #include "XspfProps.h" #include "XspfReader.h" #include "XspfReaderCallback.h" #include "XspfSeamlessFormatter.h" #include "XspfStack.h" // #include "XspfToolbox.h" #include "XspfTrack.h" // #include "XspfVersion.h" #include "XspfWriter.h" // #include "XspfXmlFormatter.h" #endif // XSPF_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfChunkCallback.cpp000066400000000000000000000056301516712004000302100ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfChunkCallback.cpp * Implementation of XspfChunkCallback. */ #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfChunkCallback. */ class XspfChunkCallbackPrivate { friend class XspfChunkCallback; // No membes yet /** * Creates a new XspfChunkCallbackPrivate object. */ XspfChunkCallbackPrivate() { } /** * Copy constructor. * * @param source Source to copy from */ XspfChunkCallbackPrivate(XspfChunkCallbackPrivate const & /*source*/) { } }; /// @endcond XspfChunkCallback::XspfChunkCallback() : d(new XspfChunkCallbackPrivate()) { } XspfChunkCallback::XspfChunkCallback(XspfChunkCallback const & source) : d(new XspfChunkCallbackPrivate(*(source.d))) { } XspfChunkCallback & XspfChunkCallback::operator=(XspfChunkCallback const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfChunkCallback::~XspfChunkCallback() { delete this->d; } void XspfChunkCallback::notifyStop() { } void XspfChunkCallback::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfChunkCallback.h000066400000000000000000000072441516712004000276600ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfChunkCallback.h * Interface of XspfChunkCallback. */ #ifndef XSPF_CHUNK_CALLBACK_H #define XSPF_CHUNK_CALLBACK_H namespace Xspf { class XspfChunkCallbackPrivate; /** * Hands out text chunks to a XspfReader. * This enables parsing from non-linear input * structures. It can also be used to parse * bug XSPF files in smaller chunks to lower * memory usage. */ class XspfChunkCallback { friend class XspfReader; private: /// @cond DOXYGEN_NON_API XspfChunkCallbackPrivate * const d; ///< D pointer /// @endcond protected: /** * Creates a new chunk callback. */ XspfChunkCallback(); /** * Copy constructor. * * @param source Source to copy from */ XspfChunkCallback(XspfChunkCallback const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfChunkCallback & operator=(XspfChunkCallback const & source); /** * Destroys this chunk callback. */ virtual ~XspfChunkCallback(); /** * Returns the minimum size in bytes of the * buffer handed to fillBuffer in a subsequent * call. * * @return Size in bytes */ virtual int getMinimumBufferByteSize() = 0; /** * Fulls buffer with a new * chunk of input. the chunk copies must * not exceed the number of bytes returned * by the last call to getMinimumBufferByteSize. * NOTE: You do not have to zero-terminate * the string written. If you do so do not count * this into the return value. * * @param buffer Buffer to write to * @return Number of bytes actually written */ virtual int fillBuffer(void * buffer) = 0; /** * Notifies this chunk callback, that * no more chunks will be needed. You can close * the resource read from in here. */ virtual void notifyStop(); /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond }; } #endif // XSPF_CHUNK_CALLBACK_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfData.cpp000066400000000000000000000427061516712004000264010ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfData.cpp * Implementation of XspfData. */ #include #include #include namespace Xspf { /*static*/ const bool XspfData::COPY = true; /*static*/ const bool XspfData::TRANSFER = false; /// @cond DOXYGEN_NON_API /** * D object for XspfData. */ class XspfDataPrivate { friend class XspfData; XML_Char const * image; ///< Image URI XML_Char const * info; ///< Info URI XML_Char const * annotation; ///< Annotation XML_Char const * creator; ///< Creator/artist XML_Char const * title; ///< Title bool ownImage; ///< Image memory ownership flag bool ownInfo; ///< Info memory ownership flag bool ownAnnotation; ///< Annotation memory ownership flag bool ownCreator; ///< Creator memory ownership flag bool ownTitle; ///< Title memory ownership flag std::deque *, std::pair *> *> * links; ///< List of link pairs std::deque *, std::pair *> *> * metas; ///< List of meta pairs std::deque *> * extensions; ///< List of extensions /** * Creates a new D object. */ XspfDataPrivate() : image(NULL), info(NULL), annotation(NULL), creator(NULL), title(NULL), ownImage(false), ownInfo(false), ownAnnotation(false), ownCreator(false), ownTitle(false), links(NULL), metas(NULL), extensions(NULL) { } /** * Copy constructor. * * @param source Source to copy from */ XspfDataPrivate(XspfDataPrivate const & source) : image(source.ownImage ? Toolbox::newAndCopy(source.image) : source.image), info(source.ownInfo ? Toolbox::newAndCopy(source.info) : source.info), annotation(source.ownAnnotation ? Toolbox::newAndCopy(source.annotation) : source.annotation), creator(source.ownCreator ? Toolbox::newAndCopy(source.creator) : source.creator), title(source.ownTitle ? Toolbox::newAndCopy(source.title) : source.title), ownImage(source.ownImage), ownInfo(source.ownInfo), ownAnnotation(source.ownAnnotation), ownCreator(source.ownCreator), ownTitle(source.ownTitle), links(NULL), metas(NULL), extensions(NULL) { copyMetasOrLinks(this->links, source.links); copyMetasOrLinks(this->metas, source.metas); copyExtensions(this->extensions, source.extensions); } /** * Assignment operator. * * @param source Source to copy from */ XspfDataPrivate & operator=(XspfDataPrivate const & source) { if (this != &source) { free(); assign(source); } return *this; } /** * Destroys this D object. */ ~XspfDataPrivate() { free(); } void free() { // Frees all data, does not set to NULL Toolbox::freeIfOwned(this->title, this->ownTitle); Toolbox::freeIfOwned(this->creator, this->ownCreator); Toolbox::freeIfOwned(this->annotation, this->ownAnnotation); Toolbox::freeIfOwned(this->image, this->ownImage); Toolbox::freeIfOwned(this->info, this->ownInfo); freeMetasOrLinks(this->links); freeMetasOrLinks(this->metas); freeExtensions(this->extensions); } void assign(XspfDataPrivate const & source) { // Assigns all members, does not free current content Toolbox::copyIfOwned(this->title, this->ownTitle, source.title, source.ownTitle); Toolbox::copyIfOwned(this->creator, this->ownCreator, source.creator, source.ownCreator); Toolbox::copyIfOwned(this->annotation, this->ownAnnotation, source.annotation, source.ownAnnotation); Toolbox::copyIfOwned(this->image, this->ownImage, source.image, source.ownImage); Toolbox::copyIfOwned(this->info, this->ownInfo, source.info, source.ownInfo); copyMetasOrLinks(this->links, source.links); copyMetasOrLinks(this->metas, source.metas); copyExtensions(this->extensions, source.extensions); } static inline void freeMetasOrLinks(std::deque *, std::pair *> *> * & container) { if (container != NULL) { std::deque *, std::pair *> *> ::const_iterator iter = container->begin(); while (iter != container->end()) { std::pair *, std::pair *> * const entry = *iter; if (entry->first->second) { delete [] entry->first->first; } delete entry->first; if (entry->second->second) { delete [] entry->second->first; } delete entry->second; delete entry; iter++; } container->clear(); delete container; container = NULL; } } static inline void copyMetasOrLinks(std::deque *, std::pair *> *> * & dest, std::deque *, std::pair *> *> * const & source) { dest = new std::deque *, std::pair *> *>(); if (source != NULL) { std::deque *, std::pair *> *>::const_iterator iter = source->begin(); while (iter != source->end()) { const std::pair *, std::pair *> * const entry = *iter; bool const ownRel = entry->first->second; bool const ownContent = entry->second->second; XML_Char const * const rel = ownRel ? Toolbox::newAndCopy(entry->first->first) : entry->first->first; XML_Char const * const content = ownContent ? Toolbox::newAndCopy(entry->second->first) : entry->second->first; XspfData::appendHelper(dest, rel, ownRel, content, ownContent); iter++; } } } static inline void freeExtensions(std::deque *> * & container) { if (container != NULL) { std::deque *>::const_iterator iter = container->begin(); while (iter != container->end()) { std::pair * const entry = *iter; if (entry->second) { delete entry->first; } delete entry; iter++; } container->clear(); delete container; container = NULL; } } static inline void copyExtensions(std::deque< std::pair *> * & dest, std::deque< std::pair *> * const & source) { dest = new std::deque *>(); if (source != NULL) { std::deque *>::const_iterator iter = source->begin(); while (iter != source->end()) { const std::pair * const entry = *iter; bool const own = entry->second; XspfExtension const * const extension = own ? entry->first->clone() : entry->first; XspfData::appendHelper(dest, extension, own); iter++; } } } }; /// @endcond XspfData::XspfData() : d(new XspfDataPrivate()) { // NOOP } XspfData::XspfData(XspfData const & source) : d(new XspfDataPrivate(*(source.d))) { // NOOP } XspfData & XspfData::operator=(XspfData const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfData::~XspfData() { delete this->d; } void XspfData::giveAnnotation(XML_Char const * annotation, bool copy) { Toolbox::deleteNewAndCopy(this->d->annotation, this->d->ownAnnotation, annotation, copy); } void XspfData::giveCreator(XML_Char const * creator, bool copy) { Toolbox::deleteNewAndCopy(this->d->creator, this->d->ownCreator, creator, copy); } void XspfData::giveInfo(XML_Char const * info, bool copy) { Toolbox::deleteNewAndCopy(this->d->info, this->d->ownInfo, info, copy); } void XspfData::giveImage(XML_Char const * image, bool copy) { Toolbox::deleteNewAndCopy(this->d->image, this->d->ownImage, image, copy); } void XspfData::giveTitle(XML_Char const * title, bool copy) { Toolbox::deleteNewAndCopy(this->d->title, this->d->ownTitle, title, copy); } void XspfData::giveAppendLink(XML_Char const * rel, bool copyRel, XML_Char const * content, bool copyContent) { appendHelper(this->d->links, copyRel ? Toolbox::newAndCopy(rel) : rel, true, copyContent ? Toolbox::newAndCopy(content) : content, true); } void XspfData::giveAppendMeta(XML_Char const * rel, bool copyRel, XML_Char const * content, bool copyContent) { appendHelper(this->d->metas, copyRel ? Toolbox::newAndCopy(rel) : rel, true, copyContent ? Toolbox::newAndCopy(content) : content, true); } void XspfData::giveAppendExtension(XspfExtension const * extension, bool copy) { appendHelper(this->d->extensions, copy ? extension->clone() : extension, true); } void XspfData::lendAnnotation(XML_Char const * annotation) { Toolbox::deleteNewAndCopy(this->d->annotation, this->d->ownAnnotation, annotation, false); } void XspfData::lendCreator(XML_Char const * creator) { Toolbox::deleteNewAndCopy(this->d->creator, this->d->ownCreator, creator, false); } void XspfData::lendInfo(XML_Char const * info) { Toolbox::deleteNewAndCopy(this->d->info, this->d->ownInfo, info, false); } void XspfData::lendImage(XML_Char const * image) { Toolbox::deleteNewAndCopy(this->d->image, this->d->ownImage, image, false); } void XspfData::lendTitle(XML_Char const * title) { Toolbox::deleteNewAndCopy(this->d->title, this->d->ownTitle, title, false); } void XspfData::lendAppendLink(XML_Char const * rel, XML_Char const * content) { appendHelper(this->d->links, rel, false, content, false); } void XspfData::lendAppendMeta(XML_Char const * rel, XML_Char const * content) { appendHelper(this->d->metas, rel, false, content, false); } void XspfData::lendAppendExtension(XspfExtension * extension) { appendHelper(this->d->extensions, extension, false); } XML_Char * XspfData::stealTitle() { return stealHelper(this->d->title, this->d->ownTitle); } XML_Char * XspfData::stealAnnotation() { return stealHelper(this->d->annotation, this->d->ownAnnotation); } XML_Char * XspfData::stealCreator() { return stealHelper(this->d->creator, this->d->ownCreator); } XML_Char * XspfData::stealInfo() { return stealHelper(this->d->info, this->d->ownInfo); } XML_Char * XspfData::stealImage() { return stealHelper(this->d->image, this->d->ownImage); } std::pair * XspfData::stealFirstMeta() { return stealFirstHelper(this->d->metas); } std::pair * XspfData::stealFirstLink() { return stealFirstHelper(this->d->links); } XspfExtension * XspfData::stealFirstExtension() { return stealFirstHelper(this->d->extensions); } const XML_Char * XspfData::getImage() const { return this->d->image; } const XML_Char * XspfData::getInfo() const { return this->d->info; } const XML_Char * XspfData::getAnnotation() const { return this->d->annotation; } const XML_Char * XspfData::getCreator() const { return this->d->creator; } const XML_Char * XspfData::getTitle() const { return this->d->title; } std::pair * XspfData::getLink(int index) const { return getHelper(this->d->links, index); } std::pair * XspfData::getMeta(int index) const { return getHelper(this->d->metas, index); } const XspfExtension * XspfData::getExtension(int index) const { return getHelper(this->d->extensions, index); } int XspfData::getLinkCount() const { return (this->d->links == NULL) ? 0 : static_cast(this->d->links->size()); } int XspfData::getMetaCount() const { return (this->d->metas == NULL) ? 0 : static_cast(this->d->metas->size()); } int XspfData::getExtensionCount() const { return (this->d->extensions == NULL) ? 0 : static_cast(this->d->extensions->size()); } /*static*/ void XspfData::appendHelper( std::deque *, std::pair *> *> * & container, XML_Char const * rel, bool ownRel, XML_Char const * content, bool ownContent) { if (container == NULL) { container = new std::deque *, std::pair *> *>; } std::pair * const first = new std::pair(rel, ownRel); std::pair * const second = new std::pair(content, ownContent); std::pair *, std::pair *> * const entry = new std::pair *, std::pair *>(first, second); container->push_back(entry); } /*static*/ void XspfData::appendHelper(std::deque *> * & container, XspfExtension const * extension, bool own) { if (container == NULL) { container = new std::deque *>; } std::pair * const entry = new std::pair(extension, own); container->push_back(entry); } /*static*/ XML_Char * XspfData::stealHelper(XML_Char const * & property, bool own) { XML_Char const * const res = Toolbox::getSetNull(property); if (own) { return const_cast(res); } else if (res == NULL) { return NULL; } else { return Toolbox::newAndCopy(res); } } /*static*/ std::pair * XspfData::stealFirstHelper( std::deque *, std::pair *> *> * & container) { if ((container == NULL) || container->empty()) { return NULL; } std::pair *, std::pair *> * const entry = container->front(); container->pop_front(); std::pair * const res = new std::pair( entry->first->second ? const_cast(entry->first->first) : Toolbox::newAndCopy(entry->first->first), entry->second->second ? const_cast(entry->second->first) : Toolbox::newAndCopy(entry->second->first)); delete entry->first; delete entry->second; delete entry; return res; } /*static*/ XspfExtension * XspfData::stealFirstHelper( std::deque *> * & container) { if ((container == NULL) || container->empty()) { return NULL; } std::pair * const entry = container->front(); container->pop_front(); XspfExtension * res = entry->second ? const_cast(entry->first) : entry->first->clone(); delete entry; return res; } /*static*/ std::pair * XspfData::getHelper(std::deque *, std::pair *> *> * & container, int index) { if ((container == NULL) || container->empty() || (index < 0) || (index >= static_cast(container->size()))) { return NULL; } std::pair *, std::pair *> * const entry = container->at(index); // NOTE: getX() just peeps at data so don't clone anything std::pair * const res = new std::pair( entry->first->first, entry->second->first); return res; } /*static*/ const XspfExtension * XspfData::getHelper(std::deque *> * & container, int index) { if ((container == NULL) || container->empty() || (index < 0) || (index >= static_cast(container->size()))) { return NULL; } // NOTE: getX() just peeps at data so don't clone anything std::pair * const entry = container->at(index); return entry->first; } void XspfData::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfData.h000066400000000000000000000315641516712004000260460ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfData.h * Interface of XspfData. */ #ifndef XSPF_DATA_H #define XSPF_DATA_H #include "XspfDefines.h" #include namespace Xspf { class XspfExtension; class XspfDataPrivate; /** * Provides shared functionality for XspfTrack and XspfProps. */ class XspfData { friend class XspfDataPrivate; private: /// @cond DOXYGEN_NON_API XspfDataPrivate * const d; ///< D pointer /// @endcond protected: /** * Creates a new XspfData object. */ XspfData(); /** * Copy constructor. * * @param source Source to copy from */ XspfData(XspfData const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfData & operator=(XspfData const & source); /** * Destroys this XspfData object and deletes all * memory associated with it that has not been stolen before. */ virtual ~XspfData(); public: /** * Overwrites the image property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param image Image string to set * @param copy Copy flag */ void giveImage(XML_Char const * image, bool copy); /** * Overwrites the info property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param info Info string to set * @param copy Copy flag */ void giveInfo(XML_Char const * info, bool copy); /** * Overwrites the annotation property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param annotation Annotation string to set * @param copy Copy flag */ void giveAnnotation(XML_Char const * annotation, bool copy); /** * Overwrites the creator property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param creator Creator string to set * @param copy Copy flag */ void giveCreator(XML_Char const * creator, bool copy); /** * Overwrites the title property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param title Title string to set * @param copy Copy flag */ void giveTitle(XML_Char const * title, bool copy); /** * Appends a link to the link list. * * @param rel Link rel to append * @param copyRel Rel copy flag * @param content Link content to append * @param copyContent Content copy flag */ void giveAppendLink(XML_Char const * rel, bool copyRel, XML_Char const * content, bool copyContent); /** * Appends a meta to the meta list. * * @param rel Meta rel to append * @param copyRel Rel copy flag * @param content Meta content to append * @param copyContent Content copy flag */ void giveAppendMeta(XML_Char const * rel, bool copyRel, XML_Char const * content, bool copyContent); /** * Appends an extension to the extension list. * * @param extension Extension to append * @param copy Copy flag */ void giveAppendExtension(XspfExtension const * extension, bool copy); /** * Overwrites the image property. The string is * only assigned not copied. The ownership is * not transferred. * * @param image Image string to set */ void lendImage(XML_Char const * image); /** * Overwrites the info property. The string is * only assigned not copied. The ownership is * not transferred. * * @param info Info string to set */ void lendInfo(XML_Char const * info); /** * Overwrites the annotation property. The string is * only assigned not copied. The ownership is * not transferred. * * @param annotation Annotation string to set */ void lendAnnotation(XML_Char const * annotation); /** * Overwrites the creator property. The string is * only assigned not copied. The ownership is * not transferred. * * @param creator Creator string to set */ void lendCreator(XML_Char const * creator); /** * Overwrites the title property. The string is * only assigned not copied. The ownership is * not transferred. * * @param title Title string to set */ void lendTitle(XML_Char const * title); /** * Appends a link pair to the link list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param rel Link rel to append * @param content Link content to append */ void lendAppendLink(XML_Char const * rel, XML_Char const * content); /** * Appends a meta pair to the meta list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param rel Meta rel to append * @param content Meta content to append */ void lendAppendMeta(XML_Char const * rel, XML_Char const * content); /** * Appends an extension to the extension list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param extension Extension to append */ void lendAppendExtension(XspfExtension * extension); /** * Steals the image property. * * @return Image URI, can be NULL */ XML_Char * stealImage(); /** * Steals the info property. * * @return Info URI, can be NULL */ XML_Char * stealInfo(); /** * Steals the annotation property. * * @return Annotation, can be NULL */ XML_Char * stealAnnotation(); /** * Steals the creator property. * * @return Creator, can be NULL */ XML_Char * stealCreator(); /** * Steals the title property. * * @return Title, can be NULL */ XML_Char * stealTitle(); /** * Steals the first link pair from the list. * If the list is empty NULL is returned. * * NOTE: Do not forget to delete the pair! * * @return First link pair, can be NULL */ std::pair * stealFirstLink(); /** * Steals the first meta pair from the list. * If the list is empty NULL is returned. * * NOTE: Do not forget to delete the pair! * * @return First meta pair, can be NULL */ std::pair * stealFirstMeta(); /** * Steals the extension from the list. * If the list is empty NULL is returned. * * NOTE: Do not forget to delete the extension! * * @return First extension, can be NULL */ XspfExtension * stealFirstExtension(); /** * Returns the image property. * * @return Image URI, can be NULL */ XML_Char const * getImage() const; /** * Returns the info property. * * @return Info URI, can be NULL */ XML_Char const * getInfo() const; /** * Returns the annotation property. * * @return Annotation, can be NULL */ XML_Char const * getAnnotation() const; /** * Returns the creator property. * * @return Creator, can be NULL */ XML_Char const * getCreator() const; /** * Returns the title property. * * @return Title, can be NULL */ XML_Char const * getTitle() const; /** * Gets a specific link pair from the list. * If the list is empty NULL is returned. * * NOTE: The returned pair has to be deleted manually! * * @return Specified link pair, can be NULL */ std::pair * getLink(int index) const; /** * Gets a specific meta pair from the list. * If the list is empty NULL is returned. * * NOTE: The returned pair has to be deleted manually! * * @return Specified meta pair, can be NULL */ std::pair * getMeta(int index) const; /** * Gets a specific extension from the list. * If the list is empty NULL is returned. * * NOTE: The returned extension has to be deleted manually! * * @return Specified extension, can be NULL */ XspfExtension const * getExtension(int index) const; /** * Returns the number of link pairs. * * @return Number of link pairs */ int getLinkCount() const; /** * Returns the number of meta pairs. * * @return Number of meta pairs */ int getMetaCount() const; /** * Returns the number of extensions. * * @return Number of extensions */ int getExtensionCount() const; private: /** * Appends a meta or link pair to a container. * * @param container Container to work with * @param rel Rel to append * @param ownRel Rel ownership flag * @param content Content to append * @param ownContent Content ownership flag */ static void appendHelper(std::deque *, std::pair *> *> * & container, XML_Char const * rel, bool ownRel, XML_Char const * content, bool ownContent); /** * Appends an extension to a container. * * @param container Container to work with * @param extenstion Extenstion to append * @param own Ownership flag */ static void appendHelper(std::deque< std::pair *> * & container, XspfExtension const * extenstion, bool own); protected: /** * Steals a property. If the property's memory is not owned * a clone is returned. In any case you own the memory * return and have to delete it. * * @param property Property to steal * @param own Owner flag * @return Stolen property value, can be NULL */ static XML_Char * stealHelper(XML_Char const * & property, bool own); private: /** * Steals the first entry from a container. * * @param container Container to steal from * @return First entry, can be NULL */ static std::pair * stealFirstHelper( std::deque *, std::pair *> *> * & container); /** * Steals the first entry from a container. * * @param container Container to steal from * @return First entry, can be NULL */ static XspfExtension * stealFirstHelper(std::deque< std::pair *> * & container); /** * Returns a specific entry from a container * or NULL if the entry does not exist. * * NOTE: The returned pair has to be deleted manually! * * @param container Container to work with * @param index Index of the entry to return * @return Entry content, can be NULL */ static std::pair * getHelper( std::deque *, std::pair *> *> * & container, int index); /** * Returns a specific entry from a container * or NULL if the entry does not exist. * * NOTE: The returned pair has to be deleted manually! * * @param container Container to work with * @param index Index of the entry to return * @return Entry content, can be NULL */ static XspfExtension const * getHelper( std::deque *> * & container, int index); protected: /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond public: static bool const COPY; ///< Memory is copied static bool const TRANSFER; ///< Memory ownership is transfered }; } #endif // XSPF_DATA_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfDataWriter.cpp000066400000000000000000000154541516712004000275760ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfDataWriter.cpp * Implementation of XspfDataWriter. */ #include "XspfDataWriter.h" #include #include #include #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfDataWriter. */ class XspfDataWriterPrivate { friend class XspfDataWriter; XspfData const * data; ///< Data object to write XspfXmlFormatter * output; ///< Formatter to use XML_Char * baseUri; ///< Base URI to reduce URIs against /** * Creates a new D object. */ XspfDataWriterPrivate() : data(NULL), output(NULL), baseUri(NULL) { } /** * Destroys this D object. */ ~XspfDataWriterPrivate() { delete [] baseUri; } }; /// @endcond XspfDataWriter::XspfDataWriter() : d(new XspfDataWriterPrivate()) { } XspfDataWriter::XspfDataWriter(XspfDataWriter const & source) : d(new XspfDataWriterPrivate(*(source.d))) { } XspfDataWriter & XspfDataWriter::operator=(XspfDataWriter const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfDataWriter::~XspfDataWriter() { delete this->d; } XspfXmlFormatter * & XspfDataWriter::getOutput() const { return this->d->output; } XML_Char const * XspfDataWriter::getBaseUri() const { return this->d->baseUri; } void XspfDataWriter::setBaseUri(XML_Char const * baseUri) { Toolbox::deleteNewAndCopy(&this->d->baseUri, baseUri); } void XspfDataWriter::setData(XspfData const * data) { this->d->data = data; } void XspfDataWriter::writePrimitive(XML_Char const * name, XML_Char const * body) { XML_Char const * atts[1] = {NULL}; this->d->output->writeHomeStart(name, atts); this->d->output->writeBody(body); this->d->output->writeHomeEnd(name); } void XspfDataWriter::writePrimitive(XML_Char const * name, int body) { XML_Char const * atts[1] = {NULL}; this->d->output->writeHomeStart(name, atts); this->d->output->writeBody(body); this->d->output->writeHomeEnd(name); } void XspfDataWriter::writeImage() { assert(this->d->data != NULL); XML_Char const * const image = this->d->data->getImage(); if (image != NULL) { XML_Char * const relUri = makeRelativeUri(image); writePrimitive(_PT("image"), relUri); delete [] relUri; } } void XspfDataWriter::writeInfo() { assert(this->d->data != NULL); XML_Char const * const info = this->d->data->getInfo(); if (info != NULL) { XML_Char * const relUri = makeRelativeUri(info); writePrimitive(_PT("info"), relUri); delete [] relUri; } } void XspfDataWriter::writeAnnotation() { assert(this->d->data != NULL); XML_Char const * const annotation = this->d->data->getAnnotation(); if (annotation != NULL) { writePrimitive(_PT("annotation"), annotation); } } void XspfDataWriter::writeCreator() { assert(this->d->data != NULL); XML_Char const * const creator = this->d->data->getCreator(); if (creator != NULL) { writePrimitive(_PT("creator"), creator); } } void XspfDataWriter::writeTitle() { assert(this->d->data != NULL); XML_Char const * const title = this->d->data->getTitle(); if (title != NULL) { writePrimitive(_PT("title"), title); } } void XspfDataWriter::writeLinks() { assert(this->d->data != NULL); int index = 0; const std::pair * entry; for (;;) { entry = this->d->data->getLink(index++); if (entry == NULL) { return; } XML_Char const * atts[3] = {_PT("rel"), entry->first, NULL}; this->d->output->writeHomeStart(_PT("link"), atts); XML_Char * const relUri = makeRelativeUri(entry->second); this->d->output->writeBody(relUri); delete [] relUri; this->d->output->writeHomeEnd(_PT("link")); delete entry; // since the pair was created for us } } void XspfDataWriter::writeMetas() { assert(this->d->data != NULL); int index = 0; const std::pair * entry; for (;;) { entry = this->d->data->getMeta(index++); if (entry == NULL) { return; } XML_Char const * atts[3] = {_PT("rel"), entry->first, NULL}; this->d->output->writeHomeStart(_PT("meta"), atts); this->d->output->writeBody(entry->second); this->d->output->writeHomeEnd(_PT("meta")); delete entry; // since the pair was created for us } } void XspfDataWriter::writeExtensions() { assert(this->d->data != NULL); int index = 0; XspfExtension const * entry; for (;;) { entry = this->d->data->getExtension(index++); if (entry == NULL) { return; } XspfExtensionWriter * const writer = entry->newWriter(this->d->output, this->d->baseUri); if (writer != NULL) { writer->write(); delete writer; } } } XML_Char * XspfDataWriter::makeRelativeUri(XML_Char const * sourceUri) const { if (this->d->baseUri == NULL) { // Leave absolute return Toolbox::newAndCopy(sourceUri); } else { XML_Char * const relUri = Toolbox::makeRelativeUri( sourceUri, this->d->baseUri); // Fall back to original value for better backwards compatibility return (relUri != NULL) ? relUri : Toolbox::newAndCopy(sourceUri); } } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfDataWriter.h000066400000000000000000000105501516712004000272330ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfDataWriter.h * Interface of XspfDataWriter. */ #ifndef XSPF_DATA_WRITER_H #define XSPF_DATA_WRITER_H #include #include namespace Xspf { class XspfData; class XspfXmlFormatter; class XspfDataWriterPrivate; /** * Writes a data object to an XML formatter. */ class XspfDataWriter { private: /// @cond DOXYGEN_NON_API XspfDataWriterPrivate * const d; ///< D pointer /// @endcond protected: /** * Creates a new data writer. */ XspfDataWriter(); /** * Copy constructor. * * @param source Source to copy from */ XspfDataWriter(XspfDataWriter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfDataWriter & operator=(XspfDataWriter const & source); /** * Destroys this data writer. */ virtual ~XspfDataWriter(); /** * Assigns the data object to write. * * @param data Data object to write */ void setData(XspfData const * data); /** * Write a primitive element in one go. * Primitives are elements with no nested content. * * @param name Element name * @param body String body */ void writePrimitive(XML_Char const * name, XML_Char const * body); /** * Write a primitive element in one go. * Primitives are elements with no nested content. * * @param name Element name * @param body Number body */ void writePrimitive(XML_Char const * name, int body); /** * Writes the image property. */ void writeImage(); /** * Writes the info property. */ void writeInfo(); /** * Writes the annotation property. */ void writeAnnotation(); /** * Writes the creator property. */ void writeCreator(); /** * Writes the title property. */ void writeTitle(); /** * Writes the list of link pairs. */ void writeLinks(); /** * Writes the list of meta pairs. */ void writeMetas(); /** * Writes the list of extensions. */ void writeExtensions(); /** * Reduces an (usually) absolute URI to a relative one * if possible according to the current base URI. * * @param sourceUri URI to reduce * @return New'ed URI */ XML_Char * makeRelativeUri(XML_Char const * sourceUri) const; /** * Gives access to the XML formatter in use. * * @return XML formatter reference */ XspfXmlFormatter * & getOutput() const; /** * Return the base URI. * * @return Base URI, can be \c NULL */ XML_Char const * getBaseUri() const; /** * Sets the base URI. * * @param baseUri Base URI to set, can be \c NULL */ void setBaseUri(XML_Char const * baseUri); }; } #endif // XSPF_DATA_WRITER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfDateTime.cpp000066400000000000000000000213751516712004000272230ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfDateTime.cpp * Implementation of XspfDateTime. */ #include #include #if defined(sun) || defined(__sun) # include // for strncmp() #endif namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfDateTime. */ class XspfDateTimePrivate { friend class XspfDateTime; int year; ///< Year [-9999..+9999] but not zero int month; ///< Month [1..12] int day; ///< Day [1..31] int hour; ///< Hour [0..23] int minutes; ///< Minutes [0..59] int seconds; ///< Seconds [0..59] int distHours; ///< Time shift hours [-14..+14] int distMinutes; ///< Time shift minutes [-59..+59] /** * Creates a new D object. * * @param year Year [-9999..+9999] but not zero * @param month Month [1..12] * @param day Day [1..31] * @param hour Hour [0..23] * @param minutes Minutes [0..59] * @param seconds Seconds [0..59] * @param distHours Time shift hours [-14..+14] * @param distMinutes Time shift minutes [-59..+59] */ XspfDateTimePrivate(int year, int month, int day, int hour, int minutes, int seconds, int distHours, int distMinutes) : year(year), month(month), day(day), hour(hour), minutes(minutes), seconds(seconds), distHours(distHours), distMinutes(distMinutes) { } /** * Destroys this D object. */ ~XspfDateTimePrivate() { } }; /// @endcond XspfDateTime::XspfDateTime(int year, int month, int day, int hour, int minutes, int seconds, int distHours, int distMinutes) : d(new XspfDateTimePrivate(year, month, day, hour, minutes, seconds, distHours, distMinutes)) { } XspfDateTime::XspfDateTime() : d(new XspfDateTimePrivate(0, 0, 0, -1, -1, -1, 0, 0)) { } XspfDateTime::XspfDateTime(XspfDateTime const & source) : d(new XspfDateTimePrivate(*(source.d))) { } XspfDateTime & XspfDateTime::operator=(XspfDateTime const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfDateTime::~XspfDateTime() { delete this->d; } XspfDateTime * XspfDateTime::clone() const { return new XspfDateTime(this->d->year, this->d->month, this->d->day, this->d->hour, this->d->minutes, this->d->seconds, this->d->distHours, this->d->distMinutes); } int XspfDateTime::getYear() const { return this->d->year; } int XspfDateTime::getMonth() const { return this->d->month; } int XspfDateTime::getDay() const { return this->d->day; } int XspfDateTime::getHour() const { return this->d->hour; } int XspfDateTime::getMinutes() const { return this->d->minutes; } int XspfDateTime::getSeconds() const { return this->d->seconds; } int XspfDateTime::getDistHours() const { return this->d->distHours; } int XspfDateTime::getDistMinutes() const { return this->d->distMinutes; } void XspfDateTime::setYear(int year) { this->d->year = year; } void XspfDateTime::setMonth(int month) { this->d->month = month; } void XspfDateTime::setDay(int day) { this->d->day = day; } void XspfDateTime::setHour(int hour) { this->d->hour = hour; } void XspfDateTime::setMinutes(int minutes) { this->d->minutes = minutes; } void XspfDateTime::setSeconds(int seconds) { this->d->seconds = seconds; } void XspfDateTime::setDistHours(int distHours) { this->d->distHours = distHours; } void XspfDateTime::setDistMinutes(int distMinutes) { this->d->distMinutes = distMinutes; } namespace { /** * Calls atoi() on a limited number of characters. * * @param text Text * @param len Number of characters to read * @return Result of atoi() * @since 1.0.0rc1 */ int PORT_ANTOI(XML_Char const * text, int len) { XML_Char * final = new XML_Char[len + 1]; ::PORT_STRNCPY(final, text, len); final[len] = _PT('\0'); int const res = ::PORT_ATOI(final); delete [] final; return res; } } // anon namespace /*static*/ bool XspfDateTime::extractDateTime(XML_Char const * text, XspfDateTime * output) { // http://www.w3.org/TR/xmlschema-2/#dateTime-lexical-representation // '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? // '-'? bool const leadingMinus = (*text == _PT('-')); if (leadingMinus) { text++; } // yyyy if ((::PORT_STRNCMP(text, _PT("0001"), 4) < 0) || (::PORT_STRNCMP(_PT("9999"), text, 4) < 0)) { return false; } int const year = PORT_ANTOI(text, 4); output->setYear(year); text += 4; // '-' mm if ((::PORT_STRNCMP(text, _PT("-01"), 3) < 0) || (::PORT_STRNCMP(_PT("-12"), text, 3) < 0)) { return false; } int const month = PORT_ANTOI(text + 1, 2); output->setMonth(month); text += 3; // '-' dd if ((::PORT_STRNCMP(text, _PT("-01"), 3) < 0) || (::PORT_STRNCMP(_PT("-31"), text, 3) < 0)) { return false; } int const day = PORT_ANTOI(text + 1, 2); output->setDay(day); text += 3; // Month specific day check switch (month) { case 2: switch (day) { case 31: case 30: return false; case 29: if (((year % 400) != 0) && (((year % 4) != 0) || ((year % 100) == 0))) { // Not a leap year return false; } break; case 28: break; } break; case 4: case 6: case 9: case 11: if (day > 30) { return false; } break; } // 'T' hh if ((::PORT_STRNCMP(text, _PT("T00"), 3) < 0) || (::PORT_STRNCMP(_PT("T23"), text, 3) < 0)) { return false; } output->setHour(PORT_ANTOI(text + 1, 2)); text += 3; // ':' mm if ((::PORT_STRNCMP(text, _PT(":00"), 3) < 0) || (::PORT_STRNCMP(_PT(":59"), text, 3) < 0)) { return false; } output->setMinutes(PORT_ANTOI(text + 1, 2)); text += 3; // ':' ss if ((::PORT_STRNCMP(text, _PT(":00"), 2) < 0) || (::PORT_STRNCMP(_PT(":59"), text, 2) < 0)) { return false; } output->setSeconds(PORT_ANTOI(text + 1, 2)); text += 3; // ('.' s+)? if (*text == _PT('.')) { text++; int counter = 0; while ((*text >= _PT('0')) && (*text <= _PT('9'))) { text++; counter++; } if (counter == 0) { return false; } else { // The fractional second string, if present, must not end in '0' if (*(text - 1) == _PT('0')) { return false; } } } // (zzzzzz)? := (('+' | '-') hh ':' mm) | 'Z' XML_Char const * const timeZoneStart = text; switch (*text) { case _PT('+'): case _PT('-'): { text++; if ((::PORT_STRNCMP(text, _PT("00"), 2) < 0) || (::PORT_STRNCMP(_PT("14"), text, 2) < 0)) { return false; } int const distHours = PORT_ANTOI(text, 2); output->setDistHours(distHours); text += 2; if ((::PORT_STRNCMP(text, _PT(":00"), 3) < 0) || (::PORT_STRNCMP(_PT(":59"), text, 3) < 0)) { return false; } int const distMinutes = PORT_ANTOI(text + 1, 2); output->setDistMinutes(distMinutes); if ((distHours == 14) && (distMinutes != 0)) { return false; } text += 3; if (*text != _PT('\0')) { return false; } if (*timeZoneStart == _PT('-')) { output->setDistHours(-distHours); output->setDistMinutes(-distMinutes); } } break; case _PT('Z'): text++; if (*text != _PT('\0')) { return false; } // NO BREAK case _PT('\0'): output->setDistHours(0); output->setDistMinutes(0); break; default: return false; } return true; } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfDateTime.h000066400000000000000000000117751516712004000266730ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfDateTime.h * Interface of XspfDateTime. */ #ifndef XSPF_DATE_TIME_H #define XSPF_DATE_TIME_H #include "XspfDefines.h" namespace Xspf { class XspfDateTimePrivate; /** * Represents a "dateTime" timestamp * without fractional second component. */ class XspfDateTime { private: /// @cond DOXYGEN_NON_API XspfDateTimePrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new dateTime timestamp. * The given parameters must be valid and are not * checked for validity inside. * * @param year Year [-9999..+9999] but not zero * @param month Month [1..12] * @param day Day [1..31] * @param hour Hour [0..23] * @param minutes Minutes [0..59] * @param seconds Seconds [0..59] * @param distHours Time shift hours [-14..+14] * @param distMinutes Time shift minutes [-59..+59] */ XspfDateTime(int year, int month, int day, int hour, int minutes, int seconds, int distHours, int distMinutes); /** * Creates a new dateTime timestamp. */ XspfDateTime(); /** * Copy constructor. * * @param source Source to copy from */ XspfDateTime(XspfDateTime const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfDateTime & operator=(XspfDateTime const & source); /** * Destroys this dateTime timestamp. */ ~XspfDateTime(); /** * Clones this dateTime object. * *`@return Cloned object */ XspfDateTime * clone() const; /** * Returns the year. * * @return Year */ int getYear() const; /** * Returns the month. * * @return Month */ int getMonth() const; /** * Returns the day. * * @return Day */ int getDay() const; /** * Returns the hour. * * @return Hour */ int getHour() const; /** * Returns the minutes. * * @return Minutes */ int getMinutes() const; /** * Returns the seconds. * * @return Seconds */ int getSeconds() const; /** * Returns the time shift hours. * * @return Time shift hours */ int getDistHours() const; /** * Returns the time shift minutes. * * @return Time shift minutes */ int getDistMinutes() const; /** * Sets the year. * * @param year Year to set */ void setYear(int year); /** * Sets the month. * * @param month Month to set */ void setMonth(int month); /** * Sets the day. * * @param day Day to set */ void setDay(int day); /** * Sets the hour. * * @param hour Hour to set */ void setHour(int hour); /** * Sets the minutes. * * @param minutes Minutes to set */ void setMinutes(int minutes); /** * Sets the seconds. * * @param seconds Seconds to set */ void setSeconds(int seconds); /** * Sets the time shift hours. * * @param distHours Time shift hours */ void setDistHours(int distHours); /** * Sets the time shift minutes. * * @param distMinutes Time shift minutes */ void setDistMinutes(int distMinutes); /** * Extracts a dateTime from text. * * @param text Text * @param output dateTime storage destination * @return Valid dateTime flag * @since 1.0.0rc1 */ static bool extractDateTime(XML_Char const * text, XspfDateTime * output); }; } // namespace Xspf #endif // XSPF_DATE_TIME_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfDefines.h000066400000000000000000000107661516712004000265530ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfDefines.h */ #ifndef XSPF_DEFINES_H #define XSPF_DEFINES_H #include "XspfVersion.h" // Namespace handling #define XSPF_NS_HOME _PT("http://xspf.org/ns/0/") ///< XSPF namespace URI #define XSPF_NS_HOME_LEN 21 ///< XSPF namespace URI string length #define XSPF_NS_SEP_CHAR _PT(' ') ///< Namespace separator as character #define XSPF_NS_SEP_STRING _PT(" ") ///< Namespace separator as string #define XML_NS_HOME _PT("http://www.w3.org/XML/1998/namespace") ///< XML namespace URI #define XML_NS_HOME_LEN 36 ///< XML namespace URI string length // Expat 1.95.8 or later #include #if (!defined(XML_MAJOR_VERSION) || !defined(XML_MINOR_VERSION) \ || !defined(XML_MICRO_VERSION) || (XML_MAJOR_VERSION < 1) \ || ((XML_MAJOR_VERSION == 1) && ((XML_MINOR_VERSION < 95) \ || ((XML_MINOR_VERSION == 95) && (XML_MICRO_VERSION < 8))))) # error Expat 1.95.8 or later is required #endif /** * Maximum size in bytes of a file that * will be loaded into a buffer in whole */ #define XSPF_MAX_BLOCK_SIZE 100000 /// @cond DOXYGEN_IGNORE // Deny overriding from outside #undef XSPF_OS_WINDOWS #undef XSPF_OS_UNIX // Portability defines #if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) // Windows ========================= #include #include #define XSPF_OS_WINDOWS 1 // ================================= # ifdef UNICODE # ifndef _UNICODE # error _UNICODE not defined # endif # else # ifdef _UNICODE # error UNICODE not defined # endif # endif #else // Unix, ANSI ====================== #define XSPF_OS_UNIX 1 // ================================= #endif // OS-specific selection macro #ifdef XSPF_OS_WINDOWS # define XSPF_OS_SELECT(windows, unix) windows #else # ifdef XSPF_OS_UNIX # define XSPF_OS_SELECT(windows, unix) unix # endif #endif #define PORT_ATOI XSPF_OS_SELECT(_ttoi, atoi) #define PORT_FOPEN XSPF_OS_SELECT(_tfopen, fopen) #define PORT_MAIN XSPF_OS_SELECT(_tmain, main) #define PORT_PRINTF XSPF_OS_SELECT(_tprintf, printf) #ifdef UNICODE # define PORT_SNPRINTF XSPF_OS_SELECT(_snwprintf, snprintf) #else # define PORT_SNPRINTF XSPF_OS_SELECT(_snprintf, snprintf) #endif #define PORT_STRCMP XSPF_OS_SELECT(_tcscmp, strcmp) #define PORT_STRCPY XSPF_OS_SELECT(_tcscpy, strcpy) #define PORT_STRLEN XSPF_OS_SELECT(_tcslen, strlen) #define PORT_STRNCMP XSPF_OS_SELECT(_tcsncmp, strncmp) #define PORT_STRNCPY XSPF_OS_SELECT(_tcsncpy, strncpy) #define PORT_STRNICMP XSPF_OS_SELECT(_tcsnicmp, strnicmp) #define _PT(x) XSPF_OS_SELECT(_T(x), x) /// @endcond #endif // XSPF_DEFINES_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtension.cpp000066400000000000000000000067721516712004000275070ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtension.cpp * Implementation of XspfExtension. */ #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfExtension. */ class XspfExtensionPrivate { friend class XspfExtension; XML_Char const * applicationUri; ///< Application URI /** * Creates a new D object. */ XspfExtensionPrivate(XML_Char const * applicationUri) : applicationUri(Toolbox::newAndCopy(applicationUri)) { } /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionPrivate(XspfExtensionPrivate const & source) : applicationUri(Toolbox::newAndCopy(source.applicationUri)) { } /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionPrivate & operator=(XspfExtensionPrivate const & source) { if (this != &source) { delete [] this->applicationUri; this->applicationUri = Toolbox::newAndCopy(source.applicationUri); } return *this; } /** * Destroys this D object. */ ~XspfExtensionPrivate() { delete [] this->applicationUri; } }; /// @endcond XspfExtension::XspfExtension(XML_Char const * applicationUri) : d(new XspfExtensionPrivate(applicationUri)) { } XspfExtension::XspfExtension(XspfExtension const & source) : d(new XspfExtensionPrivate(*(source.d))) { } XspfExtension & XspfExtension::operator=(XspfExtension const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfExtension::~XspfExtension() { delete this->d; } XML_Char const * XspfExtension::getApplicationUri() const { return this->d->applicationUri; } void XspfExtension::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtension.h000066400000000000000000000070061516712004000271430ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtension.h * Interface of XspfExtension. */ #ifndef XSPF_EXTENSION_H #define XSPF_EXTENSION_H #include "XspfDefines.h" namespace Xspf { class XspfXmlFormatter; class XspfExtensionWriter; class XspfTrackWriter; class XspfPropsWriter; class XspfExtensionPrivate; /** * Extends XspfTrack and XspfProps objects by arbitrary information. */ class XspfExtension { private: /// @cond DOXYGEN_NON_API XspfExtensionPrivate * const d; ///< D pointer /// @endcond protected: /** * Creates a new XspfExtension object. * * @param applicationUri Application URI */ XspfExtension(XML_Char const * applicationUri); public: /** * Copy constructor. * * @param source Source to copy from */ XspfExtension(XspfExtension const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfExtension & operator=(XspfExtension const & source); /** * Destroys this XspfExtension object and deletes all * memory associated with it. */ virtual ~XspfExtension(); /** * Clones this extension. * * @return A clone of this extension */ virtual XspfExtension * clone() const = 0; /** * Returns the application URI. * * @return Application URI */ XML_Char const * getApplicationUri() const; /** * Creates a new writer that can write * this extension instance * * @param output Output formatter to use * @param baseUri Base URI to reduce URIs against * @return Extension writer for this */ virtual XspfExtensionWriter * newWriter(XspfXmlFormatter * output, XML_Char const * baseUri) const = 0; protected: /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond }; } // namespace Xspf #endif // XSPF_EXTENSION_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionReader.cpp000066400000000000000000000074021516712004000306210ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionReader.cpp * Implementation of XspfExtensionReader. */ #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfExtensionReader. */ class XspfExtensionReaderPrivate { friend class XspfExtensionReader; XspfReader * reader; ///< XspfReader to interact with /** * Creates a new D object. * * @param reader XspfReader to interact with */ XspfExtensionReaderPrivate(XspfReader * reader) : reader(reader) { } /** * Destroys this D object. */ ~XspfExtensionReaderPrivate() { } }; /// @endcond XspfExtensionReader::XspfExtensionReader(XspfReader * reader) : d(new XspfExtensionReaderPrivate(reader)) { } XspfExtensionReader::XspfExtensionReader(XspfExtensionReader const & source) : d(new XspfExtensionReaderPrivate(*(source.d))) { } XspfExtensionReader & XspfExtensionReader::operator=(XspfExtensionReader const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfExtensionReader::~XspfExtensionReader() { delete this->d; } bool XspfExtensionReader::handleError(int code, XML_Char const * text) { return this->d->reader->handleError(code, text); } bool XspfExtensionReader::handleError(int code, XML_Char const * format, XML_Char const * param) { return this->d->reader->handleError(code, format, param); } XspfStack & XspfExtensionReader::getElementStack() const { return this->d->reader->getElementStack(); } XspfStack > & XspfExtensionReader::getBaseUriStack() const { return this->d->reader->getBaseUriStack(); } bool XspfExtensionReader::handleXmlBaseAttribute(XML_Char const * xmlBase) { return this->d->reader->handleXmlBaseAttribute(xmlBase); } XspfExtensionReader * XspfExtensionReader::createBrother() const { return createBrother(this->d->reader); } void XspfExtensionReader::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionReader.h000066400000000000000000000133411516712004000302650ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionReader.h * Interface of XspfExtensionReader. */ #ifndef XSPF_EXTENSION_READER_H #define XSPF_EXTENSION_READER_H #include "XspfDefines.h" #include namespace Xspf { template class XspfStack; class XspfReader; class XspfExtension; class XspfExtensionReaderPrivate; class XspfExtensionReaderFactoryPrivate; /** * Provides the base for specific extention readers to derive from. */ class XspfExtensionReader { friend class XspfReader; friend class XspfReaderPrivate; friend class XspfExtensionReaderFactory; friend class XspfExtensionReaderFactoryPrivate; private: /// @cond DOXYGEN_NON_API XspfExtensionReaderPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new XspfExtensionReader object. * * @param reader XspfReader to interact with */ XspfExtensionReader(XspfReader * reader); /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionReader(XspfExtensionReader const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionReader & operator=(XspfExtensionReader const & source); /** * Destroys this XspfExtensionReader object and deletes all * memory associated with it. */ virtual ~XspfExtensionReader(); protected: /** * Passes error handling to the parent XspfReader. * * @param code Error code * @param text Error description */ bool handleError(int code, XML_Char const * text); /** * Passes error handling to the parent XspfReader. * * @param code Error code * @param format Error description format string containg %s * @param param Text parameter to insert for %s */ bool handleError(int code, XML_Char const * format, XML_Char const * param); /** * Gives access to the element stack in use. * * @return Element stack reference */ XspfStack & getElementStack() const; /** * Gives access to the Base URI stack in use. * * @return Base URI stack reference */ XspfStack > & getBaseUriStack() const; /** * Passes xml:base handling to the parent XspfReader. * * @param xmlBase Value of xml:base attribute * @return Continue parsing flag */ bool handleXmlBaseAttribute(XML_Char const * xmlBase); protected: /** * Handles tag opening inside an extension including * the extension tag itself. * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values * @return Continue parsing flag */ virtual bool handleExtensionStart(XML_Char const * fullName, XML_Char const ** atts) = 0; /** * Handles tag closing inside an extension including * the extension tag itself. * * @param fullName Full tag name (" ") * @return Continue parsing flag */ virtual bool handleExtensionEnd(XML_Char const * fullName) = 0; /** * Handles element content. * * @param s Text content * @param len Characters allowed to read */ virtual bool handleExtensionCharacters(XML_Char const * s, int len) = 0; /** * Makes a XspfExtension of the data collected. * * @return New built extension */ virtual XspfExtension * wrap() = 0; /** * Creates new XspfExtensionReader of the very same * type as this reader. * * @param reader XspfReader to interact with, must not be NULL * @return A new extension reader of the same type. */ virtual XspfExtensionReader * createBrother(XspfReader * reader) const = 0; private: /** * Creates new XspfExtensionReader of the very same * type as this reader that will work with the same * XspfReader as this instance. * * @return A new extension reader of the same type. */ XspfExtensionReader * createBrother() const; protected: /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond }; } // namespace Xspf #endif // XSPF_EXTENSION_READER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionReaderFactory.cpp000066400000000000000000000246501516712004000321550ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionReaderFactory.cpp * Implementation of XspfExtensionReaderFactory. */ #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfExtensionReaderFactory. */ class XspfExtensionReaderFactoryPrivate { friend class XspfExtensionReaderFactory; ///< Map of extension readers for playlist extensions std::map playlistExtensionReaders; ///< Map of extension readers for track extensions std::map trackExtensionReaders; ///< Catch-all extension reader for playlist extensions XspfExtensionReader const * playlistCatchAllReader; ///< Catch-all extension reader for track extensions XspfExtensionReader const * trackCatchAllReader; /** * Copies the extension reader and URI clones kept in a container * over to another container. * NOTE: The destination container is not * cleared before. * * @param dest Container to copy into * @param source Container to copy from */ static void copyMap(std::map & dest, const std::map & source) { // Copy examples and application URIs std::map ::const_iterator iter = source.begin(); while (iter != source.end()) { XML_Char const * const applicationUri = Toolbox::newAndCopy(iter->first); XspfExtensionReader const * const clone = iter->second->createBrother(); dest.insert(std::pair(applicationUri, clone)); iter++; } } /** * Deletes the extension reader and URI clones kept in a container. * NOTE: The container itself is not deleted. * * @param container Container to delete in */ static void freeMap( std::map & container) { // Free examples and application URIs std::map::iterator iter = container.begin(); while (iter != container.end()) { delete [] iter->first; delete iter->second; iter++; } } /** * Creates a new D object. */ XspfExtensionReaderFactoryPrivate() : playlistCatchAllReader(NULL), trackCatchAllReader(NULL) { } /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionReaderFactoryPrivate( XspfExtensionReaderFactoryPrivate const & source) : playlistCatchAllReader((source.playlistCatchAllReader == NULL) ? NULL : source.playlistCatchAllReader->createBrother()), trackCatchAllReader((source.trackCatchAllReader == NULL) ? NULL : source.trackCatchAllReader->createBrother()) { copyMap(this->playlistExtensionReaders, source.playlistExtensionReaders); copyMap(this->trackExtensionReaders, source.trackExtensionReaders); } /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionReaderFactoryPrivate & operator=( XspfExtensionReaderFactoryPrivate const & source) { // playlistExtensionReaders freeMap(this->playlistExtensionReaders); this->playlistExtensionReaders.clear(); copyMap(this->playlistExtensionReaders, source.playlistExtensionReaders); // trackExtensionReaders freeMap(this->trackExtensionReaders); this->trackExtensionReaders.clear(); copyMap(this->trackExtensionReaders, source.trackExtensionReaders); // playlistCatchAllReader if (this->playlistCatchAllReader != NULL) { delete this->playlistCatchAllReader; } this->playlistCatchAllReader = (source.playlistCatchAllReader == NULL) ? NULL : source.playlistCatchAllReader->createBrother(); // trackCatchAllReader if (this->trackCatchAllReader != NULL) { delete this->trackCatchAllReader; } this->trackCatchAllReader = (source.trackCatchAllReader == NULL) ? NULL : source.trackCatchAllReader->createBrother(); return *this; } /** * Destroys this D object. */ ~XspfExtensionReaderFactoryPrivate() { freeMap(this->playlistExtensionReaders); freeMap(this->trackExtensionReaders); if (this->playlistCatchAllReader != NULL) { delete this->playlistCatchAllReader; } if (this->trackCatchAllReader != NULL) { delete this->trackCatchAllReader; } } }; /// @endcond XspfExtensionReaderFactory::XspfExtensionReaderFactory() : d(new XspfExtensionReaderFactoryPrivate()) { } XspfExtensionReaderFactory::XspfExtensionReaderFactory( XspfExtensionReaderFactory const & source) : d(new XspfExtensionReaderFactoryPrivate(*(source.d))) { } XspfExtensionReaderFactory & XspfExtensionReaderFactory::operator=( XspfExtensionReaderFactory const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfExtensionReaderFactory::~XspfExtensionReaderFactory() { delete this->d; } inline void XspfExtensionReaderFactory::registerReader( std::map & container, XspfExtensionReader const * & catchAll, XspfExtensionReader const * example, XML_Char const * triggerUri) { if (example == NULL) { return; } XspfExtensionReader const * const clone = example->createBrother(); // CatchAll reader? if (triggerUri == NULL) { // Overwrite old catcher if (catchAll != NULL) { delete catchAll; } catchAll = clone; } else { std::map ::iterator found = container.find(triggerUri); if (found != container.end()) { // Overwrite existing entry delete found->second; found->second = clone; } else { // Add new entry with duped URI container.insert(std::pair( Toolbox::newAndCopy(triggerUri), clone)); } } } void XspfExtensionReaderFactory::registerPlaylistExtensionReader( XspfExtensionReader const * example, XML_Char const * triggerUri) { registerReader(this->d->playlistExtensionReaders, this->d->playlistCatchAllReader, example, triggerUri); } void XspfExtensionReaderFactory::registerTrackExtensionReader( XspfExtensionReader const * example, XML_Char const * triggerUri) { registerReader(this->d->trackExtensionReaders, this->d->trackCatchAllReader, example, triggerUri); } inline void XspfExtensionReaderFactory::unregisterReader( std::map & container, XspfExtensionReader const * & catchAll, XML_Char const * triggerUri) { // CatchAll reader? if (triggerUri == NULL) { // Remove catcher if (catchAll != NULL) { delete catchAll; catchAll = NULL; } } else { std::map ::iterator found = container.find(triggerUri); if (found != container.end()) { delete found->second; container.erase(found); } } } void XspfExtensionReaderFactory::unregisterPlaylistExtensionReader( XML_Char const * triggerUri) { unregisterReader(this->d->playlistExtensionReaders, this->d->playlistCatchAllReader, triggerUri); } void XspfExtensionReaderFactory::unregisterTrackExtensionReader( XML_Char const * triggerUri) { unregisterReader(this->d->trackExtensionReaders, this->d->trackCatchAllReader, triggerUri); } inline XspfExtensionReader * XspfExtensionReaderFactory::newReader( std::map & container, XspfExtensionReader const * catchAll, XML_Char const * applicationUri, XspfReader * reader) { std::map::const_iterator found = container.find(applicationUri); if (found != container.end()) { return found->second->createBrother(reader); } else { if (catchAll != NULL) { return catchAll->createBrother(reader); } else { return NULL; } } } XspfExtensionReader * XspfExtensionReaderFactory::newPlaylistExtensionReader(XML_Char const * applicationUri, XspfReader * reader) { return newReader(this->d->playlistExtensionReaders, this->d->playlistCatchAllReader, applicationUri, reader); } XspfExtensionReader * XspfExtensionReaderFactory::newTrackExtensionReader( XML_Char const * applicationUri, XspfReader * reader) { return newReader(this->d->trackExtensionReaders, this->d->trackCatchAllReader, applicationUri, reader); } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionReaderFactory.h000066400000000000000000000154571516712004000316270ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionReaderFactory.h * Interface of XspfExtensionReaderFactory. */ #ifndef XSPF_EXTENSION_READER_FACTROY_H #define XSPF_EXTENSION_READER_FACTROY_H #include "XspfDefines.h" #include "XspfToolbox.h" #include namespace Xspf { class XspfExtensionReader; class XspfReader; class XspfExtensionReaderFactoryPrivate; /** * Manages creation of XspfExtensionReader instances. * XspfExtensionReaders can be registered/unregistered dynamically. */ class XspfExtensionReaderFactory { private: /// @cond DOXYGEN_NON_API XspfExtensionReaderFactoryPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new XspfExtensionReaderFactory object. */ XspfExtensionReaderFactory(); /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionReaderFactory(const XspfExtensionReaderFactory & source); /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionReaderFactory & operator=( XspfExtensionReaderFactory const & source); /** * Destroys this XspfExtensionReaderFactory object and deletes all * memory associated with it. */ ~XspfExtensionReaderFactory(); /** * Overwrites the registered reader for the given application URI. * Pass NULL for the URI to make this the catch-all reader. * The reader will be cloned internally so can safely delete * the instance passed for registration. * * @param example Representative for the extension reader cleass * @param triggerUri Application URI associate, must not be NULL */ void registerPlaylistExtensionReader(XspfExtensionReader const * example, XML_Char const * triggerUri); /** * Overwrites the registered reader for the given application URI. * Pass NULL for the URI to make this the catch-all reader. * The reader will be cloned internally so can safely delete * the instance passed for registration. * * @param example Representative for the extension reader cleass * @param triggerUri Application URI associate, must not be NULL */ void registerTrackExtensionReader(XspfExtensionReader const * example, XML_Char const * triggerUri); /** * Unregisteres the given application URI. * NOTE: This URI will still be handled if a catch-all * handler has been set. * * @param triggerUri Application URI to unregister */ void unregisterPlaylistExtensionReader( XML_Char const * triggerUri); /** * Unregisteres the given application URI. * NOTE: This URI will still be handled if a catch-all * handler has been set. * * @param triggerUri Application URI to unregister */ void unregisterTrackExtensionReader( XML_Char const * triggerUri); /** * Creates a new XspfExtensionReader whose type was * registered for this application URI. * * @param applicationUri Application URI * @param reader XspfReader for the extension reader * @return New playlist extension reader */ XspfExtensionReader * newPlaylistExtensionReader( XML_Char const * applicationUri, XspfReader * reader); /** * Creates a new XspfExtensionReader whose type was * registered for this application URI. * * @param applicationUri Application URI * @param reader XspfReader for the extension reader * @return New track extension reader */ XspfExtensionReader * newTrackExtensionReader( XML_Char const * applicationUri, XspfReader * reader); private: /** * Overwrites the registered reader for the given application URI. * Pass NULL for the URI to make this the catch-all reader. * The reader will be cloned internally so can safely delete * the instance passed for registration. * * @param container Container to unregister from * @param catchAll Catch-all slot to modifiy * @param example Reader class representative * @param triggerUri Application URI to unregister */ void registerReader(std::map & container, XspfExtensionReader const * & catchAll, XspfExtensionReader const * example, XML_Char const * triggerUri); /** * Unregisteres the given application URI. * * @param container Container to unregister from * @param catchAll Catch-all slot to modifiy * @param triggerUri Application URI to unregister */ void unregisterReader(std::map & container, XspfExtensionReader const * & catchAll, XML_Char const * triggerUri); /** * Creates a new XspfExtensionReader whose type was * registered for this application URI. * * @param container Container to use * @param catchAll Catch-all slot to use * @param applicationUri Application URI * @param reader XspfReader for the extension reader * @return New extension reader */ XspfExtensionReader * newReader(std::map & container, XspfExtensionReader const * catchAll, XML_Char const * applicationUri, XspfReader * reader); }; } #endif // XSPF_EXTENSION_READER_FACTROY_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionWriter.cpp000066400000000000000000000115651516712004000307000ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionWriter.cpp * Implementation of XspfExtensionWriter. */ #include #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfExtensionWriter. */ class XspfExtensionWriterPrivate { friend class XspfExtensionWriter; XspfExtension const * extension; ///< Extension to write XspfXmlFormatter * output; ///< Output formatter to write to XML_Char * baseUri; ///< Base URI to reduce URIs against /** * Creates a new D object. */ XspfExtensionWriterPrivate(XspfExtension const * extension, XspfXmlFormatter * output, XML_Char const * baseUri) : extension(extension), output(output), baseUri(Toolbox::newAndCopy(baseUri)) { } /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionWriterPrivate( XspfExtensionWriterPrivate const & source) : extension(source.extension), output(source.output), baseUri(Toolbox::newAndCopy(source.baseUri)) { } /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionWriterPrivate & operator=( XspfExtensionWriterPrivate const & source) { this->extension = source.extension; this->output = source.output; Toolbox::deleteNewAndCopy(&this->baseUri, source.baseUri); return *this; } /** * Destroys this D object. */ ~XspfExtensionWriterPrivate() { delete [] this->baseUri; } }; /// @endcond XspfExtensionWriter::XspfExtensionWriter( XspfExtension const * extension, XspfXmlFormatter * output, XML_Char const * baseUri) : d(new XspfExtensionWriterPrivate(extension, output, baseUri)) { } XspfExtensionWriter::XspfExtensionWriter( XspfExtensionWriter const & source) : d(new XspfExtensionWriterPrivate(*(source.d))) { } XspfExtensionWriter & XspfExtensionWriter::operator=(XspfExtensionWriter const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfExtensionWriter::~XspfExtensionWriter() { delete this->d; } void XspfExtensionWriter::writeExtensionStart( XML_Char const * const * nsRegs) { // Open , register namespaces XML_Char const * atts[3] = {_PT("application"), this->d->extension->getApplicationUri(), NULL}; this->d->output->writeHomeStart(_PT("extension"), atts, nsRegs); } void XspfExtensionWriter::writeExtensionStop() { // Close this->d->output->writeHomeEnd(_PT("extension")); } XML_Char const * const * XspfExtensionWriter::getNamespaceRegs() { // Note "static"! static XML_Char const * nsRegs[1] = { NULL }; return nsRegs; } void XspfExtensionWriter::write() { writeExtensionStart(getNamespaceRegs()); writeExtensionBody(); writeExtensionStop(); } XspfXmlFormatter * & XspfExtensionWriter::getOutput() { return this->d->output; } const XspfExtension * XspfExtensionWriter::getExtension() { return this->d->extension; } XML_Char const * XspfExtensionWriter::getBaseUri() const { return this->d->baseUri; } void XspfExtensionWriter::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfExtensionWriter.h000066400000000000000000000105531516712004000303410ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfExtensionWriter.h * Interface of XspfExtensionWriter. */ #ifndef XSPF_EXTENSION_WRITER_H #define XSPF_EXTENSION_WRITER_H #include "XspfDefines.h" #include namespace Xspf { class XspfExtension; class XspfXmlFormatter; class XspfExtensionWriterPrivate; /** * Writes a XspfExtension to a XspfXmlFormatter. */ class XspfExtensionWriter { private: /// @cond DOXYGEN_NON_API XspfExtensionWriterPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new XspfExtensionWriter object. * * @param extension Extension to write * @param output Output formatter to write to * @param baseUri Absolute base URI to reduce URIs against, * is \c NULL if only absolute URIs are wanted */ XspfExtensionWriter(XspfExtension const * extension, XspfXmlFormatter * output, XML_Char const * baseUri); /** * Copy constructor. * * @param source Source to copy from */ XspfExtensionWriter(XspfExtensionWriter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfExtensionWriter & operator=(XspfExtensionWriter const & source); /** * Destroys this XspfExtensionWriter object and deletes all * memory associated with it. */ virtual ~XspfExtensionWriter(); /** * Writes the associated extension to the output formater. */ void write(); private: /** * Writes the opening extension tag also registering all * previously unknown namespaces. * * @param nsRegs NULL-terminated list of namespace registrations (uri/prefix pairs) */ void writeExtensionStart(XML_Char const * const * nsRegs); protected: /** * Writes the extension body. */ virtual void writeExtensionBody() = 0; private: /** * Writes the closing extension tag. */ void writeExtensionStop(); protected: /** * Returns a list of the namespaces used inside * the extension body. Moreprecisely this * is an alternating NULL-terminated list * of URI/prefix pairs. * * @return List of URI/prefix pairs */ virtual XML_Char const * const * getNamespaceRegs(); /** * Returns the extension to be written. * * @return Extension */ XspfExtension const * getExtension(); /** * Gives access to the XML formatter in use. * * @return XML formatter reference */ XspfXmlFormatter * & getOutput(); /** * Returns the base URI in use. * * @return Base URI, can be \c NULL */ XML_Char const * getBaseUri() const; /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond }; } // namespace Xspf #endif // XSPF_EXTENSION_WRITER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfIndentFormatter.cpp000066400000000000000000000115061516712004000306270ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfIndentFormatter.cpp * Implementation of XspfIndentFormatter. */ #include #include namespace Xspf { /** * Specifies the type of basic XML unit. */ enum XspfElemPos { XSPF_ELEM_DUMMY, ///< Stack returns 0 if empty XSPF_ELEM_START, ///< Opening tag XSPF_ELEM_BODY ///< Tag body }; /// @cond DOXYGEN_NON_API /** * D object for XspfIndentFormatter. */ class XspfIndentFormatterPrivate { friend class XspfIndentFormatter; int level; ///< Element tree depth XspfStack stack; ///< Tag position stack int shift; ///< Indent shift /** * Creates a new D object. * * @param shift Non-positive indent shift (-2 will create two tabs less) */ XspfIndentFormatterPrivate(int shift) : level(0), stack(), shift(shift) { } /** * Copy constructor. * * @param source Source to copy from */ XspfIndentFormatterPrivate(const XspfIndentFormatterPrivate & source) : level(source.level), stack(source.stack), shift(source.shift) { } /** * Destroys this D object. */ ~XspfIndentFormatterPrivate() { this->stack.clear(); } }; /// @endcond XspfIndentFormatter::XspfIndentFormatter(int shift) : XspfXmlFormatter(), d(new XspfIndentFormatterPrivate(shift)) { // Fix broken indent shift if (this->d->shift > 0) { this->d->shift = 0; } } XspfIndentFormatter::XspfIndentFormatter(XspfIndentFormatter const & source) : XspfXmlFormatter(source), d(new XspfIndentFormatterPrivate(*(source.d))) { } XspfIndentFormatter & XspfIndentFormatter::operator=(XspfIndentFormatter const & source) { if (this != &source) { XspfXmlFormatter::operator=(source); *(this->d) = *(source.d); } return *this; } XspfIndentFormatter::~XspfIndentFormatter() { delete this->d; } void XspfIndentFormatter::writeStart(XML_Char const * name, XML_Char const * const * atts) { // XML Header this->writeXmlDeclaration(); *this->getOutput() << _PT("\n"); // Indent for (int i = -(this->d->shift); i < this->d->level; i++) { *this->getOutput() << _PT('\t'); } // Element *this->getOutput() << _PT('<') << name; while (atts[0] != NULL) { *this->getOutput() << _PT(' ') << atts[0] << _PT("=\"") << atts[1] << _PT("\""); atts += 2; } *this->getOutput() << _PT(">"); this->d->level++; this->d->stack.push(XSPF_ELEM_START); } void XspfIndentFormatter::writeEnd(XML_Char const * name) { this->d->level--; if (this->d->stack.top() != XSPF_ELEM_BODY) { *this->getOutput() << _PT('\n'); for (int i = -(this->d->shift); i < this->d->level; i++) { *this->getOutput() << _PT('\t'); } } else { // Pop body this->d->stack.pop(); } // Pop start this->d->stack.pop(); *this->getOutput() << _PT("'); if (this->d->level == 0) { *this->getOutput() << _PT("\n"); } } void XspfIndentFormatter::writeBody(XML_Char const * text) { writeCharacterData(text); this->d->stack.push(XSPF_ELEM_BODY); } void XspfIndentFormatter::writeBody(int number) { *this->getOutput() << number; this->d->stack.push(XSPF_ELEM_BODY); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfIndentFormatter.h000066400000000000000000000061771516712004000303040ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfIndentFormatter.h * Interface of XspfIndentFormatter. */ #ifndef XSPF_INDENT_FORMATTER_H #define XSPF_INDENT_FORMATTER_H #include "XspfXmlFormatter.h" namespace Xspf { template class XspfStack; class XspfIndentFormatterPrivate; /** * Outputs XML with proper indentation and newlines. * The finishing newline is optional. */ class XspfIndentFormatter : public XspfXmlFormatter { private: /// @cond DOXYGEN_NON_API XspfIndentFormatterPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new XspfIndentFormatter object with custom indent shift. * * @param shift Non-positive indent shift (-2 will create two tabs less) */ XspfIndentFormatter(int shift = 0); /** * Copy constructor. * * @param source Source to copy from */ XspfIndentFormatter(XspfIndentFormatter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfIndentFormatter & operator=(XspfIndentFormatter const & source); /** * Destroys this XspfIndentFormatter object and deletes all * memory associated with it. */ ~XspfIndentFormatter(); private: void writeStart(XML_Char const * name, XML_Char const * const * atts); void writeEnd(XML_Char const * name); void writeBody(XML_Char const * text); void writeBody(int number); }; } #endif // XSPF_INDENT_FORMATTER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfProps.cpp000066400000000000000000000306311516712004000266250ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfProps.cpp * Implementation of XspfProps. */ #include #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfProps. */ class XspfPropsPrivate { friend class XspfProps; XML_Char const * location; ///< Location URI XML_Char const * license; ///< License URI XML_Char const * identifier; ///< Identifier URI bool ownLocation; ///< Location memory ownership flag bool ownLicense; ///< License memory ownership flag bool ownIdentifier; ///< Identifier memory ownership flag std::deque *> *> * attributions; ///< List of location and identifier URIs XspfDateTime const * date; ///< Date bool ownDate; ///< Date memory ownership flag int version; ///< XSPF version /** * Creates a new D object. */ XspfPropsPrivate() :location(NULL), license(NULL), identifier(NULL), ownLocation(false), ownLicense(false), ownIdentifier(false), attributions(NULL), date(NULL), ownDate(false), version(1) { } /** * Copy constructor. * * @param source Source to copy from */ XspfPropsPrivate(XspfPropsPrivate const & source) : location(source.ownLocation ? Toolbox::newAndCopy(source.location) : source.location), license(source.ownLicense ? Toolbox::newAndCopy(source.license) : source.license), identifier(source.ownIdentifier ? Toolbox::newAndCopy(source.identifier) : source.identifier), ownLocation(source.ownLocation), ownLicense(source.ownLicense), ownIdentifier(source.ownIdentifier), attributions(NULL), // Created in appendHelper date(source.ownDate ? new XspfDateTime(*(source.date)) : source.date), ownDate(source.ownDate), version(source.version) { if (source.attributions != NULL) { copyAttributions(this->attributions, source.attributions); } } /** * Assignment operator. * * @param source Source to copy from */ XspfPropsPrivate & operator=(XspfPropsPrivate const & source) { if (this != &source) { free(); assign(source); } return *this; } /** * Destroys this D object. */ ~XspfPropsPrivate() { free(); } static void copyAttributions(std::deque *> *> * & dest, const std::deque *> *> * source) { std::deque *> *> ::const_iterator iter = source->begin(); while (iter != source->end()) { const std::pair *> * const entry = *iter; bool const ownership = entry->second->second; XML_Char const * const value = ownership ? Toolbox::newAndCopy(entry->second->first) : entry->second->first; bool const isLocation = entry->first; XspfProps::appendHelper(dest, value, ownership, isLocation); iter++; } } void assign(XspfPropsPrivate const & source) { // Assigns all members, does not free current content Toolbox::copyIfOwned(this->location, this->ownLocation, source.location, source.ownLocation); Toolbox::copyIfOwned(this->license, this->ownLicense, source.license, source.ownLicense); Toolbox::copyIfOwned(this->identifier, this->ownIdentifier, source.identifier, source.ownIdentifier); this->attributions = NULL; // Created by appendHelper this->date = source.ownDate ? new XspfDateTime(*(source.date)) : source.date; this->ownDate = source.ownDate; this->version = source.version; if (source.attributions != NULL) { copyAttributions(this->attributions, source.attributions); } } void free() { // Frees all data, does not set to NULL Toolbox::freeIfOwned(this->location, this->ownLocation); Toolbox::freeIfOwned(this->identifier, this->ownIdentifier); Toolbox::freeIfOwned(this->license, this->ownLicense); if (this->attributions != NULL) { std::deque *> *>::const_iterator iter = this->attributions->begin(); while (iter != this->attributions->end()) { std::pair *> * const entry = *iter; if (entry->second->second) { delete [] entry->second->first; } delete entry->second; delete entry; iter++; } delete this->attributions; this->attributions = NULL; } if (this->ownDate && (this->date != NULL)) { delete this->date; this->date = NULL; } } }; /// @endcond XspfProps::XspfProps() : XspfData(), d(new XspfPropsPrivate()) { } XspfProps::XspfProps(XspfProps const & source) : XspfData(source), d(new XspfPropsPrivate(*(source.d))) { } XspfProps & XspfProps::operator=(XspfProps const & source) { if (this != &source) { XspfData::operator=(source); *(this->d) = *(source.d); } return *this; } XspfProps::~XspfProps() { delete this->d; } void XspfProps::giveLocation(XML_Char const * location, bool copy) { Toolbox::deleteNewAndCopy(this->d->location, this->d->ownLocation, location, copy); } void XspfProps::giveLicense(XML_Char const * license, bool copy) { Toolbox::deleteNewAndCopy(this->d->license, this->d->ownLicense, license, copy); } void XspfProps::giveIdentifier(XML_Char const * identifier, bool copy) { Toolbox::deleteNewAndCopy(this->d->identifier, this->d->ownIdentifier, identifier, copy); } void XspfProps::giveAppendAttributionIdentifier(XML_Char const * identifier, bool copy) { bool const IS_IDENTIFIER = false; appendHelper(this->d->attributions, copy ? Toolbox::newAndCopy(identifier) : identifier, true, IS_IDENTIFIER); } void XspfProps::giveAppendAttributionLocation(XML_Char const * location, bool copy) { bool const IS_LOCATION = true; appendHelper(this->d->attributions, copy ? Toolbox::newAndCopy(location) : location, true, IS_LOCATION); } void XspfProps::giveDate(XspfDateTime const * date, bool copy) { XspfProps::deleteNewAndCopy(this->d->date, this->d->ownDate, date, copy); } void XspfProps::lendLocation(XML_Char const * location) { Toolbox::deleteNewAndCopy(this->d->location, this->d->ownLocation, location, false); } void XspfProps::lendLicense(XML_Char const * license) { Toolbox::deleteNewAndCopy(this->d->license, this->d->ownLicense, license, false); } void XspfProps::lendIdentifier(XML_Char const * identifier) { Toolbox::deleteNewAndCopy(this->d->identifier, this->d->ownIdentifier, identifier, false); } void XspfProps::lendAppendAttributionIdentifier(XML_Char const * identifier) { appendHelper(this->d->attributions, identifier, false, false); } void XspfProps::lendAppendAttributionLocation(XML_Char const * location) { appendHelper(this->d->attributions, location, false, true); } void XspfProps::lendDate(XspfDateTime const * date) { XspfProps::deleteNewAndCopy(this->d->date, this->d->ownDate, date, false); } XML_Char * XspfProps::stealLocation() { return XspfData::stealHelper(this->d->location, this->d->ownLocation); } XML_Char * XspfProps::stealIdentifier() { return XspfData::stealHelper(this->d->identifier, this->d->ownIdentifier); } XML_Char * XspfProps::stealLicense() { return XspfData::stealHelper(this->d->license, this->d->ownLicense); } std::pair * XspfProps::stealFirstAttribution() { return stealFirstHelper(this->d->attributions); } XspfDateTime * XspfProps::stealDate() { return stealHelper(this->d->date, this->d->ownDate); } void XspfProps::setVersion(int version) { this->d->version = version; } XML_Char const * XspfProps::getLicense() const { return this->d->license; } XML_Char const * XspfProps::getLocation() const { return this->d->location; } XML_Char const * XspfProps::getIdentifier() const { return this->d->identifier; } std::pair * XspfProps::getAttribution(int index) const { return getHelper(this->d->attributions, index); } XspfDateTime const * XspfProps::getDate() const { return this->d->date; } int XspfProps::getVersion() const { return this->d->version; } int XspfProps::getAttributionCount() const { return (this->d->attributions == NULL) ? 0 : static_cast(this->d->attributions->size()); } /*static*/ void XspfProps::appendHelper( std::deque *> *> * & container, XML_Char const * value, bool ownership, bool isLocation) { if (container == NULL) { container = new std::deque *> *>; } std::pair * const second = new std::pair(value, ownership); std::pair *> * const entry = new std::pair *>(isLocation, second); container->push_back(entry); } /*static*/ std::pair * XspfProps::getHelper( std::deque *> *> * & container, int index) { if ((container == NULL) || container->empty() || (index < 0) || (index >= static_cast(container->size()))) { return NULL; } std::pair *> * const entry = container->at(index); // NOTE: getX() just peeps at data so don't clone anything std::pair * const res = new std::pair( entry->first, entry->second->first); return res; } /*static*/ XspfDateTime * XspfProps::stealHelper( XspfDateTime const * & dateTime, bool own) { XspfDateTime const * const res = Toolbox::getSetNull(dateTime); if (own) { return const_cast(res); } else if (res == NULL) { return NULL; } else { return res->clone(); } } /*static*/ std::pair * XspfProps::stealFirstHelper( std::deque *> *> * & container) { if ((container == NULL) || container->empty()) { return NULL; } std::pair *> * const entry = container->front(); container->pop_front(); std::pair * const res = new std::pair( entry->first, entry->second->second ? const_cast(entry->second->first) : Toolbox::newAndCopy(entry->second->first)); delete entry->second; delete entry; return res; } /*static*/ void XspfProps::deleteNewAndCopy(XspfDateTime const * & dest, bool & destOwnership, XspfDateTime const * source, bool sourceCopy) { // Delete old memory if owner if (destOwnership && (dest != NULL)) { delete [] dest; } if (source == NULL) { dest = NULL; destOwnership = false; } else { // Copy new memory if desired if (sourceCopy) { XspfDateTime * const dup = source->clone(); dest = dup; destOwnership = true; } else { dest = source; destOwnership = false; } } } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfProps.h000066400000000000000000000235571516712004000263030ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfProps.h * Interface of XspfProps. */ #ifndef XSPF_PROPS_H #define XSPF_PROPS_H #include "XspfData.h" namespace Xspf { class XspfPropsPrivate; class XspfDateTime; /** * Represents the properties of playlist * without extensions. This includes all * information except the track list. */ class XspfProps : public XspfData { friend class XspfPropsPrivate; // Give access to static helpers private: /// @cond DOXYGEN_NON_API XspfPropsPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new, blank playlist property package. */ XspfProps(); /** * Copy constructor. * * @param source Source to copy from */ XspfProps(XspfProps const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfProps & operator=(XspfProps const & source); /** * Destroys this XspfProps object and deletes all * memory associated with it that has not been stolen before. */ ~XspfProps(); /** * Overwrites the identifier property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param identifier Identifier string to set * @param copy Copy flag */ void giveIdentifier(XML_Char const * identifier, bool copy); /** * Overwrites the license property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param license License string to set * @param copy Copy flag */ void giveLicense(XML_Char const * license, bool copy); /** * Overwrites the location property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param location Location string to set * @param copy Copy flag */ void giveLocation(XML_Char const * location, bool copy); /** * Appends an identifier to the attribution list. * * @param identifier Identifier to append * @param copy Copy flag */ void giveAppendAttributionIdentifier(XML_Char const * identifier, bool copy); /** * Appends an location to the attribution list. * * @param location Location to append * @param copy Copy flag */ void giveAppendAttributionLocation(XML_Char const * location, bool copy); /** * Overwrites the date property. If copy is true * the date object will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param date Date object to set * @param copy Copy flag */ void giveDate(XspfDateTime const * date, bool copy); /** * Overwrites the identifier property. The string is * only assigned not copied. The ownership is * not transferred. * * @param identifier Identifier string to set */ void lendIdentifier(XML_Char const * identifier); /** * Overwrites the license property. The string is * only assigned not copied. The ownership is * not transferred. * * @param license License string to set */ void lendLicense(XML_Char const * license); /** * Overwrites the location property. The string is * only assigned not copied. The ownership is * not transferred. * * @param location Location string to set */ void lendLocation(XML_Char const * location); /** * Appends an identifier to the attribution list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param identifier Identifier to append */ void lendAppendAttributionIdentifier(XML_Char const * identifier); /** * Appends an location to the attribution list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param location Location to append */ void lendAppendAttributionLocation(XML_Char const * location); /** * Overwrites the date property. The date object is * only assigned not copied. The ownership is * not transferred. * * @param date Date object to set */ void lendDate(XspfDateTime const * date); /** * Overwrites the XSPF version property. * * @param version XSPF version (0 or 1) */ void setVersion(int version); /** * Steals the license property. * * @return License URI, can be NULL */ XML_Char * stealLicense(); /** * Steals the location property. * * @return Location URI, can be NULL */ XML_Char * stealLocation(); /** * Steals the identifier property. * * @return Identifier URI, can be NULL */ XML_Char * stealIdentifier(); /** * Steals the first attribution entry from the list. * If the list is empty NULL is returned. * * NOTE: Do not forget to delete the pair! * * @return First attribution entry, can be NULL */ std::pair * stealFirstAttribution(); /** * Steals the date object property. * * @return Date object, can be NULL */ XspfDateTime * stealDate(); /** * Returns the license property. * * @return License, can be NULL */ XML_Char const * getLicense() const; /** * Returns the location property. * * @return Location, can be NULL */ XML_Char const * getLocation() const; /** * Returns the identifier property. * * @return Identifier, can be NULL */ XML_Char const * getIdentifier() const; /** * Gets the specific attribution entry from the list. * If the list is empty NULL is returned. * * NOTE: The returned pair has to be deleted manually! * * @return Specified attribution entry, can be NULL */ std::pair * getAttribution(int index) const; /** * Returns the number of attributions. * * @return Number of attributions */ int getAttributionCount() const; /** * Returns the date object property. * * @return Date object, can be NULL */ XspfDateTime const * getDate() const; /** * Returns the XSPF version property. * * @return XSPF version (0 or 1) */ int getVersion() const; private: /** * Appends a location or identifier to a container. * * @param container Container to work with * @param value Value * @param ownership Ownership flag * @param isLocation Location/identifier switch */ static void appendHelper(std::deque *> *> * & container, XML_Char const * value, bool ownership, bool isLocation); /** * Returns a specific entry from a container * or NULL if the entry does not exist. * * NOTE: The returned pair has to be deleted manually! * * @param container Container to work with * @param index Index of the entry to return * @return Entry content, can be NULL */ static std::pair * getHelper( std::deque *> *> * & container, int index); /** * Steals a XspfDateTime. If its memory is not owned * a clone is returned. In any case you own the memory * return and have to delete it. * * @param dateTime XspfDateTime to steal * @param own Owner flag * @return Stolen XspfDateTime value, can be NULL */ static XspfDateTime * stealHelper(XspfDateTime const * & dateTime, bool own); /** * Steals the first entry from a container. * * @param container Container to steal from * @return First entry, can be NULL */ static std::pair * stealFirstHelper( std::deque *> *> * & container); /** * Replaces the date object in dest by a duplicate of the date object * in src (using new() not malloc()). The old object is deleted. * If destOwnership is false the old string is not deleted. * If sourceCopy is false only source's pointer is copied, * not the whole object. * * @param dest Destination date object * @param destOwnership Destination ownership flag * @param source Source date object * @param sourceCopy Source copy flag */ static void deleteNewAndCopy(XspfDateTime const * & dest, bool & destOwnership, XspfDateTime const * source, bool sourceCopy); }; } #endif // XSPF_PROPS_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfPropsWriter.cpp000066400000000000000000000244321516712004000300240ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfPropsWriter.cpp * Implementation of XspfPropsWriter. */ #include "XspfPropsWriter.h" #include #include #include #include #include #include #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfPropsWriter. */ class XspfPropsWriterPrivate { friend class XspfPropsWriter; XspfProps props; ///< Playlist properties to write bool trackListEmpty; ///< Tracklist empty flag, no initialization needed std::list > initNamespaces; ///< Namespaces to register when writing bool embedBase; ///< Embed Base URI as xml:base flag, no initialization needed /** * Creates a new D object. */ XspfPropsWriterPrivate() { } /** * Copy constructor. * * @param source Source to copy from */ XspfPropsWriterPrivate(XspfPropsWriterPrivate const & source) : props(source.props), trackListEmpty(source.trackListEmpty), embedBase(source.embedBase) { copyNamespaceInits(this->initNamespaces, source.initNamespaces); } /** * Assignment operator. * * @param source Source to copy from */ XspfPropsWriterPrivate & operator=(XspfPropsWriterPrivate const & source) { if (this != &source) { this->props = source.props; this->trackListEmpty = source.trackListEmpty; this->embedBase = source.embedBase; freeNamespaceInits(this->initNamespaces); copyNamespaceInits(this->initNamespaces, source.initNamespaces); } return *this; } static void freeNamespaceInits(std::list > & container) { std::list >::iterator iter = container.begin(); while (iter != container.end()) { std::pair & entry = *iter; delete [] entry.second; iter++; } container.clear(); } static void copyNamespaceInits( std::list > & dest, const std::list > & source) { std::list >::const_iterator iter = source.begin(); while (iter != source.end()) { const std::pair & entry = *iter; XML_Char const * const uri = entry.first; XML_Char * const prefixSuggestion = Toolbox::newAndCopy(entry.second); dest.push_back( std::pair( uri, prefixSuggestion)); iter++; } } /** * Destroys this D object. */ ~XspfPropsWriterPrivate() { freeNamespaceInits(this->initNamespaces); } }; /// @endcond XspfPropsWriter::XspfPropsWriter() : XspfDataWriter(), d(new XspfPropsWriterPrivate()) { } XspfPropsWriter::XspfPropsWriter(XspfPropsWriter const & source) : XspfDataWriter(source), d(new XspfPropsWriterPrivate(*(source.d))) { } XspfPropsWriter & XspfPropsWriter::operator=(XspfPropsWriter const & source) { if (this != &source) { XspfDataWriter::operator=(source); *(this->d) = *(source.d); } return *this; } XspfPropsWriter::~XspfPropsWriter() { delete this->d; } void XspfPropsWriter::setProps(XspfProps const * props) { this->d->props = (props == NULL) ? XspfProps() : *props; setData(&this->d->props); } void XspfPropsWriter::writeAttribution() { int index = 0; std::pair * entry = this->d->props.getAttribution(index++); if (entry == NULL) { return; } XML_Char const * atts[1] = {NULL}; this->getOutput()->writeHomeStart(_PT("attribution"), atts); do { XML_Char * const relUri = makeRelativeUri(entry->second); writePrimitive(entry->first ? _PT("location") : _PT("identifier"), relUri); delete [] relUri; delete entry; // since the pair was created for us entry = this->d->props.getAttribution(index++); } while (entry != NULL); this->getOutput()->writeHomeEnd(_PT("attribution")); } void XspfPropsWriter::writeDate() { XspfDateTime const * const dateTime = this->d->props.getDate(); if (dateTime != NULL) { int const charCount = 10 + 1 + 8 + 6 + 1; XML_Char buffer[charCount]; ::PORT_SNPRINTF(buffer, charCount, _PT("%04i-%02i-%02iT%02i:%02i:%02i%s%02i:%02i"), dateTime->getYear(), dateTime->getMonth(), dateTime->getDay(), dateTime->getHour(), dateTime->getMinutes(), dateTime->getSeconds(), (dateTime->getDistHours() < 0) ? _PT("-") : _PT("+"), std::abs(dateTime->getDistHours()), std::abs(dateTime->getDistMinutes())); writePrimitive(_PT("date"), buffer); } } void XspfPropsWriter::writeIdentifier() { XML_Char const * const identifier = this->d->props.getIdentifier(); if (identifier != NULL) { XML_Char * const relUri = makeRelativeUri(identifier); writePrimitive(_PT("identifier"), relUri); delete [] relUri; } } void XspfPropsWriter::writeLicense() { XML_Char const * const license = this->d->props.getLicense(); if (license != NULL) { XML_Char * const relUri = makeRelativeUri(license); writePrimitive(_PT("license"), relUri); delete [] relUri; } } void XspfPropsWriter::writeLocation() { XML_Char const * const location = this->d->props.getLocation(); if (location != NULL) { XML_Char * const relUri = makeRelativeUri(location); writePrimitive(_PT("location"), relUri); delete [] relUri; } } void XspfPropsWriter::writePlaylistClose() { this->getOutput()->writeHomeEnd(_PT("playlist")); } void XspfPropsWriter::writePlaylistOpen() { // Make namespace registration list int const count = static_cast(this->d->initNamespaces.size()); std::list >::iterator iter = this->d->initNamespaces.begin(); XML_Char const ** nsRegs = new const XML_Char *[2 * (1 + count) + 1]; nsRegs[0] = XspfXmlFormatter::namespaceKey; nsRegs[1] = _PT(""); int walk = 2; while (iter != this->d->initNamespaces.end()) { std::pair & entry = *iter; nsRegs[walk] = entry.first; nsRegs[walk + 1] = entry.second; walk += 2; iter++; } nsRegs[walk] = NULL; // Make version int const charCount = 16; XML_Char versionText[charCount]; ::PORT_SNPRINTF(versionText, charCount, _PT("%i"), this->d->props.getVersion()); XML_Char const * atts[2 + 2 + 1] = {_PT("version"), versionText, NULL, NULL, NULL}; // Space for xml:base // Make xml:base XML_Char const * const baseUri = getBaseUri(); if (this->d->embedBase && (baseUri != NULL)) { atts[0 + 2] = _PT("xml:base"); atts[1 + 2] = baseUri; } // Write tag this->getOutput()->writeStart(XspfXmlFormatter::namespaceKey, _PT("playlist"), atts, nsRegs); // Delete reg list XspfPropsWriterPrivate::freeNamespaceInits(this->d->initNamespaces); delete [] nsRegs; } void XspfPropsWriter::writeTrackListClose() { if (this->d->trackListEmpty) { // Whole tag was written already return; } this->getOutput()->writeHomeEnd(_PT("trackList")); } void XspfPropsWriter::writeTrackListOpen() { XML_Char const * atts[1] = {NULL}; if (this->d->trackListEmpty) { if (this->d->props.getVersion() > 0) { // Empty trackList allowed this->getOutput()->writeHomeStart(_PT("trackList"), atts); this->getOutput()->writeHomeEnd(_PT("trackList")); } else { // Empty trackList forbidden this->getOutput()->writeHomeStart(_PT("trackList"), atts); this->getOutput()->writeHomeStart(_PT("track"), atts); this->getOutput()->writeHomeEnd(_PT("track")); this->getOutput()->writeHomeEnd(_PT("trackList")); } } else { this->getOutput()->writeHomeStart(_PT("trackList"), atts); } } void XspfPropsWriter::init(XspfXmlFormatter & output, XML_Char const * baseUri, bool embedBase) { this->getOutput() = &output; setBaseUri(baseUri); this->d->embedBase = embedBase; } void XspfPropsWriter::writeStartPlaylist() { writePlaylistOpen(); writeTitle(); writeCreator(); writeAnnotation(); writeInfo(); writeLocation(); writeIdentifier(); writeImage(); writeDate(); writeLicense(); writeAttribution(); writeLinks(); writeMetas(); if (this->d->props.getVersion() > 0) { writeExtensions(); } } void XspfPropsWriter::writeStartTracklist(bool trackListEmpty) { this->d->trackListEmpty = trackListEmpty; writeTrackListOpen(); } void XspfPropsWriter::writeEndTracklist() { writeTrackListClose(); } void XspfPropsWriter::writeEndPlaylist() { writePlaylistClose(); } bool XspfPropsWriter::registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion) { // TODO too late? this->d->initNamespaces.push_back(std::pair(uri, Toolbox::newAndCopy(prefixSuggestion))); return true; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfPropsWriter.h000066400000000000000000000110651516712004000274670ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfPropsWriter.h * Interface of XspfPropsWriter. */ #ifndef XSPF_PROPS_WRITER_H #define XSPF_PROPS_WRITER_H #include "XspfDataWriter.h" namespace Xspf { class XspfXmlFormatter; class XspfProps; class XspfWriter; class XspfPropsWriterPrivate; /** * Writes playlist properties to an XML formatter. */ class XspfPropsWriter : public XspfDataWriter { private: /// @cond DOXYGEN_NON_API XspfPropsWriterPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new playlist property writer. */ XspfPropsWriter(); /** * Copy constructor. * * @param source Source to copy from */ XspfPropsWriter(XspfPropsWriter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfPropsWriter & operator=(XspfPropsWriter const & source); /** * Destroys this playlist property writer. */ ~XspfPropsWriter(); protected: /** * Initializes the playlist properties writer. * Must be called before writing. * * @param output Output formatter to write to * @param baseUri Absolute base URI to reduce against. * @param embedBase Embeds base URI as xml:base in root * node if true or not if false */ void init(XspfXmlFormatter & output, XML_Char const * baseUri, bool embedBase); /** * Opens the playlist tag and writes all playlist * properties not handled by writeStartTracklist(). */ void writeStartPlaylist(); /** * Writes all playlist properties not handled by * writeStartPlaylist() and opens the tracklist tag. * * @param trackListEmpty Tracklist empty flag */ void writeStartTracklist(bool trackListEmpty); /** * Closes the tracklist tag. */ void writeEndTracklist(); /** * Closes the playlist tag. */ void writeEndPlaylist(); /** * Writes the list of attributions. */ void writeAttribution(); /** * Writes the date property. */ void writeDate(); /** * Writes the identifier property. */ void writeIdentifier(); /** * Writes the license property. */ void writeLicense(); /** * Writes the location property. */ void writeLocation(); /** * Writes the closing playlist tag. */ void writePlaylistClose(); /** * Writes the opening playlist tag. */ void writePlaylistOpen(); /** * Writes the closing trackList tag. */ void writeTrackListClose(); /** * Writes the opening trackList tag. */ void writeTrackListOpen(); // TODO void setProps(XspfProps const * props); private: /** * Preregisters an XML namespace. * * @param uri Namespace URI * @param prefixSuggestion Suggested prefix * @return Success flag */ bool registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion); friend class XspfWriter; }; } #endif // XSPF_PROPS_WRITER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfReader.cpp000066400000000000000000002042151516712004000267250ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfReader.cpp * Implementation of XspfReader. */ #include #include #include #include #include #include #include "XspfSkipExtensionReader.h" #include #include #include "XspfStrictReaderCallback.h" #include #include #include #include #include // atoi #include // size_t #include // int #if (URI_VER_MAJOR == 0) && ((URI_VER_MINOR < 7) || ((URI_VER_MINOR == 7) && (URI_VER_RELEASE < 2))) # error uriparser 0.7.2 or later is required #endif namespace { int const XSPF_FALLBACK_VERSION = 1; struct EntityInfo { int valueLen; int lookupSum; int lookupDepth; EntityInfo(int valueLen, int lookupSum, int lookupDepth) : valueLen(valueLen), lookupSum(lookupSum), lookupDepth(lookupDepth) { } }; typedef std::basic_string StringType; typedef std::map MapType; typedef std::pair PairType; int const MAX_LENGTH_PER_ENTITY_VALUE = 100000; int const MAX_LOOKUP_SUM_PER_ENTITY_VALUE = 10000; int const MAX_LOOKUP_DEPTH_PER_ENTITY_VALUE = 5; XML_Char * makeString(XML_Char const * first, XML_Char const * afterLast) { size_t const len = afterLast - first; XML_Char * dup = new XML_Char[len + 1]; ::PORT_STRNCPY(dup, first, len); dup[len] = '\0'; return dup; } XML_Char * nextEntityRefMalloc(XML_Char const * start, XML_Char const * & atAmpersand, XML_Char const * & afterSemiColon) { XML_Char const * walker = start; while (true) { switch (walker[0]) { case '\0': // No complete entity found atAmpersand = start; afterSemiColon = walker; return NULL; case '&': // Entity start found atAmpersand = walker; break; case ';': // Entity stop found if (atAmpersand != NULL) { afterSemiColon = walker + 1; return makeString(atAmpersand + 1, walker); } break; } walker++; } } } // anon namespace namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfReader. */ class XspfReaderPrivate { friend class XspfReader; friend class XspfExtensionReader; private: XspfStack elementStack; ///< Element stack XspfStack > baseUriStack; ///< Element stack XspfProps * props; ///< Playlist properties slot XspfTrack * track; ///< Track slot int version; ///< XSPF version XML_Parser parser; ///< Expat parser handle XspfReaderCallback * callback; ///< Reader callback bool ownCallback; std::basic_string accum; ///< Element content accumulator std::basic_string lastRelValue; ///< Value of the previous "rel" attribute XspfExtensionReader * extensionReader; ///< Current extension reader XspfExtensionReaderFactory * extensionReaderFactory; ///< Extension reader factory int errorCode; ///< Error code bool insideExtension; ///< Flag wether the parser is inside an extension element bool skip; ///< Flag indicating skip-reading to ignore certain kinds of errors unsigned int skipStopLevel; ///< Level on which skipping should stop bool firstPlaylistAnnotation; ///< First annotation in playlist flag bool firstPlaylistAttribution; ///< First attributation in playlist flag bool firstPlaylistCreator; ///< First creator in playlist flag bool firstPlaylistDate; ///< First date in playlist flag bool firstPlaylistIdentifier; ///< First identifier in playlist flag bool firstPlaylistImage; ///< First image in playlist flag bool firstPlaylistInfo; ///< First info in playlist flag bool firstPlaylistLicense; ///< First license in playlist flag bool firstPlaylistLocation; ///< First location in playlist flag bool firstPlaylistTitle; ///< First title in playlist flag bool firstPlaylistTrackList; ///< First trackList in playlist flag bool firstTrackTitle; ///< First title in track flag bool firstTrackCreator; ///< First creator in track flag bool firstTrackAnnotation; ///< First annotation in track flag bool firstTrackInfo; ///< First info in track flag bool firstTrackImage; ///< First image in track flag bool firstTrackAlbum; ///< First album in track flag bool firstTrackTrackNum; ///< First trackNum in track flag bool firstTrackDuration; ///< First duration in track flag bool firstTrack; ///< First track flag MapType entityNameToValueLen; // TODO int maxLengthPerEntity; // TODO int maxTotalLookupsPerEntity; // TODO int maxLookupDepthPerEntity; // TODO bool limitLengthPerEntityValue; // TODO bool limitLookupSumPerEntityValue; // TODO bool limitLookupDepthPerEntityValue; // TODO /** * Creates a new D object. * * @param handlerFactory Factory used to create handlers */ XspfReaderPrivate(XspfExtensionReaderFactory * handlerFactory) : elementStack(), props(NULL), track(NULL), version(-1), callback(NULL), ownCallback(false), extensionReader(NULL), extensionReaderFactory(handlerFactory), errorCode(XSPF_READER_SUCCESS), insideExtension(false), skip(false), skipStopLevel(0), firstPlaylistAnnotation(true), firstPlaylistAttribution(true), firstPlaylistCreator(true), firstPlaylistDate(true), firstPlaylistIdentifier(true), firstPlaylistImage(true), firstPlaylistInfo(true), firstPlaylistLicense(true), firstPlaylistLocation(true), firstPlaylistTitle(true), firstPlaylistTrackList(true), firstTrackTitle(true), firstTrackCreator(true), firstTrackAnnotation(true), firstTrackInfo(true), firstTrackImage(true), firstTrackAlbum(true), firstTrackTrackNum(true), firstTrackDuration(true), firstTrack(true), entityNameToValueLen(), maxLengthPerEntity(MAX_LENGTH_PER_ENTITY_VALUE), maxTotalLookupsPerEntity(MAX_LOOKUP_SUM_PER_ENTITY_VALUE), maxLookupDepthPerEntity(MAX_LOOKUP_DEPTH_PER_ENTITY_VALUE), limitLengthPerEntityValue(false), limitLookupSumPerEntityValue(false), limitLookupDepthPerEntityValue(false) { } /** * Copy constructor. * * @param source Source to copy from */ XspfReaderPrivate(XspfReaderPrivate const & source) : elementStack(source.elementStack), props((source.props != NULL) ? new XspfProps(*(source.props)) : NULL), track((source.track != NULL) ? new XspfTrack(*(source.track)) : NULL), version(source.version), callback(source.ownCallback ? new XspfStrictReaderCallback : source.callback), ownCallback(source.ownCallback), extensionReader((source.extensionReader != NULL) ? source.extensionReader->createBrother() : NULL), extensionReaderFactory(source.extensionReaderFactory), errorCode(source.errorCode), insideExtension(source.insideExtension), skip(source.skip), skipStopLevel(source.skipStopLevel), firstPlaylistAnnotation(source.firstPlaylistAnnotation), firstPlaylistAttribution(source.firstPlaylistAttribution), firstPlaylistCreator(source.firstPlaylistCreator), firstPlaylistDate(source.firstPlaylistDate), firstPlaylistIdentifier(source.firstPlaylistIdentifier), firstPlaylistImage(source.firstPlaylistImage), firstPlaylistInfo(source.firstPlaylistInfo), firstPlaylistLicense(source.firstPlaylistLicense), firstPlaylistLocation(source.firstPlaylistLocation), firstPlaylistTitle(source.firstPlaylistTitle), firstPlaylistTrackList(source.firstPlaylistTrackList), firstTrackTitle(source.firstTrackTitle), firstTrackCreator(source.firstTrackCreator), firstTrackAnnotation(source.firstTrackAnnotation), firstTrackInfo(source.firstTrackInfo), firstTrackImage(source.firstTrackImage), firstTrackAlbum(source.firstTrackAlbum), firstTrackTrackNum(source.firstTrackTrackNum), firstTrackDuration(source.firstTrackDuration), firstTrack(source.firstTrack), entityNameToValueLen(source.entityNameToValueLen), maxLengthPerEntity(source.maxLengthPerEntity), maxTotalLookupsPerEntity(source.maxTotalLookupsPerEntity), maxLookupDepthPerEntity(source.maxLookupDepthPerEntity), limitLengthPerEntityValue(source.limitLengthPerEntityValue), limitLookupSumPerEntityValue(source.limitLookupSumPerEntityValue), limitLookupDepthPerEntityValue(source.limitLookupDepthPerEntityValue) { } /** * Assignment operator. * * @param source Source to copy from */ XspfReaderPrivate & operator=(XspfReaderPrivate const & source) { if (this != &source) { // stack this->elementStack = source.elementStack; // props if (this->props != NULL) { delete this->props; } this->props = (source.props != NULL) ? new XspfProps(*(source.props)) : NULL; // props if (this->track != NULL) { delete this->track; } this->track = (source.track != NULL) ? new XspfTrack(*(source.track)) : NULL; this->version = source.version; this->callback = source.ownCallback ? new XspfStrictReaderCallback : source.callback; this->ownCallback = source.ownCallback; // extension reader if (this->extensionReader != NULL) { delete this->track; } this->extensionReader = (source.extensionReader != NULL) ? source.extensionReader->createBrother() : NULL; this->extensionReaderFactory = source.extensionReaderFactory; this->errorCode = source.errorCode; this->insideExtension = source.insideExtension; this->skip = source.skip; this->skipStopLevel = source.skipStopLevel; this->firstPlaylistAnnotation = source.firstPlaylistAnnotation; this->firstPlaylistAttribution = source.firstPlaylistAttribution; this->firstPlaylistCreator = source.firstPlaylistCreator; this->firstPlaylistDate = source.firstPlaylistDate; this->firstPlaylistIdentifier = source.firstPlaylistIdentifier; this->firstPlaylistImage = source.firstPlaylistImage; this->firstPlaylistInfo = source.firstPlaylistInfo; this->firstPlaylistLicense = source.firstPlaylistLicense; this->firstPlaylistLocation = source.firstPlaylistLocation; this->firstPlaylistTitle = source.firstPlaylistTitle; this->firstPlaylistTrackList = source.firstPlaylistTrackList; this->firstTrackTitle = source.firstTrackTitle; this->firstTrackCreator = source.firstTrackCreator; this->firstTrackAnnotation = source.firstTrackAnnotation; this->firstTrackInfo = source.firstTrackInfo; this->firstTrackImage = source.firstTrackImage; this->firstTrackAlbum = source.firstTrackAlbum; this->firstTrackTrackNum = source.firstTrackTrackNum; this->firstTrackDuration = source.firstTrackDuration; this->firstTrack = source.firstTrack; this->entityNameToValueLen = source.entityNameToValueLen; this->maxLengthPerEntity = source.maxLengthPerEntity; this->maxTotalLookupsPerEntity = source.maxTotalLookupsPerEntity; this->maxLookupDepthPerEntity = source.maxLookupDepthPerEntity; this->limitLengthPerEntityValue = source.limitLengthPerEntityValue; this->limitLookupSumPerEntityValue = source.limitLookupSumPerEntityValue; this->limitLookupDepthPerEntityValue = source.limitLookupDepthPerEntityValue; } return *this; } /** * Destroys this D object. */ ~XspfReaderPrivate() { if (this->props != NULL) { delete this->props; } if (this->track != NULL) { delete this->track; } if (this->extensionReader != NULL) { delete this->extensionReader; } if (this->ownCallback) { delete this->callback; } } }; /// @endcond XspfReader::XspfReader(XspfExtensionReaderFactory * handlerFactory) : d(new XspfReaderPrivate(handlerFactory)) { } void XspfReader::makeReusable() { // Reset everything but the error state this->d->elementStack.clear(); this->d->baseUriStack.clear(); if (this->d->props != NULL) { delete this->d->props; this->d->props = NULL; } if (this->d->track != NULL) { delete this->d->track; this->d->track = NULL; } if (this->d->ownCallback) { delete this->d->callback; this->d->ownCallback = false; } this->d->callback = NULL; this->d->accum.clear(); this->d->lastRelValue.clear(); this->d->firstPlaylistAnnotation = true; this->d->firstPlaylistAttribution = true; this->d->firstPlaylistCreator = true; this->d->firstPlaylistDate = true; this->d->firstPlaylistIdentifier = true; this->d->firstPlaylistImage = true; this->d->firstPlaylistInfo = true; this->d->firstPlaylistLicense = true; this->d->firstPlaylistLocation = true; this->d->firstPlaylistTitle = true; this->d->firstPlaylistTrackList = true; this->d->firstTrackTitle = true; this->d->firstTrackCreator = true; this->d->firstTrackAnnotation = true; this->d->firstTrackInfo = true; this->d->firstTrackImage = true; this->d->firstTrackAlbum = true; this->d->firstTrackTrackNum = true; this->d->firstTrackDuration = true; this->d->firstTrack = true; this->d->insideExtension = false; this->d->skip = false; this->d->skipStopLevel = 0; this->d->version = -1; if (this->d->extensionReader != NULL) { delete this->d->extensionReader; this->d->extensionReader = NULL; } this->d->entityNameToValueLen.clear(); } XspfReader::XspfReader(XspfReader const & source) : d(new XspfReaderPrivate(*(source.d))) { } XspfReader & XspfReader::operator=(XspfReader const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfReader::~XspfReader() { delete this->d; } bool XspfReader::onBeforeParse(XspfReaderCallback * callback, XML_Char const * baseUri) { this->d->ownCallback = (callback == NULL); this->d->callback = (callback == NULL) ? new XspfStrictReaderCallback : callback; // Init base URI stack if (!Toolbox::isAbsoluteUri(baseUri)) { handleFatalError(XSPF_READER_ERROR_BASE_URI_USELESS, _PT("Base URI is not a valid absolute URI.")); return false; } std::basic_string baseUriString(baseUri); this->d->baseUriStack.push(baseUriString); clearError(); // Create parser this->d->parser = ::XML_ParserCreateNS(NULL, XSPF_NS_SEP_CHAR); // Put class pointer into user data ::XML_SetUserData(this->d->parser, this); // Register handlers ::XML_SetElementHandler(this->d->parser, masterStart, masterEnd); ::XML_SetCharacterDataHandler(this->d->parser, masterCharacters); ::XML_SetEntityDeclHandler(this->d->parser, masterEntityDeclaration); return true; } void XspfReader::onAfterParse() { ::XML_ParserFree(this->d->parser); makeReusable(); } /*static*/ bool XspfReader::isXmlBase(XML_Char const * attributeKey) { return (!::PORT_STRNCMP(attributeKey, XML_NS_HOME, XML_NS_HOME_LEN) && !::PORT_STRCMP(attributeKey + XML_NS_HOME_LEN + 1, _PT("base"))); } bool XspfReader::handleXmlBaseAttribute(XML_Char const * xmlBase) { // Check URI if (!Toolbox::isUri(xmlBase)) { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_INVALID, XSPF_READER_TEXT_ZERO_WRONG_ATTRIBUTE_TYPE( _PT("xml:base"), _PT("URI")))) { return false; } } // Make absolute and push on URI stack XML_Char const * const resolveAgainst = this->d->baseUriStack.top().c_str(); XML_Char * const resolvedUri = Toolbox::makeAbsoluteUri( xmlBase, resolveAgainst); this->d->baseUriStack.push(std::basic_string( const_cast(resolvedUri))); delete [] resolvedUri; return true; } XML_Char * XspfReader::makeAbsoluteUri(XML_Char const * sourceUri) const { XML_Char const * const baseUri = this->d->baseUriStack.top().c_str(); XML_Char * const res = Toolbox::makeAbsoluteUri(sourceUri, baseUri); return res; } void XspfReader::setExpatError() { XML_Error const expatCode = ::XML_GetErrorCode(this->d->parser); handleFatalError(XSPF_READER_ERROR_EXPAT + static_cast(expatCode), XSPF_READER_TEXT_ONE_EXPAT_ERROR, ::XML_ErrorString(expatCode)); } int XspfReader::parseFile(XML_Char const * filename, XspfReaderCallback * callback, XML_Char const * baseUri) { // Init if (!onBeforeParse(callback, baseUri)) { return this->d->errorCode; } // Check filename if (filename == NULL) { handleFatalError(XSPF_READER_ERROR_NO_INPUT, XSPF_READER_TEXT_ZERO_FILENAME_NULL); return this->d->errorCode; } // Open file FILE * file = ::PORT_FOPEN(filename, _PT("r")); if (file == NULL) { handleFatalError(XSPF_READER_ERROR_NO_INPUT, XSPF_READER_TEXT_ONE_FILE_READING_ERROR, filename); return this->d->errorCode; } // Get filesize ::fseek(file, 0, SEEK_END); long const filesize = ::ftell(file); ::fseek(file, 0, SEEK_SET); // Read and parse file void * buffer; if (filesize > XSPF_MAX_BLOCK_SIZE) { // In several blocks long sizeLeft = filesize; while (sizeLeft > 0) { long const blockSize = std::min(sizeLeft, XSPF_MAX_BLOCK_SIZE); buffer = ::XML_GetBuffer(this->d->parser, blockSize); ::fread(buffer, 1, blockSize, file); sizeLeft -= blockSize; if (::XML_ParseBuffer(this->d->parser, blockSize, sizeLeft == 0) == XML_STATUS_ERROR) { if (this->d->errorCode == XSPF_READER_SUCCESS) { setExpatError(); } break; } } ::fclose(file); } else { // One single go buffer = ::XML_GetBuffer(this->d->parser, filesize); ::fread(buffer, 1, filesize, file); ::fclose(file); if (::XML_ParseBuffer(this->d->parser, filesize, 1) == XML_STATUS_ERROR) { if (this->d->errorCode == XSPF_READER_SUCCESS) { setExpatError(); } } } notifySuccess(); // Cleanup onAfterParse(); return this->d->errorCode; } int XspfReader::parseMemory(char const * memory, int numBytes, XspfReaderCallback * callback, XML_Char const * baseUri) { // Init if (!onBeforeParse(callback, baseUri)) { return this->d->errorCode; } // Parse if (::XML_Parse(this->d->parser, memory, numBytes, 1) == XML_STATUS_ERROR) { if (this->d->errorCode == XSPF_READER_SUCCESS) { setExpatError(); } } notifySuccess(); // Cleanup onAfterParse(); return this->d->errorCode; } int XspfReader::parseChunks(XspfChunkCallback * inputCallback, XspfReaderCallback * dataCallback, XML_Char const * baseUri) { // Init if (!onBeforeParse(dataCallback, baseUri)) { return this->d->errorCode; } // Parse chunks in a loop for (;;) { // Ask callback for buffer size int const bufferByteSize = inputCallback->getMinimumBufferByteSize(); void * buffer = NULL; // init not needed // Create and fill buffer int bytesToParse = 0; if (bufferByteSize > 0) { buffer = ::XML_GetBuffer(this->d->parser, bufferByteSize); bytesToParse = inputCallback->fillBuffer(buffer); } // Parse chunk if (::XML_ParseBuffer(this->d->parser, bytesToParse, bytesToParse == 0) == XML_STATUS_ERROR) { // Error if (this->d->errorCode == XSPF_READER_SUCCESS) { setExpatError(); } break; } else { // Fine, continue? if (bytesToParse == 0) { break; } } } inputCallback->notifyStop(); notifySuccess(); // .. on dataCallback // Cleanup onAfterParse(); return this->d->errorCode; } bool XspfReader::checkAndSkipNamespace(XML_Char const * fullName, XML_Char const * & localName) { if (::PORT_STRNCMP(fullName, XSPF_NS_HOME, XSPF_NS_HOME_LEN)) { if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { return false; } // Catch as instead localName = fullName; while ((localName[0] != _PT('\0')) && (localName[0] != XSPF_NS_SEP_CHAR)) { localName++; } if (localName[0] == _PT('\0')) { // No namespace -> reset localName = fullName; } else { // Namespace -> jump to local name localName++; } } else { localName = fullName + XSPF_NS_HOME_LEN + 1; } return true; } bool XspfReader::handleStartOne(XML_Char const * fullName, XML_Char const ** atts) { // Check and skip namespace XML_Char const * localName; if (!checkAndSkipNamespace(fullName, localName)) { return false; } // Check root name if (::PORT_STRCMP(localName, _PT("playlist"))) { if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_WRONG_ROOT_NAME, fullName)) { return false; } } this->d->props = new XspfProps(); if (!handlePlaylistAttribs(atts)) { return false; } this->d->elementStack.push(TAG_PLAYLIST); this->d->props->setVersion(this->d->version); return true; } bool XspfReader::handleStartTwo(XML_Char const * fullName, XML_Char const ** atts) { // Check and skip namespace XML_Char const * localName; if (!checkAndSkipNamespace(fullName, localName)) { return false; } switch (localName[0]) { case _PT('a'): switch (localName[1]) { case _PT('n'): if (::PORT_STRCMP(localName + 2, _PT("notation"))) { break; } if (this->d->firstPlaylistAnnotation) { this->d->firstPlaylistAnnotation = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("annotation")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_ANNOTATION); return true; } break; case _PT('t'): if (::PORT_STRCMP(localName + 2, _PT("tribution"))) { break; } if (this->d->firstPlaylistAttribution) { this->d->firstPlaylistAttribution = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("attribution")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_ATTRIBUTION); return true; } break; } break; case _PT('c'): if (::PORT_STRCMP(localName + 1, _PT("reator"))) { break; } if (this->d->firstPlaylistCreator) { this->d->firstPlaylistCreator = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("creator")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_CREATOR); return true; } break; case _PT('d'): if (::PORT_STRCMP(localName + 1, _PT("ate"))) { break; } if (this->d->firstPlaylistDate) { this->d->firstPlaylistDate = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("date")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_DATE); return true; } break; case _PT('e'): if (::PORT_STRCMP(localName + 1, _PT("xtension"))) { break; } // Tag only allowed in v1 if (this->d->version == 0) { if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN_VERSION_ZERO, fullName)) { return false; } } XML_Char const * applicationUri; if (handleExtensionAttribs(atts, applicationUri)) { if (applicationUri == NULL) { this->d->elementStack.push(TAG_PLAYLIST_EXTENSION); skipFromHere(); return true; } else { this->d->insideExtension = true; // Create suitable handler if (this->d->extensionReaderFactory != NULL) { this->d->extensionReader = this->d->extensionReaderFactory ->newPlaylistExtensionReader(applicationUri, this); } if (this->d->extensionReader == NULL) { this->d->extensionReader = new XspfSkipExtensionReader(this); } return this->d->extensionReader->handleExtensionStart(fullName, atts); } } else { return false; } break; case _PT('i'): switch (localName[1]) { case _PT('d'): if (::PORT_STRCMP(localName + 2, _PT("entifier"))) { break; } if (this->d->firstPlaylistIdentifier) { this->d->firstPlaylistIdentifier = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("identifier")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_IDENTIFIER); return true; } break; case _PT('m'): if (::PORT_STRCMP(localName + 2, _PT("age"))) { break; } if (this->d->firstPlaylistImage) { this->d->firstPlaylistImage = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("image")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_IMAGE); return true; } break; case _PT('n'): if (::PORT_STRCMP(localName + 2, _PT("fo"))) { break; } if (this->d->firstPlaylistInfo) { this->d->firstPlaylistInfo = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("info")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_INFO); return true; } break; } break; case _PT('l'): switch (localName[1]) { case _PT('i'): switch (localName[2]) { case _PT('c'): if (::PORT_STRCMP(localName + 3, _PT("ense"))) { break; } if (this->d->firstPlaylistLicense) { this->d->firstPlaylistLicense = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("license")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_LICENSE); return true; } break; case _PT('n'): if (::PORT_STRCMP(localName + 3, _PT("k"))) { break; } { XML_Char const * rel = NULL; // No init needed if (handleMetaLinkAttribs(atts, rel)) { this->d->elementStack.push(TAG_PLAYLIST_LINK); if (rel != NULL) { this->d->lastRelValue.assign(atts[1]); } else { skipFromHere(); } return true; } else { return false; } } break; } break; case _PT('o'): if (::PORT_STRCMP(localName + 2, _PT("cation"))) { break; } if (this->d->firstPlaylistLocation) { this->d->firstPlaylistLocation = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("location")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_LOCATION); return true; } break; } break; case _PT('m'): if (::PORT_STRCMP(localName + 1, _PT("eta"))) { break; } { XML_Char const * rel = NULL; // No init needed if (handleMetaLinkAttribs(atts, rel)) { this->d->elementStack.push(TAG_PLAYLIST_META); if (rel != NULL) { this->d->lastRelValue.assign(atts[1]); } else { skipFromHere(); } return true; } else { return false; } } break; case _PT('t'): switch (localName[1]) { case _PT('i'): if (::PORT_STRCMP(localName + 2, _PT("tle"))) { break; } if (this->d->firstPlaylistTitle) { this->d->firstPlaylistTitle = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("title")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TITLE); return true; } break; case _PT('r'): if (::PORT_STRCMP(localName + 2, _PT("ackList"))) { break; } if (this->d->firstPlaylistTrackList) { this->d->firstPlaylistTrackList = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("trackList")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST); return true; } break; } break; } if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { return false; } this->d->elementStack.push(TAG_UNKNOWN); skipFromHere(); return true; } bool XspfReader::handleStartThree(XML_Char const * fullName, XML_Char const ** atts) { // Check and skip namespace XML_Char const * localName; if (!checkAndSkipNamespace(fullName, localName)) { return false; } switch (this->d->elementStack.top()) { case TAG_PLAYLIST_ATTRIBUTION: switch (localName[0]) { case _PT('i'): if (::PORT_STRCMP(localName + 1, _PT("dentifier"))) { break; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } this->d->elementStack.push(TAG_PLAYLIST_ATTRIBUTION_IDENTIFIER); return true; case _PT('l'): if (::PORT_STRCMP(localName + 1, _PT("ocation"))) { break; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } this->d->elementStack.push(TAG_PLAYLIST_ATTRIBUTION_LOCATION); return true; } break; case TAG_PLAYLIST_TRACKLIST: if (::PORT_STRCMP(localName, _PT("track"))) { break; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } this->d->firstTrack = false; this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK); this->d->track = new XspfTrack(); return true; } if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { return false; } this->d->elementStack.push(TAG_UNKNOWN); skipFromHere(); return true; } bool XspfReader::handleStartFour(XML_Char const * fullName, XML_Char const ** atts) { if (this->d->elementStack.top() != TAG_PLAYLIST_TRACKLIST_TRACK) { return false; } // Check and skip namespace XML_Char const * localName; if (!checkAndSkipNamespace(fullName, localName)) { return false; } switch (localName[0]) { case _PT('a'): switch (localName[1]) { case _PT('l'): if (::PORT_STRCMP(localName + 2, _PT("bum"))) { break; } if (this->d->firstTrackAlbum) { this->d->firstTrackAlbum = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("album")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_ALBUM); return true; } break; case _PT('n'): if (::PORT_STRCMP(localName + 2, _PT("notation"))) { break; } if (this->d->firstTrackAnnotation) { this->d->firstTrackAnnotation = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("annotation")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_ANNOTATION); return true; } break; case _PT('r'): if (::PORT_STRCMP(localName + 2, _PT("tist"))) { break; } // Note: Element //playlist/trackList/track/artist // is not valid XSPF. This is a loose fallback. if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { return false; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_CREATOR); return true; } break; } break; case _PT('c'): if (::PORT_STRCMP(localName + 1, _PT("reator"))) { break; } if (this->d->firstTrackCreator) { this->d->firstTrackCreator = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("creator")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_CREATOR); return true; } break; case _PT('d'): if (::PORT_STRCMP(localName + 1, _PT("uration"))) { break; } if (this->d->firstTrackDuration) { this->d->firstTrackDuration = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("duration")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_DURATION); return true; } break; case _PT('e'): if (::PORT_STRCMP(localName + 1, _PT("xtension"))) { break; } // Tag only allowed in v1 if (this->d->version == 0) { if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN_VERSION_ZERO, fullName)) { return false; } } XML_Char const * applicationUri; if (handleExtensionAttribs(atts, applicationUri)) { if (applicationUri == NULL) { this->d->elementStack.push( TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION); skipFromHere(); return true; } else { this->d->insideExtension = true; // Create suitable handler if (this->d->extensionReaderFactory != NULL) { this->d->extensionReader = this->d->extensionReaderFactory ->newTrackExtensionReader(applicationUri, this); } if (this->d->extensionReader == NULL) { this->d->extensionReader = new XspfSkipExtensionReader(this); } return this->d->extensionReader->handleExtensionStart(fullName, atts); } } else { return false; } break; case _PT('i'): switch (localName[1]) { case _PT('d'): if (::PORT_STRCMP(localName + 2, _PT("entifier"))) { break; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_IDENTIFIER); return true; case _PT('m'): if (::PORT_STRCMP(localName + 2, _PT("age"))) { break; } if (this->d->firstTrackImage) { this->d->firstTrackImage = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("image")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_IMAGE); return true; } break; case _PT('n'): if (::PORT_STRCMP(localName + 2, _PT("fo"))) { break; } if (this->d->firstTrackInfo) { this->d->firstTrackInfo = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("info")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_INFO); return true; } break; } break; case _PT('l'): switch (localName[1]) { case _PT('i'): if (::PORT_STRCMP(localName + 2, _PT("nk"))) { break; } { XML_Char const * rel = NULL; // No init needed if (handleMetaLinkAttribs(atts, rel)) { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_LINK); if (rel != NULL) { this->d->lastRelValue.assign(atts[1]); } else { skipFromHere(); } return true; } else { return false; } } break; case _PT('o'): if (::PORT_STRCMP(localName + 2, _PT("cation"))) { break; } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_LOCATION); return true; } break; case _PT('m'): if (::PORT_STRCMP(localName + 1, _PT("eta"))) { break; } { XML_Char const * rel = NULL; // No init needed if (handleMetaLinkAttribs(atts, rel)) { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_META); if (rel != NULL) { this->d->lastRelValue.assign(atts[1]); } else { skipFromHere(); } return true; } else { return false; } } break; case _PT('t'): switch (localName[1]) { case _PT('i'): if (::PORT_STRCMP(localName + 2, _PT("tle"))) { break; } if (this->d->firstTrackTitle) { this->d->firstTrackTitle = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("title")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_TITLE); return true; } break; case _PT('r'): if (::PORT_STRCMP(localName + 2, _PT("ackNum"))) { break; } if (this->d->firstTrackTrackNum) { this->d->firstTrackTrackNum = false; } else { if (!handleError(XSPF_READER_ERROR_ELEMENT_TOOMANY, XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS( XSPF_NS_HOME, _PT("trackNum")))) { return false; } } if (!handleNoAttribsExceptXmlBase(atts)) { return false; } else { this->d->elementStack.push(TAG_PLAYLIST_TRACKLIST_TRACK_TRACKNUM); return true; } break; } break; } if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { return false; } this->d->elementStack.push(TAG_UNKNOWN); skipFromHere(); return true; } void XspfReader::handleStart(XML_Char const * fullName, XML_Char const ** atts) { if (this->d->skip) { this->d->elementStack.push(TAG_UNKNOWN); return; } bool res = true; if (this->d->insideExtension) { res = this->d->extensionReader->handleExtensionStart(fullName, atts); } else { switch (this->d->elementStack.size() + 1) { case 1: res = handleStartOne(fullName, atts); break; case 2: res = handleStartTwo(fullName, atts); break; case 3: res = handleStartThree(fullName, atts); break; case 4: res = handleStartFour(fullName, atts); break; case 5: if (!handleError(XSPF_READER_ERROR_ELEMENT_FORBIDDEN, XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN, fullName)) { res = false; } else { this->d->elementStack.push(TAG_UNKNOWN); skipFromHere(); } break; } } if (!res) { stop(); } // Grow base URI stack as needed size_t const curBaseUriCount = this->d->baseUriStack.size(); size_t const wantedBaseUriCount = this->d->elementStack.size(); for (size_t i = curBaseUriCount; i < wantedBaseUriCount; i++) { this->d->baseUriStack.push(this->d->baseUriStack.top()); } } bool XspfReader::handleEndOne(XML_Char const * /*fullName*/) { if (this->d->firstPlaylistTrackList) { if (!handleError(XSPF_READER_ERROR_ELEMENT_MISSING, XSPF_READER_TEXT_ZERO_ELEMENT_MISSING( XSPF_NS_HOME, _PT("trackList")))) { return false; } } // Call property callback assert(this->d->callback != NULL); // Note: setProps() deletes the props for us this->d->callback->setProps(this->d->props); this->d->props = NULL; return true; } bool XspfReader::handleEndTwo(XML_Char const * /*fullName*/) { const unsigned int stackTop = this->d->elementStack.top(); // Collapse elements // NOTE: whitespace in the middle of , // , and is illegal anyway // which is why we we only cut head and tail here switch (stackTop) { case TAG_PLAYLIST_INFO: case TAG_PLAYLIST_LOCATION: case TAG_PLAYLIST_IDENTIFIER: case TAG_PLAYLIST_IMAGE: case TAG_PLAYLIST_DATE: case TAG_PLAYLIST_LICENSE: case TAG_PLAYLIST_LINK: case TAG_PLAYLIST_META: Toolbox::trimString(this->d->accum); break; default: ; // NOOP } XML_Char const * const finalAccum = this->d->accum.c_str(); switch (stackTop) { case TAG_PLAYLIST_ANNOTATION: this->d->props->giveAnnotation(finalAccum, XspfData::COPY); break; /* case TAG_PLAYLIST_ATTRIBUTION: break; */ case TAG_PLAYLIST_CREATOR: this->d->props->giveCreator(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_DATE: { XspfDateTime * const dateTime = new XspfDateTime; if (!XspfDateTime::extractDateTime(finalAccum, dateTime)) { delete dateTime; if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("date"), _PT("dateTime")))) { return false; } } else { this->d->props->giveDate(dateTime, XspfData::TRANSFER); } } break; /* case TAG_PLAYLIST_EXTENSION: break; */ case TAG_PLAYLIST_IDENTIFIER: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("identifier"), _PT("URI")))) { return false; } } else { this->d->props->giveIdentifier(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_IMAGE: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("image"), _PT("URI")))) { return false; } } else { this->d->props->giveImage(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_INFO: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("info"), _PT("URI")))) { return false; } } else { this->d->props->giveInfo(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_LICENSE: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("license"), _PT("URI")))) { return false; } } else { this->d->props->giveLicense(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_LINK: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("link"), _PT("URI")))) { return false; } } else { this->d->props->giveAppendLink( this->d->lastRelValue.c_str(), XspfData::COPY, makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_LOCATION: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("location"), _PT("URI")))) { return false; } } else { this->d->props->giveLocation( makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_META: this->d->props->giveAppendMeta( this->d->lastRelValue.c_str(), XspfData::COPY, finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TITLE: this->d->props->giveTitle(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST: // Check if empty for v0 if ((this->d->version == 0) && (this->d->firstTrack)) { if (!handleError(XSPF_READER_ERROR_ELEMENT_MISSING, XSPF_READER_TEXT_ZERO_ELEMENT_MISSING_VERSION_ZERO( XSPF_NS_HOME, _PT("track")))) { return false; } } break; } this->d->accum.clear(); return true; } bool XspfReader::handleEndThree(XML_Char const * /*fullName*/) { const unsigned int stackTop = this->d->elementStack.top(); // Collapse elements // NOTE: whitespace in the middle of , // , and is illegal anyway // which is why we we only cut head and tail here switch (stackTop) { case TAG_PLAYLIST_ATTRIBUTION_IDENTIFIER: case TAG_PLAYLIST_ATTRIBUTION_LOCATION: Toolbox::trimString(this->d->accum); break; default: ; // NOOP } XML_Char const * const finalAccum = this->d->accum.c_str(); switch (stackTop) { case TAG_PLAYLIST_ATTRIBUTION_IDENTIFIER: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("identifier"), _PT("URI")))) { return false; } } else { this->d->props->giveAppendAttributionIdentifier(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_ATTRIBUTION_LOCATION: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("location"), _PT("URI")))) { return false; } } else { this->d->props->giveAppendAttributionLocation(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK: // Call track callback assert(this->d->callback != NULL); // Note: addTrack() deletes the track for us this->d->callback->addTrack(this->d->track); this->d->track = NULL; this->d->firstTrackTitle = true; this->d->firstTrackCreator = true; this->d->firstTrackAnnotation = true; this->d->firstTrackInfo = true; this->d->firstTrackImage = true; this->d->firstTrackAlbum = true; this->d->firstTrackTrackNum = true; this->d->firstTrackDuration = true; } this->d->accum.clear(); return true; } bool XspfReader::handleEndFour(XML_Char const * /*fullName*/) { const unsigned int stackTop = this->d->elementStack.top(); // Collapse elements // NOTE: whitespace in the middle of , // , and is illegal anyway // which is why we we only cut head and tail here switch (stackTop) { case TAG_PLAYLIST_TRACKLIST_TRACK_LOCATION: case TAG_PLAYLIST_TRACKLIST_TRACK_IDENTIFIER: case TAG_PLAYLIST_TRACKLIST_TRACK_INFO: case TAG_PLAYLIST_TRACKLIST_TRACK_IMAGE: case TAG_PLAYLIST_TRACKLIST_TRACK_TRACKNUM: case TAG_PLAYLIST_TRACKLIST_TRACK_DURATION: case TAG_PLAYLIST_TRACKLIST_TRACK_LINK: case TAG_PLAYLIST_TRACKLIST_TRACK_META: Toolbox::trimString(this->d->accum); break; default: ; // NOOP } XML_Char const * const finalAccum = this->d->accum.c_str(); switch (stackTop) { case TAG_PLAYLIST_TRACKLIST_TRACK_ALBUM: this->d->track->giveAlbum(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST_TRACK_ANNOTATION: this->d->track->giveAnnotation(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST_TRACK_CREATOR: this->d->track->giveCreator(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST_TRACK_DURATION: int duration; if (!Toolbox::extractInteger(finalAccum, 0, &duration)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("duration"), _PT("unsigned integer")))) { return false; } } else { this->d->track->setDuration(duration); } break; /* case TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION: break; */ case TAG_PLAYLIST_TRACKLIST_TRACK_IDENTIFIER: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("identifier"), _PT("URI")))) { return false; } } else { this->d->track->giveAppendIdentifier( makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK_IMAGE: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("image"), _PT("URI")))) { return false; } } else { this->d->track->giveImage(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK_INFO: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("info"), _PT("URI")))) { return false; } } else { this->d->track->giveInfo(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK_LINK: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("link"), _PT("URI")))) { return false; } } else { this->d->track->giveAppendLink( this->d->lastRelValue.c_str(), XspfData::COPY, makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK_LOCATION: if (!Toolbox::isUri(finalAccum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("location"), _PT("URI")))) { return false; } } else { this->d->track->giveAppendLocation(makeAbsoluteUri(finalAccum), XspfData::TRANSFER); } break; case TAG_PLAYLIST_TRACKLIST_TRACK_META: this->d->track->giveAppendMeta(this->d->lastRelValue.c_str(), XspfData::COPY, finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST_TRACK_TITLE: this->d->track->giveTitle(finalAccum, XspfData::COPY); break; case TAG_PLAYLIST_TRACKLIST_TRACK_TRACKNUM: int trackNum; if (!Toolbox::extractInteger(finalAccum, 1, &trackNum)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE( XSPF_NS_HOME, _PT("trackNum"), _PT("unsigned integer greater zero")))) { return false; } } else { this->d->track->setTrackNum(trackNum); } break; } this->d->accum.clear(); return true; } void XspfReader::handleEnd(XML_Char const * fullName) { if (this->d->skip) { if (this->d->elementStack.size() == this->d->skipStopLevel) { this->d->skip = false; } this->d->elementStack.pop(); return; } bool extensionLeft = false; int pushBackTag = TAG_UNKNOWN; // Init not needed but kills the warning... if (this->d->insideExtension) { switch (this->d->elementStack.size()) { case 2: if (this->d->elementStack.top() == TAG_PLAYLIST_EXTENSION) { pushBackTag = TAG_PLAYLIST_EXTENSION; extensionLeft = true; } break; case 4: if (this->d->elementStack.top() == TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION) { pushBackTag = TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION; extensionLeft = true; } break; } if (!this->d->extensionReader->handleExtensionEnd(fullName)) { stop(); return; } if (extensionLeft) { this->d->insideExtension = false; // Add extension XspfExtension * const extension = this->d->extensionReader->wrap(); if (extension != NULL) { XspfData * const target = (pushBackTag == TAG_PLAYLIST_EXTENSION) ? static_cast(this->d->props) : static_cast(this->d->track); target->giveAppendExtension(extension, XspfData::TRANSFER); } // Destroy extension reader delete this->d->extensionReader; this->d->extensionReader = NULL; this->d->elementStack.push(pushBackTag); } else { return; } } bool res = false; switch (this->d->elementStack.size()) { case 1: res = handleEndOne(fullName); break; case 2: res = handleEndTwo(fullName); break; case 3: res = handleEndThree(fullName); break; case 4: res = handleEndFour(fullName); break; } if (!res) { stop(); return; } // Shrink base URI stack while always keeping the external // base URI at the bottom of the stack size_t const curBaseUriCount = this->d->baseUriStack.size(); size_t const wantedBaseUriCount = this->d->elementStack.size(); for (size_t i = curBaseUriCount; i > wantedBaseUriCount; i--) { this->d->baseUriStack.pop(); } // Prevent popping twice // if (!extensionLeft) { this->d->elementStack.pop(); // } } void XspfReader::handleCharacters(XML_Char const * s, int len) { if (this->d->skip) { return; } if (this->d->insideExtension) { if (!this->d->extensionReader->handleExtensionCharacters(s, len)) { stop(); } return; } switch (this->d->elementStack.size()) { case 1: // Must be all whitespace at root if (!Toolbox::isWhiteSpace(s, len)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN( XSPF_NS_HOME, _PT("playlist")))) { stop(); return; } } break; case 2: switch (this->d->elementStack.top()) { case TAG_PLAYLIST_TRACKLIST: // Must be all whitespace if (!Toolbox::isWhiteSpace(s, len)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN( XSPF_NS_HOME, _PT("trackList")))) { stop(); return; } } break; case TAG_PLAYLIST_ATTRIBUTION: // Must be all whitespace if (!Toolbox::isWhiteSpace(s, len)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN( XSPF_NS_HOME, _PT("attribution")))) { stop(); return; } } break; default: // Append unmodified this->d->accum.append(s, len); } break; case 3: switch (this->d->elementStack.top()) { case TAG_PLAYLIST_TRACKLIST_TRACK: // Must be all whitespace if (!Toolbox::isWhiteSpace(s, len)) { if (!handleError(XSPF_READER_ERROR_CONTENT_INVALID, XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN( XSPF_NS_HOME, _PT("track")))) { stop(); return; } } break; default: // Append unmodified this->d->accum.append(s, len); } break; case 4: // Append unmodified this->d->accum.append(s, len); break; } } void XspfReader::handleEntityDeclaration(XML_Char const * entityName, XML_Char const * value) { XML_Char const * walker = value; int valueLen = 0; int lookupSum = 0; int lookupDepth = 0; while (walker[0] != _PT('\0')) { XML_Char const * atAmpersand = NULL; XML_Char const * afterSemiColon = NULL; XML_Char * entityRefname = nextEntityRefMalloc(walker, atAmpersand, afterSemiColon); valueLen += static_cast(atAmpersand - walker); if (entityRefname != NULL) { MapType::iterator found = this->d->entityNameToValueLen.find( StringType(entityRefname)); delete[] entityRefname; EntityInfo const info = (found != this->d->entityNameToValueLen.end()) ? found->second : EntityInfo(1, 0, 0); valueLen += info.valueLen; lookupSum += info.lookupSum + 1; int const minLookupDepth = info.lookupDepth + 1; if (lookupDepth < minLookupDepth) { lookupDepth = minLookupDepth; } } else { valueLen += static_cast(afterSemiColon - walker); break; } walker = afterSemiColon; } EntityInfo const info(valueLen, lookupSum, lookupDepth); this->d->entityNameToValueLen.insert(PairType(entityName, info)); if (this->d->limitLengthPerEntityValue && (valueLen > this->d->maxLengthPerEntity)) { handleFatalError(XSPF_READER_ERROR_MALICIOUS_SPACE, _PT("Input considered harmful: Entity taking too much space")); stop(); } else if (this->d->limitLookupSumPerEntityValue && (lookupSum > this->d->maxTotalLookupsPerEntity)) { handleFatalError(XSPF_READER_ERROR_MALICIOUS_LOOKUP_SUM, _PT("Input considered harmful: Entity requiring too many lookups")); stop(); } else if (this->d->limitLookupDepthPerEntityValue && (lookupDepth > this->d->maxLookupDepthPerEntity)) { handleFatalError(XSPF_READER_ERROR_MALICIOUS_LOOKUP_DEPTH, _PT("Input considered harmful: Entity requiring too deep lookup")); stop(); } } void XspfReader::stop() { // Remove handlers ::XML_SetElementHandler(this->d->parser, NULL, NULL); ::XML_SetCharacterDataHandler(this->d->parser, NULL); // Full stop ::XML_StopParser(this->d->parser, XML_FALSE); } bool XspfReader::handlePlaylistAttribs(XML_Char const ** atts) { bool versionFound = false; for (int i = 0; atts[i] != NULL; i += 2) { if (!::PORT_STRCMP(atts[i], _PT("version"))) { // Check and set version int dummyVersion; if (!Toolbox::extractInteger(atts[i + 1], 0, &dummyVersion) || (dummyVersion > 1)) { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_INVALID, XSPF_READER_TEXT_ONE_WRONG_VERSION, atts[i + 1])) { return false; } dummyVersion = XSPF_FALLBACK_VERSION; } this->d->version = dummyVersion; versionFound = true; } else if (isXmlBase(atts[i])) { // xml:base XML_Char const * const xmlBase = atts[i + 1]; if (!handleXmlBaseAttribute(xmlBase)) { return false; } } else { // Forbidden attribute if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN, atts[i])) { return false; } } } if (!versionFound) { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_MISSING, XSPF_READER_TEXT_ZERO_ATTRIBUTE_MISSING( _PT("version")))) { return false; } this->d->version = XSPF_FALLBACK_VERSION; } return true; } namespace { /** * Checks whether a key URI contains version information. */ bool containsVersion(XML_Char const * text) { if (text == NULL) { return true; } while (true) { switch (text[0]) { case _PT('\0'): return false; case _PT('0'): // fall through case _PT('1'): // fall through case _PT('2'): // fall through case _PT('3'): // fall through case _PT('4'): // fall through case _PT('5'): // fall through case _PT('6'): // fall through case _PT('7'): // fall through case _PT('8'): // fall through case _PT('9'): // fall through return true; default: text++; } } } } // anon namespace bool XspfReader::handleMetaLinkAttribs(XML_Char const ** atts, XML_Char const * & rel) { rel = NULL; for (int i = 0; atts[i] != NULL; i += 2) { if (!::PORT_STRCMP(atts[0], _PT("rel"))) { // Check URI if (Toolbox::isUri(atts[1])) { rel = atts[1]; // Extra checks if (!Toolbox::isAbsoluteUri(atts[1])) { if (!handleWarning(XSPF_READER_WARNING_KEY_WITH_REL_URI, XSPF_READER_TEXT_ZERO_KEY_WITH_REL_URI(_PT("rel")))) { return false; } } if (!containsVersion(atts[1])) { if (!handleWarning(XSPF_READER_WARNING_KEY_WITHOUT_VERSION, XSPF_READER_TEXT_ZERO_KEY_WITHOUT_VERSION(_PT("rel")))) { return false; } } } else { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_INVALID, XSPF_READER_TEXT_ZERO_WRONG_ATTRIBUTE_TYPE( _PT("rel"), _PT("URI")))) { return false; } } } else if (isXmlBase(atts[i])) { // xml:base XML_Char const * const xmlBase = atts[i + 1]; if (!handleXmlBaseAttribute(xmlBase)) { return false; } } else { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN, atts[0])) { return false; } } } if (rel == NULL) { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_MISSING, XSPF_READER_TEXT_ZERO_ATTRIBUTE_MISSING(_PT("rel")))) { return false; } } return true; } bool XspfReader::handleExtensionAttribs(XML_Char const ** atts, XML_Char const * & application) { application = NULL; for (int i = 0; atts[i] != NULL; i += 2) { if (!::PORT_STRCMP(atts[0], _PT("application"))) { // Check URI if (Toolbox::isUri(atts[1])) { application = atts[1]; } else { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_INVALID, XSPF_READER_TEXT_ZERO_WRONG_ATTRIBUTE_TYPE( _PT("application"), _PT("URI")))) { return false; } } } else if (isXmlBase(atts[i])) { // xml:base XML_Char const * const xmlBase = atts[i + 1]; if (!handleXmlBaseAttribute(xmlBase)) { return false; } } else { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN, atts[0])) { return false; } } } if (application == NULL) { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_MISSING, XSPF_READER_TEXT_ZERO_ATTRIBUTE_MISSING( _PT("application")))) { return false; } } return true; } bool XspfReader::handleNoAttribsExceptXmlBase(XML_Char const ** atts) { // No attributes? for (int i = 0; atts[i] != NULL; i += 2) { if (isXmlBase(atts[i])) { // xml:base XML_Char const * const xmlBase = atts[i + 1]; if (!handleXmlBaseAttribute(xmlBase)) { return false; } } else { if (!handleError(XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN, atts[0])) { return false; } } } return true; // Continue parsing } bool XspfReader::handleError(int code, XML_Char const * text) { int const line = ::XML_GetCurrentLineNumber(this->d->parser); int const column = ::XML_GetCurrentColumnNumber(this->d->parser); XML_Char const * const finalText = (text != NULL) ? text : _PT(""); assert(this->d->callback != NULL); bool const keepParsing = this->d->callback->handleError( line, column, code, finalText); if (!keepParsing) { this->d->errorCode = code; } return keepParsing; } bool XspfReader::handleError(int code, XML_Char const * format, XML_Char const * param) { XML_Char * finalText; if (param != NULL) { size_t const charCount = ::PORT_STRLEN(format) + ::PORT_STRLEN(param) + 1; finalText = new XML_Char[charCount]; ::PORT_SNPRINTF(finalText, charCount, format, param); } else { finalText = const_cast( (format != NULL) ? format : _PT("")); } int const line = ::XML_GetCurrentLineNumber(this->d->parser); int const column = ::XML_GetCurrentColumnNumber(this->d->parser); assert(this->d->callback != NULL); bool const keepParsing = this->d->callback->handleError( line, column, code, finalText); if (param != NULL) { delete [] finalText; } if (!keepParsing) { this->d->errorCode = code; } return keepParsing; } void XspfReader::handleFatalError(int code, XML_Char const * format, XML_Char const * param) { XML_Char * finalText; if (param != NULL) { size_t const charCount = ::PORT_STRLEN(format) + ::PORT_STRLEN(param) + 1; finalText = new XML_Char[charCount]; ::PORT_SNPRINTF(finalText, charCount, format, param); } else { finalText = const_cast( (format != NULL) ? format : _PT("")); } int const line = ::XML_GetCurrentLineNumber(this->d->parser); int const column = ::XML_GetCurrentColumnNumber(this->d->parser); assert(this->d->callback != NULL); this->d->callback->notifyFatalError( line, column, code, finalText); this->d->errorCode = code; if (param != NULL) { delete [] finalText; } } void XspfReader::handleFatalError(int code, XML_Char const * text) { int const line = ::XML_GetCurrentLineNumber(this->d->parser); int const column = ::XML_GetCurrentColumnNumber(this->d->parser); XML_Char const * const finalText = (text != NULL) ? text : _PT(""); assert(this->d->callback != NULL); this->d->callback->notifyFatalError( line, column, code, finalText); this->d->errorCode = code; } bool XspfReader::handleWarning(int code, XML_Char const * text) { int const line = ::XML_GetCurrentLineNumber(this->d->parser); int const column = ::XML_GetCurrentColumnNumber(this->d->parser); XML_Char const * const finalText = (text != NULL) ? text : _PT(""); assert(this->d->callback != NULL); return this->d->callback->handleWarning(line, column, code, finalText); } void XspfReader::clearError() { this->d->errorCode = XSPF_READER_SUCCESS; } /*static*/ void XspfReader::masterStart(void * userData, XML_Char const * fullName, XML_Char const ** atts) { XspfReader * const parser = reinterpret_cast(userData); parser->handleStart(fullName, atts); } /*static*/ void XspfReader::masterEnd(void * userData, XML_Char const * fullName) { XspfReader * const parser = reinterpret_cast(userData); parser->handleEnd(fullName); } /*static*/ void XspfReader::masterCharacters(void * userData, XML_Char const * s, int len) { XspfReader * const parser = reinterpret_cast(userData); parser->handleCharacters(s, len); } /*static*/ void XspfReader::masterEntityDeclaration(void * userData, XML_Char const * entityName, int /*is_parameter_entity*/, XML_Char const * value, int value_length, XML_Char const * /*base*/, XML_Char const * /*systemId*/, XML_Char const * /*publicId*/, XML_Char const * /*notationName*/) { if (value == NULL) { return; } XspfReader * const parser = reinterpret_cast(userData); XML_Char * const zeroTerminatedValue = new XML_Char[value_length + 1]; ::PORT_STRNCPY(zeroTerminatedValue, value, value_length); zeroTerminatedValue[value_length] = _PT('\0'); parser->handleEntityDeclaration(entityName, zeroTerminatedValue); delete[] zeroTerminatedValue; } XspfStack & XspfReader::getElementStack() const { return this->d->elementStack; } XspfStack > & XspfReader::getBaseUriStack() const { return this->d->baseUriStack; } void XspfReader::notifySuccess() const { assert(this->d->callback != NULL); this->d->callback->notifySuccess(); } void XspfReader::skipFromHere() { this->d->skip = true; this->d->skipStopLevel = static_cast( this->d->elementStack.size()); } void XspfReader::limitLengthPerEntityValue(bool enabled) { this->d->limitLengthPerEntityValue = enabled; } void XspfReader::limitLookupSumPerEntityValue(bool enabled) { this->d->limitLookupSumPerEntityValue = enabled; } void XspfReader::limitLookupDepthPerEntityValue(bool enabled) { this->d->limitLookupDepthPerEntityValue = enabled; } void XspfReader::enableMaliciousXmlDetection(bool enabled) { limitLengthPerEntityValue(enabled); limitLookupSumPerEntityValue(enabled); limitLookupDepthPerEntityValue(enabled); } void XspfReader::setMaxLengthPerEntityValue(int maxLength) { this->d->maxLengthPerEntity = maxLength; } void XspfReader::setMaxLookupSumPerEntityValue(int maxLookupSum) { this->d->maxTotalLookupsPerEntity = maxLookupSum; } void XspfReader::setMaxLookupDepthPerEntityValue(int maxLookupDepth) { this->d->maxLookupDepthPerEntity = maxLookupDepth; } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfReader.h000066400000000000000000000550411516712004000263730ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfReader.h * Interface of XspfReader. */ #ifndef XSPF_READER_H #define XSPF_READER_H #include "XspfDefines.h" #include namespace Xspf { /// @cond DOXYGEN_IGNORE // Messages with ONE "%s" in it #define XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN _PT("Attribute '%s' not allowed.") #define XSPF_READER_TEXT_ONE_EXPAT_ERROR _PT("Expat error '%s'") #define XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN _PT("Element '%s' not allowed.") #define XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN_VERSION_ZERO _PT("Element '%s' not allowed in XSPF-0.") #define XSPF_READER_TEXT_ONE_FILE_READING_ERROR _PT("File '%s' could not be read.") #define XSPF_READER_TEXT_ONE_WRONG_ROOT_NAME _PT("Root element must be '") XSPF_NS_HOME XSPF_NS_SEP_STRING _PT("playlist', not '%s'.") #define XSPF_READER_TEXT_ONE_WRONG_VERSION _PT("Version must be '0' or '1', not '%s'.") // Messages with ZERO "%s" in it #define XSPF_READER_TEXT_ZERO_ATTRIBUTE_MISSING(name) _PT("Attribute '") name _PT("' missing.") #define XSPF_READER_TEXT_ZERO_ELEMENT_MISSING(ns, name) _PT("Element '") ns XSPF_NS_SEP_STRING name _PT("' missing.") #define XSPF_READER_TEXT_ZERO_ELEMENT_MISSING_VERSION_ZERO(ns, name) _PT("Element '") ns XSPF_NS_SEP_STRING name _PT("' missing. This is not allowed in XSPF-0.") #define XSPF_READER_TEXT_ZERO_FILENAME_NULL _PT("Filename must not be NULL.") #define XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS(ns, name) _PT("Only one '") ns XSPF_NS_SEP_STRING name _PT("' allowed.") #define XSPF_READER_TEXT_ZERO_WRONG_ATTRIBUTE_TYPE(attr, type) _PT("Attribute '") attr _PT("' is not a valid ") type _PT(".") #define XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE(ns, elem, type) _PT("Content of '") ns XSPF_NS_SEP_STRING elem _PT("' is not a valid ") type _PT(".") #define XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN(ns, elem) _PT("Content of '") ns XSPF_NS_SEP_STRING elem _PT("' must be whitespace or child elements, not text.") #define XSPF_READER_TEXT_ZERO_KEY_WITHOUT_VERSION(name) _PT("Attribute '") name _PT("' does not carry version information.") #define XSPF_READER_TEXT_ZERO_KEY_WITH_REL_URI(name) _PT("Attribute '") name _PT("' does not contain an absolute URI.") /// @endcond /** * Specifies the result of a parse operation. */ enum XspfReaderReturnCode { XSPF_READER_SUCCESS, ///< Everything fine XSPF_READER_ERROR_NO_INPUT, ///< No input given XSPF_READER_ERROR_ELEMENT_TOOMANY, ///< Element occurs more often than allowed XSPF_READER_ERROR_ELEMENT_FORBIDDEN, ///< Element is not allowed at that place XSPF_READER_ERROR_ELEMENT_MISSING, ///< Required element missing XSPF_READER_ERROR_ATTRIBUTE_INVALID, ///< Attribute with invalid value XSPF_READER_ERROR_ATTRIBUTE_MISSING, ///< Required attribute missing XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, ///< Attribute not allowed at that place XSPF_READER_ERROR_CONTENT_INVALID, ///< Element body has invalid format XSPF_READER_ERROR_BASE_URI_USELESS, ///< Given base URI is not a valid absolute URI XSPF_READER_WARNING_KEY_WITHOUT_VERSION, ///< A key attribute holds an unversioned URI XSPF_READER_WARNING_KEY_WITH_REL_URI, ///< A key attribute holds a relative URI XSPF_READER_ERROR_MALICIOUS_SPACE, ///< An entity is taking to much space XSPF_READER_ERROR_MALICIOUS_LOOKUP_SUM, ///< An entity takes to many lookups in sum XSPF_READER_ERROR_MALICIOUS_LOOKUP_DEPTH, //< An entity's lookup depth is too high // Insert new codes HERE! // This one must come last! XSPF_READER_ERROR_EXPAT = 0x1000 /// First Expat error code }; /* playlist 1 title ? creator ? annotation ? info ? location ? identifier ? image ? date ? license ? attribution ? location * identifier * link * meta * extension * ... * trackList 1 track +|* location * identifier * title ? creator ? annotation ? info ? image ? album ? trackNum (uint > 0) ? duration (uint) ? link * meta * extension * */ /** * Specifies the type of tag element. */ enum XspfTag { // Stack returns 0 if empty TAG_UNKNOWN, ///< Unknown type TAG_PLAYLIST, ///< playlist tag TAG_PLAYLIST_TITLE, ///< playlist.title tag TAG_PLAYLIST_CREATOR, ///< playlist.creator tag TAG_PLAYLIST_ANNOTATION, ///< playlist.annotation tag TAG_PLAYLIST_INFO, ///< playlist.info tag TAG_PLAYLIST_LOCATION, ///< playlist.location tag TAG_PLAYLIST_IDENTIFIER, ///< playlist.identifier tag TAG_PLAYLIST_IMAGE, ///< playlist.image tag TAG_PLAYLIST_DATE, ///< playlist.date tag TAG_PLAYLIST_LICENSE, ///< playlist.license tag TAG_PLAYLIST_ATTRIBUTION, ///< playlist.attribution tag TAG_PLAYLIST_ATTRIBUTION_LOCATION, ///< playlist.attribution.location tag TAG_PLAYLIST_ATTRIBUTION_IDENTIFIER, ///< playlist.attribution.identifier tag TAG_PLAYLIST_LINK, ///< playlist.link tag TAG_PLAYLIST_META, ///< playlist.meta tag TAG_PLAYLIST_EXTENSION, ///< playlist.extension tag TAG_PLAYLIST_TRACKLIST, ///< playlist.tracklist tag TAG_PLAYLIST_TRACKLIST_TRACK, ///< playlist.tracklist.track tag TAG_PLAYLIST_TRACKLIST_TRACK_LOCATION, ///< playlist.tracklist.track.location tag TAG_PLAYLIST_TRACKLIST_TRACK_IDENTIFIER, ///< playlist.tracklist.track.identifier tag TAG_PLAYLIST_TRACKLIST_TRACK_TITLE, ///< playlist.tracklist.track.title tag TAG_PLAYLIST_TRACKLIST_TRACK_CREATOR, ///< playlist.tracklist.track.creator tag TAG_PLAYLIST_TRACKLIST_TRACK_ANNOTATION, ///< playlist.tracklist.track.annotation tag TAG_PLAYLIST_TRACKLIST_TRACK_INFO, ///< playlist.tracklist.track.info tag TAG_PLAYLIST_TRACKLIST_TRACK_IMAGE, ///< playlist.tracklist.track.image tag TAG_PLAYLIST_TRACKLIST_TRACK_ALBUM, ///< playlist.tracklist.track.album tag TAG_PLAYLIST_TRACKLIST_TRACK_TRACKNUM, ///< playlist.tracklist.track.tracknum tag TAG_PLAYLIST_TRACKLIST_TRACK_DURATION, ///< playlist.tracklist.track.duration tag TAG_PLAYLIST_TRACKLIST_TRACK_LINK, ///< playlist.tracklist.track.link tag TAG_PLAYLIST_TRACKLIST_TRACK_META, ///< playlist.tracklist.track.meta tag TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION, ///< playlist.tracklist.track.extension tag // Insert XSPF-2 codes HERE! // This one must come last! TAG_USER = 0x1000 ///< First user/extension tag code }; class XspfProps; class XspfDateTime; class XspfTrack; class XspfReaderCallback; template class XspfStack; class XspfChunkCallback; class XspfExtensionReaderFactory; class XspfExtensionReader; class XspfReaderPrivate; /** * Reads a XSPF playlist from a file. */ class XspfReader { private: /// @cond DOXYGEN_NON_API XspfReaderPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new reader. * * @param handlerFactory Factory used to create handlers */ XspfReader(XspfExtensionReaderFactory * handlerFactory = NULL); /** * Copy constructor. * * @param source Source to copy from */ XspfReader(XspfReader const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfReader & operator=(XspfReader const & source); /** * Frees all own memory. */ ~XspfReader(); /** * Reads an XSPF playlist from a file. * * @param filename Filename of the file to read * @param callback Reader callback that will receive the playlist's information. * Passing \c NULL will make the reader use a XspfStrictReaderCallback * instance internally. * @param baseUri Absolute external base URI to resolve URIs against * @return Error/warning code that aborted parsing or \c XSPF_READER_SUCCESS. * @since 1.0.0rc1 */ int parseFile(XML_Char const * filename, XspfReaderCallback * callback, XML_Char const * baseUri); /** * Reads an XSPF playlist from a block of memory. * * @param memory Memory block to parse * @param numBytes Size of memory in bytes * @param callback Reader callback that will receive the playlist's information * Passing \c NULL will make the reader use a XspfStrictReaderCallback * instance internally. * @param baseUri Absolute external base URI to resolve URIs against * @return Error/warning code that aborted parsing or \c XSPF_READER_SUCCESS. * @since 1.0.0rc1 */ int parseMemory(char const * memory, int numBytes, XspfReaderCallback * callback, XML_Char const * baseUri); /** * Reads an XSPF playlist from a chunk callback. * * @param inputCallback Chunk callback, must not be \c NULL * @param dataCallback Reader callback that will receive the playlist's information * Passing \c NULL will make the reader use a XspfStrictReaderCallback * instance internally. * @param baseUri Absolute external base URI to resolve URIs against * @return Error/warning code that aborted parsing or \c XSPF_READER_SUCCESS. * @since 1.0.0rc1 */ int parseChunks(XspfChunkCallback * inputCallback, XspfReaderCallback * dataCallback, XML_Char const * baseUri); /** * Enables/disables the restriction on the length of entity values. * * @experimental * @param enabled Enabled flag * @see setMaxLengthPerEntityValue * @since 1.0.0 */ void limitLengthPerEntityValue(bool enabled); /** * Enables/disables the restriction on the sum of lookups per entity value. * * @experimental * @param enabled Enabled flag * @see setMaxLookupSumPerEntityValue * @since 1.0.0 */ void limitLookupSumPerEntityValue(bool enabled); /** * Enables/disables the restriction on the lookup depth of entity values. * * @experimental * @param enabled Enabled flag * @see setMaxLookupDepthPerEntityValue * @since 1.0.0 */ void limitLookupDepthPerEntityValue(bool enabled); /** * Enables/disables all means of malicious XML detection. * This function is provided for convenience. * * @experimental * @param enabled Enabled flag * @see limitLengthPerEntityValue, setMaxLengthPerEntityValue * @see limitLookupSumPerEntityValue, setMaxLookupSumPerEntityValue * @see limitLookupDepthPerEntityValue, setMaxLookupDepthPerEntityValue * @since 1.0.0 */ void enableMaliciousXmlDetection(bool enabled); /** * Adjusts the limit on the length of entity values. * * @experimental * @param maxLength Inclusive limit to set * @see limitLengthPerEntityValue * @since 1.0.0 */ void setMaxLengthPerEntityValue(int maxLength); /** * Adjusts the limit on the sum of lookups per entity value. * * @experimental * @param maxLookupSum Inclusive limit to set * @see limitLookupSumPerEntityValue * @since 1.0.0 */ void setMaxLookupSumPerEntityValue(int maxLookupSum); /** * Adjusts the limit on the lookup depth of entity values. * * @experimental * @param maxLookupDepth Inclusive limit to set * @see limitLookupDepthPerEntityValue * @since 1.0.0 */ void setMaxLookupDepthPerEntityValue(int maxLookupDepth); private: /** * Make the parser reusable so it can parse another file. */ void makeReusable(); /** * Handles the occurrence of a skippable error. * * @param code Error code * @param text Error description * @return Continue parsing flag */ bool handleError(int code, XML_Char const * text); /** * Handles the occurrence of a skippable error. * * @param code Error code * @param format Error description format string containing %s * @param param Text parameter to insert for %s * @return Continue parsing flag */ bool handleError(int code, XML_Char const * format, XML_Char const * param); /** * Handles the occurrence of a fatal error. * * @param code Error code * @param text Error description */ void handleFatalError(int code, XML_Char const * text); /** * Handles the occurrence of a fatal error. * * @param code Error code * @param format Error description format string containing %s * @param param Text parameter to insert for %s */ void handleFatalError(int code, XML_Char const * format, XML_Char const * param); /** * Handles the occurrence of a warning. * * @param code Warning code * @param text Warning description * @return Continue parsing flag */ bool handleWarning(int code, XML_Char const * text); /** * Sets the error code and text based on information from Expat. * This is needed for all non-XSPF errors, e.g. XML errors. */ void setExpatError(); /** * Halts the parser. */ void stop(); /** * Forwards tag opening handling to the correct handler. * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values */ void handleStart(XML_Char const * fullName, XML_Char const ** atts); /** * Handles tag opening on level one (e.g. playlist). * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values * @return Continue parsing flag */ bool handleStartOne(XML_Char const * fullName, XML_Char const ** atts); /** * Handles tag opening on level two (e.g. playlist.title). * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values * @return Continue parsing flag */ bool handleStartTwo(XML_Char const * fullName, XML_Char const ** atts); /** * Handles tag opening on level three (e.g. playlist.trackList.track). * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values * @return Continue parsing flag */ bool handleStartThree(XML_Char const * fullName, XML_Char const ** atts); /** * Handles tag opening on level four (e.g. playlist.trackList.track.title). * * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values * @return Continue parsing flag */ bool handleStartFour(XML_Char const * fullName, XML_Char const ** atts); /** * Handles element content. * * @param s Text content * @param len Characters allowed to read */ void handleCharacters(XML_Char const * s, int len); /** * Handles entity declarations. * * @param entityName Name of the entity to be declared * @param value Value to be assigned */ void handleEntityDeclaration(XML_Char const * entityName, XML_Char const * value); /** * Forwards tag closing handling to the correct handler. * * @param fullName Full tag name (" ") */ void handleEnd(XML_Char const * fullName); /** * Handles tag closing on level one (e.g. playlist). * * @param fullName Full tag name (" ") * @return Continue parsing flag */ bool handleEndOne(XML_Char const * fullName); /** * Handles tag closing on level two (e.g. playlist.title). * * @param fullName Full tag name (" ") * @return Continue parsing flag */ bool handleEndTwo(XML_Char const * fullName); /** * Handles tag closing on level three (e.g. playlist.trackList.track). * * @param fullName Full tag name (" ") * @return Continue parsing flag */ bool handleEndThree(XML_Char const * fullName); /** * Handles tag closing on level four (e.g. playlist.trackList.track.title). * * @param fullName Full tag name (" ") * @return Continue parsing flag */ bool handleEndFour(XML_Char const * fullName); /** * Checks the attributes of the playlist tag * and extracts the XSPF version from it. * * @param atts Alternating list of attribute keys and values * @return Attributes okay flag */ bool handlePlaylistAttribs(XML_Char const ** atts); /** * Checks the attributes of the meta tag for * both playlist.meta and playlist.trackList.track.meta. * * @param atts Alternating list of attribute keys and values * @param rel Value of the 'rel' attribute or \c NULL * @return Attributes okay flag */ bool handleMetaLinkAttribs(XML_Char const ** atts, XML_Char const * & rel); /** * Checks the attributes of the extension tag for * both playlist.extension and playlist.trackList.track.extension. * * @param atts Alternating list of attribute keys and values * @param application Points to the application URI in case of success * @return Attributes okay flag */ bool handleExtensionAttribs(XML_Char const ** atts, XML_Char const * & application); /** * Checks the attributes of a tag that must not have any attributes. * * @param atts Alternating list of attribute keys and values * @return No attributes flag */ bool handleNoAttribsExceptXmlBase(XML_Char const ** atts); /** * Resets the error status to success. */ void clearError(); /** * Forwards tag opening handling to the correct class instance. * * @param userData Instance pointer * @param fullName Full tag name (" ") * @param atts Alternating list of attribute keys and values */ static void masterStart(void * userData, XML_Char const * fullName, XML_Char const ** atts); /** * Forwards tag closing handling to the correct class instance. * * @param userData Instance pointer * @param fullName Full tag name (" ") */ static void masterEnd(void * userData, XML_Char const * fullName); /** * Forwards element content handling to the correct class instance. * * @param userData Instance pointer * @param s Text content * @param len Characters allowed to read */ static void masterCharacters(void * userData, XML_Char const * s, int len); /** * Forwards entity declaration handling to the correct class instance. * * @param userData Instance pointer * @param entityName Name of the entity to be declared * @param is_parameter_entity TODO * @param value Value to be assigned, not necessarily zero-terminated * @param value_length Length of \p value in characters * @param base TODO * @param systemId TODO * @param publicId TODO * @param notationName TODO */ static void masterEntityDeclaration(void * userData, XML_Char const * entityName, int is_parameter_entity, XML_Char const * value, int value_length, XML_Char const * base, XML_Char const * systemId, XML_Char const * publicId, XML_Char const * notationName); /** * Initializes parsing. * * @param callback Reader callback that will receive the playlist's information * @param baseUri Absolute external base URI to resolve URIs against * @return true to continue init, false to abort */ bool onBeforeParse(XspfReaderCallback * callback, XML_Char const * baseUri); /** * Cleans up behind parsing. */ void onAfterParse(); public: /** * Checks if \p attributeKey is the xml:base attribute * * @param attributeKey Attribute key to check * @return Equality flag */ static bool isXmlBase(XML_Char const * attributeKey); private: /** * Handles an appearing xml:base attribute. * * @param xmlBase Value of xml:base attribute * @return Continue parsing flag */ bool handleXmlBaseAttribute(XML_Char const * xmlBase); /** * Transforms a (possibly relative) URI into an absolute URI * in respect to the current base URI at this point of parsing. * * @param sourceUri URI to transform * @return New'ed absolute URI or \c NULL */ XML_Char * makeAbsoluteUri(XML_Char const * sourceUri) const; /** * Returns the internal element stack. * * @return Element stack */ XspfStack & getElementStack() const; /** * Returns the internal base URI stack. * * @return Base URI stack */ XspfStack > & getBaseUriStack() const; /** * Puts the reader ninto skipping mode. * If this function is called with //playlist.meta * on top of the element stack the reader will skip * everything until //playlist.meta is closed. */ void skipFromHere(); /** * Takes a tag and sets \c localName * to the start of localName. * * @param fullName Full name of the element * @param localName Local name of the element if the * namespace matched xspf, original full name * otherwise * @return Continue parsing flag */ bool checkAndSkipNamespace(XML_Char const * fullName, XML_Char const * & localName); /** * Notifies the reader callback that parsing has * finished successfully. */ void notifySuccess() const; friend class XspfExtensionReader; }; } // namespace Xspf #endif // XSPF_READER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfReaderCallback.cpp000066400000000000000000000055011516712004000303370ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfReaderCallback.cpp * Implementation of XspfReaderCallback. */ #include #include #include namespace Xspf { XspfReaderCallback::XspfReaderCallback() { } XspfReaderCallback::~XspfReaderCallback() { } void XspfReaderCallback::addTrack(XspfTrack * track) { delete track; } void XspfReaderCallback::setProps(XspfProps * props) { delete props; } void XspfReaderCallback::notifyFatalError(int /*line*/, int /*column*/, int /*errorCode*/, XML_Char const * /*description*/) { } bool XspfReaderCallback::handleError(int /*line*/, int /*column*/, int /*errorCode*/, XML_Char const * /*description*/) { return true; // Continue parsing } bool XspfReaderCallback::handleWarning(int /*line*/, int /*column*/, int /*warningCode*/, XML_Char const * /*description*/) { return true; // Continue parsing } void XspfReaderCallback::notifySuccess() { } void XspfReaderCallback::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfReaderCallback.h000066400000000000000000000115341516712004000300070ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfReaderCallback.h * Interface of XspfReaderCallback. */ #ifndef XSPF_READER_CALLBACK_H #define XSPF_READER_CALLBACK_H #include "XspfDefines.h" namespace Xspf { class XspfProps; class XspfTrack; class XspfReader; class XspfReaderCallbackPrivate; /** * Is called by a XspfReader when new pieces of information * become available. */ class XspfReaderCallback { public: /** * Creates a new reader callback. */ XspfReaderCallback(); /** * Destroys this reader callback. */ virtual ~XspfReaderCallback(); protected: /** * Is called when a new, complete track is available. * Deleting track is up to you. * * @param track New track, never NULL */ virtual void addTrack(XspfTrack * track); /** * Is called when all playlist properties are available. * Deleting props is up to you. * * @param props Playlist properties, never NULL */ virtual void setProps(XspfProps * props); /** * Is called when a fatal error occurs. This includes * errors on XML level which cannot be skipped due to the * nature of XML. * * @param line Line of the input containing the error, can be < 1 * @param column Column of the input containing the error, can be < 1 * @param errorCode Code identifying the error * @param description Description of the error * @since 1.0.0.rc3 */ virtual void notifyFatalError(int line, int column, int errorCode, XML_Char const * description); /** * Is called when a XSPF content error occurs. Return \c true to * continue parsing or \c to abort. * Please note that \p line and \p column might not be precise. * * @param line Line of the input containing the error * @param column Column of the input containing the error * @param errorCode Code identifying the error * @param description Description of the error * @return Continue parsing flag * @since 1.0.0rc1 */ virtual bool handleError(int line, int column, int errorCode, XML_Char const * description); /** * Is called when a warning occurs. Return \c true to continue parsing * or \c to abort. Please note that the precision of the \p line and \p * column values in part is the responsibility of Expat. * * @param line Line of the input producing the warning * @param column Column of the input producing the warning * @param warningCode Code identifying the warning * @param description Description of the warning * @return Continue parsing flag * @since 1.0.0rc1 */ virtual bool handleWarning(int line, int column, int warningCode, XML_Char const * description); /** * Notifies this reader callback, that reading this * file has finished successfully. 'Success' here means * that either no errors occured at all or that all errors * have been ignored/skipped. * * @since 1.0.0.rc3 */ virtual void notifySuccess(); /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond friend class XspfReader; }; } // namespace Xspf #endif // XSPF_READER_CALLBACK_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfSeamlessFormatter.cpp000066400000000000000000000067121516712004000311650ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfSeamlessFormatter.cpp * Implementation of XspfSeamlessFormatter. */ #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfSeamlessFormatter. */ class XspfSeamlessFormatterPrivate { friend class XspfSeamlessFormatter; /** * Creates a new D object. */ XspfSeamlessFormatterPrivate() { } /** * Destroys this D object. */ ~XspfSeamlessFormatterPrivate() { } }; /// @endcond XspfSeamlessFormatter::XspfSeamlessFormatter() : XspfXmlFormatter(), d(new XspfSeamlessFormatterPrivate()) { } XspfSeamlessFormatter::XspfSeamlessFormatter(XspfSeamlessFormatter const & source) : XspfXmlFormatter(source), d(new XspfSeamlessFormatterPrivate(*(source.d))) { } XspfSeamlessFormatter & XspfSeamlessFormatter::operator=(XspfSeamlessFormatter const & source) { if (this != &source) { XspfXmlFormatter::operator=(source); *(this->d) = *(source.d); } return *this; } XspfSeamlessFormatter::~XspfSeamlessFormatter() { delete this->d; } void XspfSeamlessFormatter::writeStart(XML_Char const * name, XML_Char const * const * atts) { // XML Header this->writeXmlDeclaration(); // Element *this->getOutput() << _PT('<') << name; while (atts[0] != NULL) { *this->getOutput() << _PT(' ') << atts[0] << _PT("=\"") << atts[1] << _PT("\""); atts += 2; } *this->getOutput() << _PT(">"); } void XspfSeamlessFormatter::writeEnd(XML_Char const * name) { *this->getOutput() << _PT("'); } void XspfSeamlessFormatter::writeBody(XML_Char const * text) { writeCharacterData(text); } void XspfSeamlessFormatter::writeBody(int number) { *this->getOutput() << number; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfSeamlessFormatter.h000066400000000000000000000061251516712004000306300ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfSeamlessFormatter.h * Interface of XspfSeamlessFormatter. */ #ifndef XSPF_SEAMLESS_FORMATTER_H #define XSPF_SEAMLESS_FORMATTER_H #include "XspfXmlFormatter.h" namespace Xspf { class XspfSeamlessFormatterPrivate; /** * Outputs XML without any indentation or newlines. * Please only use this XML formatter if you have to * squeeze out the very last byte. Please consider using * XspfIndentFormatter instead, which produces much * more readable output. */ class XspfSeamlessFormatter : public XspfXmlFormatter { private: /// @cond DOXYGEN_NON_API XspfSeamlessFormatterPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new zero-whitespace formatter. */ XspfSeamlessFormatter(); /** * Copy constructor. * * @param source Source to copy from */ XspfSeamlessFormatter(XspfSeamlessFormatter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfSeamlessFormatter & operator=(XspfSeamlessFormatter const & source); /** * Deletes all own memory. */ ~XspfSeamlessFormatter(); private: void writeStart(XML_Char const * name, XML_Char const * const * atts); void writeEnd(XML_Char const * name); void writeBody(XML_Char const * text); void writeBody(int number); }; } #endif // XSPF_SEAMLESS_FORMATTER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfSkipExtensionReader.cpp000066400000000000000000000100251516712004000314430ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfSkipExtensionReader.cpp * Implementation of XspfSkipExtensionReader. */ #include "XspfSkipExtensionReader.h" #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfSkipExtensionReader. */ class XspfSkipExtensionReaderPrivate { friend class XspfSkipExtensionReader; /** * Creates a new D object. */ XspfSkipExtensionReaderPrivate() { } /** * Destroys this D object. */ ~XspfSkipExtensionReaderPrivate() { } }; /// @endcond XspfSkipExtensionReader::XspfSkipExtensionReader(XspfReader * reader) : XspfExtensionReader(reader), d(new XspfSkipExtensionReaderPrivate()) { } XspfSkipExtensionReader::XspfSkipExtensionReader(XspfSkipExtensionReader const & source) : XspfExtensionReader(source), d(new XspfSkipExtensionReaderPrivate(*(source.d))) { } XspfSkipExtensionReader & XspfSkipExtensionReader::operator=(XspfSkipExtensionReader const & source) { if (this != &source) { XspfExtensionReader::operator=(source); *(this->d) = *(source.d); } return *this; } XspfSkipExtensionReader::~XspfSkipExtensionReader() { delete this->d; } bool XspfSkipExtensionReader::handleExtensionStart( XML_Char const * /*fullName*/, XML_Char const ** /*atts*/) { switch (this->getElementStack().size() + 1) { case 2: // We only get called on this level for playlist.extension // Name and attributes have already been checked. this->getElementStack().push(TAG_PLAYLIST_EXTENSION); return true; case 4: if (this->getElementStack().top() == TAG_PLAYLIST_TRACKLIST_TRACK) { // Name and attributes have already been checked. this->getElementStack().push(TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION); return true; } break; } this->getElementStack().push(TAG_UNKNOWN); return true; } bool XspfSkipExtensionReader::handleExtensionEnd( XML_Char const * /*fullName*/) { this->getElementStack().pop(); return true; } bool XspfSkipExtensionReader::handleExtensionCharacters( XML_Char const * /*s*/, int /*len*/) { return true; } XspfExtension * XspfSkipExtensionReader::wrap() { return NULL; } XspfExtensionReader * XspfSkipExtensionReader::createBrother( XspfReader * reader) const { return new XspfSkipExtensionReader(reader); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfSkipExtensionReader.h000066400000000000000000000061541516712004000311200ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfSkipExtensionReader.h * Interface of XspfSkipExtensionReader. */ #ifndef XSPF_SKIP_EXTENSION_HANDLER_H #define XSPF_SKIP_EXTENSION_HANDLER_H #include namespace Xspf { class XspfSkipExtensionReaderPrivate; /** * Skips the extension body. */ class XspfSkipExtensionReader : public XspfExtensionReader { private: /// @cond DOXYGEN_NON_API XspfSkipExtensionReaderPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new skipping extension reader. */ XspfSkipExtensionReader(XspfReader * reader); /** * Copy constructor. * * @param source Source to copy from */ XspfSkipExtensionReader(XspfSkipExtensionReader const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfSkipExtensionReader & operator=(XspfSkipExtensionReader const & source); /** * Destroys this reader and deletes all memory * associated with it. */ ~XspfSkipExtensionReader(); private: bool handleExtensionStart(XML_Char const * fullName, XML_Char const ** atts); bool handleExtensionEnd(XML_Char const * fullName); bool handleExtensionCharacters(XML_Char const * s, int len); XspfExtension * wrap(); XspfExtensionReader * createBrother(XspfReader * reader) const; }; } // namespace Xspf #endif // XSPF_SKIP_EXTENSION_HANDLER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfStack.h000066400000000000000000000053221516712004000262330ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfStack.h * Interface and implemenatation of XspfStack. */ #ifndef XSPF_STACK_H #define XSPF_STACK_H #include "XspfDefines.h" #include namespace Xspf { /** * A generic stack data structure. */ template class XspfStack : private std::stack { public: /// Holds the height of the stack typedef typename std::stack::size_type size_type; /** * Returns the number of elements on the stack. */ size_type size() const { return std::stack::size(); } /** * Returns the topmost element on the stack. */ T const & top() const { return std::stack::top(); } /** * Pushes @a value on top of the stack. */ void push(T const & value) { std::stack::push(value); } /** * Pops the topmost element off the stack. */ void pop() { std::stack::pop(); } /** * Clears the stack. */ void clear() { std::stack::c.clear(); } }; } #endif // XSPF_STACK_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfStrictReaderCallback.cpp000066400000000000000000000043561516712004000315370ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfStrictReaderCallback.cpp * Implementation of XspfStrictReaderCallback. */ #include "XspfStrictReaderCallback.h" namespace Xspf { XspfStrictReaderCallback::XspfStrictReaderCallback() { } XspfStrictReaderCallback::~XspfStrictReaderCallback() { } bool XspfStrictReaderCallback::handleError(int /*line*/, int /*column*/, int /*errorCode*/, XML_Char const * /*description*/) { return false; // Stop parsing } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfStrictReaderCallback.h000066400000000000000000000047351516712004000312050ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfStrictReaderCallback.h * Interface of XspfStrictReaderCallback. */ #ifndef XSPF_STRICT_READER_CALLBACK_H #define XSPF_STRICT_READER_CALLBACK_H #include namespace Xspf { /** * Provides an error-rejecting Null Object reader callback. */ class XspfStrictReaderCallback : public XspfReaderCallback { public: /** * Creates a new strict reader callback. */ XspfStrictReaderCallback(); /** * Destroys this strict reader callback. */ virtual ~XspfStrictReaderCallback(); protected: bool handleError(int line, int column, int errorCode, XML_Char const * description); }; } // namespace Xspf #endif // XSPF_STRICT_READER_CALLBACK_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfToolbox.cpp000066400000000000000000000240251516712004000271500ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfToolbox.cpp * Implementation of Xspf::Toolbox. */ #include #include #include namespace Xspf { namespace Toolbox { /// @cond DOXYGEN_NON_API bool XspfStringCompare::operator()(XML_Char const * s1, XML_Char const * s2) const { // Same address implies same content // and saves the string comparison if (s1 == s2) { return false; } else { return ::PORT_STRCMP(s1, s2) < 0; } } /// @endcond XML_Char * newAndCopy(XML_Char const * source) { if (source == NULL) { return NULL; } XML_Char * dup = new XML_Char[static_cast(PORT_STRLEN(source)) + 1]; PORT_STRCPY(dup, source); return dup; } void deleteNewAndCopy(XML_Char ** dest, XML_Char const * src) { if (dest == NULL) { return; } if (*dest != NULL) { delete [] *dest; } if (src == NULL) { *dest = NULL; } else { int const srcLen = static_cast(::PORT_STRLEN(src)); if (srcLen > 0) { *dest = new XML_Char[static_cast(srcLen) + 1]; PORT_STRCPY(*dest, src); } else { *dest = NULL; } } } void deleteNewAndCopy(XML_Char const * & dest, bool & destOwnership, XML_Char const * source, bool sourceCopy) { // Delete old memory if owner if (destOwnership && (dest != NULL)) { delete [] dest; } if (source == NULL) { dest = NULL; destOwnership = false; } else { // Copy new memory if desired if (sourceCopy) { int const sourceLen = static_cast(::PORT_STRLEN(source)); if (sourceLen > 0) { XML_Char * const tempDest = new XML_Char[static_cast(sourceLen) + 1]; PORT_STRCPY(tempDest, source); dest = tempDest; destOwnership = true; } else { dest = NULL; destOwnership = false; } } else { dest = source; destOwnership = false; } } } void copyIfOwned(XML_Char const * & dest, bool & ownDest, XML_Char const * source, bool ownSource) { if (source != NULL) { // Memory owned? if (ownSource) { // Deep copy, both own their own copy dest = newAndCopy(source); } else { // Shallow copy, both lend the same memory dest = source; } ownDest = ownSource; } else { dest = NULL; } } void freeIfOwned(XML_Char const * & dest, bool ownDest) { if (ownDest && (dest != NULL)) { delete [] dest; } // dest = NULL; } #ifndef XSPF_DOXYGEN #ifdef UNICODE # define UriParserState UriParserStateW # define UriUri UriUriW # define uriFreeUriMembers uriFreeUriMembersW # define uriParseUri uriParseUriW # define uriAddBaseUri uriAddBaseUriW # define uriToStringCharsRequired uriToStringCharsRequiredW # define uriToString uriToStringW # define uriRemoveBaseUri uriRemoveBaseUriW #else // ifdef UNICODE # define UriParserState UriParserStateA # define UriUri UriUriA # define uriFreeUriMembers uriFreeUriMembersA # define uriParseUri uriParseUriA # define uriAddBaseUri uriAddBaseUriA # define uriToStringCharsRequired uriToStringCharsRequiredA # define uriToString uriToStringA # define uriRemoveBaseUri uriRemoveBaseUriA #endif // ifdef UNICODE #endif // ifndef XSPF_DOXYGEN namespace { /** * Returns a string representation of the given URI * allocated with new[]. You are resposible to delete * this string when it's not needed anymore. * * @param uri URI to make string from * @return Newly-allocated URI string */ XML_Char * makeUriString(UriUri const & uri) { XML_Char * uriString; int charsRequired; if (uriToStringCharsRequired(&uri, &charsRequired) != URI_SUCCESS) { return NULL; } charsRequired++; uriString = new XML_Char[charsRequired]; if (uriToString(uriString, &uri, charsRequired, NULL) != URI_SUCCESS) { delete [] uriString; return NULL; } return uriString; } /** * Either resolves (addOrRemoveBase == true) or reduces * (addOrRemoveBase == false) a source URI against a base * URI. The resulting string has been allocated through new[] * and must be deleted manually after. * * @param sourceUri Source URI to transform * @param baseUri Base URI to work against * @param addOrRemoveBase Mode switch, see above * @return NULL or a newly-allocated string */ XML_Char * allocTransformUri(XML_Char const * sourceUri, XML_Char const * baseUri, bool addOrRemoveBase) { UriParserState state; UriUri absoluteDest; UriUri relativeSource; UriUri absoluteBase; state.uri = &relativeSource; if (uriParseUri(&state, sourceUri) != URI_SUCCESS) { uriFreeUriMembers(&relativeSource); return NULL; } state.uri = &absoluteBase; if (uriParseUri(&state, baseUri) != URI_SUCCESS) { uriFreeUriMembers(&relativeSource); uriFreeUriMembers(&absoluteBase); return NULL; } int res; if (addOrRemoveBase) { res = uriAddBaseUri(&absoluteDest, &relativeSource, &absoluteBase); } else { res = uriRemoveBaseUri(&absoluteDest, &relativeSource, &absoluteBase, URI_FALSE); } if (res != URI_SUCCESS) { uriFreeUriMembers(&relativeSource); uriFreeUriMembers(&absoluteBase); return NULL; } XML_Char * const uriString = makeUriString(absoluteDest); uriFreeUriMembers(&relativeSource); uriFreeUriMembers(&absoluteBase); uriFreeUriMembers(&absoluteDest); return uriString; } } // anon namespace XML_Char * makeAbsoluteUri(XML_Char const * sourceUri, XML_Char const * baseUri) { bool const ADD_BASE = true; return allocTransformUri(sourceUri, baseUri, ADD_BASE); } XML_Char * makeRelativeUri(XML_Char const * sourceUri, XML_Char const * baseUri) { bool const REMOVE_BASE = false; return allocTransformUri(sourceUri, baseUri, REMOVE_BASE); } bool isUri(XML_Char const * text) { #ifdef UNICODE UriParserStateW stateW; UriUriW uriW; stateW.uri = &uriW; int const res = uriParseUriW(&stateW, text); uriFreeUriMembersW(&uriW); #else UriParserStateA stateA; UriUriA uriA; stateA.uri = &uriA; int const res = uriParseUriA(&stateA, text); uriFreeUriMembersA(&uriA); #endif return (res == 0); } bool isAbsoluteUri(XML_Char const * text) { #ifdef UNICODE UriParserStateW stateW; UriUriW uriW; stateW.uri = &uriW; int const res = uriParseUriW(&stateW, text); bool const validAndAbsolute = (res == 0) && (uriW.scheme.first != NULL); uriFreeUriMembersW(&uriW); #else UriParserStateA stateA; UriUriA uriA; stateA.uri = &uriA; int const res = uriParseUriA(&stateA, text); bool const validAndAbsolute = (res == 0) && (uriA.scheme.first != NULL); uriFreeUriMembersA(&uriA); #endif return validAndAbsolute; } bool extractInteger(XML_Char const * text, int inclusiveMinimum, int * output) { int & number = *output; number = ::PORT_ATOI(text); if ((number < inclusiveMinimum) || ((number == 0) && ::PORT_STRCMP(text, _PT("0")))) { return false; } else { return true; } } bool isWhiteSpace(XML_Char const * text, int numChars) { if ((text == NULL) || (numChars < 1)) { return true; } XML_Char const * walk = text; do { switch (*walk) { case _PT('\0'): return true; case _PT(' '): case _PT('\t'): case _PT('\x0a'): case _PT('\x0d'): walk++; break; default: return false; } } while (walk - text < numChars); return true; } void cutOffWhiteSpace(XML_Char const * input, int inputNumChars, XML_Char const * & blackSpaceStart, int & blackSpaceNumChars) { if ((input == NULL) || (inputNumChars < 1)) { blackSpaceStart = NULL; blackSpaceNumChars = 0; return; } XML_Char const * walk = input; XML_Char const * firstBlackChar = NULL; XML_Char const * lastBlackChar = NULL; do { switch (*walk) { case _PT(' '): case _PT('\t'): case _PT('\x0a'): case _PT('\x0d'): break; default: if (firstBlackChar == NULL) { firstBlackChar = walk; } lastBlackChar = walk; break; } walk++; } while (walk - input < inputNumChars); if (firstBlackChar == NULL) { // No black space blackSpaceStart = walk; // Right after the string blackSpaceNumChars = 0; } else { // Black space found blackSpaceStart = firstBlackChar; blackSpaceNumChars = static_cast(lastBlackChar - firstBlackChar) + 1; } } void trimString(std::basic_string & target) { XML_Char const * const data = target.data(); int const len = static_cast(target.length()); XML_Char const * blackSpaceStart = NULL; int blackSpaceNumChars = 0; cutOffWhiteSpace(data, len, blackSpaceStart, blackSpaceNumChars); if (blackSpaceStart == NULL) { target.clear(); } else { target = std::basic_string(target, blackSpaceStart - data, blackSpaceNumChars); } } } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfToolbox.h000066400000000000000000000166111516712004000266170ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfToolbox.h * Interface of Xspf::Toolbox. */ #ifndef XSPF_TOOLBOX_H #define XSPF_TOOLBOX_H #include "XspfDefines.h" #include #include namespace Xspf { class XspfDateTime; /** * Provides common helper functions. */ namespace Toolbox { /// @cond DOXYGEN_NON_API /** * Compares the content of two strings. * Used with STL containers. */ struct XspfStringCompare { /** * Returns true if string s1 is lower than * s2, false otherwise. * * @return s1 < s2 */ bool operator()(XML_Char const * s1, XML_Char const * s2) const; }; /// @endcond /** * Duplicates the string (using new() not malloc()) * and returns the duplicate. If source * is NULL the return value also is NULL. * * @param source Source text * @return Duplacated text or NULL */ XML_Char * newAndCopy(XML_Char const * source); /** * Replaces the string in *dest by a duplicate of the string in src * (using new() not malloc()). The old string is deleted. * * @param dest Destination text * @param src Source text */ void deleteNewAndCopy(XML_Char ** dest, XML_Char const * src); /** * Replaces the string in dest by a duplicate of the string in src * (using new() not malloc()). The old string is deleted. If destOwnership * is false the old string is not deleted. If sourceCopy is false only * source's pointer is copied, not the string. * * @param dest Destination text * @param destOwnership Destination ownership flag * @param source Source text * @param sourceCopy Source copy flag */ void deleteNewAndCopy(XML_Char const * & dest, bool & destOwnership, XML_Char const * source, bool sourceCopy); /** * Sets a pointer to NULL and returns the * original value. This helper is used for stealing * memory. * * @param dest Destination * @return Old value */ template T const * getSetNull(T const * & dest) { T const * backup = dest; dest = NULL; return backup; } /** * Copies a string's content if owned or just it's address if not. * * @param dest Reference of destination string * @param ownDest Reference of destination owner flag * @param source Source string * @param ownSource Source owner flag */ void copyIfOwned(XML_Char const * & dest, bool & ownDest, XML_Char const * source, bool ownSource); /** * Deletes the text behind dest if owned * and non-NULL. * NOTE: dest is not set to NULL after * * @param dest Reference of string to delete * @param ownDest Owner flag, false will prevent deletion */ void freeIfOwned(XML_Char const * & dest, bool ownDest); /** * Resolves a URI reference against a given base URI. If the given URI already * is absolute the result will be that URI again. You can think of this function * as "make my URI absolute if it isn't already". * Please note you are responbsible to run delete [] on the return value. * * @param sourceUri Relative URI to resolve * @param baseUri Absolute base URI to resolve against * @return NULL or an absolute URI allocated with new[]. * @since 1.0.0rc1 */ XML_Char * makeAbsoluteUri(XML_Char const * sourceUri, XML_Char const * baseUri); /** * Reduces a given absolute URI to a relative URI reference if possible. * If there is no commonality between sourceUri and baseUri * the resulting URI will still be absolute. You can think of this function * as "make my URI relative if possible". * Please note you are responbsible to run delete [] on the return value. * * @param sourceUri Absolute URI to reduce * @param baseUri Absolute base URI to reduce against * @return NULL or an URI allocated with new[]. * @since 1.0.0rc1 */ XML_Char * makeRelativeUri(XML_Char const * sourceUri, XML_Char const * baseUri); /** * Checks wether text is a valid URI. * * @param text Text * @return Valid URI flag * @since 1.0.0rc1 */ bool isUri(XML_Char const * text); /** * Checks wether text is a valid absolute URI. * * @param text Text * @return Valid absolute URI flag * @since 1.0.0rc1 */ bool isAbsoluteUri(XML_Char const * text); /** * Extracts an integer from text. * * @param text Text * @param inclusiveMinimum Inclusive minimum * @param output Integer storage destination * @return Valid integer less or equal inclusiveMinimum flag * @since 1.0.0rc1 */ bool extractInteger(XML_Char const * text, int inclusiveMinimum, int * output); /** * Checks a string for being all whitespace. * Whitespace is: ' ', '\\r', '\\n', '\\t' as defined here: * http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace * * @param text Text to check * @param numChars Length of text in characters * @return All-whitespace flag * @since 1.0.0rc1 */ bool isWhiteSpace(XML_Char const * text, int numChars); /** * Cuts off whitespace at head and tail. The source string * is not modified so this more is a detection function. * * @param input Source text * @param inputNumChars Length of source in characters * @param blackSpaceStart Pointer to first non-white character * @param blackSpaceNumChars Length of characters until whitespace tail * @since 1.0.0rc1 */ void cutOffWhiteSpace(XML_Char const * input, int inputNumChars, XML_Char const * & blackSpaceStart, int & blackSpaceNumChars); /** * Cuts off whitespace at head and tail. * * @param target String object to modify * @since 1.0.0rc1 */ void trimString(std::basic_string & target); } // namespace Toolbox } // namespace Xspf #endif // XSPF_TOOLBOX_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfTrack.cpp000066400000000000000000000213161516712004000265660ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfTrack.cpp * Implementation of XspfTrack. */ #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfTrack. */ class XspfTrackPrivate { friend class XspfTrack; XML_Char const * album; ///< Album bool ownAlbum; ///< Album memory ownership flag std::deque *> * locations; ///< List of URI locations std::deque *> * identifiers; ///< List of URI identifiers int trackNum; ///< Number of the track, must be positive int duration; ///< Duration in milliseconds, must be non-negative /** * Creates a new D object. */ XspfTrackPrivate() : album(NULL), ownAlbum(false), locations(NULL), identifiers(NULL), trackNum(-1), duration(-1) { } /** * Copy constructor. * * @param source Source to copy from */ XspfTrackPrivate(XspfTrackPrivate const & source) : album(source.ownAlbum ? Toolbox::newAndCopy(source.album) : source.album), ownAlbum(source.ownAlbum), locations(NULL), // Created in copyDeque identifiers(NULL), // Created in copyDeque trackNum(source.trackNum), duration(source.duration) { if (source.locations != NULL) { copyDeque(this->locations, source.locations); } if (source.identifiers != NULL) { copyDeque(this->identifiers, source.identifiers); } } /** * Assignment operator. * * @param source Source to copy from */ XspfTrackPrivate & operator=(XspfTrackPrivate const & source) { if (this != &source) { free(); assign(source); } return *this; } /** * Destroys this D object. */ ~XspfTrackPrivate() { free(); } void free() { Toolbox::freeIfOwned(this->album, this->ownAlbum); if (this->locations != NULL) { freeDeque(this->locations); } if (this->identifiers != NULL) { freeDeque(this->identifiers); } } void assign(XspfTrackPrivate const & source) { Toolbox::copyIfOwned(this->album, this->ownAlbum, source.album, source.ownAlbum); if (source.locations != NULL) { copyDeque(this->locations, source.locations); } if (source.identifiers != NULL) { copyDeque(this->identifiers, source.identifiers); } this->trackNum = source.trackNum; this->duration = source.duration; } static void freeDeque(std::deque< std::pair *> * & container) { std::deque *>::const_iterator iter = container->begin(); while (iter != container->end()) { std::pair * const entry = *iter; if (entry->second) { delete [] entry->first; } delete entry; iter++; } container->clear(); delete container; container = NULL; } static void copyDeque(std::deque< std::pair *> * & dest, const std::deque< std::pair *> * source) { std::deque *>::const_iterator iter = source->begin(); while (iter != source->end()) { std::pair * const entry = *iter; bool const ownership = entry->second; XML_Char const * const value = ownership ? Toolbox::newAndCopy(entry->first) : entry->first; XspfTrack::appendHelper(dest, value, ownership); iter++; } } }; /// @endcond XspfTrack::XspfTrack() : XspfData(), d(new XspfTrackPrivate()) { } XspfTrack::XspfTrack(XspfTrack const & source) : XspfData(source), d(new XspfTrackPrivate(*(source.d))) { } XspfTrack & XspfTrack::operator=(XspfTrack const & source) { if (this != &source) { XspfData::operator=(source); *(this->d) = *(source.d); } return *this; } XspfTrack::~XspfTrack() { delete this->d; } void XspfTrack::giveAlbum(XML_Char const * album, bool copy) { Toolbox::deleteNewAndCopy(this->d->album, this->d->ownAlbum, album, copy); } void XspfTrack::lendAlbum(XML_Char const * album) { Toolbox::deleteNewAndCopy(this->d->album, this->d->ownAlbum, album, false); } void XspfTrack::setTrackNum(int trackNum) { this->d->trackNum = trackNum; } void XspfTrack::setDuration(int duration) { this->d->duration = duration; } int XspfTrack::getTrackNum() const { return this->d->trackNum; } int XspfTrack::getDuration() const { return this->d->duration; } XML_Char * XspfTrack::stealAlbum() { return XspfData::stealHelper(this->d->album, this->d->ownAlbum); } XML_Char const * XspfTrack::getAlbum() const { return this->d->album; } void XspfTrack::giveAppendIdentifier(XML_Char const * identifier, bool copy) { appendHelper(this->d->identifiers, copy ? Toolbox::newAndCopy(identifier) : identifier, true); } void XspfTrack::giveAppendLocation(XML_Char const * location, bool copy) { appendHelper(this->d->locations, copy ? Toolbox::newAndCopy(location) : location, true); } void XspfTrack::lendAppendIdentifier(XML_Char const * identifier) { appendHelper(this->d->identifiers, identifier, false); } void XspfTrack::lendAppendLocation(XML_Char const * location) { appendHelper(this->d->locations, location, false); } XML_Char * XspfTrack::stealFirstIdentifier() { return stealFirstHelper(this->d->identifiers); } XML_Char * XspfTrack::stealFirstLocation() { return stealFirstHelper(this->d->locations); } XML_Char const * XspfTrack::getIdentifier(int index) const { return getHelper(this->d->identifiers, index); } XML_Char const * XspfTrack::getLocation(int index) const { return getHelper(this->d->locations, index); } int XspfTrack::getIdentifierCount() const { return (this->d->identifiers == NULL) ? 0 : static_cast(this->d->identifiers->size()); } int XspfTrack::getLocationCount() const { return (this->d->locations == NULL) ? 0 : static_cast(this->d->locations->size()); } /*static*/ void XspfTrack::appendHelper( std::deque *> * & container, XML_Char const * value, bool ownership) { if (container == NULL) { container = new std::deque *>; } std::pair * const entry = new std::pair(value, ownership); container->push_back(entry); } /*static*/ XML_Char * XspfTrack::stealFirstHelper( std::deque *> * & container) { if ((container == NULL) || container->empty()) { return NULL; } std::pair * const entry = container->front(); container->pop_front(); XML_Char * const res = entry->second ? const_cast(entry->first) : Toolbox::newAndCopy(entry->first); delete entry; return res; } /*static*/ XML_Char const * XspfTrack::getHelper( std::deque *> * & container, int index) { if ((container == NULL) || container->empty() || (index < 0) || (index >= static_cast(container->size()))) { return NULL; } std::pair * const entry = container->at(index); // NOTE: getX() just peeps at data so don't clone anything return entry->first; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfTrack.h000066400000000000000000000152061516712004000262340ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfTrack.h * Interface of XspfTrack. */ #ifndef XSPF_TRACK_H #define XSPF_TRACK_H #include "XspfData.h" namespace Xspf { class XspfTrackPrivate; /** * Represents an XSPF track without extensions. */ class XspfTrack : public XspfData { friend class XspfTrackPrivate; private: /// @cond DOXYGEN_NON_API XspfTrackPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new, blank track. */ XspfTrack(); /** * Copy constructor. * * @param source Source to copy from */ XspfTrack(XspfTrack const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfTrack & operator=(XspfTrack const & source); /** * Deletes all memory that has not been stolen before. */ ~XspfTrack(); /** * Overwrites the album property. If copy is true * the string will be copied, otherwise just assigned. * In both cases the associated memory will be deleted on * object destruction. * * @param album Album string to set * @param copy Copy flag */ void giveAlbum(XML_Char const * album, bool copy); /** * Appends an identifier to the identifier list. * * @param identifier Identifier to append * @param copy Copy flag */ void giveAppendIdentifier(XML_Char const * identifier, bool copy); /** * Appends an location to the location list. * * @param location Location to append * @param copy Copy flag */ void giveAppendLocation(XML_Char const * location, bool copy); /** * Overwrites the album property. The string is * only assigned not copied. The ownership is * not transferred. * * @param album Album string to set */ void lendAlbum(XML_Char const * album); /** * Appends an location to the location list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param location Location to append */ void lendAppendLocation(XML_Char const * location); /** * Appends an identifier to the identifier list. * The associated memory is neither copied nor * deleted on onject destruction. * * @param identifier Identifier to append */ void lendAppendIdentifier(XML_Char const * identifier); /** * Overwrites the track number property. * * @param trackNum Track number to set */ void setTrackNum(int trackNum); /** * Overwrites the duration property. * Durations are in milliseconds. * * @param duration Duration to set */ void setDuration(int duration); /** * Steals the album property. * * @return Album, can be NULL */ XML_Char * stealAlbum(); /** * Steals the first identifier from the list. * If the list is empty NULL is returned. * * @return First identifier, can be NULL */ XML_Char * stealFirstIdentifier(); /** * Steals the first location from the list. * If the list is empty NULL is returned. * * @return First location, can be NULL */ XML_Char * stealFirstLocation(); /** * Returns the album property. * * @return Album, can be NULL */ XML_Char const * getAlbum() const; /** * Gets a specific identifier from the list. * If the list is empty NULL is returned. * * @return Specified identifier, can be NULL */ XML_Char const * getIdentifier(int index) const; /** * Gets a specific location from the list. * If the list is empty NULL is returned. * * @return Specified location, can be NULL */ XML_Char const * getLocation(int index) const; /** * Returns the number of identifiers. * * @return Number of identifiers */ int getIdentifierCount() const; /** * Returns the number of locations. * * @return Number of locations */ int getLocationCount() const; /** * Returns the duration property. * Durations are measured in milliseconds. * * @return Duration, zero-based, -1 if unknown */ int getDuration() const; /** * Returns the track number property. * * @return Track number, one-based, -1 if unknown */ int getTrackNum() const; private: /** * Appends an entry to a container. * * @param container Container to work with * @param value Value to append * @param ownership Ownership flag */ static void appendHelper(std::deque *> * & container, XML_Char const * value, bool ownership); /** * Steals the first entry from a container. * * @param container Container to steal from * @return First entry, can be NULL */ static XML_Char * stealFirstHelper(std::deque *> * & container); /** * Returns a specific entry from a container * or NULL if the entry does not exist. * * @param container Container to work with * @param index Index of the entry to return * @return Entry content, can be NULL */ static XML_Char const * getHelper(std::deque *> * & container, int index); }; } #endif // XSPF_TRACK_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfTrackWriter.cpp000066400000000000000000000120511516712004000277570ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfTrackWriter.cpp * Implementation of XspfTrackWriter. */ #include "XspfTrackWriter.h" #include #include #include #include #include namespace Xspf { /// @cond DOXYGEN_NON_API /** * D object for XspfTrackWriter. */ class XspfTrackWriterPrivate { friend class XspfTrackWriter; private: XspfTrack const * track; ///< Track to write int version; ///< XSPF version to produce /** * Creates a new D object. */ XspfTrackWriterPrivate() : track(NULL) { } /** * Destroys this D object. */ ~XspfTrackWriterPrivate() { } }; /// @endcond XspfTrackWriter::XspfTrackWriter() : XspfDataWriter(), d(new XspfTrackWriterPrivate()) { } XspfTrackWriter::XspfTrackWriter(XspfTrackWriter const & source) : XspfDataWriter(source), d(new XspfTrackWriterPrivate(*(source.d))) { } XspfTrackWriter & XspfTrackWriter::operator=(XspfTrackWriter const & source) { if (this != &source) { XspfDataWriter::operator=(source); *(this->d) = *(source.d); } return *this; } XspfTrackWriter::~XspfTrackWriter() { delete this->d; } void XspfTrackWriter::setTrack(XspfTrack const * track) { setData(track); this->d->track = track; } void XspfTrackWriter::init(XspfXmlFormatter & output, int version, XML_Char const * baseUri) { this->getOutput() = &output; this->d->version = version; setBaseUri(baseUri); } void XspfTrackWriter::write() { writeTrackOpen(); writeLocations(); writeIdentifiers(); writeTitle(); writeCreator(); writeAnnotation(); writeInfo(); writeImage(); writeAlbum(); writeTrackNum(); writeDuration(); writeLinks(); writeMetas(); if (this->d->version > 0) { writeExtensions(); } writeTrackClose(); } void XspfTrackWriter::writeAlbum() { assert(this->d->track != NULL); XML_Char const * const album = this->d->track->getAlbum(); if (album != NULL) { writePrimitive(_PT("album"), album); } } void XspfTrackWriter::writeDuration() { assert(this->d->track != NULL); int const duration = this->d->track->getDuration(); if (duration != -1) { writePrimitive(_PT("duration"), duration); } } void XspfTrackWriter::writeTrackNum() { assert(this->d->track != NULL); int const trackNum = this->d->track->getTrackNum(); if (trackNum != -1) { writePrimitive(_PT("trackNum"), trackNum); } } void XspfTrackWriter::writeLocations() { assert(this->d->track != NULL); int index = 0; XML_Char const * location; for (;;) { location = this->d->track->getLocation(index++); if (location == NULL) { return; } XML_Char * const relUri = makeRelativeUri(location); writePrimitive(_PT("location"), relUri); delete [] relUri; } } void XspfTrackWriter::writeIdentifiers() { assert(this->d->track != NULL); int index = 0; XML_Char const * identifier; for (;;) { identifier = this->d->track->getIdentifier(index++); if (identifier == NULL) { return; } XML_Char * const relUri = makeRelativeUri(identifier); writePrimitive(_PT("identifier"), relUri); delete [] relUri; } } void XspfTrackWriter::writeTrackClose() { this->getOutput()->writeHomeEnd(_PT("track")); } void XspfTrackWriter::writeTrackOpen() { XML_Char const * atts[1] = {NULL}; this->getOutput()->writeHomeStart(_PT("track"), atts); } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfTrackWriter.h000066400000000000000000000072351516712004000274340ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfTrackWriter.h * Interface of XspfTrackWriter. */ #ifndef XSPF_TRACK_WRITER_H #define XSPF_TRACK_WRITER_H #include "XspfDataWriter.h" namespace Xspf { class XspfXmlFormatter; class XspfTrack; class XspfWriter; class XspfTrackWriterPrivate; /** * Writes a track to an XML formatter. */ class XspfTrackWriter : public XspfDataWriter { private: /// @cond DOXYGEN_NON_API XspfTrackWriterPrivate * const d; ///< D pointer /// @endcond public: /** * Creates a new track writer. */ XspfTrackWriter(); /** * Copy constructor. * * @param source Source to copy from */ XspfTrackWriter(XspfTrackWriter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfTrackWriter & operator=(XspfTrackWriter const & source); /** * Destroys this track writer. */ ~XspfTrackWriter(); /** * Sets the track to write. * * @param track Track to write */ void setTrack(XspfTrack const * track); protected: /** * Initializes the track writer. * Must be called before writing. * * @param output Output formatter to write to * @param version XSPF version to produce * @param baseUri Absolute base URI to reduce against. */ void init(XspfXmlFormatter & output, int version, XML_Char const * baseUri); /** * Writes this track to the formatter. */ void write(); /** * Writes the album property. */ void writeAlbum(); /** * Writes the duration property. */ void writeDuration(); /** * Writes the list of identifiers. */ void writeIdentifiers(); /** * Writes the list of locations. */ void writeLocations(); /** * Writes the closing track tag. */ void writeTrackClose(); /** * Writes the opening track tag. */ void writeTrackOpen(); /** * Writes the trackNum property. */ void writeTrackNum(); friend class XspfWriter; }; } #endif // XSPF_TRACK_WRITER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfVersion.h000066400000000000000000000044751516712004000266230ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfVersion.h * Holds libxspf version constants. */ #ifndef XSPF_VERSION_H #define XSPF_VERSION_H // Version constants #define XSPF_VER_MAJOR 1 ///< Major version number #define XSPF_VER_MINOR 2 ///< Minor version number #define XSPF_VER_RELEASE 0 ///< Release version number #define XSPF_VER_SUFFIX_ASCII "" ///< ASCII Version suffix string (e.g. "rc1") #define XSPF_VER_SUFFIX _PT(XSPF_VER_SUFFIX_ASCII) ///< Version suffix string (e.g. "rc1") #endif // XSPF_VERSION_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfWriter.cpp000066400000000000000000000221331516712004000267740ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfWriter.cpp * Implementation of XspfWriter. */ #include #include "XspfPropsWriter.h" #include "XspfTrackWriter.h" #include #include #include #include #include namespace Xspf { /*static*/ bool const XspfWriter::EMBED_AS_XML_BASE = true; /*static*/ bool const XspfWriter::NO_XML_BASE = false; /// @cond DOXYGEN_NON_API /** * D object for XspfWriter. */ class XspfWriterPrivate { friend class XspfWriter; XspfXmlFormatter * formatter; ///< Output formatter in use XspfPropsWriter propsWriter; ///< Related playlist properties std::basic_ostringstream * accum; ///< Output text accumulator bool trackListEmpty; ///< Tracklist empty flag bool headerWritten; ///< playlist and trackList tag opened flag bool footerWritten; ///< trackList and trackList tag closed flag int version; ///< XSPF version to use XML_Char * baseUri; ///< Base URI to reduce URIs against /** * Creates a new D object. */ XspfWriterPrivate(XspfXmlFormatter & formatter, XML_Char const * baseUri) : formatter(&formatter), propsWriter(), accum(new std::basic_ostringstream()), trackListEmpty(true), headerWritten(false), footerWritten(false), version(-1), baseUri(Toolbox::newAndCopy(baseUri)) { } /** * Copy constructor. * * @param source Source to copy from */ XspfWriterPrivate(XspfWriterPrivate const & source) : formatter(source.formatter), propsWriter(source.propsWriter), accum(new std::basic_ostringstream()), trackListEmpty(source.trackListEmpty), headerWritten(source.headerWritten), footerWritten(source.footerWritten), version(source.version), baseUri(Toolbox::newAndCopy(source.baseUri)) { this->accum->str(source.accum->str()); } /** * Assignment operator. * * @param source Source to copy from */ XspfWriterPrivate & operator=(XspfWriterPrivate const & source) { if (this != &source) { this->formatter = source.formatter; this->propsWriter = source.propsWriter; this->accum->str(source.accum->str()); this->trackListEmpty = source.trackListEmpty; this->headerWritten = source.headerWritten; this->footerWritten = source.footerWritten; this->version = source.version; Toolbox::deleteNewAndCopy(&this->baseUri, source.baseUri); } return *this; } /** * Destroys this D object. */ ~XspfWriterPrivate() { delete this->accum; delete [] this->baseUri; } }; /// @endcond XspfWriter::XspfWriter(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase) : d(new XspfWriterPrivate(formatter, baseUri)) { // Init formatter formatter.setOutput(*(this->d->accum)); this->d->propsWriter.init(*(this->d->formatter), baseUri, embedBase); } /*static*/ XspfWriter * XspfWriter::makeWriter(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase, int * errorCode) { // Check base URI if ((baseUri != NULL) && !Toolbox::isAbsoluteUri(baseUri)) { if (errorCode != NULL) { *errorCode = XSPF_WRITER_ERROR_BASE_URI_USELESS; } return NULL; } // Create if (errorCode != NULL) { *errorCode = XSPF_WRITER_SUCCESS; } return new XspfWriter(formatter, baseUri, embedBase); } XspfWriter::XspfWriter(XspfWriter const & source) : d(new XspfWriterPrivate(*(source.d))) { } XspfWriter & XspfWriter::operator=(XspfWriter const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfWriter::~XspfWriter() { delete this->d; } bool XspfWriter::registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion) { // Too late? if (this->d->headerWritten) { return false; } return this->d->propsWriter.registerNamespace(uri, prefixSuggestion); } bool XspfWriter::addTrack(XspfTrack const * track) { if (track == NULL) { return false; } // Playlist already finalized? if (this->d->footerWritten) { return false; } XspfTrackWriter trackWriter; trackWriter.setTrack(track); // First track ever? if (!this->d->headerWritten) { this->d->propsWriter.setProps(NULL); this->d->version = 1; this->d->propsWriter.writeStartPlaylist(); this->d->propsWriter.writeStartTracklist(false); this->d->headerWritten = true; } trackWriter.init(*(this->d->formatter), this->d->version, this->d->baseUri); trackWriter.write(); this->d->trackListEmpty = false; return true; } bool XspfWriter::addTrack(XspfTrack const & track) { return addTrack(&track); } bool XspfWriter::setProps(XspfProps const * props) { if (this->d->headerWritten) { return false; } this->d->propsWriter.setProps(props); this->d->version = (props == NULL) ? 1 : props->getVersion(); this->d->propsWriter.writeStartPlaylist(); this->d->propsWriter.writeStartTracklist(false); this->d->headerWritten = true; return true; } bool XspfWriter::setProps(XspfProps const & props) { return setProps(&props); } void XspfWriter::onBeforeWrite() { // Header if (!this->d->headerWritten) { this->d->propsWriter.writeStartPlaylist(); this->d->propsWriter.writeStartTracklist(true); this->d->headerWritten = true; } // Footer if (!this->d->footerWritten) { this->d->propsWriter.writeEndTracklist(); this->d->propsWriter.writeEndPlaylist(); this->d->footerWritten = true; } } int XspfWriter::writeFile(XML_Char const * filename) { // Open file FILE * const file = ::PORT_FOPEN(filename, _PT("wb")); if (file == NULL) { // TODO return XSPF_WRITER_ERROR_OPENING; } onBeforeWrite(); // Get final input std::basic_string final = this->d->accum->str(); XML_Char const * const rawFinal = final.c_str(); int const rawFinalLen = static_cast(::PORT_STRLEN(rawFinal)); // UTF-8 conversion on Unicode Windows #if (defined(UNICODE) && (defined(__WIN32__) || defined(WIN32))) char * rawFinalUtf8 = new char[rawFinalLen * 4]; int const rawFinalUtf8Len = ::WideCharToMultiByte(CP_UTF8, 0, rawFinal, rawFinalLen, rawFinalUtf8, rawFinalLen * 4, NULL, NULL); ::fwrite(rawFinalUtf8, 1, rawFinalUtf8Len, file); delete [] rawFinalUtf8; #else ::fwrite(rawFinal, sizeof(XML_Char), rawFinalLen, file); #endif ::fclose(file); return XSPF_WRITER_SUCCESS; } int XspfWriter::writeMemory(char * & memory, int & numBytes) { onBeforeWrite(); // Get final input std::basic_string final = this->d->accum->str(); XML_Char const * const rawFinal = final.c_str(); int const rawFinalLen = static_cast(::PORT_STRLEN(rawFinal)); // UTF-8 conversion on Unicode Windows #if (defined(UNICODE) && (defined(__WIN32__) || defined(WIN32))) memory = new char[rawFinalLen * 4]; numBytes = ::WideCharToMultiByte(CP_UTF8, 0, rawFinal, rawFinalLen, memory, rawFinalLen * 4, NULL, NULL); #else memory = new char[rawFinalLen + 1]; memcpy(memory, rawFinal, rawFinalLen); memory[rawFinalLen] = '\0'; numBytes = rawFinalLen; #endif return XSPF_WRITER_SUCCESS; } void XspfWriter::reset(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase) { // Init formatter and content writer this->d->formatter = &formatter; formatter.setOutput(*this->d->accum); this->d->propsWriter.init(*this->d->formatter, baseUri, embedBase); this->d->trackListEmpty = true; this->d->headerWritten = false; this->d->footerWritten = false; // Clear buffer delete this->d->accum; this->d->accum = new std::basic_ostringstream; } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfWriter.h000066400000000000000000000161641516712004000264500ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfWriter.h * Interface of XspfWriter. */ #ifndef XSPF_WRITER_H #define XSPF_WRITER_H #include "XspfDefines.h" namespace Xspf { class XspfXmlFormatter; class XspfTrack; class XspfProps; class XspfWriterPrivate; /** * Specifies the result of a write operation. */ enum XspfWriterReturnCode { XSPF_WRITER_SUCCESS, ///< Everything fine XSPF_WRITER_ERROR_OPENING, ///< File could not be opened XSPF_WRITER_ERROR_BASE_URI_USELESS ///< Given base URI is not a valid absolute URI }; /** * Writes a playlist as XSPF to a file. * XSPF version 0 and 1 are supported. */ class XspfWriter { private: /// @cond DOXYGEN_NON_API XspfWriterPrivate * const d; ///< D pointer /// @endcond private: /** * Creates a new playlist writer. * * @param formatter XML formatter to use * @param baseUri Absolute base URI to reduce against, * pass \c NULL to keep all URIs absolute * @param embedBase Embeds base URI as xml:base attribute in * root node if true or not if false * @since 1.0.0 */ XspfWriter(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase); public: /** * Creates a new playlist writer. * * @param formatter XML formatter to use * @param baseUri Absolute base URI to reduce against, * pass \c NULL to keep all URIs absolute * @param embedBase Embeds base URI as xml:base in root * node if true or not if false * @param errorCode Place to write error code or * \c XSPF_WRITER_SUCCESS to. * @return \c NULL on error or a new'ed XspfWriter * that you have to delete manually later. * @since 1.0.0 */ static XspfWriter * makeWriter(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase = false, int * errorCode = NULL); /** * Copy constructor. * * @param source Source to copy from */ XspfWriter(XspfWriter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfWriter & operator=(XspfWriter const & source); /** * Frees all own memory. */ ~XspfWriter(); /** * Pre-registers a namespace so it can still * appear in the root element. * * @attention * registerNamespace() must be called before any calls * to setProps() or addTrack(). * * @param uri Namespace URI * @param prefixSuggestion Suggested prefix * @return Success flag */ bool registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion); /** * Appends a track to the playlist. * The \p track instance passed can be safely deleted * after the call returns. * * @param track Track to append * @return Success flag * @since 1.0.0 */ bool addTrack(XspfTrack const * track); /** * Appends a track to the playlist. * The \p track instance passed can be safely deleted * after the call returns. * * @param track Track to append * @return Success flag * @since 1.0.0 */ bool addTrack(XspfTrack const & track); /** * Sets playlist-wide properties of the playlist to be written * including the version of XSPF to be used. * The \p props instance passed can be safely deleted * after the call returns. * * @attention * setProps() must be called before any calls to addTrack(). * * @param props Playlist properties to set, can be NULL * @return Success flag * @since 1.0.0 */ bool setProps(XspfProps const * props); /** * Sets playlist-wide properties of the playlist to be written * including the version of XSPF to be used. * The \p props instance passed can be safely deleted * after the call returns. * * @attention * setProps() must be called before any calls to addTrack(). * * @param props Playlist properties to set, can be NULL * @return Success flag * @since 1.0.0 */ bool setProps(XspfProps const & props); /** * Finalizes the playlist and writes it to a file. * You can call this method several times to write * the same playlist to several files but you cannot * add new tracks anymore. Call reset() to start over. * * @param filename Filename of the file to write to * @return Error code */ int writeFile(XML_Char const * filename); /** * Finalizes the playlist and writes it to a block of memory. * You can call this method several times to write * the same playlist to several files but you cannot * add new tracks anymore. Call reset() to start over. * * @param memory Reference to output memory block, delete[] on your own * @param numBytes Size of the memory block in bytes * @return Error code */ int writeMemory(char * & memory, int & numBytes); /** * Clears all previously added tracks and makes the writer * reusable by another playlist. * * @param formatter XML formatter to use * @param baseUri Absolute base URI to reduce against. * @param embedBase Embeds base URI as xml:base in root * node if true or not if false * @since 1.0.0 */ void reset(XspfXmlFormatter & formatter, XML_Char const * baseUri, bool embedBase = false); private: /** * Does work common to all writing modes. */ void onBeforeWrite(); public: /// Base URI is embedded into the document static bool const EMBED_AS_XML_BASE; /// Base URI is not embedded into the document static bool const NO_XML_BASE; }; } #endif // XSPF_WRITER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfXmlFormatter.cpp000066400000000000000000000330321516712004000301440ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfXmlFormatter.cpp * Implementation of XspfXmlFormatter. */ #include #include #include #include #include #include namespace Xspf { /*static*/ XML_Char const * const XspfXmlFormatter::namespaceKey = XSPF_NS_HOME; /// @cond DOXYGEN_NON_API /** * D object for XspfXmlFormatter. */ class XspfXmlFormatterPrivate { friend class XspfXmlFormatter; int level; ///< Nesting level, 0 before root element has been written, 1 after that std::map namespaceToPrefix; ///< Namespace prefix map std::list undo; ///< Ordered registration undo list std::set prefixPool; ///< Set of registered prefixes bool declarationWritten; ///< XML declaration written flag std::basic_ostringstream * output; ///< Output accumulator /** * Creates a new D object. */ XspfXmlFormatterPrivate() : level(0), namespaceToPrefix(), undo(), prefixPool(), declarationWritten(false), output(NULL) { } /** * Copy constructor. * * @param source Source to copy from */ XspfXmlFormatterPrivate(XspfXmlFormatterPrivate const & source) : level(source.level), namespaceToPrefix(), undo(), prefixPool(), declarationWritten(source.declarationWritten), output(source.output) { assign(source); } /** * Assignment operator. * * @param source Source to copy from */ XspfXmlFormatterPrivate & operator=(XspfXmlFormatterPrivate const & source) { if (this != &source) { this->level = source.level; freeMap(this->namespaceToPrefix); freeList(this->undo); this->prefixPool.clear(); // Same strings again, don'tdelet twice this->declarationWritten = source.declarationWritten; this->output = source.output; assign(source); } return *this; } /** * Destroys this D object. */ ~XspfXmlFormatterPrivate() { freeMap(this->namespaceToPrefix); freeList(this->undo); this->prefixPool.clear(); // Same strings again, don'tdelet twice } void assign(XspfXmlFormatterPrivate const & source) { std::map ::const_iterator iter = source.namespaceToPrefix.begin(); while (iter != source.namespaceToPrefix.end()) { XML_Char const * const uri = iter->first; XML_Char * const prefix = iter->second; registerNamespace(uri, prefix); iter++; } } static void freeMap(std::map & container) { std::map::iterator iter = container.begin(); while (iter != container.end()) { delete [] iter->second; iter++; } container.clear(); } static void freeList(std::list< XspfNamespaceRegistrationUndo *> & container) { std::list::iterator iter = container.begin(); while (iter != container.end()) { XspfNamespaceRegistrationUndo * const entry = *iter; delete entry; iter++; } container.clear(); } bool registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion) { // Uri registered already? std::map ::iterator found = this->namespaceToPrefix.find(uri); if (found != this->namespaceToPrefix.end()) { return false; // == Existing } // Find unbound prefix (appending "x" if occupied) XML_Char * testPrefix = Toolbox::newAndCopy(prefixSuggestion); while (this->prefixPool.find(testPrefix) != this->prefixPool.end()) { int const testPrefixLen = static_cast(::PORT_STRLEN(testPrefix)); int const charCount = testPrefixLen + 1 + 1; XML_Char * nextPrefix = new XML_Char[charCount]; ::PORT_SNPRINTF(nextPrefix, charCount, _PT("%sx"), testPrefix); delete [] testPrefix; testPrefix = nextPrefix; } // Add prefix to map and pool this->namespaceToPrefix.insert(std::pair(uri, testPrefix)); this->prefixPool.insert(testPrefix); // Create undo entry XspfNamespaceRegistrationUndo * undo = new XspfNamespaceRegistrationUndo(this->level, uri); this->undo.push_front(undo); return true; // == Added } }; /// @endcond XspfXmlFormatter::XspfXmlFormatter() : d(new XspfXmlFormatterPrivate()) { } XspfXmlFormatter::XspfXmlFormatter(XspfXmlFormatter const & source) : d(new XspfXmlFormatterPrivate(*(source.d))) { } XspfXmlFormatter & XspfXmlFormatter::operator=(XspfXmlFormatter const & source) { if (this != &source) { *(this->d) = *(source.d); } return *this; } XspfXmlFormatter::~XspfXmlFormatter() { delete this->d; } void XspfXmlFormatter::writeXmlDeclaration() { if (!this->d->declarationWritten) { *this->d->output << _PT(""); this->d->declarationWritten = true; } } const XML_Char * XspfXmlFormatter::getPrefix(XML_Char const * nsUri) const { std::map ::const_iterator found = this->d->namespaceToPrefix.find(nsUri); if (found != this->d->namespaceToPrefix.end()) { return found->second; } else { return NULL; } } XML_Char * XspfXmlFormatter::makeFullName(XML_Char const * nsUri, XML_Char const * localName) const { XML_Char const * const prefix = getPrefix(nsUri); if (prefix != NULL) { int const prefixLen = static_cast(::PORT_STRLEN(prefix)); int const localNameLen = static_cast(::PORT_STRLEN(localName)); XML_Char * fullName = NULL; if (prefixLen == 0) { // Default namespace fullName = new XML_Char[localNameLen + 1]; ::PORT_STRCPY(fullName, localName); } else { // Namespace with prefix fullName = new XML_Char[prefixLen + 1 + localNameLen + 1]; ::PORT_STRCPY(fullName, prefix); ::PORT_STRCPY(fullName + prefixLen, _PT(":")); ::PORT_STRCPY(fullName + prefixLen + 1, localName); } return fullName; } else { // TODO What exactly do we do with unregistered // namespace URIs? Register a new prefix and use it? return Toolbox::newAndCopy(localName); } } bool XspfXmlFormatter::registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion) { return this->d->registerNamespace(uri, prefixSuggestion); } void XspfXmlFormatter::cleanupNamespaceRegs() { std::list::iterator iter = this->d->undo.begin(); while (iter != this->d->undo.end()) { XspfNamespaceRegistrationUndo * const entry = *iter; if (entry->level >= this->d->level) { std::map ::iterator foundUri = this->d->namespaceToPrefix.find(entry->uri); if (foundUri != this->d->namespaceToPrefix.end()) { XML_Char * & prefix = foundUri->second; // Remove prefix std::set::iterator foundPrefix = this->d->prefixPool.find(prefix); if (foundPrefix != this->d->prefixPool.end()) { this->d->prefixPool.erase(foundPrefix); } delete [] prefix; // Remove URI this->d->namespaceToPrefix.erase(foundUri); } this->d->undo.erase(iter); delete entry; } else { break; } iter = this->d->undo.begin(); } } void XspfXmlFormatter::setOutput(std::basic_ostringstream & output) { this->d->output = &output; } void XspfXmlFormatter::writeStart(XML_Char const * ns, XML_Char const * localName, XML_Char const * const * atts, XML_Char const * const * nsRegs) { if (nsRegs != NULL) { std::list > attribs; // Process namespace registrations XML_Char const * const * nsRegsWalk = nsRegs; while (nsRegsWalk[0] != NULL) { XML_Char const * const & uri = nsRegsWalk[0]; XML_Char const * const & prefix = nsRegsWalk[1]; // New namespace? if (registerNamespace(uri, prefix)) { XML_Char const * const finalPrefix = getPrefix(uri); XML_Char * finalKey = NULL; if (::PORT_STRLEN(finalPrefix) == 0) { // Default namespace finalKey = new XML_Char[5 + 1]; ::PORT_STRCPY(finalKey, _PT("xmlns")); } else { // Namespace with prefix int const finalPrefixLen = static_cast(::PORT_STRLEN(finalPrefix)); finalKey = new XML_Char[5 + 1 + finalPrefixLen + 1]; ::PORT_STRCPY(finalKey, _PT("xmlns:")); ::PORT_STRCPY(finalKey + 6, finalPrefix); } attribs.push_back(std::pair(finalKey, uri)); } nsRegsWalk += 2; } // Append normal attributes XML_Char const * const * attsWalk = atts; while (attsWalk[0] != NULL) { // TODO Copying the first is a lazy hack. Improve. attribs.push_back(std::pair( Toolbox::newAndCopy(attsWalk[0]), attsWalk[1])); attsWalk += 2; } // Convert int const attribCount = static_cast(attribs.size()); XML_Char const ** finalAtts = new const XML_Char *[2 * attribCount + 1]; std::list >::iterator iter = attribs.begin(); XML_Char const ** finalAttsWalk = finalAtts; while (iter != attribs.end()) { finalAttsWalk[0] = (*iter).first; finalAttsWalk[1] = (*iter).second; finalAttsWalk += 2; iter++; } finalAttsWalk[0] = NULL; // Write tag XML_Char const * fullName = makeFullName(ns, localName); writeStart(fullName, finalAtts); // Full cleanup delete [] fullName; finalAttsWalk = finalAtts; while (finalAttsWalk[0] != NULL) { delete [] finalAttsWalk[0]; finalAttsWalk += 2; } delete [] finalAtts; } else { // No registrations XML_Char const * fullName = makeFullName(ns, localName); writeStart(fullName, atts); delete [] fullName; } this->d->level++; } void XspfXmlFormatter::writeEnd(XML_Char const * ns, XML_Char const * localName) { XML_Char const * fullName = makeFullName(ns, localName); writeEnd(fullName); delete [] fullName; cleanupNamespaceRegs(); this->d->level--; } void XspfXmlFormatter::writeHomeStart(XML_Char const * localName, XML_Char const * const * atts, XML_Char const * const * nsRegs) { writeStart(XspfXmlFormatter::namespaceKey, localName, atts, nsRegs); } void XspfXmlFormatter::writeHomeEnd(XML_Char const * localName) { writeEnd(XspfXmlFormatter::namespaceKey, localName); } void XspfXmlFormatter::writeCharacterData(XML_Char const * data) { if (data == NULL) { return; } // Extensible Markup Language (XML) 1.0 (Fourth Edition) // 2.4 Character Data and Markup // http://www.w3.org/TR/REC-xml/#syntax XML_Char const * start = data; XML_Char const * end = data; for (;;) { switch (*end) { case _PT('\0'): this->d->output->write(start, static_cast(end - start)); return; case _PT('<'): this->d->output->write(start, static_cast(end - start)); *this->d->output << _PT("<"); end++; start = end; break; case _PT('&'): this->d->output->write(start, static_cast(end - start)); *this->d->output << _PT("&"); end++; start = end; break; case _PT('\''): this->d->output->write(start, static_cast(end - start)); *this->d->output << _PT("'"); end++; start = end; break; case _PT('"'): this->d->output->write(start, static_cast(end - start)); *this->d->output << _PT("""); end++; start = end; break; case _PT(']'): if ((*(end + 1) == _PT(']')) && (*(end + 2) == _PT('>'))) { this->d->output->write(start, static_cast(end - start)); *this->d->output << _PT("]]>"); end += 3; start = end; } else { end++; } break; default: end++; break; } } } std::basic_ostringstream * & XspfXmlFormatter::getOutput() { return this->d->output; } void XspfXmlFormatter::virtualHook(int /*methodId*/, void * /*parameters*/) { } } // namespace Xspf boca-1.0.7+git20260412.690d4ffe+dfsg/components/playlist/xspf/xspf/XspfXmlFormatter.h000066400000000000000000000157361516712004000276240ustar00rootroot00000000000000/* * libxspf - XSPF playlist handling library * * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file XspfXmlFormatter.h * Interface of XspfXmlFormatter. */ #ifndef XSPF_XML_FORMATTER_H #define XSPF_XML_FORMATTER_H #include "XspfDefines.h" #include namespace Xspf { class XspfWriter; /// @cond DOXYGEN_NON_API /** * Holds information necessary to undo a namespace registration */ struct XspfNamespaceRegistrationUndo { int level; ///< Level, the namespace was registered on. Root is level 0. XML_Char const * uri; ///< Namespace URI /** * Creates a new undo entry. * * @param level Nesting level, 0 for root element * @param uri Namespace URI */ XspfNamespaceRegistrationUndo(int level, XML_Char const * uri) : level(level), uri(uri) { } }; /// @endcond class XspfXmlFormatterPrivate; /** * Outputs XML. */ class XspfXmlFormatter { private: /// @cond DOXYGEN_NON_API XspfXmlFormatterPrivate * const d; ///< D pointer /// @endcond protected: /** * Creates a new formatter. */ XspfXmlFormatter(); /** * Copy constructor. * * @param source Source to copy from */ XspfXmlFormatter(XspfXmlFormatter const & source); /** * Assignment operator. * * @param source Source to copy from */ XspfXmlFormatter & operator=(XspfXmlFormatter const & source); /** * Destroys this formatter and deletes all memory * associated with it. */ virtual ~XspfXmlFormatter(); /** * Writes the XML declaration. */ virtual void writeXmlDeclaration(); private: /** * Looks up the associated prefix for namespace * nsUri. * * @param nsUri Namespace URI * @return Registered namespace prefix */ XML_Char const * getPrefix(XML_Char const * nsUri) const; /** * Looks up the associated prefix for namespace nsUri * and makes a full element name of that and localName. * * @param nsUri Namespace URI * @param localName Local element name * @return Full element name, delete on your own */ XML_Char * makeFullName(XML_Char const * nsUri, XML_Char const * localName) const; /** * Unregisteres all namespace URIs that were registered * on a higher level and are thus not needed any more. */ void cleanupNamespaceRegs(); /** * Finds an unmapped namespace prefix based on the * given suggestion and maps the namespace URI to it. * * @param uri Namespace URI * @param prefixSuggestion Suggested prefix */ bool registerNamespace(XML_Char const * uri, XML_Char const * prefixSuggestion); public: /** * Associate the formatter with an output accumulator. * * @param output Output accumulator */ void setOutput(std::basic_ostringstream & output); /** * Opens the tag localname from namespace * ns. * * @param ns Namespace URI * @param localName Local element name * @param atts NULL-terminated list of attributes (key/value pairs) * @param nsRegs NULL-terminated list of namespace registrations (uri/prefix pairs) */ void writeStart(XML_Char const * ns, XML_Char const * localName, XML_Char const * const * atts, XML_Char const * const * nsRegs = NULL); /** * Closes the tag localname from namespace * ns. * * @param ns Namespace URI * @param localName Local element name */ void writeEnd(XML_Char const * ns, XML_Char const * localName); /** * Opens the tag localname from the XSPF namespace. * * @param localName Local element name * @param atts NULL-terminated list of attributes (key/value pairs) * @param nsRegs NULL-terminated list of namespace registrations (uri/prefix pairs) */ void writeHomeStart(XML_Char const * localName, XML_Char const * const * atts, XML_Char const * const * nsRegs = NULL); /** * Closes the tag localname from the XSPF namespace. * * @param localName Local element name */ void writeHomeEnd(XML_Char const * localName); protected: /** * Opens the tag name and adds the attributes atts. * atts is not NULL and *atts is an alternating * list of attribute keys and values. Its length is uneven and the last * entry is NULL. * * @param name Name of the tag to open * @param atts Alternating list of attribute key and value */ virtual void writeStart(XML_Char const * name, XML_Char const * const * atts) = 0; /** * Closes the tag name. * * @param name Name of the tag to close */ virtual void writeEnd(XML_Char const * name) = 0; public: /** * Adds element content. * * @param text Text content */ virtual void writeBody(XML_Char const * text) = 0; /** * Adds element content. * * @param number Integer content */ virtual void writeBody(int number) = 0; /** * Writes well-formed character data to the output accumulator. * * @param data Character data */ void writeCharacterData(XML_Char const * data); static XML_Char const * const namespaceKey; ///< Namespace key pointer protected: /** * Returns the output stream in use. */ std::basic_ostringstream * & getOutput(); /// @cond DOXYGEN_NON_API void virtualHook(int methodId, void * parameters); /// @endcond friend class XspfWriter; // allow access to registerNamespace }; } // namespace Xspf #endif // XSPF_XML_FORMATTER_H boca-1.0.7+git20260412.690d4ffe+dfsg/components/shared/000077500000000000000000000000001516712004000216175ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/shared/mp3frame.cpp000066400000000000000000000075021516712004000240410ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "mp3frame.h" Int BoCA::MP3Frame::GetMPEGFrameSize(const Buffer &header) { /* MPEG bitrate table - [version][layer][bitrate] */ const UnsignedInt16 mpegBitrate[4][4][16] = { { // Version 2.5 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1 }, { // Reserved { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Invalid }, { // Version 2 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1 }, { // Version 1 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }, // Layer 3 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, // Layer 2 { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // Layer 1 } }; /* MPEG sample rate table - [version][srate] */ const UnsignedInt16 mpegSampleRate[4][4] = { { 11025, 12000, 8000, 0 }, // MPEG 2.5 { 0, 0, 0, 0 }, // Reserved { 22050, 24000, 16000, 0 }, // MPEG 2 { 44100, 48000, 32000, 0 } // MPEG 1 }; /* MPEG samples per frame table - [version][layer] */ const UnsignedInt16 mpegFrameSamples[4][4] = { { 0, 576, 1152, 384 }, // MPEG 2.5 { 0, 0, 0, 0 }, // Reserved { 0, 576, 1152, 384 }, // MPEG 2 { 0, 1152, 1152, 384 } // MPEG 1 }; /* MPEG unit size - [layer] */ const UnsignedInt8 mpegUnitSize[4] = { 0, 1, 1, 4 }; // Reserved, 3, 2, 1 /* Check header validity. */ if ((header[0] & 0xFF) != 0xFF || // 8 synchronization bits (header[1] & 0xE0) != 0xE0 || // 3 synchronization bits (header[1] & 0x18) == 0x08 || // reserved version (header[1] & 0x06) == 0x00 || // reserved layer (header[2] & 0xF0) == 0xF0) return 0; // reserved bitrate /* Get header values. */ Int version = (header[1] & 0x18) >> 3; // version Int layer = (header[1] & 0x06) >> 1; // layer Int padding = (header[2] & 0x02) >> 1; // padding Int bitrate = (header[2] & 0xf0) >> 4; // bitrate Int sampleRate = (header[2] & 0x0c) >> 2; // samplerate /* Return frame size. */ return (((Float) mpegFrameSamples[version][layer] / 8.0 * (Float) (mpegBitrate[version][layer][bitrate] * 1000)) / (Float) mpegSampleRate[version][sampleRate]) + ((padding) ? mpegUnitSize[layer] : 0); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/shared/mp3frame.h000066400000000000000000000013221516712004000235000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include namespace BoCA { class MP3Frame { public: static Int GetMPEGFrameSize(const Buffer &header); }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/shared/vbrtag.cpp000066400000000000000000000057531516712004000236220ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "vbrtag.h" #include static UnsignedInt32 ReadInt32(UnsignedByte *buffer) { /* Read big endian 32 bit int. */ return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; } BoCA::VbrTag::VbrTag() { offset = -1; flags = 0; frames = 0; bytes = 0; quality = -1; delay = 0; padding = 0; memset(toc, 0, sizeof(toc)); } Bool BoCA::VbrTag::Parse(const Buffer &buffer) { this->offset = -1; this->flags = 0; /* Determine header offset. */ Int version = (buffer[1] >> 3) & 1; Int mode = (buffer[3] >> 6) & 3; Int offset = 0; if (version) // MPEG 1 { if (mode != 3) offset = 32 + 4; else offset = 17 + 4; } else // MPEG 2 { if (mode != 3) offset = 17 + 4; else offset = 9 + 4; } /* Check for known header type. */ if ((buffer[offset] == 'X' && buffer[offset + 1] == 'i' && buffer[offset + 2] == 'n' && buffer[offset + 3] == 'g') || (buffer[offset] == 'I' && buffer[offset + 1] == 'n' && buffer[offset + 2] == 'f' && buffer[offset + 3] == 'o')) { this->offset = offset; /* Read flags and data. */ Int index = offset + 4; { this->flags = ReadInt32(buffer + index); index += 4; } if (this->flags & FLAG_FRAMES) { this->frames = ReadInt32(buffer + index); index += 4; } if (this->flags & FLAG_BYTES) { this->bytes = ReadInt32(buffer + index); index += 4; } if (this->flags & FLAG_TOC) { for (Int i = 0; i < 100; i++) this->toc[i] = buffer[index + i]; index += 100; } if (this->flags & FLAG_QUALITY) { this->quality = ReadInt32(buffer + index); index += 4; } /* Check for valid gapless data in LAME tag. */ UnsignedInt16 crc = Hash::CRC16::Compute(buffer, offset + 0x9A); if (buffer.Size() >= 192 && buffer[offset + 0x9A] == (crc >> 8) && buffer[offset + 0x9B] == (crc & 0xFF)) { this->flags |= FLAG_GAPLESS; this->delay = ( buffer[offset + 0x8D] << 4) | ((buffer[offset + 0x8E] & 0xF0) >> 4); this->padding = ((buffer[offset + 0x8E] & 0x0F) << 8) | ( buffer[offset + 0x8F] ); } return True; } else if ((buffer[0x24] == 'V' && buffer[0x25] == 'B' && buffer[0x26] == 'R' && buffer[0x27] == 'I')) { this->offset = 0x24; this->flags = FLAG_FRAMES | FLAG_BYTES; Int index = this->offset + 10; { this->bytes = ReadInt32(buffer + index); index += 4; } { this->frames = ReadInt32(buffer + index) - 1; index += 4; } return True; } return False; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/shared/vbrtag.h000066400000000000000000000025761516712004000232670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include namespace BoCA { class VbrTag { public: static const UnsignedInt FLAG_FRAMES = 0x01; static const UnsignedInt FLAG_BYTES = 0x02; static const UnsignedInt FLAG_TOC = 0x04; static const UnsignedInt FLAG_QUALITY = 0x08; static const UnsignedInt FLAG_GAPLESS = 0x10; VbrTag(); Int offset; // header offset in frame UnsignedInt flags; // available information flags UnsignedInt frames; // total bit stream frames UnsignedInt bytes; // total bit stream bytes Int quality; // VBR quality indicator UnsignedInt delay; // delay before first valid audio sample UnsignedInt padding; // padding samples in last frame UnsignedByte toc[100]; // TOC entries Bool Parse(const Buffer &); }; }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/000077500000000000000000000000001516712004000216225ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/Makefile000077500000000000000000000014741516712004000232730ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = apev2 cart flac id3v1 id3v2 mp4 riff vorbis ifeq ($(BUILD_OSX),True) FOLDERS += tocplist else ifeq ($(BUILD_WIN32),True) FOLDERS += wma endif .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/apev2/000077500000000000000000000000001516712004000226375ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/apev2/Makefile000077500000000000000000000011211516712004000242750ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = apev2 TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = apev2.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/apev2/apev2.cpp000066400000000000000000000753531516712004000243750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "apev2.h" using namespace smooth::IO; using namespace BoCA::AS; const String &BoCA::TaggerAPEv2::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ APEv2 Tagger \ 1.0 \ apev2-tag \ tagger \ \ Monkey's Audio \ ape \ mac \ \ \ APEv2 \ \ \ \ UTF-8 \ \ \ \ \ "; return componentSpecs; } const String BoCA::TaggerAPEv2::ConfigID = "Tags"; BoCA::TaggerAPEv2::TaggerAPEv2() { } BoCA::TaggerAPEv2::~TaggerAPEv2() { } Error BoCA::TaggerAPEv2::RenderBuffer(Buffer &buffer, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroAPEv2", True); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool writeMCDI = currentConfig->GetIntValue(ConfigID, "WriteMCDI", True); Bool preserveReplayGain = currentConfig->GetIntValue(ConfigID, "PreserveReplayGain", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToAPEv2 = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToAPEv2", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Set output encoding. */ String::OutputFormat outputFormat("UTF-8"); /* Save basic information. */ const Info &info = track.GetInfo(); buffer.Resize(32); Int numItems = 0; if (info.artist != NIL) { RenderAPEItem("Artist", info.artist, buffer); numItems++; } if (info.title != NIL) { RenderAPEItem("Title", info.title, buffer); numItems++; } if (info.album != NIL) { RenderAPEItem("Album", info.album, buffer); numItems++; } if (info.year > 0) { RenderAPEItem("Year", String::FromInt(info.year), buffer); numItems++; } if (info.genre != NIL) { RenderAPEItem("Genre", info.genre, buffer); numItems++; } if (info.label != NIL) { RenderAPEItem("Publisher", info.label, buffer); numItems++; } if (info.isrc != NIL) { RenderAPEItem("ISRC", info.isrc, buffer); numItems++; } if (info.track > 0) { String trackString = String(prependZero && info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track)); if (info.numTracks > 0) trackString.Append("/").Append(prependZero && info.numTracks < 10 ? "0" : NIL).Append(String::FromInt(info.numTracks)); { RenderAPEItem("Track", trackString, buffer); numItems++; } } if (info.disc > 0) { String discString = String(prependZero && info.disc < 10 ? "0" : NIL).Append(String::FromInt(info.disc)); if (info.numDiscs > 0) discString.Append("/").Append(prependZero && info.numDiscs < 10 ? "0" : NIL).Append(String::FromInt(info.numDiscs)); { RenderAPEItem("Disc", discString, buffer); numItems++; } } if (info.rating >= 0) { RenderAPEItem("RATING", String::FromInt(info.rating), buffer); numItems++; } if (info.comment != NIL && !replaceExistingComments) { RenderAPEItem("Comment", info.comment, buffer, False); numItems++; } else if (defaultComment != NIL && numItems > 0) { RenderAPEItem("Comment", defaultComment, buffer ); numItems++; } /* Save other text info. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) { RenderAPEItem("Album Artist", value, buffer ); numItems++; } else if (key == INFO_CONTENTGROUP) { RenderAPEItem("Grouping", value, buffer ); numItems++; } else if (key == INFO_SUBTITLE) { RenderAPEItem("Subtitle", value, buffer ); numItems++; } else if (key == INFO_BAND) { RenderAPEItem("Ensemble", value, buffer ); numItems++; } else if (key == INFO_PERFORMER) { RenderAPEItem("Performer", value, buffer ); numItems++; } else if (key == INFO_CONDUCTOR) { RenderAPEItem("Conductor", value, buffer ); numItems++; } else if (key == INFO_REMIXER) { RenderAPEItem("MixArtist", value, buffer ); numItems++; } else if (key == INFO_COMPOSER) { RenderAPEItem("Composer", value, buffer ); numItems++; } else if (key == INFO_ARRANGER) { RenderAPEItem("Arranger", value, buffer ); numItems++; } else if (key == INFO_PRODUCER) { RenderAPEItem("Producer", value, buffer ); numItems++; } else if (key == INFO_ENGINEER) { RenderAPEItem("Engineer", value, buffer ); numItems++; } else if (key == INFO_MOVEMENT) { RenderAPEItem("Movement", value, buffer ); numItems++; } else if (key == INFO_MOVEMENTTOTAL) { RenderAPEItem("MovementTotal", value, buffer ); numItems++; } else if (key == INFO_MOVEMENTNAME) { RenderAPEItem("MovementName", value, buffer ); numItems++; } else if (key == INFO_BPM) { RenderAPEItem("BPM", value, buffer ); numItems++; } else if (key == INFO_INITIALKEY) { RenderAPEItem("InitialKey", value, buffer ); numItems++; } else if (key == INFO_COPYRIGHT) { RenderAPEItem("Copyright", value, buffer ); numItems++; } else if (key == INFO_MEDIATYPE) { RenderAPEItem("Media", value, buffer ); numItems++; } else if (key == INFO_CATALOGNUMBER) { RenderAPEItem("CatalogNumber", value, buffer ); numItems++; } else if (key == INFO_BARCODE) { RenderAPEItem("Barcode", value, buffer ); numItems++; } else if (key == INFO_RELEASECOUNTRY) { RenderAPEItem("ReleaseCountry", value, buffer ); numItems++; } else if (key == INFO_DISCSUBTITLE) { RenderAPEItem("DiscSubtitle", value, buffer ); numItems++; } else if (key == INFO_LYRICS) { RenderAPEItem("Lyrics", value, buffer, False); numItems++; } else if (key == INFO_SCRIPT) { RenderAPEItem("Script", value, buffer); numItems++; } else if (key == INFO_SORT_ARTIST) { RenderAPEItem("ArtistSort", value, buffer ); numItems++; } else if (key == INFO_SORT_ALBUM) { RenderAPEItem("AlbumSort", value, buffer ); numItems++; } else if (key == INFO_SORT_ALBUMARTIST) { RenderAPEItem("AlbumArtistSort", value, buffer ); numItems++; } else if (key == INFO_SORT_COMPOSER) { RenderAPEItem("ComposerSort", value, buffer ); numItems++; } else if (key == INFO_SORT_TITLE) { RenderAPEItem("TitleSort", value, buffer ); numItems++; } else if (key == INFO_WEB_ARTIST) { RenderAPEItem("Artist URL", value, buffer ); numItems++; } else if (key == INFO_WEB_PUBLISHER) { RenderAPEItem("Publisher URL", value, buffer ); numItems++; } else if (key == INFO_WEB_SOURCE) { RenderAPEItem("File URL", value, buffer ); numItems++; } else if (key == INFO_WEB_COPYRIGHT) { RenderAPEItem("Copyright URL", value, buffer ); numItems++; } else if (key == INFO_WEB_COMMERCIAL) { RenderAPEItem("Buy URL", value, buffer ); numItems++; } else if (key == INFO_ASIN) { RenderAPEItem("Asin", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ARTISTID) { RenderAPEItem("MusicBrainz_ArtistId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ALBUMID) { RenderAPEItem("MusicBrainz_AlbumId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ALBUMARTISTID) { RenderAPEItem("MusicBrainz_AlbumArtistId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_WORKID) { RenderAPEItem("MusicBrainz_WorkId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_DISCID) { RenderAPEItem("MusicBrainz_DiscId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_TRACKID) { RenderAPEItem("MusicBrainz_TrackId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ORIGINALARTISTID) { RenderAPEItem("MusicBrainz_OriginalArtistId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ORIGINALALBUMID) { RenderAPEItem("MusicBrainz_OriginalAlbumId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASEGROUPID) { RenderAPEItem("MusicBrainz_ReleaseGroupId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASETRACKID) { RenderAPEItem("MusicBrainz_ReleaseTrackId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_TRMID) { RenderAPEItem("MusicBrainz_TrmId", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASETYPE) { RenderAPEItem("MusicBrainz_AlbumType", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASESTATUS) { RenderAPEItem("MusicBrainz_AlbumStatus", value, buffer ); numItems++; } } /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { { RenderAPEItem("replaygain_track_gain", info.track_gain, buffer); numItems++; } { RenderAPEItem("replaygain_track_peak", info.track_peak, buffer); numItems++; } } if (info.album_gain != NIL && info.album_peak != NIL) { { RenderAPEItem("replaygain_album_gain", info.album_gain, buffer); numItems++; } { RenderAPEItem("replaygain_album_peak", info.album_peak, buffer); numItems++; } } } /* Save CD table of contents. */ if (writeMCDI && info.mcdi.IsValid()) { RenderAPEBinaryItem("MCDI", info.mcdi.GetData(), buffer); numItems++; } /* Save encoder version. */ Application *app = Application::Get(); { RenderAPEItem("Tool Name", app->getClientName.Call(), buffer); numItems++; } { RenderAPEItem("Tool Version", app->getClientVersion.Call(), buffer); numItems++; } /* Save album art. */ if (albumArtWriteToTags && albumArtWriteToAPEv2) { foreach (const Picture &picInfo, track.pictures) { String itemName = "Cover Art"; Buffer picBuffer(picInfo.data.Size() + 19); if (picInfo.type == 3) itemName.Append(" (front)"); else if (picInfo.type == 4) itemName.Append(" (back)"); else itemName.Append(" (other)"); if (picInfo.mime == "image/png") strncpy((char *) (unsigned char *) picBuffer, "c:\\music\\cover.png", 19); else strncpy((char *) (unsigned char *) picBuffer, "c:\\music\\cover.jpg", 19); memcpy(picBuffer + 19, picInfo.data, picInfo.data.Size()); RenderAPEBinaryItem(itemName, picBuffer, buffer); numItems++; } } /* Save chapters. */ if (track.tracks.Length() > 0 && writeChapters) { Registry &boca = Registry::Get(); /* Save temporary cue sheet. */ PlaylistComponent *cuesheet = (PlaylistComponent *) boca.CreateComponentByID("cuesheet-playlist"); if (cuesheet != NIL) { Config *cuesheetConfig = Config::Copy(currentConfig); cuesheetConfig->SetStringValue("Tags", "DefaultComment", NIL); cuesheet->SetConfiguration(cuesheetConfig); /* Update track filenames and offsets. */ Array chapters = track.tracks; const Format &format = track.GetFormat(); Int64 offset = 0; foreach (Track &chapterTrack, chapters) { const Format &chapterFormat = chapterTrack.GetFormat(); Info chapterInfo = chapterTrack.GetInfo(); chapterTrack.fileName = S::System::System::GetTempDirectory().Append(File(track.fileName).GetFileName()); chapterTrack.sampleOffset = offset; if (chapterInfo.artist == NIL) chapterInfo.artist = info.artist; if (chapterInfo.album == NIL) chapterInfo.album = info.album; if (chapterInfo.genre == NIL) chapterInfo.genre = info.genre; if (chapterInfo.year <= 0) chapterInfo.year = info.year; chapterTrack.SetInfo(chapterInfo); if (chapterTrack.length >= 0) offset += Math::Round(Float(chapterTrack.length) * format.rate / chapterFormat.rate); else if (chapterTrack.approxLength >= 0) offset += Math::Round(Float(chapterTrack.approxLength) * format.rate / chapterFormat.rate); } /* Create temporary cuesheet file. */ String cueFile = S::System::System::GetTempDirectory().Append("cuesheet_temp_").Append(String::FromInt(track.fileName.ComputeCRC32())).Append(".cue"); cuesheet->SetTrackList(chapters); cuesheet->WritePlaylist(cueFile); boca.DeleteComponent(cuesheet); Config::Free(cuesheetConfig); /* Read generated cuesheet. */ String::InputFormat inputFormat("UTF-8"); InStream in(STREAM_FILE, cueFile, IS_READ); String data = in.InputString(in.Size()); data.Replace(L"\xFEFF", NIL); data.Replace("\r\n", "\n"); in.Close(); File(cueFile).Delete(); /* Write cuesheet to tag. */ { RenderAPEItem("Cuesheet", data, buffer, False); numItems++; } } } /* Render tag header and footer. */ if (numItems > 0) { Int tagSize = buffer.Size(); RenderAPEHeader(tagSize, numItems, buffer); RenderAPEFooter(tagSize, numItems, buffer); } else { buffer.Resize(0); } return Success(); } Int BoCA::TaggerAPEv2::RenderAPEHeader(Int tagSize, Int numItems, Buffer &buffer) { OutStream out(STREAM_BUFFER, buffer, 32); out.OutputString("APETAGEX"); out.OutputNumber(2000, 4); out.OutputNumber(tagSize, 4); out.OutputNumber(numItems, 4); out.OutputNumber(0xA0000000, 4); out.OutputNumber(0, 4); out.OutputNumber(0, 4); return Success(); } Int BoCA::TaggerAPEv2::RenderAPEFooter(Int tagSize, Int numItems, Buffer &buffer) { buffer.Resize(buffer.Size() + 32); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - 32, 32); out.OutputString("APETAGEX"); out.OutputNumber(2000, 4); out.OutputNumber(tagSize, 4); out.OutputNumber(numItems, 4); out.OutputNumber(0x80000000, 4); out.OutputNumber(0, 4); out.OutputNumber(0, 4); return Success(); } Int BoCA::TaggerAPEv2::RenderAPEItem(const String &id, const String &value, Buffer &buffer, Bool trim) { String data = trim ? value.Trim() : value; Int dataSize = data != NIL ? strlen(data) : 0; Int size = id.Length() + dataSize + 9; buffer.Resize(buffer.Size() + size); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - size, size); out.OutputNumber(dataSize, 4); out.OutputNumber(0, 4); out.OutputString(id); out.OutputNumber(0, 1); out.OutputString(data); return Success(); } Int BoCA::TaggerAPEv2::RenderAPEBinaryItem(const String &id, const Buffer &value, Buffer &buffer) { Int size = id.Length() + value.Size() + 9; buffer.Resize(buffer.Size() + size); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - size, size); out.OutputNumber(value.Size(), 4); out.OutputNumber(0x01 << 1, 4); // set binary flag out.OutputString(id); out.OutputNumber(0, 1); out.OutputData(value, value.Size()); return Success(); } Error BoCA::TaggerAPEv2::ParseBuffer(const Buffer &buffer, Track &track) { const Config *currentConfig = GetConfiguration(); Int numItems = 0; Int offset = 32; if (!ParseAPEHeader(buffer, NIL, &numItems)) { offset = 0; if (!ParseAPEFooter(buffer, NIL, &numItems)) return Error(); } String::InputFormat inputFormat("UTF-8"); Info info = track.GetInfo(); for (Int i = 0; i < numItems; i++) { String id; String value; Buffer item; Int previousOffset = offset; ParseAPEItem(buffer, offset, &id, &value); if (id != "!Binary" && value == NIL) continue; else if (id == "!Binary" ) ParseAPEBinaryItem(buffer, offset, &id, item); id = id.ToUpper(); if (id == "ARTIST") info.artist = value; else if (id == "TITLE") info.title = value; else if (id == "ALBUM") info.album = value; else if (id == "YEAR") info.year = value.ToInt(); else if (id == "GENRE") info.genre = value; else if (id == "COMMENT") { ParseAPEItem(buffer, previousOffset, &id, &value, False); info.comment = value; } else if (id == "PUBLISHER") info.label = value; else if (id == "LABEL") info.label = value; else if (id == "ISRC") { if (Info::IsISRC(value)) info.isrc = value; } else if (id == "RATING") info.rating = Math::Min(100, value.ToInt()); else if (id == "ALBUM ARTIST") info.SetOtherInfo(INFO_ALBUMARTIST, value); else if (id == "GROUPING") info.SetOtherInfo(INFO_CONTENTGROUP, value); else if (id == "SUBTITLE") info.SetOtherInfo(INFO_SUBTITLE, value); else if (id == "ENSEMBLE" || id == "ORCHESTRA") info.SetOtherInfo(INFO_BAND, value); else if (id == "PERFORMER") info.SetOtherInfo(INFO_PERFORMER, value); else if (id == "CONDUCTOR") info.SetOtherInfo(INFO_CONDUCTOR, value); else if (id == "MIXARTIST") info.SetOtherInfo(INFO_REMIXER, value); else if (id == "COMPOSER") info.SetOtherInfo(INFO_COMPOSER, value); else if (id == "ARRANGER") info.SetOtherInfo(INFO_ARRANGER, value); else if (id == "PRODUCER") info.SetOtherInfo(INFO_PRODUCER, value); else if (id == "ENGINEER") info.SetOtherInfo(INFO_ENGINEER, value); else if (id == "MOVEMENT") { info.SetOtherInfo(INFO_MOVEMENT, String::FromInt(value.ToInt())); if (value.Contains("/")) info.SetOtherInfo(INFO_MOVEMENTTOTAL, String::FromInt(value.Tail(value.Length() - value.Find("/") - 1).ToInt())); } else if (id == "MOVEMENTTOTAL") info.SetOtherInfo(INFO_MOVEMENTTOTAL, value); else if (id == "MOVEMENTNAME") info.SetOtherInfo(INFO_MOVEMENTNAME, value); else if (id == "BPM") { if (value.ToInt() > 0) info.SetOtherInfo(INFO_BPM, value); } else if (id == "INITIALKEY") info.SetOtherInfo(INFO_INITIALKEY, value); else if (id == "COPYRIGHT") info.SetOtherInfo(INFO_COPYRIGHT, value); else if (id == "MEDIA") info.SetOtherInfo(INFO_MEDIATYPE, value); else if (id == "CATALOGNUMBER") info.SetOtherInfo(INFO_CATALOGNUMBER, value); else if (id == "BARCODE") info.SetOtherInfo(INFO_BARCODE, value); else if (id == "RELEASECOUNTRY") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); else if (id == "DISCSUBTITLE") info.SetOtherInfo(INFO_DISCSUBTITLE, value); else if (id == "LYRICS") { ParseAPEItem(buffer, previousOffset, &id, &value, False); info.SetOtherInfo(INFO_LYRICS, value); } else if (id == "SCRIPT") info.SetOtherInfo(INFO_SCRIPT, value); else if (id == "ARTISTSORT") info.SetOtherInfo(INFO_SORT_ARTIST, value); else if (id == "ALBUMSORT") info.SetOtherInfo(INFO_SORT_ALBUM, value); else if (id == "ALBUMARTISTSORT") info.SetOtherInfo(INFO_SORT_ALBUMARTIST, value); else if (id == "COMPOSERSORT") info.SetOtherInfo(INFO_SORT_COMPOSER, value); else if (id == "TITLESORT") info.SetOtherInfo(INFO_SORT_TITLE, value); else if (id == "WEBLINK" || id == "ARTIST URL") info.SetOtherInfo(INFO_WEB_ARTIST, value); else if (id == "PUBLISHER URL") info.SetOtherInfo(INFO_WEB_PUBLISHER, value); else if (id == "FILE URL") info.SetOtherInfo(INFO_WEB_SOURCE, value); else if (id == "COPYRIGHT URL") info.SetOtherInfo(INFO_WEB_COPYRIGHT, value); else if (id == "BUY URL") info.SetOtherInfo(INFO_WEB_COMMERCIAL, value); else if (id == "TRACK") { info.track = value.ToInt(); if (value.Contains("/")) info.numTracks = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } else if (id == "DISC") { info.disc = value.ToInt(); if (value.Contains("/")) info.numDiscs = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } else if (id == "ASIN") info.SetOtherInfo(INFO_ASIN, value); else if (id.StartsWith("MUSICBRAINZ")) { if (id == "MUSICBRAINZ_ARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ARTISTID, value); else if (id == "MUSICBRAINZ_ALBUMID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMID, value); else if (id == "MUSICBRAINZ_ALBUMARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMARTISTID, value); else if (id == "MUSICBRAINZ_WORKID") info.SetOtherInfo(INFO_MUSICBRAINZ_WORKID, value); else if (id == "MUSICBRAINZ_DISCID") info.SetOtherInfo(INFO_MUSICBRAINZ_DISCID, value); else if (id == "MUSICBRAINZ_TRACKID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRACKID, value); else if (id == "MUSICBRAINZ_ORIGINALARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALARTISTID, value); else if (id == "MUSICBRAINZ_ORIGINALALBUMID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALALBUMID, value); else if (id == "MUSICBRAINZ_RELEASEGROUPID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASEGROUPID, value); else if (id == "MUSICBRAINZ_RELEASETRACKID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETRACKID, value); else if (id == "MUSICBRAINZ_TRMID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRMID, value); else if (id == "MUSICBRAINZ_ALBUMTYPE") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETYPE, value); else if (id == "MUSICBRAINZ_ALBUMSTATUS") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASESTATUS, value); } else if (id.StartsWith("REPLAYGAIN")) { if (id == "REPLAYGAIN_TRACK_GAIN") info.track_gain = value; else if (id == "REPLAYGAIN_TRACK_PEAK") info.track_peak = value; else if (id == "REPLAYGAIN_ALBUM_GAIN") info.album_gain = value; else if (id == "REPLAYGAIN_ALBUM_PEAK") info.album_peak = value; } else if (id == "MCDI") { /* Check validity of MCDI data and assign. */ MCDI mcdi(item); if (mcdi.IsValid()) info.mcdi.SetData(item); } else if (id.StartsWith("COVER ART")) { if (currentConfig->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { Picture picture; /* Read and ignore file name. Then copy * picture data to Picture object. */ for (Int i = 0; i < item.Size(); i++) { if (item[i] == 0) { picture.data.Set(item + i + 1, item.Size() - i - 1); break; } } if (id.EndsWith("(FRONT)")) picture.type = 3; // Cover (front) else if (id.EndsWith("(BACK)")) picture.type = 4; // Cover (back) else picture.type = 0; // Other if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } } } else if (id == "CUESHEET") { if (currentConfig->GetIntValue(ConfigID, "ReadEmbeddedCueSheets", True)) { String::OutputFormat outputFormat("UTF-8"); /* Output cuesheet to temporary file. */ String cuesheet = value.Replace("\r\n", "\n"); String cueFile = S::System::System::GetTempDirectory().Append("cuesheet_temp_").Append(String::FromInt(track.fileName.ComputeCRC32())).Append(".cue"); OutStream out(STREAM_FILE, cueFile, OS_REPLACE); /* Write UTF-8 BOM. */ if (value[0] != 0xFEFF) out.OutputNumberRaw(0xEFBBBF, 3); /* Write cuesheet line by line. */ const Array &lines = cuesheet.Explode("\n"); out.OutputLine(String("FILE \"").Append(track.fileName).Append("\" WAVE")); foreach (const String &line, lines) { if (!line.Trim().StartsWith("FILE")) out.OutputLine(line); } out.Close(); /* Get cue sheet stream info. */ AS::Registry &boca = AS::Registry::Get(); AS::DecoderComponent *decoder = (AS::DecoderComponent *) boca.CreateComponentByID("cuesheet-dec"); if (decoder != NIL) { Track cueTrack; Config *cueConfig = Config::Copy(GetConfiguration()); cueConfig->SetIntValue("Tags", "ReadChapters", False); cueConfig->SetIntValue("Tags", "ReadEmbeddedCueSheets", False); cueConfig->SetIntValue("CueSheet", "ReadInformationTags", True); cueConfig->SetIntValue("CueSheet", "PreferCueSheets", True); cueConfig->SetIntValue("CueSheet", "LookForAlternativeFiles", False); cueConfig->SetIntValue("CueSheet", "IgnoreErrors", False); decoder->SetConfiguration(cueConfig); decoder->GetStreamInfo(cueFile, cueTrack); boca.DeleteComponent(decoder); Config::Free(cueConfig); if (cueTrack.tracks.Length() > 0) track.tracks = cueTrack.tracks; } File(cueFile).Delete(); } } else { /* Save any other tags as user defined text. */ info.other.Add(String(INFO_USERTEXT).Append(":").Append(id).Append(":|:").Append(value)); } } /* Set artist to album artist if artist is not filled. */ if (info.artist == NIL) info.artist = info.GetOtherInfo(INFO_ALBUMARTIST); /* Remove sub-tracks if main track has a track number. */ if (info.track > 0) track.tracks.RemoveAll(); track.SetInfo(info); return Success(); } Error BoCA::TaggerAPEv2::ParseStreamInfo(const String &fileName, Track &track) { /* Open file and check size. */ InStream in(STREAM_FILE, fileName, IS_READ); if (in.Size() < 32) return Error(); /* Read header tag. */ Buffer buffer(32); Int tagSize = 0; in.InputData(buffer, 32); if (ParseAPEHeader(buffer, &tagSize, NIL)) { buffer.Resize(tagSize); in.InputData(buffer, tagSize); return ParseBuffer(buffer, track); } /* Read footer tag. */ in.Seek(in.Size() - 32); in.InputData(buffer, 32); if (ParseAPEFooter(buffer, &tagSize, NIL)) { buffer.Resize(tagSize); in.Seek(in.Size() - tagSize); in.InputData(buffer, tagSize); return ParseBuffer(buffer, track); } return Error(); } Bool BoCA::TaggerAPEv2::ParseAPEHeader(const Buffer &buffer, Int *tagSize, Int *numItems) { InStream in(STREAM_BUFFER, buffer, 32); if (in.InputString(8) != "APETAGEX") return False; if (in.InputNumber(4) >= 3000) return False; if (tagSize != NIL) *tagSize = in.InputNumber(4); else in.RelSeek(4); if (numItems != NIL) *numItems = in.InputNumber(4); else in.RelSeek(4); return True; } Bool BoCA::TaggerAPEv2::ParseAPEFooter(const Buffer &buffer, Int *tagSize, Int *numItems) { InStream in(STREAM_BUFFER, buffer + buffer.Size() - 32, 32); if (in.InputString(8) != "APETAGEX") return False; if (in.InputNumber(4) >= 3000) return False; if (tagSize != NIL) *tagSize = in.InputNumber(4); else in.RelSeek(4); if (numItems != NIL) *numItems = in.InputNumber(4); else in.RelSeek(4); return True; } Bool BoCA::TaggerAPEv2::ParseAPEItem(const Buffer &buffer, Int &offset, String *id, String *value, Bool trim) { InStream in(STREAM_BUFFER, buffer + offset, buffer.Size() - offset - 32); Int valueBytes = in.InputNumber(4); Int flags = in.InputNumber(4); /* Check if this is a binary tag item. */ if (((flags >> 1) & 3) == 1) { *id = "!Binary"; return True; } *id = NIL; Byte lastChar = 0; do { lastChar = in.InputNumber(1); (*id)[id->Length()] = lastChar; } while (lastChar != 0); *value = in.InputString(valueBytes); if (trim) *value = value->Trim(); offset += in.GetPos(); return True; } Bool BoCA::TaggerAPEv2::ParseAPEBinaryItem(const Buffer &buffer, Int &offset, String *id, Buffer &value) { InStream in(STREAM_BUFFER, buffer + offset, buffer.Size() - offset - 32); Int valueBytes = in.InputNumber(4); in.InputNumber(4); *id = NIL; Byte lastChar = 0; do { lastChar = in.InputNumber(1); (*id)[id->Length()] = lastChar; } while (lastChar != 0); value.Resize(valueBytes); in.InputData(value, valueBytes); offset += in.GetPos(); return True; } Error BoCA::TaggerAPEv2::UpdateStreamInfo(const String &fileName, const Track &track) { /* Open file and check size. */ InStream in(STREAM_FILE, fileName, IS_READ); if (in.Size() < 32) return Error(); /* Check for APEv2 tag at the beginning of the file. */ Buffer buffer(32); Int tagSize = 0; in.InputData(buffer, 32); if (ParseAPEHeader(buffer, &tagSize, NIL)) { /* Copy to temporary file. */ in.RelSeek(tagSize); String tempFile = String(fileName).Append(".boca.temp"); OutStream out(STREAM_FILE, tempFile, OS_REPLACE); if (out.GetLastError() == IO_ERROR_OK) { Buffer buffer; RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); buffer.Resize(128 * 1024); for (Int64 i = in.GetPos(); i < in.Size(); i += buffer.Size()) { Int bytes = Math::Min(in.Size() - i, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); } in.Close(); out.Close(); File(fileName).Delete(); File(tempFile).Move(fileName); return Success(); } return Error(); } /* Check for APEv2 tag at the end of the file. */ in.Seek(in.Size() - 32); in.InputData(buffer, 32); if (ParseAPEFooter(buffer, &tagSize, NIL)) { /* Check if this tag also has a header. */ in.RelSeek(-12); if (in.InputNumber(4) & 0x80000000) tagSize += 32; /* Copy to temporary file. */ in.Seek(0); String tempFile = String(fileName).Append(".boca.temp"); OutStream out(STREAM_FILE, tempFile, OS_REPLACE); if (out.GetLastError() == IO_ERROR_OK) { Buffer buffer; buffer.Resize(128 * 1024); for (Int64 i = tagSize; i < in.Size(); i += buffer.Size()) { Int bytes = Math::Min(in.Size() - i, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); } buffer.Resize(0); RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); in.Close(); out.Close(); File(fileName).Delete(); File(tempFile).Move(fileName); return Success(); } return Error(); } in.Close(); /* Append new APEv2 tag. */ OutStream out(STREAM_FILE, fileName, OS_APPEND); if (out.GetLastError() == IO_ERROR_OK) { Buffer buffer; RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); return Success(); } return Error(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/apev2/apev2.h000066400000000000000000000034541516712004000240330ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(TaggerAPEv2) namespace BoCA { class TaggerAPEv2 : public CS::TaggerComponent { private: static const String ConfigID; Int RenderAPEHeader(Int, Int, Buffer &); Int RenderAPEFooter(Int, Int, Buffer &); Int RenderAPEItem(const String &, const String &, Buffer &, Bool = True); Int RenderAPEBinaryItem(const String &, const Buffer &, Buffer &); Bool ParseAPEHeader(const Buffer &, Int *, Int *); Bool ParseAPEFooter(const Buffer &, Int *, Int *); Bool ParseAPEItem(const Buffer &, Int &, String *, String *, Bool = True); Bool ParseAPEBinaryItem(const Buffer &, Int &, String *, Buffer &); public: static const String &GetComponentSpecs(); TaggerAPEv2(); ~TaggerAPEv2(); Error ParseBuffer(const Buffer &, Track &); Error ParseStreamInfo(const String &, Track &); Error RenderBuffer(Buffer &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerAPEv2) BoCA_END_COMPONENT(TaggerAPEv2) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/cart/000077500000000000000000000000001516712004000225535ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/cart/Makefile000066400000000000000000000011171516712004000242130ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = cart TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = cart.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/cart/cart.cpp000066400000000000000000000232001516712004000242050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "cart.h" using namespace smooth::IO; const String &BoCA::TaggerCart::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ RIFF Cart Tagger \ 1.0 \ cart-tag \ tagger \ \ Microsoft Wave Files \ wav \ \ \ RIFF 64 Audio Files \ rf64 \ \ \ RIFF Cart Tag \ \ ISO-8859-1 \ UTF-8 \ \ \ \ \ "; return componentSpecs; } const String BoCA::TaggerCart::ConfigID = "Tags"; BoCA::TaggerCart::TaggerCart() { } BoCA::TaggerCart::~TaggerCart() { } Error BoCA::TaggerCart::RenderBuffer(Buffer &buffer, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); String encodingID = currentConfig->GetStringValue(ConfigID, "RIFFCartTagEncoding", "ISO-8859-1"); /* Set output encoding. */ String::OutputFormat outputFormat(encodingID); const Info &info = track.GetInfo(); const Format &format = track.GetFormat(); buffer.Resize(8); /* Cart chunk version 1.01. */ RenderStringItem("0101", 4, buffer); /* Artist and title. */ RenderStringItem(info.title, 64, buffer); RenderStringItem(info.artist, 64, buffer); /* Cut number. */ RenderStringItem(NIL, 64, buffer); /* Client ID. */ RenderStringItem(NIL, 64, buffer); /* Category. */ RenderStringItem("MUS", 64, buffer); /* Classification. */ RenderStringItem(NIL, 64, buffer); /* Out cue. */ RenderStringItem(info.album, 64, buffer); /* Start date and time. */ RenderStringItem("1900-01-01", 10, buffer); RenderStringItem("00:00:00", 8, buffer); /* End date and time. */ RenderStringItem("9999-12-31", 10, buffer); RenderStringItem("23:59:59", 8, buffer); /* Application ID and version. */ RenderStringItem(Application::Get()->getClientName.Call(), 64, buffer); RenderStringItem(Application::Get()->getClientVersion.Call(), 64, buffer); /* User defined string. */ RenderStringItem(String(info.genre).Append(info.year > 0 ? String("|").Append(String::FromInt(info.year)) : String()), 64, buffer); /* Level reference. */ RenderIntegerItem(Math::Pow(2, format.bits - 1), 4, buffer); /* Timers. */ for (Int i = 0; i < 7; i++) RenderTimerItem(NIL, 0, buffer); if (track.length >= 0) RenderTimerItem("EOD", track.length, buffer); else RenderTimerItem(NIL, 0, buffer); /* Reserved. */ RenderStringItem(NIL, 276, buffer); /* URL. */ RenderStringItem(NIL, 1024, buffer); /* Tag header. */ RenderTagHeader(buffer); return Success(); } Int BoCA::TaggerCart::RenderTagHeader(Buffer &buffer) { OutStream out(STREAM_BUFFER, buffer, 8); out.OutputString("cart"); out.OutputNumber(buffer.Size() - 8, 4); return Success(); } Int BoCA::TaggerCart::RenderStringItem(const String &value, Int bufferSize, Buffer &buffer) { buffer.Resize(buffer.Size() + bufferSize); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - bufferSize, bufferSize); Int stringSize = (value.Trim() != NIL) ? strlen(value.Trim()) : 0; out.OutputString(stringSize <= bufferSize ? value.Trim() : value.Trim().Head(bufferSize)); for (Int i = 0; i < bufferSize - stringSize; i++) out.OutputNumber(0, 1); return Success(); } Int BoCA::TaggerCart::RenderIntegerItem(Int value, Int bufferSize, Buffer &buffer) { buffer.Resize(buffer.Size() + bufferSize); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - bufferSize, bufferSize); out.OutputNumber(value, bufferSize); return Success(); } Int BoCA::TaggerCart::RenderTimerItem(const String &fourcc, Int value, Buffer &buffer) { buffer.Resize(buffer.Size() + 8); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - 8, 8); Int fourccSize = (fourcc != NIL) ? strlen(fourcc) : 0; out.OutputString(fourccSize <= 4 ? fourcc : fourcc.Head(4)); for (Int i = 0; i < 4 - fourccSize; i++) out.OutputNumber(0, 1); out.OutputNumber(value, 4); return Success(); } Error BoCA::TaggerCart::ParseBuffer(const Buffer &buffer, Track &track) { InStream in(STREAM_BUFFER, buffer, buffer.Size()); Bool error = False; /* Read cart chunk. */ if (in.InputString(4) != "cart") error = True; /* Skip header. */ in.RelSeek(4); /* Parse individual comment items. */ Info info = track.GetInfo(); String::InputFormat inputFormat("ISO-8859-1"); /* Cart chunk version. */ String version = in.InputString(4); /* Continue if version == 1.x. */ if (version.ToInt() >= 100 && version.ToInt() < 200) { /* Artist and title. */ info.title = in.InputString(64).Trim(); info.artist = in.InputString(64).Trim(); /* Cut number. */ in.RelSeek(64); /* Client ID. */ in.RelSeek(64); /* Category. */ in.RelSeek(64); /* Classification. */ in.RelSeek(64); /* Out cue. */ in.RelSeek(64); /* Start date and time. */ in.RelSeek(18); /* End date and time. */ in.RelSeek(18); /* Application ID and version. */ in.RelSeek(64); in.RelSeek(64); /* User defined string. */ in.RelSeek(64); /* Level reference. */ in.RelSeek(4); /* Timers. */ for (Int i = 0; i < 8; i++) in.RelSeek(8); /* Reserved. */ in.RelSeek(276); /* URL. */ in.RelSeek(1024); } track.SetInfo(info); if (error) return Error(); else return Success(); } Error BoCA::TaggerCart::ParseStreamInfo(const String &fileName, Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Read RIFF chunk. */ String riff = in.InputString(4); if (riff != "RIFF" && riff != "RF64") return Error(); UnsignedInt32 rSize = in.InputNumber(4); in.RelSeek(4); /* Find and parse cart chunk. */ Bool error = False; String chunk; Int64 dSize = -1; while (!error && chunk != "cart") { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) in.InputNumber(4); if (chunk == "cart") { Buffer buffer(cSize + 8); in.RelSeek(-8); in.InputData(buffer, cSize + 8); if (ParseBuffer(buffer, track) != Success()) error = True; } else if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(cSize - 16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) cSize = in.Size() - in.GetPos(); if (dSize >= 0) in.RelSeek(dSize + dSize % 2); else in.RelSeek(cSize + cSize % 2); } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) error = True; } } if (error) return Error(); return Success(); } Error BoCA::TaggerCart::UpdateStreamInfo(const String &fileName, const Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Read RIFF chunk. */ Bool error = False; String riff = in.InputString(4); if (riff != "RIFF" && riff != "RF64") return Error(); /* Create output file. */ OutStream out(STREAM_FILE, fileName.Append(".temp"), OS_REPLACE); UnsignedInt32 rSize = in.InputNumber(4); UnsignedInt32 rFormat = in.InputNumber(4); out.OutputString(riff); out.OutputNumber(rSize, 4); out.OutputNumber(rFormat, 4); Int64 dSize = -1; Buffer buffer(131072); while (!error) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ String chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) in.InputNumber(4); if (chunk == "cart") { /* Skip cart chunk. */ if (!in.RelSeek(cSize + cSize % 2)) error = True; continue; } out.OutputString(chunk); out.OutputNumber(cSize, 4); if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(-16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) error = True; if (dSize >= 0) cSize = dSize; } /* Write chunk data to output file. */ cSize += cSize % 2; while (!error && cSize > 0) { Int64 bytes = Math::Min(cSize, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); cSize -= bytes; } } /* Write new metadata. */ if (!error) { /* Write cart chunk. */ buffer.Resize(0); RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); /* Update file size. */ UnsignedInt64 fileSize = out.GetPos() - 8; rSize = Math::Min(0xFFFFFFFF, fileSize); out.Seek(4); out.OutputNumber(rSize, 4); } /* Clean up. */ in.Close(); out.Close(); if (error) { File(fileName.Append(".temp")).Delete(); return Error(); } File(fileName).Delete(); File(fileName.Append(".temp")).Move(fileName); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/cart/cart.h000066400000000000000000000026311516712004000236570ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(TaggerCart) namespace BoCA { class TaggerCart : public CS::TaggerComponent { private: static const String ConfigID; Int RenderTagHeader(Buffer &); Int RenderStringItem(const String &, Int, Buffer &); Int RenderIntegerItem(Int, Int, Buffer &); Int RenderTimerItem(const String &, Int, Buffer &); public: static const String &GetComponentSpecs(); TaggerCart(); ~TaggerCart(); Error ParseBuffer(const Buffer &, Track &); Error ParseStreamInfo(const String &, Track &); Error RenderBuffer(Buffer &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerCart) BoCA_END_COMPONENT(TaggerCart) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/000077500000000000000000000000001516712004000225275ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/Makefile000077500000000000000000000012111516712004000241650ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = flac TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o flac.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/dllinterface.cpp000077500000000000000000000200261516712004000256720ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC = NIL; FLAC__METADATA_CHAIN_NEW ex_FLAC__metadata_chain_new = NIL; FLAC__METADATA_CHAIN_DELETE ex_FLAC__metadata_chain_delete = NIL; FLAC__METADATA_CHAIN_READ_WITH_CALLBACKS ex_FLAC__metadata_chain_read_with_callbacks = NIL; FLAC__METADATA_CHAIN_READ_OGG_WITH_CALLBACKS ex_FLAC__metadata_chain_read_ogg_with_callbacks = NIL; FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS ex_FLAC__metadata_chain_write_with_callbacks = NIL; FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS_AND_TEMPFILE ex_FLAC__metadata_chain_write_with_callbacks_and_tempfile = NIL; FLAC__METADATA_CHAIN_SORT_PADDING ex_FLAC__metadata_chain_sort_padding = NIL; FLAC__METADATA_CHAIN_CHECK_IF_TEMPFILE_NEEDED ex_FLAC__metadata_chain_check_if_tempfile_needed = NIL; FLAC__METADATA_CHAIN_STATUS ex_FLAC__metadata_chain_status = NIL; FLAC__METADATA_ITERATOR_NEW ex_FLAC__metadata_iterator_new = NIL; FLAC__METADATA_ITERATOR_DELETE ex_FLAC__metadata_iterator_delete = NIL; FLAC__METADATA_ITERATOR_INIT ex_FLAC__metadata_iterator_init = NIL; FLAC__METADATA_ITERATOR_NEXT ex_FLAC__metadata_iterator_next = NIL; FLAC__METADATA_ITERATOR_PREV ex_FLAC__metadata_iterator_prev = NIL; FLAC__METADATA_ITERATOR_GET_BLOCK_TYPE ex_FLAC__metadata_iterator_get_block_type = NIL; FLAC__METADATA_ITERATOR_GET_BLOCK ex_FLAC__metadata_iterator_get_block = NIL; FLAC__METADATA_ITERATOR_DELETE_BLOCK ex_FLAC__metadata_iterator_delete_block = NIL; FLAC__METADATA_ITERATOR_INSERT_BLOCK_AFTER ex_FLAC__metadata_iterator_insert_block_after = NIL; FLAC__METADATA_OBJECT_NEW ex_FLAC__metadata_object_new = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE ex_FLAC__metadata_object_picture_set_mime_type = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION ex_FLAC__metadata_object_picture_set_description = NIL; FLAC__METADATA_OBJECT_PICTURE_SET_DATA ex_FLAC__metadata_object_picture_set_data = NIL; FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT ex_FLAC__metadata_object_vorbiscomment_append_comment = NIL; FLAC__VENDOR_STRING_TYPE ex_FLAC__VENDOR_STRING = NIL; DynamicLoader *flacdll = NIL; Bool LoadFLACDLL() { flacdll = BoCA::Utilities::LoadCodecDLL("FLAC"); if (flacdll == NIL) return False; ex_FLAC_API_SUPPORTS_OGG_FLAC = (FLAC_API_SUPPORTS_OGG_FLAC_TYPE) flacdll->GetFunctionAddress("FLAC_API_SUPPORTS_OGG_FLAC"); ex_FLAC__metadata_chain_new = (FLAC__METADATA_CHAIN_NEW) flacdll->GetFunctionAddress("FLAC__metadata_chain_new"); ex_FLAC__metadata_chain_delete = (FLAC__METADATA_CHAIN_DELETE) flacdll->GetFunctionAddress("FLAC__metadata_chain_delete"); ex_FLAC__metadata_chain_read_with_callbacks = (FLAC__METADATA_CHAIN_READ_WITH_CALLBACKS) flacdll->GetFunctionAddress("FLAC__metadata_chain_read_with_callbacks"); ex_FLAC__metadata_chain_read_ogg_with_callbacks = (FLAC__METADATA_CHAIN_READ_OGG_WITH_CALLBACKS) flacdll->GetFunctionAddress("FLAC__metadata_chain_read_ogg_with_callbacks"); ex_FLAC__metadata_chain_write_with_callbacks = (FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS) flacdll->GetFunctionAddress("FLAC__metadata_chain_write_with_callbacks"); ex_FLAC__metadata_chain_write_with_callbacks_and_tempfile = (FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS_AND_TEMPFILE) flacdll->GetFunctionAddress("FLAC__metadata_chain_write_with_callbacks_and_tempfile"); ex_FLAC__metadata_chain_sort_padding = (FLAC__METADATA_CHAIN_SORT_PADDING) flacdll->GetFunctionAddress("FLAC__metadata_chain_sort_padding"); ex_FLAC__metadata_chain_check_if_tempfile_needed = (FLAC__METADATA_CHAIN_CHECK_IF_TEMPFILE_NEEDED) flacdll->GetFunctionAddress("FLAC__metadata_chain_check_if_tempfile_needed"); ex_FLAC__metadata_chain_status = (FLAC__METADATA_CHAIN_STATUS) flacdll->GetFunctionAddress("FLAC__metadata_chain_status"); ex_FLAC__metadata_iterator_new = (FLAC__METADATA_ITERATOR_NEW) flacdll->GetFunctionAddress("FLAC__metadata_iterator_new"); ex_FLAC__metadata_iterator_delete = (FLAC__METADATA_ITERATOR_DELETE) flacdll->GetFunctionAddress("FLAC__metadata_iterator_delete"); ex_FLAC__metadata_iterator_init = (FLAC__METADATA_ITERATOR_INIT) flacdll->GetFunctionAddress("FLAC__metadata_iterator_init"); ex_FLAC__metadata_iterator_next = (FLAC__METADATA_ITERATOR_NEXT) flacdll->GetFunctionAddress("FLAC__metadata_iterator_next"); ex_FLAC__metadata_iterator_prev = (FLAC__METADATA_ITERATOR_PREV) flacdll->GetFunctionAddress("FLAC__metadata_iterator_prev"); ex_FLAC__metadata_iterator_get_block_type = (FLAC__METADATA_ITERATOR_GET_BLOCK_TYPE) flacdll->GetFunctionAddress("FLAC__metadata_iterator_get_block_type"); ex_FLAC__metadata_iterator_get_block = (FLAC__METADATA_ITERATOR_GET_BLOCK) flacdll->GetFunctionAddress("FLAC__metadata_iterator_get_block"); ex_FLAC__metadata_iterator_delete_block = (FLAC__METADATA_ITERATOR_DELETE_BLOCK) flacdll->GetFunctionAddress("FLAC__metadata_iterator_delete_block"); ex_FLAC__metadata_iterator_insert_block_after = (FLAC__METADATA_ITERATOR_INSERT_BLOCK_AFTER) flacdll->GetFunctionAddress("FLAC__metadata_iterator_insert_block_after"); ex_FLAC__metadata_object_new = (FLAC__METADATA_OBJECT_NEW) flacdll->GetFunctionAddress("FLAC__metadata_object_new"); ex_FLAC__metadata_object_picture_set_mime_type = (FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_mime_type"); ex_FLAC__metadata_object_picture_set_description = (FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_description"); ex_FLAC__metadata_object_picture_set_data = (FLAC__METADATA_OBJECT_PICTURE_SET_DATA) flacdll->GetFunctionAddress("FLAC__metadata_object_picture_set_data"); ex_FLAC__metadata_object_vorbiscomment_append_comment = (FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT) flacdll->GetFunctionAddress("FLAC__metadata_object_vorbiscomment_append_comment"); ex_FLAC__VENDOR_STRING = (FLAC__VENDOR_STRING_TYPE) flacdll->GetFunctionAddress("FLAC__VENDOR_STRING"); if (ex_FLAC_API_SUPPORTS_OGG_FLAC == NIL || ex_FLAC__metadata_chain_new == NIL || ex_FLAC__metadata_chain_delete == NIL || ex_FLAC__metadata_chain_read_with_callbacks == NIL || ex_FLAC__metadata_chain_read_ogg_with_callbacks == NIL || ex_FLAC__metadata_chain_write_with_callbacks == NIL || ex_FLAC__metadata_chain_write_with_callbacks_and_tempfile == NIL || ex_FLAC__metadata_chain_sort_padding == NIL || ex_FLAC__metadata_chain_check_if_tempfile_needed == NIL || ex_FLAC__metadata_chain_status == NIL || ex_FLAC__metadata_iterator_new == NIL || ex_FLAC__metadata_iterator_delete == NIL || ex_FLAC__metadata_iterator_init == NIL || ex_FLAC__metadata_iterator_next == NIL || ex_FLAC__metadata_iterator_prev == NIL || ex_FLAC__metadata_iterator_get_block_type == NIL || ex_FLAC__metadata_iterator_delete_block == NIL || ex_FLAC__metadata_iterator_insert_block_after == NIL || ex_FLAC__metadata_object_new == NIL || ex_FLAC__metadata_object_picture_set_mime_type == NIL || ex_FLAC__metadata_object_picture_set_description == NIL || ex_FLAC__metadata_object_picture_set_data == NIL || ex_FLAC__metadata_object_vorbiscomment_append_comment == NIL || ex_FLAC__VENDOR_STRING == NIL) { FreeFLACDLL(); return False; } return True; } Void FreeFLACDLL() { BoCA::Utilities::FreeCodecDLL(flacdll); flacdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/dllinterface.h000077500000000000000000000126451516712004000253470ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #undef callbacks #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *flacdll; Bool LoadFLACDLL(); Void FreeFLACDLL(); typedef int *FLAC_API_SUPPORTS_OGG_FLAC_TYPE; typedef FLAC__Metadata_Chain * (*FLAC__METADATA_CHAIN_NEW) (); typedef void (*FLAC__METADATA_CHAIN_DELETE) (FLAC__Metadata_Chain *); typedef FLAC__bool (*FLAC__METADATA_CHAIN_READ_WITH_CALLBACKS) (FLAC__Metadata_Chain *, FLAC__IOHandle, FLAC__IOCallbacks); typedef FLAC__bool (*FLAC__METADATA_CHAIN_READ_OGG_WITH_CALLBACKS) (FLAC__Metadata_Chain *, FLAC__IOHandle, FLAC__IOCallbacks); typedef FLAC__bool (*FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS) (FLAC__Metadata_Chain *, FLAC__bool, FLAC__IOHandle, FLAC__IOCallbacks); typedef FLAC__bool (*FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS_AND_TEMPFILE) (FLAC__Metadata_Chain *, FLAC__bool, FLAC__IOHandle, FLAC__IOCallbacks, FLAC__IOHandle, FLAC__IOCallbacks); typedef void (*FLAC__METADATA_CHAIN_SORT_PADDING) (FLAC__Metadata_Chain *); typedef FLAC__bool (*FLAC__METADATA_CHAIN_CHECK_IF_TEMPFILE_NEEDED) (FLAC__Metadata_Chain *); typedef FLAC__Metadata_ChainStatus (*FLAC__METADATA_CHAIN_STATUS) (FLAC__Metadata_Chain *); typedef FLAC__Metadata_Iterator * (*FLAC__METADATA_ITERATOR_NEW) (); typedef void (*FLAC__METADATA_ITERATOR_DELETE) (FLAC__Metadata_Iterator *); typedef void (*FLAC__METADATA_ITERATOR_INIT) (FLAC__Metadata_Iterator *, FLAC__Metadata_Chain *); typedef FLAC__bool (*FLAC__METADATA_ITERATOR_NEXT) (FLAC__Metadata_Iterator *); typedef FLAC__bool (*FLAC__METADATA_ITERATOR_PREV) (FLAC__Metadata_Iterator *); typedef FLAC__MetadataType (*FLAC__METADATA_ITERATOR_GET_BLOCK_TYPE) (const FLAC__Metadata_Iterator *); typedef FLAC__StreamMetadata * (*FLAC__METADATA_ITERATOR_GET_BLOCK) (const FLAC__Metadata_Iterator *); typedef FLAC__bool (*FLAC__METADATA_ITERATOR_DELETE_BLOCK) (FLAC__Metadata_Iterator *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_ITERATOR_INSERT_BLOCK_AFTER) (FLAC__Metadata_Iterator *, FLAC__StreamMetadata *); typedef FLAC__StreamMetadata * (*FLAC__METADATA_OBJECT_NEW) (FLAC__MetadataType); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE) (FLAC__StreamMetadata *, char *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION) (FLAC__StreamMetadata *, FLAC__byte *, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_PICTURE_SET_DATA) (FLAC__StreamMetadata *, FLAC__byte *, FLAC__uint32, FLAC__bool); typedef FLAC__bool (*FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT) (FLAC__StreamMetadata *, FLAC__StreamMetadata_VorbisComment_Entry, FLAC__bool); typedef char * *FLAC__VENDOR_STRING_TYPE; extern FLAC_API_SUPPORTS_OGG_FLAC_TYPE ex_FLAC_API_SUPPORTS_OGG_FLAC; extern FLAC__METADATA_CHAIN_NEW ex_FLAC__metadata_chain_new; extern FLAC__METADATA_CHAIN_DELETE ex_FLAC__metadata_chain_delete; extern FLAC__METADATA_CHAIN_READ_WITH_CALLBACKS ex_FLAC__metadata_chain_read_with_callbacks; extern FLAC__METADATA_CHAIN_READ_OGG_WITH_CALLBACKS ex_FLAC__metadata_chain_read_ogg_with_callbacks; extern FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS ex_FLAC__metadata_chain_write_with_callbacks; extern FLAC__METADATA_CHAIN_WRITE_WITH_CALLBACKS_AND_TEMPFILE ex_FLAC__metadata_chain_write_with_callbacks_and_tempfile; extern FLAC__METADATA_CHAIN_SORT_PADDING ex_FLAC__metadata_chain_sort_padding; extern FLAC__METADATA_CHAIN_CHECK_IF_TEMPFILE_NEEDED ex_FLAC__metadata_chain_check_if_tempfile_needed; extern FLAC__METADATA_CHAIN_STATUS ex_FLAC__metadata_chain_status; extern FLAC__METADATA_ITERATOR_NEW ex_FLAC__metadata_iterator_new; extern FLAC__METADATA_ITERATOR_DELETE ex_FLAC__metadata_iterator_delete; extern FLAC__METADATA_ITERATOR_INIT ex_FLAC__metadata_iterator_init; extern FLAC__METADATA_ITERATOR_NEXT ex_FLAC__metadata_iterator_next; extern FLAC__METADATA_ITERATOR_PREV ex_FLAC__metadata_iterator_prev; extern FLAC__METADATA_ITERATOR_GET_BLOCK_TYPE ex_FLAC__metadata_iterator_get_block_type; extern FLAC__METADATA_ITERATOR_GET_BLOCK ex_FLAC__metadata_iterator_get_block; extern FLAC__METADATA_ITERATOR_DELETE_BLOCK ex_FLAC__metadata_iterator_delete_block; extern FLAC__METADATA_ITERATOR_INSERT_BLOCK_AFTER ex_FLAC__metadata_iterator_insert_block_after; extern FLAC__METADATA_OBJECT_NEW ex_FLAC__metadata_object_new; extern FLAC__METADATA_OBJECT_PICTURE_SET_MIME_TYPE ex_FLAC__metadata_object_picture_set_mime_type; extern FLAC__METADATA_OBJECT_PICTURE_SET_DESCRIPTION ex_FLAC__metadata_object_picture_set_description; extern FLAC__METADATA_OBJECT_PICTURE_SET_DATA ex_FLAC__metadata_object_picture_set_data; extern FLAC__METADATA_OBJECT_VORBISCOMMENT_APPEND_COMMENT ex_FLAC__metadata_object_vorbiscomment_append_comment; extern FLAC__VENDOR_STRING_TYPE ex_FLAC__VENDOR_STRING; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/flac.cpp000066400000000000000000000231111516712004000241360ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "flac.h" using namespace smooth::IO; const String &BoCA::TaggerFLAC::GetComponentSpecs() { static String componentSpecs; if (flacdll != NIL) { componentSpecs = " \ \ \ \ FLAC Audio Tagger \ 1.0 \ flac-tag \ tagger \ vorbis-tag \ \ FLAC Audio Files \ flac \ \ \ "; if (*ex_FLAC_API_SUPPORTS_OGG_FLAC == 1) { componentSpecs.Append(" \ \ \ Ogg FLAC Files \ oga \ \ \ "); } componentSpecs.Append(" \ \ \ FLAC Metadata \ \ \ \ UTF-8 \ \ \ \ \ "); } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadFLACDLL(); } Void smooth::DetachDLL() { FreeFLACDLL(); } namespace BoCA { size_t FLACIOCallbackRead(void *, size_t, size_t, FLAC__IOHandle); size_t FLACIOCallbackWrite(const void *, size_t, size_t, FLAC__IOHandle); int FLACIOCallbackSeek(FLAC__IOHandle, FLAC__int64, int); FLAC__int64 FLACIOCallbackTell(FLAC__IOHandle); int FLACIOCallbackEof(FLAC__IOHandle); }; const String BoCA::TaggerFLAC::ConfigID = "Tags"; BoCA::TaggerFLAC::TaggerFLAC() { } BoCA::TaggerFLAC::~TaggerFLAC() { } Error BoCA::TaggerFLAC::RenderStreamInfo(const String &streamURI, const Track &track) { /* Render works like update for FLAC files. */ return UpdateStreamInfo(streamURI, track); } Error BoCA::TaggerFLAC::UpdateStreamInfo(const String &streamURI, const Track &track) { InStream in(STREAM_FILE, streamURI, IS_READ | IS_WRITE); String fileType = in.InputString(4); if (fileType != "fLaC" && fileType != "OggS") return Error(); if (fileType == "OggS" && *ex_FLAC_API_SUPPORTS_OGG_FLAC == 0) return Error(); /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool enableFLACMetadata = currentConfig->GetIntValue(ConfigID, "EnableFLACMetadata", True); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroFLACMetadata", True); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToFLAC = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToFLACMetadata", True); /* Set up callbacks. */ FLAC__IOCallbacks callbacks; callbacks.read = FLACIOCallbackRead; callbacks.write = FLACIOCallbackWrite; callbacks.seek = FLACIOCallbackSeek; callbacks.tell = FLACIOCallbackTell; callbacks.eof = FLACIOCallbackEof; callbacks.close = NIL; FLAC__bool success = false; FLAC__Metadata_Chain *chain = ex_FLAC__metadata_chain_new(); if (fileType == "fLaC") success = ex_FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle) &in, callbacks); else if (fileType == "OggS") success = ex_FLAC__metadata_chain_read_ogg_with_callbacks(chain, (FLAC__IOHandle) &in, callbacks); if (!success) { ex_FLAC__metadata_chain_delete(chain); return Error(); } FLAC__Metadata_Iterator *iterator = ex_FLAC__metadata_iterator_new(); ex_FLAC__metadata_iterator_init(iterator, chain); /* Delete existing metadata first. */ Int64 pictureSizeBefore = 0; do { FLAC__MetadataType type = ex_FLAC__metadata_iterator_get_block_type(iterator); if (type == FLAC__METADATA_TYPE_VORBIS_COMMENT) ex_FLAC__metadata_iterator_delete_block(iterator, true); else if (type == FLAC__METADATA_TYPE_PICTURE) { pictureSizeBefore += ex_FLAC__metadata_iterator_get_block(iterator)->length; ex_FLAC__metadata_iterator_delete_block(iterator, false); } } while (ex_FLAC__metadata_iterator_next(iterator)); /* Now write updated metadata. */ const Info &info = track.GetInfo(); Buffer vcBuffer; if (enableFLACMetadata && (info.HasBasicInfo() || (track.tracks.Length() > 0 && writeChapters))) { FLAC__StreamMetadata *vorbiscomment = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); AS::Registry &boca = AS::Registry::Get(); AS::TaggerComponent *tagger = (AS::TaggerComponent *) boca.CreateComponentByID("vorbis-tag"); if (tagger != NIL) { /* Disable writing album art to Vorbis comment tags for FLAC files. */ Config *taggerConfig = Config::Copy(currentConfig); taggerConfig->SetIntValue(ConfigID, "CoverArtWriteToVorbisComment", False); taggerConfig->SetIntValue(ConfigID, "TrackPrependZeroVorbisComment", prependZero); tagger->SetConfiguration(taggerConfig); tagger->SetVendorString(*ex_FLAC__VENDOR_STRING); tagger->RenderBuffer(vcBuffer, track); boca.DeleteComponent(tagger); Config::Free(taggerConfig); } /* Process output comment tag and add it to FLAC metadata. */ InStream in(STREAM_BUFFER, vcBuffer, vcBuffer.Size()); in.RelSeek(in.InputNumber(4)); Int numComments = in.InputNumber(4); for (Int i = 0; i < numComments; i++) { FLAC__StreamMetadata_VorbisComment_Entry entry; entry.length = in.InputNumber(4); entry.entry = vcBuffer + in.GetPos(); ex_FLAC__metadata_object_vorbiscomment_append_comment(vorbiscomment, entry, true); in.RelSeek(entry.length); } vorbiscomment->length = vcBuffer.Size(); ex_FLAC__metadata_iterator_init(iterator, chain); ex_FLAC__metadata_iterator_insert_block_after(iterator, vorbiscomment); } /* Point iterator at seektable, if any. */ do { FLAC__MetadataType type = ex_FLAC__metadata_iterator_get_block_type(iterator); if (type == FLAC__METADATA_TYPE_SEEKTABLE) break; else if (type == FLAC__METADATA_TYPE_PADDING) { ex_FLAC__metadata_iterator_prev(iterator); break; } } while (ex_FLAC__metadata_iterator_next(iterator)); /* Insert picture metadata. */ Int64 pictureSizeAfter = 0; if (albumArtWriteToTags && albumArtWriteToFLAC) { for (Int i = 0; i < track.pictures.Length(); i++) { FLAC__StreamMetadata *picture = ex_FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE); const Picture &picInfo = track.pictures.GetNth(i); if (picInfo.mime != NIL) ex_FLAC__metadata_object_picture_set_mime_type(picture, picInfo.mime, true); if (picInfo.description != NIL) ex_FLAC__metadata_object_picture_set_description(picture, (FLAC__byte *) picInfo.description.Trim().ConvertTo("UTF-8"), true); ex_FLAC__metadata_object_picture_set_data(picture, const_cast((const UnsignedByte *) picInfo.data), picInfo.data.Size(), true); picture->data.picture.type = (FLAC__StreamMetadata_Picture_Type) picInfo.type; ex_FLAC__metadata_iterator_insert_block_after(iterator, picture); pictureSizeAfter += picture->length; } } ex_FLAC__metadata_iterator_delete(iterator); /* Adjust padding and write changes. */ ex_FLAC__metadata_chain_sort_padding(chain); if (!ex_FLAC__metadata_chain_check_if_tempfile_needed(chain) && pictureSizeBefore - pictureSizeAfter <= 4096) { OutStream out(STREAM_STREAM, &in); if (!ex_FLAC__metadata_chain_write_with_callbacks(chain, true, (FLAC__IOHandle) &out, callbacks)) { errorState = True; } } else { OutStream out(STREAM_FILE, streamURI.Append(".temp"), OS_REPLACE); if (!ex_FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, pictureSizeBefore - pictureSizeAfter <= 4096, (FLAC__IOHandle) &in, callbacks, (FLAC__IOHandle) &out, callbacks)) { errorState = True; } out.Close(); in.Close(); if (!errorState) { File(streamURI).Delete(); File(streamURI.Append(".temp")).Move(streamURI); } } ex_FLAC__metadata_chain_delete(chain); if (errorState) return Error(); else return Success(); } size_t BoCA::FLACIOCallbackRead(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle) { InStream *stream = (InStream *) handle; return stream->InputData(ptr, size * nmemb) / size; } size_t BoCA::FLACIOCallbackWrite(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle) { OutStream *stream = (OutStream *) handle; if (stream->OutputData(ptr, size * nmemb)) return nmemb; else return 0; } int BoCA::FLACIOCallbackSeek(FLAC__IOHandle handle, FLAC__int64 offset, int whence) { Stream *stream = (Stream *) handle; if (whence == SEEK_CUR) stream->Seek(stream->GetPos() + offset); else if (whence == SEEK_SET) stream->Seek( offset); else if (whence == SEEK_END) stream->Seek(stream->Size() + offset); return 0; } FLAC__int64 BoCA::FLACIOCallbackTell(FLAC__IOHandle handle) { Stream *stream = (Stream *) handle; return stream->GetPos(); } FLAC__bool BoCA::FLACIOCallbackEof(FLAC__IOHandle handle) { Stream *stream = (Stream *) handle; return stream->GetPos() >= stream->Size(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/flac/flac.h000066400000000000000000000020621516712004000236050ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(TaggerFLAC) namespace BoCA { class TaggerFLAC : public CS::TaggerComponent { private: static const String ConfigID; public: static const String &GetComponentSpecs(); TaggerFLAC(); ~TaggerFLAC(); Error RenderStreamInfo(const String &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerFLAC) BoCA_END_COMPONENT(TaggerFLAC) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v1/000077500000000000000000000000001516712004000225505ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v1/Makefile000077500000000000000000000011211516712004000242060ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = id3v1 TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = id3v1.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v1/id3v1.cpp000066400000000000000000000203311516712004000242010ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "id3v1.h" using namespace smooth::IO; const String &BoCA::TaggerID3v1::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ ID3v1 Tagger \ 1.0 \ id3v1-tag \ tagger \ \ MPEG 1 Audio Layer 3 \ mp3 \ \ \ ID3v1 \ \ ISO-8859-1 \ ISO-8859-2 \ ISO-8859-5 \ ISO-8859-7 \ CP1251 \ \ \ \ \ "; return componentSpecs; } const String BoCA::TaggerID3v1::ConfigID = "Tags"; const String BoCA::TaggerID3v1::genres[192] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alt. Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta Rap", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop", "Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout", "Downtempo", "Dub", "EBM", "Eclectic", "Electro", "Electroclash", "Emo", "Experimental", "Garage", "Global", "IDM", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield", "Lounge", "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance", "Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical", "Audiobook", "Audio Theatre", "Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient" }; BoCA::TaggerID3v1::TaggerID3v1() { } BoCA::TaggerID3v1::~TaggerID3v1() { } Error BoCA::TaggerID3v1::RenderBuffer(Buffer &buffer, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); String encodingID = currentConfig->GetStringValue(ConfigID, "ID3v1Encoding", "ISO-8859-1"); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Open buffer. */ buffer.Resize(128); OutStream out(STREAM_BUFFER, buffer, buffer.Size()); out.OutputString("TAG"); const Info &info = track.GetInfo(); String::OutputFormat outputFormat(encodingID); { String value = info.title.Trim(); out.OutputString(value.Head(Math::Min(30, value.Length()))); for (Int i = 0; i < 30 - value.Length(); i++) out.OutputNumber(0, 1); } { String value = info.artist.Trim(); out.OutputString(value.Head(Math::Min(30, value.Length()))); for (Int i = 0; i < 30 - value.Length(); i++) out.OutputNumber(0, 1); } { String value = info.album.Trim(); out.OutputString(value.Head(Math::Min(30, value.Length()))); for (Int i = 0; i < 30 - value.Length(); i++) out.OutputNumber(0, 1); } if (info.year > 0) { String value = String::FromInt(info.year); out.OutputString(String().FillN('0', 4 - value.Length())); out.OutputString(value.Tail(Math::Min(4, value.Length()))); } else { out.OutputNumber(0, 4); } String comment; if (info.comment != NIL && !replaceExistingComments) comment = info.comment.Trim(); else if (defaultComment != NIL) comment = defaultComment.Trim(); if (info.track > 0) { { out.OutputString(comment.Head(Math::Min(28, comment.Length()))); for (Int i = 0; i < 28 - comment.Length(); i++) out.OutputNumber(0, 1); } out.OutputNumber(0, 1); out.OutputNumber(info.track, 1); } else { { out.OutputString(comment.Head(Math::Min(30, comment.Length()))); for (Int i = 0; i < 30 - comment.Length(); i++) out.OutputNumber(0, 1); } } out.OutputNumber(GetID3CategoryID(info.genre), 1); return Success(); } Error BoCA::TaggerID3v1::ParseBuffer(const Buffer &buffer, Track &track) { if (buffer.Size() != 128) return Error(); InStream in(STREAM_BUFFER, buffer, buffer.Size()); /* Check if we actually have an * ID3v1 tag, then parse it. */ if (in.InputString(3) == "TAG") { String::InputFormat inputFormat("ISO-8859-1"); Info info = track.GetInfo(); info.title = in.InputString(30).Trim(); info.artist = in.InputString(30).Trim(); info.album = in.InputString(30).Trim(); info.year = in.InputString( 4).Trim().ToInt(); info.comment = in.InputString(28).Trim(); if (in.InputNumber(1) == 0) { Int n = in.InputNumber(1); if (n > 0) info.track = n; } else { in.RelSeek(-29); info.comment = in.InputString(30).Trim(); } info.genre = GetID3CategoryName(in.InputNumber(1)); track.SetInfo(info); return Success(); } return Error(); } Error BoCA::TaggerID3v1::ParseStreamInfo(const String &fileName, Track &track) { /* Open file and check size. */ InStream in(STREAM_FILE, fileName, IS_READ); if (in.Size() < 128) return Error(); /* Copy tag to buffer and parse it. */ Buffer buffer(128); in.Seek(in.Size() - 128); in.InputData(buffer, 128); return ParseBuffer(buffer, track); } Error BoCA::TaggerID3v1::UpdateStreamInfo(const String &fileName, const Track &track) { /* Open file and check size. */ InStream in(STREAM_FILE, fileName, IS_READ); if (in.Size() < 128) return Error(); /* Find existing tag if any. */ Int offset = 0; in.Seek(in.Size() - 128); if (in.InputString(3) == "TAG") offset = -128; in.Close(); /* Append new ID3v1 tag. */ OutStream out(STREAM_FILE, fileName, OS_APPEND); if (out.GetLastError() == IO_ERROR_OK) { out.RelSeek(offset); Buffer buffer(128); RenderBuffer(buffer, track); out.OutputData(buffer, 128); return Success(); } return Error(); } const String &BoCA::TaggerID3v1::GetID3CategoryName(UnsignedInt id) { static const String empty; if (id > 191) return empty; else return genres[id]; } UnsignedInt BoCA::TaggerID3v1::GetID3CategoryID(const String &name) { for (UnsignedInt i = 0; i < 192; i++) { if (genres[i] == name) return i; } return 12; // Other } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v1/id3v1.h000066400000000000000000000024631516712004000236540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(TaggerID3v1) namespace BoCA { class TaggerID3v1 : public CS::TaggerComponent { private: static const String ConfigID; static const String genres[192]; static const String &GetID3CategoryName(UnsignedInt); static UnsignedInt GetID3CategoryID(const String &); public: static const String &GetComponentSpecs(); TaggerID3v1(); ~TaggerID3v1(); Error ParseBuffer(const Buffer &, Track &); Error ParseStreamInfo(const String &, Track &); Error RenderBuffer(Buffer &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerID3v1) BoCA_END_COMPONENT(TaggerID3v1) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/000077500000000000000000000000001516712004000225515ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/Makefile000077500000000000000000000017311516712004000242160ustar00rootroot00000000000000########## BoCA component makefile ########## .NOTPARALLEL: # Change these variables to fit your project: TARGET = id3v2 TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options # Enter object files here: OBJECTS = id3v2.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/id3 -DID3LIB_LINKOPTION=LINKOPTION_STATIC # Enter additional library dependencies here: LIBS = id3/libid3.a ifeq ($(USE_BUNDLED_ZLIB),True) LIBS += zlib/libz.a else LIBS += -lz endif # Enter addition commands for targets all and clean here: ALLCMD1 = $(call makein,id3) ALLCMD2 = CLEANCMD1 = $(call cleanin,id3) CLEANCMD2 = ifeq ($(USE_BUNDLED_ZLIB),True) ALLCMD1 += && $(call makein,zlib) CLEANCMD1 += && $(call cleanin,zlib) endif INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/000077500000000000000000000000001516712004000232305ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/Makefile000066400000000000000000000017041516712004000246720ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = container.o container_find.o container_impl.o container_parse.o container_render.o field.o field_binary.o field_frames.o field_integer.o field_string_ascii.o field_string_unicode.o frame.o frame_impl.o frame_parse.o frame_render.o globals.o header.o header_frame.o header_tag.o helpers.o io.o io_decorators.o io_helpers.o misc_support.o mp3_parse.o spec.o tag.o tag_file.o tag_impl.o tag_parse.o tag_parse_lyrics3.o tag_parse_musicmatch.o tag_parse_v1.o tag_render.o utils.o TARGET = libid3.a CCOPTS = -I"$(SRCDIR)" -DHAVE_CONFIG_H -DID3LIB_LINKOPTION=LINKOPTION_STATIC AR = ar ifeq ($(USE_BUNDLED_ZLIB),True) CCOPTS += -I"$(SRCDIR)"/../zlib endif ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .cpp.o: $(CXX) $(CCOPTS) $(CXXFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/config.h000066400000000000000000000122321516712004000246460ustar00rootroot00000000000000/* config.h.in. Generated automatically from configure.in by autoheader. */ /* ** This file has been automatically generated by 'acconfig' from aclocal.m4 ** Copyright (C) 1988 Eleftherios Gkioulekas ** ** This file is free software; as a special exception the author gives ** unlimited permission to copy and/or distribute it, with or without ** modifications, as long as this notice is preserved. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY, to the extent permitted by law; without even the ** implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* This is the top section */ /* Define if you need to in order for stat and other things to work. */ /* #undef _POSIX_SOURCE */ /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* And now the rest of the boys */ /* #undef CXX_HAS_BUGGY_FOR_LOOPS */ /* #undef CXX_HAS_NO_BOOL */ /* #undef ID3_ENABLE_DEBUG */ /* #undef ID3_DISABLE_ASSERT */ /* #undef ID3_DISABLE_CHECKS */ /* #undef ID3_ICONV_FORMAT_UTF16BE */ /* #undef ID3_ICONV_FORMAT_UTF16 */ /* #undef ID3_ICONV_FORMAT_UTF8 */ /* #undef ID3_ICONV_FORMAT_ASCII */ /* #undef ID3LIB_ICONV_OLDSTYLE */ /* #undef ID3LIB_ICONV_CAST_OK */ /* config.h defines these preprocesser symbols to be used by id3lib for * determining internal versioning information. The intent is that these * macros will be made available in the library via constants, functions, * or static methods. */ /* #undef HAVE_ZLIB */ /* #undef HAVE_GETOPT_LONG */ #define _ID3LIB_NAME "id3lib" #define _ID3LIB_VERSION "3.8.4" #define _ID3LIB_VERSION0 "3.8.4\0" #define _ID3LIB_FULLNAME "id3lib-3.8.4" #define _ID3LIB_MAJOR_VERSION 3 #define _ID3LIB_MINOR_VERSION 8 #define _ID3LIB_PATCH_VERSION 4 #define _ID3LIB_INTERFACE_AGE 0 #define _ID3LIB_BINARY_AGE 0 /* #undef ID3_COMPILED_WITH_DEBUGGING */ /* */ /* Define if you have the getopt_long function. */ #define HAVE_GETOPT_LONG 1 /* Define if you have the mkstemp function. */ /* #undef HAVE_MKSTEMP */ /* Define if you have the ftruncate function. */ /* #undef HAVE_TRUNCATE */ /* Define if you have the header file. */ #define HAVE_CCTYPE 1 /* Define if you have the header file. */ #define HAVE_CLIMITS 1 /* Define if you have the header file. */ #define HAVE_CSTDIO 1 /* Define if you have the header file. */ #define HAVE_CSTDLIB 1 /* Define if you have the header file. */ #define HAVE_CSTRING 1 /* Define if you have the header file. */ #define HAVE_FSTREAM 1 /* Define if you have the header file. */ #define HAVE_FSTREAM_H 1 /* Define if you have the header file. */ /* #undef HAVE_ICONV_H */ /* Define if you have the header file. */ #define HAVE_IOMANIP 1 /* Define if you have the header file. */ #define HAVE_IOMANIP_H 1 /* Define if you have the header file. */ #define HAVE_IOSTREAM 1 /* Define if you have the header file. */ #define HAVE_IOSTREAM_H 1 /* Define if you have the header file. */ /* #undef HAVE_LIBCW_SYS_H */ /* Define if you have the header file. */ #define HAVE_BITSET 1 /* Define if you have the header file. */ #define HAVE_STRING 1 /* Define if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define if you have the header file. */ #ifndef _MSC_VER # define HAVE_UNISTD_H 1 #endif /* Define if you have the header file. */ #define HAVE_WCHAR_H 1 /* Define if you have the header file. */ /* #undef HAVE_ZLIB_H */ /* Name of package */ #define PACKAGE "id3lib" /* Version number of package */ #define VERSION _ID3LIB_VERSION /* This is the bottom section */ // This file defines portability work-arounds for various proprietory // C++ compilers // Workaround for compilers with buggy for-loop scoping // That's quite a few compilers actually including recent versions of // Dec Alpha cxx, HP-UX CC and SGI CC. // The trivial "if" statement provides the correct scoping to the // for loop #ifdef CXX_HAS_BUGGY_FOR_LOOPS /* #undef for */ # define for if(1) for #endif // // If the C++ compiler we use doesn't have bool, then // the following is a near-perfect work-around. // You must make sure your code does not depend on "int" and "bool" // being two different types, in overloading for instance. // #ifdef CXX_HAS_NO_BOOL # define bool int # define true 1 # define false 0 #endif #if defined (ID3_ENABLE_DEBUG) && defined (HAVE_LIBCW_SYS_H) && defined (__cplusplus) # define DEBUG # include # include # define ID3D_INIT_DOUT() Debug( libcw_do.on() ) # define ID3D_INIT_WARNING() Debug( dc::warning.on() ) # define ID3D_INIT_NOTICE() Debug( dc::notice.on() ) # define ID3D_NOTICE(x) Dout( dc::notice, x ) # define ID3D_WARNING(x) Dout( dc::warning, x ) #else # define ID3D_INIT_DOUT() # define ID3D_INIT_WARNING() # define ID3D_INIT_NOTICE() # define ID3D_NOTICE(x) # define ID3D_WARNING(x) #endif /* defined (ID3_ENABLE_DEBUG) && defined (HAVE_LIBCW_SYS_H) */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container.cpp000066400000000000000000000263401516712004000257230ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "container_impl.h" #include using namespace dami; /** Default constructor. **/ ID3_Container::ID3_Container() : _impl(new ID3_ContainerImpl()), _own_impl(true) { } /** Constructor that accepts a implementation as a parameter. ** ** The implementation pointed to by impl will be used instead ** of a newly created implementation. ** ** \param impl The implementation object to use **/ ID3_Container::ID3_Container(ID3_ContainerImpl *impl) : _impl(impl), _own_impl(false) { } /** Standard copy constructor. ** ** \param tag What is copied into this tag **/ ID3_Container::ID3_Container(const ID3_Container &container) : _impl(new ID3_ContainerImpl(container)), _own_impl(true) { } ID3_Container::~ID3_Container() { if (_own_impl) delete _impl; } /** Clears the object and disassociates it from any files. ** ** Frees any resources for which the object is responsible, including all ** frames and files. After a call to Clear(), the object can be used ** again for any new or existing tag. **/ void ID3_Container::Clear() { _impl->Clear(); } /** Indicates whether the tag has been altered since the last parse, render, ** or update. ** ** If you have a tag linked to a file, you do not need this method since the ** Update() method will check for changes before writing the tag. ** ** This method is primarily intended as a status indicator for applications ** and for applications that use the Parse() and Render() methods. ** ** Setting a field, changed the ID of an attached frame, setting or grouping ** or encryption IDs, and clearing a frame or field all constitute a change ** to the tag, as do calls to the SetUnsync(), SetExtendedHeader(), and ** SetPadding() methods. ** ** \code ** if (myTag.HasChanged()) ** { ** // render and output the tag ** } ** \endcode ** ** \return Whether or not the tag has been altered. **/ bool ID3_Container::HasChanged() const { return _impl->HasChanged(); } /** Returns an over estimate of the number of bytes required to store a ** binary version of a tag. ** ** When using Render() to render a binary tag to a ** memory buffer, first use the result of this call to allocate a buffer of ** unsigned chars. ** ** \code ** if (myTag.HasChanged()) ** { ** size_t tagSize; = myTag.Size(); ** if (tagSize > 0) ** { ** uchar *buffer = new uchar[tagSize]; ** if (NULL != buffer) ** { ** size_t actualSize = myTag.Render(buffer); ** // do something useful with the first ** // 'actualSize' bytes of the buffer, ** // like push it down a socket ** delete [] buffer; ** } ** } ** } ** \endcode ** ** @see #Render ** @return The (overestimated) number of bytes required to store a binary ** version of a tag **/ size_t ID3_Container::Size() const { return _impl->Size(); } void ID3_Container::AddFrame(const ID3_Frame &frame) { _impl->AddFrame(frame); } /** Attaches a frame to the tag; the tag doesn't take responsibility for ** releasing the frame's memory when tag goes out of scope. ** ** Optionally, operator<< can also be used to attach a frame to a tag. To ** use, simply supply its parameter a pointer to the ID3_Frame object you wish ** to attach. ** ** \code ** ID3_Frame myFrame; ** myTag.AddFrame(&myFrame); ** \endcode ** ** As stated, this method attaches the frames to the tag---the tag does ** not create its own copy of the frame. Frames created by an application ** must exist until the frame is removed or the tag is finished with it. ** ** \param pFrame A pointer to the frame that is being added to the tag. ** \sa ID3_Frame **/ void ID3_Container::AddFrame(const ID3_Frame *frame) { _impl->AddFrame(frame); } /** Attaches a frame to the tag; the tag takes responsibility for ** releasing the frame's memory when tag goes out of scope. ** ** This method accepts responsibility for the attached frame's memory, and ** will delete the frame and its contents when the tag goes out of scope or is ** deleted. Therefore, be sure the frame isn't "Attached" to other tags. ** ** \code ** ID3_Frame *frame = new ID3_Frame; ** myTag.AttachFrame(frame); ** \endcode ** ** \param frame A pointer to the frame that is being added to the tag. **/ bool ID3_Container::AttachFrame(ID3_Frame *frame) { return _impl->AttachFrame(frame); } /** Removes a frame from the tag. ** ** If you already own the frame object in question, then you should already ** have a pointer to the frame you want to delete. If not, or if you wish to ** delete a pre-existing frame (from a tag you have parsed, for example), the ** use one of the Find methods to obtain a frame pointer to pass to this ** method. ** ** \code ** ID3_Frame *someFrame; ** if (someFrame = myTag.Find(ID3FID_TITLE)) ** { ** myTag.RemoveFrame(someFrame); ** } ** \endcode ** ** \sa ID3_Tag#Find ** \param pOldFrame A pointer to the frame that is to be removed from the ** tag **/ ID3_Frame* ID3_Container::RemoveFrame(const ID3_Frame *frame) { return _impl->RemoveFrame(frame); } /// Finds frame with given frame id /** Returns a pointer to the next ID3_Frame with the given ID3_FrameID; ** returns NULL if no such frame found. ** ** If there are multiple frames in the tag with the same ID (which, for some ** frames, is allowed), then subsequent calls to Find() will return ** subsequent frame pointers, wrapping if necessary. ** ** \code ** ID3_Frame *myFrame; ** if (myFrame = myTag.Find(ID3FID_TITLE)) ** { ** // do something with the frame, like copy ** // the contents into a buffer, display the ** // contents in a window, etc. ** // ... ** } ** \endcode ** ** You may optionally supply to more parameters ot this method, being an ** ID3_FieldID and a value of some sort. Depending on the field name/ID you ** supply, you may supply an integer, a char* or a unicode_t* as the third ** parameter. If you supply an ID3_FrameID, you must also supply a data ** value to compare against. ** ** This method will then return the first frame that has a matching frame ** ID, and which has a field with the same name as that which you supplied ** in the second parameter, whose calue matches that which you supplied as ** the third parameter. For example: ** ** \code ** ID3_Frame *myFrame; ** if (myFrame = myTag.Find(ID3FID_TITLE, ID3FN_TEXT, "Nirvana")) ** { ** // found it, do something with it. ** // ... ** } ** \endcode ** ** This example will return the first TITLE frame and whose TEXT field is ** 'Nirvana'. Currently there is no provision for things like 'contains', ** 'greater than', or 'less than'. If there happens to be more than one of ** these frames, subsequent calls to the Find() method will return ** subsequent frames and will wrap around to the beginning. ** ** Another example... ** ** \code ** ID3_Frame *myFrame; ** if (myFrame = myTag.Find(ID3FID_COMMENT, ID3FN_TEXTENC, ID3TE_UNICODE)) ** { ** // found it, do something with it. ** // ... ** } ** \endcode ** ** This returns the first COMMENT frame that uses Unicode as its text ** encdoing. ** ** @name Find ** @param id The ID of the frame that is to be located ** @return A pointer to the first frame found that has the given frame id, ** or NULL if no such frame. **/ ID3_Frame* ID3_Container::Find(ID3_FrameID id) const { return _impl->Find(id); } /// Finds frame with given frame id, fld id, and integer data ID3_Frame* ID3_Container::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const { return _impl->Find(id, fld, data); } /// Finds frame with given frame id, fld id, and ascii data ID3_Frame* ID3_Container::Find(ID3_FrameID id, ID3_FieldID fld, const char *data) const { String str(data); return _impl->Find(id, fld, str); } /// Finds frame with given frame id, fld id, and unicode data ID3_Frame *ID3_Container::Find(ID3_FrameID id, ID3_FieldID fld, const unicode_t *data) const { WString str = toWString(data, ucslen(data)); return _impl->Find(id, fld, str); } /** Returns the number of frames present in the tag object. ** ** This includes only those frames that id3lib recognises. This is used as ** the upper bound on calls to the GetFrame() and operator[]() methods. ** ** \return The number of frames present in the tag object. **/ size_t ID3_Container::NumFrames() const { return _impl->NumFrames(); } ID3_Container &ID3_Container::operator=( const ID3_Container &rContainer ) { if (this != &rContainer) *_impl = rContainer; return *this; } ID3_V2Spec ID3_Container::GetSpec() const { return _impl->GetSpec(); } bool ID3_Container::SetSpec(ID3_V2Spec spec) { //a user cannot set a spec lower than ID3V2_3_0, it's obsolete! ID3_V2Spec spec2use = spec < ID3V2_3_0 ? ID3V2_LATEST : spec; _impl->UserUpdatedSpec = _impl->GetSpec() != spec2use; return _impl->SetSpec(spec2use); } namespace { class IteratorImpl : public ID3_Container::Iterator { ID3_ContainerImpl::iterator _cur; ID3_ContainerImpl::iterator _end; public: IteratorImpl(ID3_ContainerImpl &container) : _cur(container.begin()), _end(container.end()) { } ID3_Frame *GetNext() { ID3_Frame *next = NULL; while (next == NULL && _cur != _end) { next = *_cur; ++_cur; } return next; } }; class ConstIteratorImpl : public ID3_Container::ConstIterator { ID3_ContainerImpl::const_iterator _cur; ID3_ContainerImpl::const_iterator _end; public: ConstIteratorImpl(ID3_ContainerImpl& container) : _cur(container.begin()), _end(container.end()) { } const ID3_Frame *GetNext() { ID3_Frame *next = NULL; while (next == NULL && _cur != _end) { next = *_cur; ++_cur; } return next; } }; } ID3_Container::Iterator *ID3_Container::CreateIterator() { return new IteratorImpl(*_impl); } ID3_Container::ConstIterator *ID3_Container::CreateIterator() const { return new ConstIteratorImpl(*_impl); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container_find.cpp000066400000000000000000000157511516712004000267270ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "container_impl.h" #include using namespace dami; ID3_ContainerImpl::const_iterator ID3_ContainerImpl::Find(const ID3_Frame *frame) const { const_iterator cur = _frames.begin(); for (; cur != _frames.end(); ++cur) { if (*cur == frame) break; } return cur; } ID3_ContainerImpl::iterator ID3_ContainerImpl::Find(const ID3_Frame *frame) { iterator cur = _frames.begin(); for (; cur != _frames.end(); ++cur) { if (*cur == frame) break; } return cur; } ID3_Frame *ID3_ContainerImpl::Find(ID3_FrameID id) const { ID3_Frame *frame = NULL; /* Reset the cursor if it isn't set. */ if (_frames.end() == _cursor) { _cursor = _frames.begin(); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { /* We want to cycle through the list to find the matching frame. We * should begin from the cursor, search each successive frame, wrapping * if necessary. The enclosing loop and the assignment statments below * ensure that we first begin at the cursor and search to the end of the * list and, if unsuccessful, start from the beginning of the list and * search to the cursor. */ const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); /* Search from the cursor to the end. */ for (const_iterator cur = begin; cur != end; ++cur) { if ((*cur != NULL) && ((*cur)->GetID() == id)) { /* We've found a valid frame. Set the cursor to be the next element. */ frame = *cur; _cursor = ++cur; break; } } } return frame; } ID3_Frame *ID3_ContainerImpl::Find(ID3_FrameID id, ID3_FieldID fldID, String data) const { ID3_Frame *frame = NULL; ID3D_NOTICE("Find: looking for comment with data = " << data.c_str()); /* Reset the cursor if it isn't set. */ if (_frames.end() == _cursor) { _cursor = _frames.begin(); ID3D_NOTICE("Find: resetting cursor"); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { ID3D_NOTICE("Find: iCount = " << iCount); /* We want to cycle through the list to find the matching frame. We * should begin from the cursor, search each successive frame, wrapping * if necessary. The enclosing loop and the assignment statments below * ensure that we first begin at the cursor and search to the end of the * list and, if unsuccessful, start from the beginning of the list and * search to the cursor. */ const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); /* Search from the cursor to the end. */ for (const_iterator cur = begin; cur != end; ++cur) { ID3D_NOTICE("Find: frame = 0x" << hex << (uint32) *cur << dec); if ((*cur != NULL) && ((*cur)->GetID() == id) && (*cur)->Contains(fldID)) { ID3_Field *fld = (*cur)->GetField(fldID); if (NULL == fld) { continue; ID3D_NOTICE("Find: didn't have the right field"); } String text(fld->GetRawText(), fld->Size()); ID3D_NOTICE("Find: text = " << text.c_str()); if (text == data) { /* We've found a valid frame. Set cursor to be the next element. */ frame = *cur; _cursor = ++cur; break; } } } } return frame; } ID3_Frame *ID3_ContainerImpl::Find(ID3_FrameID id, ID3_FieldID fldID, WString data) const { ID3_Frame *frame = NULL; /* Reset the cursor if it isn't set. */ if (_frames.end() == _cursor) { _cursor = _frames.begin(); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { /* We want to cycle through the list to find the matching frame. We * should begin from the cursor, search each successive frame, wrapping * if necessary. The enclosing loop and the assignment statments below * ensure that we first begin at the cursor and search to the end of the * list and, if unsuccessful, start from the beginning of the list and * search to the cursor. */ const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); /* Search from the cursor to the end. */ for (const_iterator cur = begin; cur != end; ++cur) { if ((*cur != NULL) && ((*cur)->GetID() == id) && (*cur)->Contains(fldID)) { ID3_Field *fld = (*cur)->GetField(fldID); if (NULL == fld) continue; WString text = toWString(fld->GetRawUnicodeText(), fld->Size()); if (text == data) { /* We've found a valid frame. Set cursor to be the next element. */ frame = *cur; _cursor = ++cur; break; } } } } return frame; } ID3_Frame *ID3_ContainerImpl::Find(ID3_FrameID id, ID3_FieldID fldID, uint32 data) const { ID3_Frame *frame = NULL; /* Reset the cursor if it isn't set. */ if (_frames.end() == _cursor) { _cursor = _frames.begin(); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { /* We want to cycle through the list to find the matching frame. We * should begin from the cursor, search each successive frame, wrapping * if necessary. The enclosing loop and the assignment statments below * ensure that we first begin at the cursor and search to the end of the * list and, if unsuccessful, start from the beginning of the list and * search to the cursor. */ const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); /* Search from the cursor to the end. */ for (const_iterator cur = begin; cur != end; ++cur) { if ((*cur != NULL) && ((*cur)->GetID() == id) && ((*cur)->GetField(fldID)->Get() == data)) { /* We've found a valid frame. Set the cursor to be the next element. */ frame = *cur; _cursor = ++cur; break; } } } return frame; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container_impl.cpp000066400000000000000000000261161516712004000267450ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "container_impl.h" #include "frame_def.h" ID3_FrameDef *ID3_FindFrameDef(ID3_FrameID id); // compares case insensitive null terminated or n sized chars int ID3_strncasecmp(const char *s1, const char *s2, int n) { // this routine is borrowed from half-life while (true) { int c1 = *s1++; int c2 = *s2++; if (!n--) return 0; // strings are equal until end point n if (c1 != c2) { if (c1 == 0) return -2; // s1 is earlier null terminated if (c2 == 0) return -3; // s2 is earlier null terminated if (c1 >= 'a' && c1 <= 'z') c1 -= ('a' - 'A'); //capitalize if (c2 >= 'a' && c2 <= 'z') c2 -= ('a' - 'A'); if (c1 != c2) return -1; // strings not equal } else if (c1 == 0 && c2 == 0) { return 0; // strings are equal } } return -1; //should not reach here } using namespace dami; bool IsUrl(String tmpUrl)//char* url) { // a url should start with http:// and be at least 11 chars (http://a.bb) OR // should start with ftp:// and be at least 10 chars (ftp://a.bb) OR // should start with mailto: and be at least 13 chars (mailto:a@b.cc) // these sizes do not take into consideration those that have emails or links directly at TLD's (e.g. a@b or http://a/ ) if ((tmpUrl.size() > 11 && ID3_strncasecmp(tmpUrl.c_str(), "http://", 7) == 0) || (tmpUrl.size() > 10 && ID3_strncasecmp(tmpUrl.c_str(), "ftp://", 6) == 0) || (tmpUrl.size() > 13 && ID3_strncasecmp(tmpUrl.c_str(), "mailto:", 7) == 0)) return true; return false; } bool ValidFrameOwner(String owner) { if (IsUrl(owner)) return true; else return false; } ID3_ContainerImpl::ID3_ContainerImpl() : _spec(ID3V2_DEFAULT), _frames(), _cursor(_frames.begin()) { this->Clear(); } ID3_ContainerImpl::ID3_ContainerImpl(const ID3_Container &container) : _spec(ID3V2_DEFAULT), _frames(), _cursor(_frames.begin()) { *this = container; } ID3_ContainerImpl::~ID3_ContainerImpl() { this->Clear(); } void ID3_ContainerImpl::Clear() { for (iterator cur = _frames.begin(); cur != _frames.end(); ++cur) { if (*cur) { delete *cur; *cur = NULL; } } UserUpdatedSpec = false; _frames.clear(); _cursor = _frames.begin(); _spec = ID3V2_DEFAULT; _changed = true; } void ID3_ContainerImpl::AddFrame(const ID3_Frame &frame) { this->AddFrame(&frame); } void ID3_ContainerImpl::AddFrame(const ID3_Frame *frame) { if (frame) { ID3_Frame *frm = new ID3_Frame(*frame); this->AttachFrame(frm); } } bool ID3_ContainerImpl::IsValidFrame(ID3_Frame& frame, bool testlinkedFrames) { ID3_Frame *testframe = &frame; ID3_Field *tmpField; ID3_Frame *tmpFrame; if (NULL == testframe) return false; // check if the frame is outdated ID3_FrameDef *myFrameDef = ID3_FindFrameDef(testframe->GetID()); if (myFrameDef != NULL) { if (this->GetSpec() > myFrameDef->eLastAppearance || this->GetSpec() < myFrameDef->eFirstAppearance) { // It's too old and doesn't have a conversion routine; disregard frame. if (myFrameDef->convert == NULL) return false; tmpFrame = myFrameDef->convert(testframe, this->GetSpec()); // It's too old and we couldn't convert; disregard frame. if (tmpFrame == NULL) return false; testframe = tmpFrame; frame = *tmpFrame; } else if (myFrameDef->convert != NULL) //fields have stayed the same, but inside the field was a structure change { // TODO: add here code when conversion routine of tcon is ready v2.3 <> v2.4 } } // check the frames on their restrictions switch (testframe->GetID()) { case ID3FID_UNIQUEFILEID: { //check for same owner tmpField = testframe->GetField(ID3FN_OWNER); if (ValidFrameOwner(tmpField->GetRawText())) { tmpFrame = this->Find(ID3FID_UNIQUEFILEID, ID3FN_OWNER, tmpField->GetRawText()); if (tmpFrame && tmpFrame != testframe) this->RemoveFrame(tmpFrame); //remove old one, there can be only one return true; } return false; } case ID3FID_CRYPTOREG: { //check for same owner tmpField = testframe->GetField(ID3FN_OWNER); if (ValidFrameOwner((char *)tmpField->GetRawText())) { tmpFrame = this->Find(ID3FID_CRYPTOREG, ID3FN_OWNER, tmpField->GetRawText()); if (tmpFrame && tmpFrame != testframe) this->RemoveFrame(tmpFrame); //remove old one, there can be only one tmpField = testframe->GetField(ID3FN_ID); tmpFrame = this->Find(ID3FID_CRYPTOREG, ID3FN_ID, tmpField->Get()); if (tmpFrame && tmpFrame != testframe) this->RemoveFrame(tmpFrame); //remove old one, there can be only one return true; } return false; } case ID3FID_GROUPINGREG: { //check for same owner tmpField = testframe->GetField(ID3FN_OWNER); if (ValidFrameOwner((char *)tmpField->GetRawText())) { tmpFrame = this->Find(ID3FID_GROUPINGREG, ID3FN_OWNER, tmpField->GetRawText()); if (tmpFrame && tmpFrame != testframe) this->RemoveFrame(tmpFrame); //remove old one, there can be only one tmpField = testframe->GetField(ID3FN_ID); tmpFrame = this->Find(ID3FID_CRYPTOREG, ID3FN_ID, tmpField->Get()); if (tmpFrame && tmpFrame != testframe) this->RemoveFrame(tmpFrame); //remove old one, there can be only one return true; } return false; } case ID3FID_PRIVATE: { //check for same owner tmpField = testframe->GetField(ID3FN_OWNER); if (ValidFrameOwner((char *)tmpField->GetRawText())) { // here the id3v2.4 specification is not clear, it states the content of the frame cannot be the same // do they mean that the there can be only one frame with the same owner? // or that the data field cannot be the same, or both.. return true; } return false; } case ID3FID_PRODUCEDNOTICE: { //should have at least a year and a space tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 4) return true; return false; } case ID3FID_COPYRIGHT: { //should have at least a year and a space tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 4) return true; return false; } case ID3FID_ENCODINGTIME: { //should have at least a year, contains a timestamp yyyy[-MM[-dd[THH[:mm[:ss]]]]] (between brackets [] is optional) tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 3) return true; return false; } case ID3FID_ORIGRELEASETIME: { //should have at least a year, contains a timestamp yyyy[-MM[-dd[THH[:mm[:ss]]]]] (between brackets [] is optional) tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 3) return true; return false; } case ID3FID_RECORDINGTIME: { //should have at least a year, contains a timestamp yyyy[-MM[-dd[THH[:mm[:ss]]]]] (between brackets [] is optional) tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 3) return true; return false; } case ID3FID_RELEASETIME: { //should have at least a year, contains a timestamp yyyy[-MM[-dd[THH[:mm[:ss]]]]] (between brackets [] is optional) tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 3) return true; return false; } case ID3FID_TAGGINGTIME: { //should have at least a year, contains a timestamp yyyy[-MM[-dd[THH[:mm[:ss]]]]] (between brackets [] is optional) tmpField = testframe->GetField(ID3FN_TEXT); String tmpText = tmpField->GetText(); if (tmpText.size() > 3) return true; return false; } case ID3FID_CDID: { //should have at least a 4 + 8*x + 8 bytes (x is nr of tracks), with a minimum of 1 track it's 20 bytes, maximum is 804 bytes (99 tracks) tmpField = testframe->GetField(ID3FN_DATA); BString tmpText = tmpField->GetBinary(); if (tmpText.size() >= 20 && tmpText.size() <= 804) { if (testlinkedFrames) { //check for existence of TRCK frame tmpFrame = this->Find(ID3FID_TRACKNUM); if (tmpFrame) return true; //todo... else return false; } return true; } return false; } default: { return true; } } } void ID3_ContainerImpl::checkFrames() { bool restart = false; for (iterator iter = this->begin(); iter != this->end(); ++iter) { ID3_Frame *frame = *iter; ID3_Frame &testframe = *frame; if (this->IsValidFrame(testframe, true) == false) { _frames.erase(iter); delete frame; restart = true; break; } } if (restart) this->checkFrames(); } bool ID3_ContainerImpl::AttachFrame(ID3_Frame *frame) { ID3_Frame &testframe = *frame; bool isvalid = IsValidFrame(testframe, false); if (isvalid) { frame = &testframe; _frames.push_back(frame); _cursor = _frames.begin(); _changed = true; return true; } if (frame) delete frame; return false; } ID3_Frame* ID3_ContainerImpl::RemoveFrame(const ID3_Frame *frame) { ID3_Frame *frm = NULL; iterator fi = Find(frame); if (fi != _frames.end()) { frm = *fi; _frames.erase(fi); _cursor = _frames.begin(); _changed = true; } return frm; } bool ID3_ContainerImpl::HasChanged() const { bool changed = _changed; if (!changed) { for (const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi) { if (*fi) changed = (*fi)->HasChanged(); if (changed) break; } } return changed; } bool ID3_ContainerImpl::SetSpec(ID3_V2Spec spec) { bool changed = _spec != spec; _spec = spec; _changed = _changed || changed; return changed; } ID3_V2Spec ID3_ContainerImpl::GetSpec() const { return _spec; } ID3_ContainerImpl &ID3_ContainerImpl::operator=(const ID3_Container &rContainer) { this->Clear(); ID3_Container::ConstIterator *iter = rContainer.CreateIterator(); const ID3_Frame *frame = NULL; while (NULL != (frame = iter->GetNext())) { this->AttachFrame(new ID3_Frame(*frame)); } delete iter; return *this; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container_impl.h000066400000000000000000000071641516712004000264140ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_CONTAINER_IMPL_H_ #define _ID3LIB_CONTAINER_IMPL_H_ #include #include #include #include #include class ID3_Reader; class ID3_Writer; namespace dami { namespace id3 { namespace v2 { bool parseFrames(ID3_ContainerImpl& tag, ID3_Reader& rdr); ID3_Err renderFrames(ID3_Writer& writer, const ID3_ContainerImpl& container); }; }; }; class ID3_ContainerImpl { typedef std::list Frames; public: typedef Frames::iterator iterator; typedef Frames::const_iterator const_iterator; public: ID3_ContainerImpl(); ID3_ContainerImpl(const ID3_Container &container); virtual ~ID3_ContainerImpl(); virtual void Clear(); virtual size_t Size() const; bool HasChanged() const; void SetChanged(bool b) { _changed = b; } void AddFrame(const ID3_Frame &); void AddFrame(const ID3_Frame *); bool AttachFrame(ID3_Frame *); bool IsValidFrame(ID3_Frame &, bool); void checkFrames(); ID3_Frame *RemoveFrame(const ID3_Frame *); ID3_Frame *Find(ID3_FrameID id) const; ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const; ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, dami::String) const; ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, dami::WString) const; size_t NumFrames() const { return _frames.size(); } ID3_ContainerImpl &operator =(const ID3_Container &); virtual ID3_V2Spec GetSpec() const; virtual bool SetSpec(ID3_V2Spec); ID3_V2Spec MinSpec() const; iterator begin() { return _frames.begin(); } iterator end() { return _frames.end(); } const_iterator begin() const { return _frames.begin(); } const_iterator end() const { return _frames.end(); } /* Deprecated! */ bool UserUpdatedSpec; // used to determine whether user used SetSpec(); protected: const_iterator Find(const ID3_Frame *) const; iterator Find(const ID3_Frame *); void ParseFile(); void ParseReader(ID3_Reader &reader); private: ID3_V2Spec _spec; // which version of the spec Frames _frames; mutable const_iterator _cursor; // which frame in list are we at mutable bool _changed; // have frames changed since last parse or render? }; #endif /* _ID3LIB_CONTAINER_IMPL_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container_parse.cpp000066400000000000000000000100751516712004000271130ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "container_impl.h" #include using namespace dami; bool id3::v2::parseFrames(ID3_ContainerImpl &container, ID3_Reader &rdr) { ID3_Reader::pos_type beg = rdr.getCur(); io::ExitTrigger et(rdr, beg); ID3_Reader::pos_type last_pos = beg; while (!rdr.atEnd() && rdr.peekChar() != '\0') { ID3D_NOTICE("id3::v2::parseFrames(): rdr.getBeg() = " << rdr.getBeg()); ID3D_NOTICE("id3::v2::parseFrames(): rdr.getCur() = " << rdr.getCur()); ID3D_NOTICE("id3::v2::parseFrames(): rdr.getEnd() = " << rdr.getEnd()); last_pos = rdr.getCur(); ID3_Frame *f = new ID3_Frame; f->SetSpec(container.GetSpec()); bool goodParse = f->Parse(rdr); size_t frameSize = rdr.getCur() - last_pos; ID3D_NOTICE("id3::v2::parseFrames(): frameSize = " << frameSize); if (frameSize == 0) { /* There is a problem. * If the frame size is 0, then we can't progress. */ ID3D_WARNING("id3::v2::parseFrames(): frame size is 0, can't " << "continue parsing frames"); delete f; /* Break for now. */ break; } else if (!goodParse) { /* Bad parse! We can't attach this frame. */ ID3D_WARNING("id3::v2::parseFrames(): bad parse, deleting frame"); delete f; } else if (f->GetID() != ID3FID_METACOMPRESSION) { ID3D_NOTICE("id3::v2::parseFrames(): attaching non-compressed " << "frame"); /* A good, uncompressed frame. Attach away! */ container.AttachFrame(f); } else { ID3D_NOTICE("id3::v2::parseFrames(): parsing ID3v2.2.1 " << "compressed frame"); /* Hmm. An ID3v2.2.1 compressed frame. It contains 1 or more * compressed frames. Uncompress and call parseFrames recursively. */ ID3_Field *fld = f->GetField(ID3FN_DATA); if (fld) { ID3_MemoryReader mr(fld->GetRawBinary(), fld->BinSize()); ID3_Reader::char_type ch = mr.readChar(); if (ch != 'z') { /* Unknown compression method. */ ID3D_WARNING("id3::v2::parseFrames(): unknown compression id " << " = '" << ch << "'"); } else { uint32 newSize = io::readBENumber(mr, sizeof(uint32)); // size_t oldSize = f->GetDataSize() - sizeof(uint32) - 1; io::CompressedReader cr(mr, newSize); parseFrames(container, cr); if (!cr.atEnd()) { /* Hmm. It didn't parse the entire uncompressed data. * Wonder why. */ ID3D_WARNING("id3::v2::parseFrames(): didn't parse entire " << "id3v2.2.1 compressed memory stream"); } } } delete f; } et.setExitPos(rdr.getCur()); } if (rdr.peekChar() == '\0') { ID3D_NOTICE("id3::v2::parseFrames: done parsing, padding at postion " << rdr.getCur()); } else { ID3D_NOTICE("id3::v2::parseFrames: done parsing, [cur, end] = [" << rdr.getCur() << ", " << rdr.getEnd() << "]"); } return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/container_render.cpp000066400000000000000000000046601516712004000272630ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "container_impl.h" #include using namespace dami; ID3_Err id3::v2::renderFrames(ID3_Writer &writer, const ID3_ContainerImpl &container) { for (ID3_ContainerImpl::const_iterator iter = container.begin(); iter != container.end(); ++iter) { const ID3_Frame *frame = *iter; if (frame) { ID3_Err err = frame->Render(writer); if (err != ID3E_NoError) return err; } } return ID3E_NoError; } ID3_V2Spec ID3_ContainerImpl::MinSpec() const { ID3_V2Spec minSpec = ID3V2_EARLIEST; for (const_iterator cur = _frames.begin(); cur != _frames.end(); ++cur) { const ID3_Frame *frame = *cur; if (!frame) continue; ID3_V2Spec frameSpec = frame->MinSpec(); if (minSpec < frameSpec) minSpec = frameSpec; } return minSpec; } size_t ID3_ContainerImpl::Size() const { if (this->NumFrames() == 0) return 0; ID3_V2Spec spec = this->MinSpec(); if (this->GetSpec() > spec) spec = this->GetSpec(); size_t frameBytes = 0; for (const_iterator cur = _frames.begin(); cur != _frames.end(); ++cur) { if (*cur) { (*cur)->SetSpec(spec); frameBytes += (*cur)->Size(); } } return frameBytes; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field.cpp000066400000000000000000001731021516712004000250230ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include #include #include "field_impl.h" #include "field_def.h" #include "frame_def.h" using namespace dami; /* This is used for unimplemented frames so that their data is preserved when * parsing and rendering */ static ID3_FieldDef ID3FD_Unimplemented[] = { { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; const ID3_FieldDef *ID3_FieldDef::DEFAULT = ID3FD_Unimplemented; static ID3_FieldDef ID3FD_Binary[] = { { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_URL[] = { { ID3FN_URL, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_UserURL[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_URL, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Text[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_UserText[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_GeneralText[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_LANGUAGE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 3, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_TermsOfUse[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_LANGUAGE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 3, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_LinkedInfo[] = { { ID3FN_ID, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 3, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_2_1, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_ID, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 4, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_URL, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Picture[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_IMAGEFORMAT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 3, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_2_1, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_MIMETYPE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_PICTURETYPE, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Chapter[] = { { ID3FN_ID, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_STARTTIME, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_ENDTIME, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_STARTOFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_ENDOFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_FRAMES, // FIELD NAME ID3FTY_FRAMES, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_TableOfContents[] = { { ID3FN_ID, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_FLAGS, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_CHAPTERS, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NLIST, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_FRAMES, // FIELD NAME ID3FTY_FRAMES, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_GEO[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_MIMETYPE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_FILENAME, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_AudioEncryption[] = { { ID3FN_OWNER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_OFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 2, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_LENGTH, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 2, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_AudioSeekPoint[] = { { ID3FN_OFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_LENGTH, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NUMBER, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 2, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NUMBITS, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_UFI[] = { { ID3FN_OWNER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_PlayCounter[] = { { ID3FN_COUNTER, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Popularimeter[] = { { ID3FN_EMAIL, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_RATING, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_COUNTER, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Private[] = { { ID3FN_OWNER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Registration[] = { { ID3FN_OWNER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_ID, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_3_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_TextList[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TEXT, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_LIST | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_EventTiming[] = { { ID3FN_TIMESTAMPFORMAT, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_SyncTempo[] = { { ID3FN_TIMESTAMPFORMAT, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Reverb[] = { { ID3FN_REVERBL, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 2, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBR, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 2, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBBOUNCESL, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBBOUNCESR, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBFEEDBACKL2L, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBFEEDBACKL2R, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBFEEDBACKR2R, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_REVERBFEEDBACKR2L, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_PREMIXL2R, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_PREMIXR2L, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Signature[] = { { ID3FN_ID, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_4_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_4_0, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Commercial[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_PRICE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_8DATE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 8, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_URL, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DELIVERY, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_SELLER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_MIMETYPE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Owner[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_PRICE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_8DATE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 8, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_SELLER, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Seek[] = { { ID3FN_OFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Position[] = { { ID3FN_TIMESTAMPFORMAT, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_OFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_Buffer[] = { { ID3FN_LENGTH, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 3, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_FLAGS, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_OFFSET, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 4, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_CDM[] = { { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_2_1, // INITIAL SPEC ID3V2_2_1, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; static ID3_FieldDef ID3FD_SyncLyrics[] = { { ID3FN_TEXTENC, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_LANGUAGE, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 3, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_TIMESTAMPFORMAT, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_CONTENTTYPE, // FIELD NAME ID3FTY_INTEGER, // FIELD TYPE 1, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DESCRIPTION, // FIELD NAME ID3FTY_TEXTSTRING, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_CSTR | ID3FF_ENCODABLE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_DATA, // FIELD NAME ID3FTY_BINARY, // FIELD TYPE 0, // FIXED LEN ID3V2_EARLIEST, // INITIAL SPEC ID3V2_LATEST, // ENDING SPEC ID3FF_NONE, // FLAGS ID3FN_NOFIELD // LINKED FIELD }, { ID3FN_NOFIELD } }; // **** Currently Implemented Frames // APIC PIC ID3FID_PICTURE Attached picture // CHAP ID3FID_CHAPTER Chapter // COMM COM ID3FID_COMMENT Comments // CTOC ID3FID_TOC Table of contents // ENCR ID3FID_CRYPTOREG Encryption method registration // GEOB GEO ID3FID_GENERALOBJECT General encapsulated object // GRID ID3FID_GROUPINGREG Group identification registration // IPLS IPL ID3FID_INVOLVEDPEOPLE Involved people list // LINK LNK ID3FID_LINKEDINFO Linked information // MVIN ID3FID_MOVEMENT Movement number // MVNM ID3FID_MOVEMENTNAME Movement name // PCNT CNT ID3FID_PLAYCOUNTER Play counter // POPM POP ID3FID_POPULARIMETER Popularimeter // PRIV ID3FID_PRIVATE Private frame // SYLT SLT ID3FID_SYNCEDLYRICS Synchronized lyric/text // TALB TAL ID3FID_ALBUM Album/Movie/Show title // TBPM TBP ID3FID_BPM BPM (beats per minute) // TCOM TCM ID3FID_COMPOSER Composer // TCON TCO ID3FID_CONTENTTYPE Content type // TCOP TCR ID3FID_COPYRIGHT Copyright message // TDAT TDA ID3FID_DATE Date // TDLY TDY ID3FID_PLAYLISTDELAY Playlist delay // TENC TEN ID3FID_ENCODEDBY Encoded by // TEXT TXT ID3FID_LYRICIST Lyricist/Text writer // TFLT TFT ID3FID_FILETYPE File type // TIME TKE ID3FID_TIME Time // TIPL ID3FID_INVOLVEDPEOPLE2 Involved people list // TIT1 TIM ID3FID_CONTENTGROUP Content group description // TIT2 TT1 ID3FID_TITLE Title/songname/content description // TIT3 TT2 ID3FID_SUBTITLE Subtitle/Description refinement // TKEY TT3 ID3FID_INITIALKEY Initial key // TLAN TLA ID3FID_LANGUAGE Language(s) // TLEN TLE ID3FID_SONGLEN Length // TMED TMT ID3FID_MEDIATYPE Media type // TOAL TOT ID3FID_ORIGALBUM Original album/movie/show title // TOFN TOF ID3FID_ORIGFILENAME Original filename // TOLY TOL ID3FID_ORIGLYRICIST Original lyricist(s)/text writer(s) // TOPE TOA ID3FID_ORIGARTIST Original artist(s)/performer(s) // TORY TOR ID3FID_ORIGYEAR Original release year // TOWN ID3FID_FILEOWNER File owner/licensee // TPE1 TP1 ID3FID_LEADARTIST Lead performer(s)/Soloist(s) // TPE2 TP2 ID3FID_BAND Band/orchestra/accompaniment // TPE3 TP3 ID3FID_CONDUCTOR Conductor/performer refinement // TPE4 TP4 ID3FID_MIXARTIST Interpreted, remixed, or otherwise modified // TPOS TPA ID3FID_PARTINSET Part of a set // TPUB TPB ID3FID_PUBLISHER Publisher // TRCK TRK ID3FID_TRACKNUM Track number/Position in set // TRDA TRD ID3FID_RECORDINGDATES Recording dates // TRSN TRN ID3FID_NETRADIOSTATION Internet radio station name // TRSO TRO ID3FID_NETRADIOOWNER Internet radio station owner // TSIZ TSI ID3FID_SIZE Size // TSRC TRC ID3FID_ISRC ISRC (international standard recording code) // TSSE TSS ID3FID_ENCODERSETTINGS Software/Hardware and encoding settings // TXXX TXX ID3FID_USERTEXT User defined text information // TYER TYE ID3FID_YEAR Year // UFID UFI ID3FID_UNIQUEFILEID Unique file identifier // USER ID3FID_TERMSOFUSE Terms of use // USLT ULT ID3FID_UNSYNCEDLYRICS Unsynchronized lyric/text transcription // WCOM WCM ID3FID_WWWCOMMERCIALINFO Commercial information // WCOP WCM ID3FID_WWWCOPYRIGHT Copyright/Legal information // WOAF WCP ID3FID_WWWAUDIOFILE Official audio file webpage // WOAR WAF ID3FID_WWWARTIST Official artist/performer webpage // WOAS WAR ID3FID_WWWAUDIOSOURCE Official audio source webpage // WORS WAS ID3FID_WWWRADIOPAGE Official internet radio station homepage // WPAY WRA ID3FID_WWWPAYMENT Payment // WPUB WPY ID3FID_WWWPUBLISHER Official publisher webpage // WXXX WXX ID3FID_WWWUSER User defined URL link // CDM ID3FID_METACOMPRESSION Compressed data meta frame // **** Currently unimplemented frames // AENC CRA ID3FID_AUDIOCRYPTO Audio encryption // COMR ID3FID_COMMERCIAL Commercial frame // EQUA EQU ID3FID_EQUALIZATION Equalization // ETCO ETC ID3FID_EVENTTIMING Event timing codes // MCDI MCI ID3FID_CDID Music CD identifier // MLLT MLL ID3FID_MPEGLOOKUP MPEG location lookup table // OWNE ID3FID_OWNERSHIP Ownership frame // POSS ID3FID_POSITIONSYNC Position synchronisation frame // RBUF BUF ID3FID_BUFFERSIZE Recommended buffer size // RVAD RVA ID3FID_VOLUMEADJ Relative volume adjustment // RVRB REV ID3FID_REVERB Reverb // SYTC STC ID3FID_SYNCEDTEMPO Synchronized tempo codes // CRM ID3FID_METACRYPTO Encrypted meta frame ID3_Frame *convertEQUA(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertIPLS(ID3_Frame *oldframe, ID3_V2Spec tospec) { if (tospec == ID3V2_4_0) { ID3_Frame *newframe = new ID3_Frame(ID3FID_INVOLVEDPEOPLE2); newframe->GetField(ID3FN_TEXTENC)->Set(oldframe->GetField(ID3FN_TEXTENC)->Get()); newframe->GetField(ID3FN_TEXT)->SetEncoding(oldframe->GetField(ID3FN_TEXT)->GetEncoding()); newframe->GetField(ID3FN_TEXT)->SetText(oldframe->GetField(ID3FN_TEXT)->GetText()); return newframe; } return NULL; } ID3_Frame *convertRVAD(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertTDAT(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertTIME(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertTORY(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertTRDA(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } ID3_Frame *convertTYER(ID3_Frame *oldframe, ID3_V2Spec tospec) { return NULL; } static ID3_FrameDef ID3_FrameDefs[] = { // short long born died replace tag file // frame id id id tag tag id discrd discrd field defs description {ID3FID_AUDIOCRYPTO, "CRA", "AENC", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_AudioEncryption, "Audio encryption"}, {ID3FID_PICTURE, "PIC", "APIC", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Picture, "Attached picture"}, {ID3FID_AUDIOSEEKPOINT, "" , "ASPI", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_AudioSeekPoint, "Audio seek point index"}, {ID3FID_CHAPTER, "" , "CHAP", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Chapter, "Chapter"}, {ID3FID_COMMENT, "COM", "COMM", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_GeneralText, "Comments"}, {ID3FID_COMMERCIAL, "" , "COMR", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Commercial, "Commercial"}, {ID3FID_TOC, "" , "CTOC", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_TableOfContents, "Table of contents"}, {ID3FID_CRYPTOREG, "" , "ENCR", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Registration, "Encryption method registration"}, {ID3FID_EQUALIZATION2, "" , "EQU2", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Unimplemented, "Equalisation (2)"}, {ID3FID_EQUALIZATION, "EQU", "EQUA", ID3V2_EARLIEST, ID3V2_3_0 , convertEQUA, false, true, ID3FD_Unimplemented, "Equalization"}, {ID3FID_EVENTTIMING, "ETC", "ETCO", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, true, ID3FD_EventTiming, "Event timing codes"}, {ID3FID_GENERALOBJECT, "GEO", "GEOB", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_GEO, "General encapsulated object"}, {ID3FID_GROUPINGREG, "" , "GRID", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Registration, "Group identification registration"}, {ID3FID_INVOLVEDPEOPLE, "IPL", "IPLS", ID3V2_EARLIEST, ID3V2_3_0 , convertIPLS, false, false, ID3FD_TextList, "Involved people list"}, {ID3FID_LINKEDINFO, "LNK", "LINK", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_LinkedInfo, "Linked information"}, {ID3FID_CDID, "MCI", "MCDI", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Binary, "Music CD identifier"}, {ID3FID_MPEGLOOKUP, "MLL", "MLLT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, true, ID3FD_Unimplemented, "MPEG location lookup table"}, {ID3FID_MOVEMENT, "" , "MVIN", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Movement number"}, {ID3FID_MOVEMENTNAME, "" , "MVNM", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Movement name"}, {ID3FID_OWNERSHIP, "" , "OWNE", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Owner, "Ownership frame"}, {ID3FID_PRIVATE, "" , "PRIV", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Private, "Private frame"}, {ID3FID_PLAYCOUNTER, "CNT", "PCNT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_PlayCounter, "Play counter"}, {ID3FID_POPULARIMETER, "POP", "POPM", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Popularimeter, "Popularimeter"}, {ID3FID_POSITIONSYNC, "" , "POSS", ID3V2_3_0 , ID3V2_LATEST, NULL, false, true, ID3FD_Position, "Position synchronisation frame"}, {ID3FID_BUFFERSIZE, "BUF", "RBUF", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Buffer, "Recommended buffer size"}, {ID3FID_VOLUMEADJ2, "" , "RVA2", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Unimplemented, "Relative volume adjustment (2)"}, {ID3FID_VOLUMEADJ, "RVA", "RVAD", ID3V2_EARLIEST, ID3V2_3_0 , convertRVAD, false, true, ID3FD_Unimplemented, "Relative volume adjustment"}, {ID3FID_REVERB, "REV", "RVRB", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Reverb, "Reverb"}, {ID3FID_SEEKFRAME, "" , "SEEK", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Seek, "Seek frame"}, {ID3FID_SIGNATURE, "" , "SIGN", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Signature, "Signature frame"}, {ID3FID_SYNCEDLYRICS, "SLT", "SYLT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_SyncLyrics, "Synchronized lyric/text"}, {ID3FID_SYNCEDTEMPO, "STC", "SYTC", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, true, ID3FD_SyncTempo, "Synchronized tempo codes"}, {ID3FID_ALBUM, "TAL", "TALB", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Album/Movie/Show title"}, {ID3FID_BPM, "TBP", "TBPM", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "BPM (beats per minute)"}, {ID3FID_COMPOSER, "TCM", "TCOM", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Composer"}, {ID3FID_CONTENTTYPE, "TCO", "TCON", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Content type"}, {ID3FID_COPYRIGHT, "TCR", "TCOP", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Copyright message"}, {ID3FID_DATE, "TDA", "TDAT", ID3V2_EARLIEST, ID3V2_3_0 , convertTDAT, false, false, ID3FD_Text, "Date"}, {ID3FID_ENCODINGTIME, "" , "TDEN", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Encoding time"}, {ID3FID_PLAYLISTDELAY, "TDY", "TDLY", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Playlist delay"}, {ID3FID_ORIGRELEASETIME, "" , "TDOR", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Original release time"}, {ID3FID_RECORDINGTIME, "" , "TDRC", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Recording time"}, {ID3FID_RELEASETIME, "" , "TDRL", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Release time"}, {ID3FID_TAGGINGTIME, "" , "TDTG", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Tagging time"}, {ID3FID_ENCODEDBY, "TEN", "TENC", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, true, ID3FD_Text, "Encoded by"}, {ID3FID_LYRICIST, "TXT", "TEXT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Lyricist/Text writer"}, {ID3FID_FILETYPE, "TFT", "TFLT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "File type"}, {ID3FID_TIME, "TIM", "TIME", ID3V2_EARLIEST, ID3V2_3_0 , convertTIME, false, false, ID3FD_Text, "Time"}, {ID3FID_INVOLVEDPEOPLE2, "" , "TIPL", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_TextList, "Involved people list"}, {ID3FID_CONTENTGROUP, "TT1", "TIT1", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Content group description"}, {ID3FID_TITLE, "TT2", "TIT2", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Title/songname/content description"}, {ID3FID_SUBTITLE, "TT3", "TIT3", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Subtitle/Description refinement"}, {ID3FID_INITIALKEY, "TKE", "TKEY", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Initial key"}, {ID3FID_LANGUAGE, "TLA", "TLAN", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Language(s)"}, {ID3FID_SONGLEN, "TLE", "TLEN", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, true, ID3FD_Text, "Length"}, {ID3FID_MUSICIANCREDITLIST, "" , "TMCL", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_TextList, "Musician credits list"}, {ID3FID_MEDIATYPE, "TMT", "TMED", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Media type"}, {ID3FID_MOOD, "" , "TMOO", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Mood"}, {ID3FID_ORIGALBUM, "TOT", "TOAL", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Original album/movie/show title"}, {ID3FID_ORIGFILENAME, "TOF", "TOFN", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Original filename"}, {ID3FID_ORIGLYRICIST, "TOL", "TOLY", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Original lyricist(s)/text writer(s)"}, {ID3FID_ORIGARTIST, "TOA", "TOPE", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Original artist(s)/performer(s)"}, {ID3FID_ORIGYEAR, "TOR", "TORY", ID3V2_EARLIEST, ID3V2_3_0 , convertTORY, false, false, ID3FD_Text, "Original release year"}, {ID3FID_FILEOWNER, "" , "TOWN", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "File owner/licensee"}, {ID3FID_LEADARTIST, "TP1", "TPE1", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Lead performer(s)/Soloist(s)"}, {ID3FID_BAND, "TP2", "TPE2", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Band/orchestra/accompaniment"}, {ID3FID_CONDUCTOR, "TP3", "TPE3", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Conductor/performer refinement"}, {ID3FID_MIXARTIST, "TP4", "TPE4", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Interpreted, remixed, or otherwise modified by"}, {ID3FID_PARTINSET, "TPA", "TPOS", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Part of a set"}, {ID3FID_PRODUCEDNOTICE, "" , "TPRO", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Produced notice"}, {ID3FID_PUBLISHER, "TPB", "TPUB", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Publisher"}, {ID3FID_TRACKNUM, "TRK", "TRCK", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Track number/Position in set"}, {ID3FID_RECORDINGDATES, "TRD", "TRDA", ID3V2_EARLIEST, ID3V2_3_0 , convertTRDA, false, false, ID3FD_Text, "Recording dates"}, {ID3FID_NETRADIOSTATION, "TRN", "TRSN", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Internet radio station name"}, {ID3FID_NETRADIOOWNER, "TRO", "TRSO", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Internet radio station owner"}, {ID3FID_SIZE, "TSI", "TSIZ", ID3V2_EARLIEST, ID3V2_3_0 , NULL, false, true, ID3FD_Text, "Size"}, {ID3FID_ALBUMARTISTSORTORDER, "" , "TSO2", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Album artist sort order"}, {ID3FID_ALBUMSORTORDER, "" , "TSOA", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Album sort order"}, {ID3FID_COMPOSERSORTORDER, "" , "TSOC", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Composer sort order"}, {ID3FID_PERFORMERSORTORDER, "" , "TSOP", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Performer sort order"}, {ID3FID_TITLESORTORDER, "" , "TSOT", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Title sort order"}, {ID3FID_ISRC, "TRC", "TSRC", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "ISRC (international standard recording code)"},//http://www.ifpi.org/isrc/isrc_handbook.html {ID3FID_ENCODERSETTINGS, "TSS", "TSSE", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Software/Hardware and settings used for encoding"}, {ID3FID_SETSUBTITLE, "" , "TSST", ID3V2_4_0 , ID3V2_LATEST, NULL, false, false, ID3FD_Text, "Set subtitle"}, {ID3FID_USERTEXT, "TXX", "TXXX", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_UserText, "User defined text information"}, {ID3FID_YEAR, "TYE", "TYER", ID3V2_EARLIEST, ID3V2_3_0 , convertTYER, false, false, ID3FD_Text, "Year"}, {ID3FID_UNIQUEFILEID, "UFI", "UFID", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_UFI, "Unique file identifier"}, {ID3FID_TERMSOFUSE, "" , "USER", ID3V2_3_0 , ID3V2_LATEST, NULL, false, false, ID3FD_TermsOfUse, "Terms of use"}, {ID3FID_UNSYNCEDLYRICS, "ULT", "USLT", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_GeneralText, "Unsynchronized lyric/text transcription"}, {ID3FID_WWWCOMMERCIALINFO, "WCM", "WCOM", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Commercial information"}, {ID3FID_WWWCOPYRIGHT, "WCP", "WCOP", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Copyright/Legal information"}, {ID3FID_WWWAUDIOFILE, "WAF", "WOAF", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Official audio file webpage"}, {ID3FID_WWWARTIST, "WAR", "WOAR", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Official artist/performer webpage"}, {ID3FID_WWWAUDIOSOURCE, "WAS", "WOAS", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Official audio source webpage"}, {ID3FID_WWWRADIOPAGE, "WRA", "WORS", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Official internet radio station homepage"}, {ID3FID_WWWPAYMENT, "WPY", "WPAY", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Payment"}, {ID3FID_WWWPUBLISHER, "WPB", "WPUB", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_URL, "Official publisher webpage"}, {ID3FID_WWWUSER, "WXX", "WXXX", ID3V2_EARLIEST, ID3V2_LATEST, NULL, false, false, ID3FD_UserURL, "User defined URL link"}, {ID3FID_METACRYPTO, "CRM", "" , ID3V2_EARLIEST, ID3V2_2_1 , NULL, false, false, ID3FD_Unimplemented, "Encrypted meta frame"}, {ID3FID_METACOMPRESSION, "CDM", "" , ID3V2_2_1 , ID3V2_2_1 , NULL, false, false, ID3FD_CDM, "Compressed data meta frame"}, {ID3FID_NOFRAME} }; /** \class ID3_Field field.h id3/field.h ** \brief The representative class of an ID3v2 field. ** ** As a general rule, you need never create an object of this type. id3lib ** uses them internally as part of the id3_frame class. You must know how to ** interact with these objects, though, and that's what this section is about. ** ** The ID3_Field contains many overloaded methods to provide these facilities ** for four different data types: integers, ASCII strings, Unicode strings, ** and binary data. ** ** An integer field supports the Get(), Set(uint32), and operator=(uint32) ** methods. ** ** Both types of strings support the GetNumTextItems() method. ** ** An ASCII string field supports the Get(char*, size_t, size_t)), ** Set(const char*), Add(const char*), and operator=(const char*) methods. ** ** A Unicode field also supports Get(unicode_t*, size_t, size_t), ** Set(const unicode_t*), Add(const unicode_t*), and ** operator=(const unicode_t*). Without elaborating, the Unicode ** methods behave exactly the same as their ASCII counterparts, taking ** \c unicode_t pointers in place of \c char pointers. ** ** All strings in id3lib are handled internally as Unicode. This means that ** when you set a field with an ASCII source type, it will be converted and ** stored internally as a Unicode string. id3lib will handle all necessary ** conversions when parsing, rendering, and retrieving. If you set a field as ** an ASCII string, then try to read the string into a \c unicode_t buffer, ** id3lib will automatically convert the string into Unicode so this will ** function as expected. The same holds true in reverse. Of course, when ** converting from Unicode to ASCII, you will experience problems when the ** Unicode string contains characters that don't map to ISO-8859-1. ** ** A binary field supports the Get(uchar*, size_t), Set(const uchar*, size_t), ** FromFile(const char*), and ToFile(const char*) methods. The binary field ** holds miscellaneous data that can't easily be described any other way, such ** as a JPEG image. ** ** As a general implementation note, you should be prepared to support all ** fields in an id3lib frame, even if all fields in the id3lib version of the ** frame aren't present in the id3v2 version. This is because of frames like ** the picture frame, which changed slightly from one version of the id3v2 ** standard to the next (the IMAGEFORMAT format in 2.0 changed to a MIMETYPE ** in 3.0). If you support all id3lib fields in a given frame, id3lib can ** generate the correct id3v2 frame for the id3v2 version you wish to support. ** Alternatively, just support the fields you know will be used in, say, 3.0 ** if you only plan to generate 3.0 tags. ** ** @author Dirk Mahoney ** @version $Id$ ** \sa ID3_Tag ** \sa ID3_Frame ** \sa ID3_Err **/ ID3_FieldImpl::ID3_FieldImpl() : _id(ID3FN_NOFIELD), _type(ID3FTY_INTEGER), _spec_begin(ID3V2_EARLIEST), _spec_end(ID3V2_LATEST), _flags(0), _linked_field(ID3FN_NOFIELD), _changed(false), _fixed_size(0), _num_items(0), _enc(ID3TE_NONE) { this->Clear(); } ID3_FieldImpl::ID3_FieldImpl(const ID3_FieldDef &def) : _id(def._id), _type(def._type), _spec_begin(def._spec_begin), _spec_end(def._spec_end), _flags(def._flags), _linked_field(def._linked_field), _changed(false), _fixed_size(def._fixed_size), _num_items(0), _enc((_type == ID3FTY_TEXTSTRING) ? ID3TE_ISO8859_1 : ID3TE_NONE) { this->Clear(); } ID3_FieldImpl::~ID3_FieldImpl() { } // returns whether field should be parsed, set's it's brand new fixed size bool ID3_FieldImpl::SetLinkedSize(size_t newfixedsize) { // check whether it has a fixed size flag and a _linked_field if (this->HasFlag(ID3FF_HASLINKEDSIZE) && _linked_field != ID3FN_NOFIELD) { // check whether it has a fixed size flag and a _linked_field if (newfixedsize != 0) { _fixed_size = newfixedsize; ID3D_NOTICE( "ID3_FieldImpl::SetLinkedSize(): used linked_fixed_size = " << newfixedsize ); return true; } else { //this field should not exist or be parsed! return false; } } return true; } /** Clears any data and frees any memory associated with the field ** ** \sa ID3_Tag::Clear() ** \sa ID3_Frame::Clear() **/ void ID3_FieldImpl::Clear() { switch (_type) { case ID3FTY_INTEGER: _integer = 0; break; case ID3FTY_BINARY: _binary.erase(); if (_fixed_size > 0) _binary.assign(_fixed_size, '\0'); break; case ID3FTY_TEXTSTRING: _text.erase(); if (_fixed_size > 0) { if (ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding())) _text.assign(_fixed_size * 2, '\0'); else if (ID3TE_IS_SINGLE_BYTE_ENC(this->GetEncoding())) _text.assign(_fixed_size, '\0'); } break; case ID3FTY_FRAMES: ID3_Container::Clear(); break; default: return; } _changed = true; return; } bool ID3_FieldImpl::HasChanged() const { return _changed; } /** \fn size_t ID3_Field::Size() const ** \brief Returns the size of a field. ** ** The value returned is dependent on the type of the field. For ASCII ** strings, this returns the number of characters in the field, not including ** any NULL-terminator. The same holds true for Unicode---it returns the ** number of characters in the field, not bytes, and this does not include ** the Unicode BOM, which isn't put in a Unicode string obtained by the ** Get(unicode_t*, size_t, size_t) method anyway. For binary and ** integer fields, this returns the number of bytes in the field. ** ** \code ** size_t howBig = myFrame.GetField(ID3FN_DATA)->Size(); ** \endcode ** ** \return The size of the field, either in bytes (for binary or integer ** fields) or characters (for strings). **/ size_t ID3_FieldImpl::BinSize() const { if (_fixed_size > 0) return _fixed_size; size_t size = this->Size(); if (_type == ID3FTY_TEXTSTRING) { ID3_TextEnc enc = this->GetEncoding(); if (ID3TE_IS_DOUBLE_BYTE_ENC(enc) && size > 0) size++; if (_flags & ID3FF_CSTR) size++; if (ID3TE_IS_DOUBLE_BYTE_ENC(enc)) size *= 2; // FIXME: I guess this is wrong } return size; } size_t ID3_FieldImpl::Size() const { size_t size = 0; // check to see if we are within the legal limit for this field 0 means // arbitrary length field if (_fixed_size > 0) size = _fixed_size; else if (_type == ID3FTY_INTEGER) size = sizeof(uint32); else if (_type == ID3FTY_TEXTSTRING) size = _text.size(); else if (_type == ID3FTY_BINARY) size = _binary.size(); else if (_type == ID3FTY_FRAMES) size = ID3_Container::Size(); else size = 0; return size; } bool ID3_FieldImpl::Parse(ID3_Reader &reader) { bool success = false; switch (this->GetType()) { case ID3FTY_INTEGER: success = this->ParseInteger(reader); break; case ID3FTY_BINARY: success = this->ParseBinary(reader); break; case ID3FTY_TEXTSTRING: success = this->ParseText(reader); break; case ID3FTY_FRAMES: success = this->ParseFrames(reader); break; default: ID3D_WARNING( "ID3_FieldImpl::Parse(): unknown field type" ); break; } return success; } ID3_FrameDef *ID3_FindFrameDef(ID3_FrameID id) { ID3_FrameDef *info = NULL; for (size_t cur = 0; ID3_FrameDefs[cur].eID != ID3FID_NOFRAME; cur++) { if (ID3_FrameDefs[cur].eID == id) { info = &ID3_FrameDefs[cur]; break; } } return info; } ID3_FrameID ID3_FindFrameID(const char *id) { ID3_FrameID fid = ID3FID_NOFRAME; for (size_t cur = 0; ID3_FrameDefs[cur].eID != ID3FID_NOFRAME; ++cur) { if (((strcmp(ID3_FrameDefs[cur].sShortTextID, id) == 0) && strlen(id) == 3) || ((strcmp(ID3_FrameDefs[cur].sLongTextID, id) == 0) && strlen(id) == 4)) { fid = ID3_FrameDefs[cur].eID; break; } } return fid; } ID3_Err ID3_FieldImpl::Render(ID3_Writer &writer) const { switch (this->GetType()) { case ID3FTY_INTEGER: RenderInteger(writer); break; case ID3FTY_BINARY: RenderBinary(writer); break; case ID3FTY_TEXTSTRING: RenderText(writer); break; case ID3FTY_FRAMES: RenderFrames(writer); break; default: ID3D_WARNING("ID3D_FieldImpl::Render(): unknown field type"); return ID3E_UnknownFieldType; } return ID3E_NoError; } /* Copies the content of one field to another. * WOW, this is another strange conditional function. * It copies the content BUT only if the types match from the start. * Strange (Ralf) */ ID3_Field &ID3_FieldImpl::operator =(const ID3_Field &rhs) { const ID3_FieldImpl *fld = (const ID3_FieldImpl *) &rhs; if (this != &rhs && this->GetType() == fld->GetType()) { switch (fld->GetType()) { case ID3FTY_INTEGER: this->SetInteger(fld->GetInteger()); break; case ID3FTY_TEXTSTRING: this->SetEncoding(fld->GetEncoding()); this->SetText(fld->GetText()); this->_num_items = fld->GetNumTextItems(); break; case ID3FTY_BINARY: this->SetBinary(fld->GetBinary()); break; case ID3FTY_FRAMES: this->Clear(); { ID3_Container::ConstIterator *iter = fld->CreateIterator(); const ID3_Frame *frame = NULL; while (NULL != (frame = iter->GetNext())) { this->AttachFrame(new ID3_Frame(*frame)); } delete iter; } break; default: break; } } return *this; } /* Sets the encoding of the underlaying text. * Please note that the id3-spec does not allow size-limited texts with encodings other than ASCII. * Also note that you should set the matching encoding field or because write operations are made * with the TEXT_ENC field value. */ bool ID3_FieldImpl::SetEncoding(ID3_TextEnc enc) { bool changed = this->IsEncodable() && (enc != this->GetEncoding()) && (ID3TE_NONE < enc && enc < ID3TE_NUMENCODINGS); if (changed) { /* Force version 2.4 if encoding is UTF16BE or UTF8. */ if (enc >= ID3TE_UTF16BE) { _spec_begin = ID3V2_4_0; _spec_end = ID3V2_4_0; } _text = convert(_text, _enc, enc); _enc = enc; _changed = true; } return changed; } /** \class ID3_FrameInfo field.h id3/field.h ** \brief Provides information about the frame and field types supported by id3lib ** ** You normally only need (at most) one instance of the ID3_FrameInfo. It ** has no member data -- only methods which provide information about the ** frame types (and their component fields) supported by id3lib as defined ** in field.cpp . ** ** Usage is straightforward. The following function uses ID3_FrameInfo ** to display a summary of all the frames known to id3lib: ** \code ** ** void ShowKnownFrameInfo { ** ID3_FrameInfo myFrameInfo; ** for (int cur = ID3FID_NOFRAME+1; cur <= myFrameInfo.MaxFrameID(); cur ++) ** { ** cout << "Short ID: " << myFrameInfo.ShortName(ID3_FrameID(cur)) << ** " Long ID: " << myFrameInfo.LongName(ID3_FrameID(cur)) << ** " Desription: " << myFrameInfo.Description(ID3_FrameID(cur)) << endl; ** } ** } ** \endcode ** ** Functions are also provided to glean more information about the individual ** fields which make up any given frame type. The following for() loop, ** embedded into the previous for() loop would provide a raw look at such ** information. Realize, of course, that the field type is meaningless ** when printed. Only when it is taken in the context of the ID3_FieldType enum ** does it take on any meaningful significance. ** ** \code ** for (int cur = ID3FID_NOFRAME+1; cur <= fi.MaxFrameID(); cur ++) ** { ** int numfields = fi.NumFields(ID3_FrameID(cur)); ** ** cout << "ID: " << fi.LongName(ID3_FrameID(cur)) << ** " FIELDS: " << numfields << endl; ** for(int i=0;i ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID) return ID3_FrameDefs[frameID - 1].sShortTextID; return NULL; } char *ID3_FrameInfo::LongName(ID3_FrameID frameID) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID) return ID3_FrameDefs[frameID - 1].sLongTextID; return NULL; } const char *ID3_FrameInfo::Description(ID3_FrameID frameID) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID) return ID3_FrameDefs[frameID - 1].sDescription; return NULL; } int ID3_FrameInfo::MaxFrameID() { return ID3FID_LASTFRAMEID - 1; } int ID3_FrameInfo::NumFields(ID3_FrameID frameID) { int fieldNum = 0; if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID) { while (ID3_FrameDefs[frameID - 1].aeFieldDefs[fieldNum]._id != ID3FN_NOFIELD) ++fieldNum; } return fieldNum; } ID3_FieldID ID3_FrameInfo::FieldID(ID3_FrameID frameID, int fieldNum) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID && fieldNum < NumFields(frameID)) return ID3_FrameDefs[frameID - 1].aeFieldDefs[fieldNum]._id; return ID3FN_NOFIELD; } ID3_FieldType ID3_FrameInfo::FieldType(ID3_FrameID frameID, int fieldNum) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID && fieldNum < NumFields(frameID)) return ID3_FrameDefs[frameID - 1].aeFieldDefs[fieldNum]._type; return ID3FTY_NONE; } size_t ID3_FrameInfo::FieldSize(ID3_FrameID frameID, int fieldNum) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID && fieldNum < NumFields(frameID)) return ID3_FrameDefs[frameID - 1].aeFieldDefs[fieldNum]._fixed_size; return 0; } flags_t ID3_FrameInfo::FieldFlags(ID3_FrameID frameID, int fieldNum) { if (frameID > ID3FID_NOFRAME && frameID < ID3FID_LASTFRAMEID && fieldNum < NumFields(frameID)) return ID3_FrameDefs[frameID - 1].aeFieldDefs[fieldNum]._flags; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_binary.cpp000066400000000000000000000113641516712004000263700ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "field_impl.h" #include #include #include using namespace dami; size_t ID3_FieldImpl::Set(const uchar *data, size_t len) { size_t size = 0; if (this->GetType() == ID3FTY_BINARY && data != NULL && len > 0) { BString str(data, len); size = dami::min(len, this->SetBinary(str)); } return size; } /** Copies the supplied unicode string to the field. ** ** Again, like the string types, the binary Set() function copies the data ** so you may dispose of the source data after a call to this method. **/ size_t ID3_FieldImpl::SetBinary(BString data) //< data to assign to this field. { size_t size = 0; if (this->GetType() == ID3FTY_BINARY) { this->Clear(); size_t fixed = _fixed_size; size = data.size(); if (fixed == 0) { _binary = data; } else { _binary.assign(data, 0, dami::min(size, fixed)); if (size < fixed) _binary.append(fixed - size, '\0'); } size = _binary.size(); _changed = true; } return size; } BString ID3_FieldImpl::GetBinary() const { BString data; if (this->GetType() == ID3FTY_BINARY) data = _binary; return data; } const uchar* ID3_FieldImpl::GetRawBinary() const { const uchar *data = NULL; if (this->GetType() == ID3FTY_BINARY) data = _binary.data(); return data; } /** Copies the field's internal string to the buffer. ** ** It copies the data in the field into the buffer, for as many bytes as the ** field contains, or the size of buffer, whichever is smaller. ** ** \code ** uchar buffer[1024]; ** myFrame.GetField(ID3FN_DATA)->Get(buffer, sizeof(buffer)); ** \endcode **/ size_t ID3_FieldImpl::Get(uchar *buffer, size_t max_bytes) const // Destination of retrieved string and max number of bytes to copy { size_t bytes = 0; if (this->GetType() == ID3FTY_BINARY) { bytes = dami::min(max_bytes, this->Size()); if (buffer != NULL && bytes > 0) ::memcpy(buffer, _binary.data(), bytes); } return bytes; } /** Copies binary data from the file specified to the field. ** ** \code ** myFrame.GetField(ID3FN_DATA)->FromFile("mypic.jpg"); ** \endcode **/ void ID3_FieldImpl::FromFile(const char *info) // Source filename { if (this->GetType() != ID3FTY_BINARY || NULL == info) return; FILE *temp_file = ::fopen(info, "rb"); if (temp_file == NULL) return; ::fseek(temp_file, 0, SEEK_END); long fileSize = ::ftell(temp_file); ::fseek(temp_file, 0, SEEK_SET); if (fileSize >= 0) { uchar *buffer = new uchar[fileSize]; if (buffer != NULL) { if (::fread(buffer, 1, fileSize, temp_file) == (size_t) fileSize) this->Set(buffer, fileSize); delete [] buffer; } } ::fclose(temp_file); } /** Copies binary data from the field to the specified file. ** ** \code ** myFrame.GetField(ID3FN_DATA)->ToFile("output.bin"); ** \endcode **/ void ID3_FieldImpl::ToFile(const char *info) const // < Destination filename { if (this->GetType() != ID3FTY_BINARY || info == NULL) return; size_t size = this->Size(); if (size > 0) { FILE *temp_file = ::fopen(info, "wb"); if (temp_file != NULL) { ::fwrite(_binary.data(), 1, size, temp_file); ::fclose(temp_file); } } return; } bool ID3_FieldImpl::ParseBinary(ID3_Reader& reader) { /* Copy the remaining bytes, unless we're fixed length, in which case * copy the minimum of the remaining bytes vs the fixed length. */ _binary = io::readAllBinary(reader); return true; } void ID3_FieldImpl::RenderBinary(ID3_Writer &writer) const { writer.writeChars(this->GetRawBinary(), this->Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_def.h000066400000000000000000000031311516712004000253000ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FIELD_DEF_H_ #define _ID3LIB_FIELD_DEF_H_ #include "id3/globals.h" struct ID3_FieldDef { ID3_FieldID _id; ID3_FieldType _type; size_t _fixed_size; ID3_V2Spec _spec_begin; ID3_V2Spec _spec_end; flags_t _flags; ID3_FieldID _linked_field; static const ID3_FieldDef *DEFAULT; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_frames.cpp000066400000000000000000000036621516712004000263630ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "field_impl.h" #include "container_impl.h" #include #include using namespace dami; bool ID3_FieldImpl::ParseFrames(ID3_Reader& reader) { ID3D_NOTICE( "ID3_FieldImpl::ParseFrames(): beg = " << reader.getBeg() ); ID3D_NOTICE( "ID3_FieldImpl::ParseFrames(): cur = " << reader.getCur() ); ID3D_NOTICE( "ID3_FieldImpl::ParseFrames(): end = " << reader.getEnd() ); bool success = false; if (!reader.atEnd()) { this->Clear(); id3::v2::parseFrames(*this->_impl, reader); _changed = false; success = true; } return success; } void ID3_FieldImpl::RenderFrames(ID3_Writer& writer) const { id3::v2::renderFrames(writer, *this->_impl); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_impl.h000066400000000000000000000124671516712004000255170ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FIELD_IMPL_H_ #define _ID3LIB_FIELD_IMPL_H_ #include struct ID3_FieldDef; struct ID3_FrameDef; class ID3_FieldImpl : public ID3_Field { friend class ID3_FrameImpl; public: ~ID3_FieldImpl(); void Clear(); size_t Size() const; size_t BinSize() const; size_t GetNumTextItems() const; /* Integer field functions */ ID3_Field &operator= (uint32 val) { this->Set(val); return *this; } void Set(uint32); uint32 Get() const; void SetInteger(uint32); uint32 GetInteger() const; /* ASCII string field functions */ ID3_Field &operator =(const char *s) { this->Set(s); return *this; } size_t Set(const char *data); size_t Get(char *, size_t) const; size_t Get(char *, size_t, size_t) const; const char *GetRawText() const; size_t Add(const char * data); dami::String GetText() const; dami::String GetTextItem(size_t) const; size_t SetText(dami::String); size_t AddText(dami::String); /* Unicode string field functions */ ID3_Field &operator= (const unicode_t *s) { this->Set(s); return *this; } size_t Set(const unicode_t*); size_t Get(unicode_t *buffer, size_t) const; size_t Get(unicode_t *buffer, size_t, size_t) const; size_t Add(const unicode_t *); const unicode_t *GetRawUnicodeText() const; /* Binary field functions */ size_t Set(const uchar *buf, size_t size); size_t Set(const char *buf, size_t size) { return this->Set(reinterpret_cast(buf), size); } size_t Get(uchar *, size_t) const; const uchar *GetRawBinary() const; void FromFile(const char *); void ToFile(const char *sInfo) const; size_t SetBinary(dami::BString); dami::BString GetBinary() const; /* Miscelaneous functions */ ID3_Field &operator=(const ID3_Field &); bool InScope(ID3_V2Spec spec) const { return _spec_begin <= spec && spec <= _spec_end; } ID3_V2Spec MinSpec() const { return _spec_begin; } ID3_V2Spec MaxSpec() const { return _spec_end; } ID3_FieldID GetID() const { return _id; } ID3_FieldID GetLinkedField() const { return _linked_field; } ID3_FieldType GetType() const { return _type; } bool SetEncoding(ID3_TextEnc enc); bool SetLinkedSize(size_t newfixedsize); bool HasFixedSize() { return _fixed_size != 0; }; ID3_TextEnc GetEncoding() const { return _enc; } bool HasFlag(const flags_t flag) const { return (_flags & flag) == flag; } bool IsEncodable() const { return this->HasFlag(ID3FF_ENCODABLE); } ID3_Err Render(ID3_Writer &) const; bool Parse(ID3_Reader &); bool HasChanged() const; private: size_t SetText_i(dami::String); size_t AddText_i(dami::String); /* To prevent public instantiation, the constructor is made private */ ID3_FieldImpl(); ID3_FieldImpl(const ID3_FieldDef&); const ID3_FieldID _id; // the ID of this field const ID3_FieldType _type; // what type is this field or should be ID3_V2Spec _spec_begin; // spec end ID3_V2Spec _spec_end; // spec begin const flags_t _flags; // special field flags const ID3_FieldID _linked_field; // the ID of field where fixed size comes from mutable bool _changed; // field changed since last parse/render? dami::BString _binary; // for binary strings dami::String _text; // for ascii strings uint32 _integer; // for numbers size_t _fixed_size; // for fixed length fields (0 if not) size_t _num_items; // the number of items in the text string ID3_TextEnc _enc; // encoding for text fields protected: void RenderInteger(ID3_Writer&) const; void RenderText(ID3_Writer&) const; void RenderBinary(ID3_Writer&) const; void RenderFrames(ID3_Writer&) const; bool ParseInteger(ID3_Reader&); bool ParseText(ID3_Reader&); bool ParseBinary(ID3_Reader&); bool ParseFrames(ID3_Reader&); }; /* Ack! Not for public use */ ID3_FrameDef *ID3_FindFrameDef(ID3_FrameID id); ID3_FrameID ID3_FindFrameID(const char *id); #endif /* _ID3LIB_FIELD_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_integer.cpp000066400000000000000000000054421516712004000265410ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "field_impl.h" #include #include using namespace dami; /** \brief Sets the value of the field to the specified integer. ** \param data The data to assign to this field **/ void ID3_FieldImpl::Set(uint32 val) { this->SetInteger(val); } void ID3_FieldImpl::SetInteger(uint32 val) { if (this->GetType() == ID3FTY_INTEGER) { this->Clear(); _integer = val; _changed = true; } } /** \fn uint32 ID3_Field::Get() const ** \brief Returns the value of the integer field. ** ** \code ** uint32 picType = myFrame.GetField(ID3FN_PICTURETYPE)->Get(); ** \endcode ** ** \return The value of the integer field **/ uint32 ID3_FieldImpl::Get() const { return this->GetInteger(); } uint32 ID3_FieldImpl::GetInteger() const { uint32 val = 0; if (this->GetType() == ID3FTY_INTEGER) { val = _integer; } return val; } bool ID3_FieldImpl::ParseInteger(ID3_Reader& reader) { ID3D_NOTICE( "ID3_FieldImpl::ParseInteger(): beg = " << reader.getBeg() ); ID3D_NOTICE( "ID3_FieldImpl::ParseInteger(): cur = " << reader.getCur() ); ID3D_NOTICE( "ID3_FieldImpl::ParseInteger(): end = " << reader.getEnd() ); bool success = false; if (!reader.atEnd()) { this->Clear(); size_t fixed = this->Size(); size_t nBytes = (fixed > 0) ? fixed : sizeof(uint32); this->Set(io::readBENumber(reader, nBytes)); _changed = false; success = true; } return success; } void ID3_FieldImpl::RenderInteger(ID3_Writer& writer) const { io::writeBENumber(writer, _integer, this->Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_string_ascii.cpp000066400000000000000000000233341516712004000275620ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "field_impl.h" #include #include using namespace dami; /** \brief Copies the supplied string to the field. ** You may dispose of the source string after a call to this method. ** \code ** myFrame.GetField(ID3FN_TEXT)->Set("ID3Lib is very cool!"); ** \endcode **/ size_t ID3_FieldImpl::Set(const char *data) { size_t len = 0; if ((this->GetType() == ID3FTY_TEXTSTRING) && data != NULL) { String str(data); len = this->SetText_i(str); } return len; } // the ::Get() function for ASCII /** Copies the contents of the field into the supplied buffer, up to the ** number of characters specified; for fields with multiple entries, the ** optional third parameter indicates which of the fields to retrieve. ** ** The third parameter is useful when using text lists (see Add(const char*) ** for more details). The default value for this third parameter is 1, ** which returns the entire string if the field contains only one item. ** ** It returns the number of characters (not bytes necessarily, and not ** including any NULL terminator) of the supplied buffer that are now used. ** ** \code ** char myBuffer[1024]; ** size_t charsUsed = myFrame.GetField(ID3FN_TEXT)->Get(buffer, 1024); ** \endcode ** ** It fills the buffer with as much data from the field as is present in the ** field, or as large as the buffer, whichever is smaller. ** ** \code ** char myBuffer[1024]; ** size_t charsUsed = myFrame.GetField(ID3FN_TEXT)->Get(buffer, 1024, 3); ** \endcode ** ** This fills the buffer with up to the first 1024 characters from the third ** element of the text list. ** ** \sa Add(const char*) **/ size_t ID3_FieldImpl::Get(char *buffer, size_t maxLength) const { size_t size = 0; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_SINGLE_BYTE_ENC(this->GetEncoding()) && buffer != NULL && maxLength > 0) { String data = this->GetText(); size = dami::min(maxLength, data.size()); ::memcpy(buffer, data.data(), size); if (size < maxLength) buffer[size] = '\0'; } return size; } size_t ID3_FieldImpl::Get(char *buf, size_t maxLen, size_t index) const { size_t size = 0; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_SINGLE_BYTE_ENC(this->GetEncoding()) && buf != NULL && maxLen > 0) { String data = this->GetTextItem(index); size = dami::min(maxLen, data.size()); ::memcpy(buf, data.data(), size); if (size < maxLen) buf[size] = '\0'; } return size; } String ID3_FieldImpl::GetText() const { String data; if (this->GetType() == ID3FTY_TEXTSTRING) data = _text; return data; } String ID3_FieldImpl::GetTextItem(size_t index) const { String data; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_SINGLE_BYTE_ENC(this->GetEncoding()) && index < this->GetNumTextItems()) { const char *raw = _text.c_str(); for (size_t i = 0; i < index; ++i) raw += strlen(raw) + 1; if (raw != NULL) data = raw; } return data; } namespace { String getFixed(String data, size_t size) { String text(data, 0, size); if (text.size() < size) text.append(size - text.size(), '\0'); return text; } } size_t ID3_FieldImpl::SetText_i(String data) { this->Clear(); if (_fixed_size > 0) _text = getFixed(data, _fixed_size); else _text = data; ID3D_NOTICE( "SetText_i: text = \"" << _text << "\"" ); _changed = true; if (_text.size() == 0) _num_items = 0; else _num_items = 1; return _text.size(); } size_t ID3_FieldImpl::SetText(String data) { size_t len = 0; if (this->GetType() == ID3FTY_TEXTSTRING) len = this->SetText_i(data); return len; } /** For fields which support this feature, adds a string to the list of ** strings currently in the field. ** ** This is useful for using id3v2 frames such as the involved people list, ** composer, and part of setp. You can use the GetNumTextItems() method to ** find out how many such items are in a list. ** ** \code ** myFrame.GetField(ID3FN_TEXT)->Add("this is a test"); ** \endcode ** ** \param string The string to add to the field **/ size_t ID3_FieldImpl::AddText_i(String data) { size_t len = 0; // how much of str we copied into this field (max is strLen) ID3D_NOTICE ("ID3_FieldImpl::AddText_i: Adding \"" << data << "\"" ); if (this->GetNumTextItems() == 0) { // there aren't any text items in the field so just assign the string to // the field len = this->SetText_i(data); } else { // ASSERT(_fixed_size == 0) _text += '\0'; if (ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding())) _text += '\0'; _text.append(data); len = data.size(); _num_items++; } return len; } size_t ID3_FieldImpl::AddText(String data) { size_t len = 0; if (this->GetType() == ID3FTY_TEXTSTRING) len = this->AddText_i(data); return len; } size_t ID3_FieldImpl::Add(const char *data) { size_t len = 0; if (this->GetType() == ID3FTY_TEXTSTRING) { String str(data); len = this->AddText_i(str); } return len; } const char *ID3_FieldImpl::GetRawText() const { const char *text = NULL; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_SINGLE_BYTE_ENC(this->GetEncoding())) text = _text.c_str(); return text; } namespace { String readEncodedText(ID3_Reader& reader, size_t len, ID3_TextEnc enc) { if (ID3TE_IS_SINGLE_BYTE_ENC(enc)) return io::readText(reader, len); return io::readUnicodeText(reader, len, enc); } String readEncodedString(ID3_Reader& reader, ID3_TextEnc enc) { if (ID3TE_IS_SINGLE_BYTE_ENC(enc)) return io::readString(reader); return io::readUnicodeString(reader, enc); } size_t writeEncodedText(ID3_Writer &writer, String data, ID3_TextEnc enc) { if (ID3TE_IS_SINGLE_BYTE_ENC(enc)) return io::writeText(writer, data); return io::writeUnicodeText(writer, data, enc); } size_t writeEncodedString(ID3_Writer &writer, String data, ID3_TextEnc enc) { if (ID3TE_IS_SINGLE_BYTE_ENC(enc)) return io::writeString(writer, data); return io::writeUnicodeString(writer, data, enc); } } bool ID3_FieldImpl::ParseText(ID3_Reader &reader) { ID3D_NOTICE( "ID3_Field::ParseText(): reader.getBeg() = " << reader.getBeg() ); ID3D_NOTICE( "ID3_Field::ParseText(): reader.getCur() = " << reader.getCur() ); ID3D_NOTICE( "ID3_Field::ParseText(): reader.getEnd() = " << reader.getEnd() ); this->Clear(); ID3_TextEnc enc = this->GetEncoding(); size_t fixed_size = this->Size(); if (fixed_size) { ID3D_NOTICE( "ID3_Field::ParseText(): fixed size string" ); // The string is of fixed length String text = readEncodedText(reader, fixed_size, enc); this->SetText(text); ID3D_NOTICE( "ID3_Field::ParseText(): fixed size string = " << text ); } else if (_flags & ID3FF_LIST) { ID3D_NOTICE( "ID3_Field::ParseText(): text list" ); // lists are always the last field in a frame. parse all remaining // characters in the reader while (!reader.atEnd()) { String text = readEncodedString(reader, enc); this->AddText(text); ID3D_NOTICE( "ID3_Field::ParseText(): adding string = " << text ); } } else if (_flags & ID3FF_NLIST) { ID3D_NOTICE( "ID3_Field::ParseText(): n elements text list" ); int num_items = io::readBENumber(reader, 1); for (int i = 0; i < num_items; i++) { String text = readEncodedString(reader, enc); this->AddText(text); ID3D_NOTICE( "ID3_Field::ParseText(): adding string = " << text ); } } else if (_flags & ID3FF_CSTR) { ID3D_NOTICE( "ID3_Field::ParseText(): null terminated string" ); String text = readEncodedString(reader, enc); this->SetText(text); ID3D_NOTICE( "ID3_Field::ParseText(): null terminated string = " << text ); } else { ID3D_NOTICE( "ID3_Field::ParseText(): last field string" ); String text = readEncodedText(reader, reader.remainingBytes(), enc); // not null terminated. this->AddText(text); ID3D_NOTICE( "ID3_Field::ParseText(): last field string = " << text ); } _changed = false; return true; } void ID3_FieldImpl::RenderText(ID3_Writer &writer) const { ID3_TextEnc enc = this->GetEncoding(); if (_flags & ID3FF_CSTR) { writeEncodedString(writer, _text, enc); } else { if (_flags & ID3FF_NLIST) io::writeBENumber(writer, _num_items, 1); writeEncodedText(writer, _text, enc); if (_flags & ID3FF_NLIST) io::writeBENumber(writer, 0, 1); } _changed = false; }; /** Returns the number of items in a text list. ** ** \code ** size_t numItems = myFrame.GetField(ID3FN_UNICODE)->GetNumItems(); ** \endcode ** ** \return The number of items in a text list. **/ size_t ID3_FieldImpl::GetNumTextItems() const { return _num_items; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/field_string_unicode.cpp000066400000000000000000000110751516712004000301170ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "field_impl.h" #include #include using namespace dami; /** \brief Copies the supplied unicode string to the field. ** ** Performs similarly as the ASCII Set() method, taking a unicode_t string ** as a parameter rather than an ascii string. ** ** \param string The unicode string to set this field to. ** \sa Add(const unicode_t*) **/ size_t ID3_FieldImpl::Set(const unicode_t *data) { size_t size = 0; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding()) && data != NULL) { String text((const char *) data, ucslen(data) * 2); size = this->SetText_i(text); } return size; } size_t ID3_FieldImpl::Add(const unicode_t *data) { size_t size = 0; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding()) && data != NULL) { String text((const char *) data, ucslen(data) * 2); size = this->AddText_i(text); } return size; } /** Copies the contents of the field into the supplied buffer, up to the ** number of characters specified; for fields with multiple entries, the ** optional third parameter indicates which of the fields to retrieve. ** ** Performs similarly as the ASCII Get(char *, size_t, size_t) method, taking ** a unicode_t string as a parameter rather than an ascii string. The ** maxChars parameter still represents the maximum number of characters, not ** bytes. ** ** \code ** unicode_t myBuffer[1024]; ** size_t charsUsed = myFrame.GetField(ID3FN_UNICODE)->Get(buffer, 1024); ** \endcode ** ** \param buffer Where the field's data is copied to ** \param maxChars The maximum number of characters to copy to the buffer. ** \param itemNum For fields with multiple items (such as the involved ** people frame, the item number to retrieve. ** \sa Get(char *, size_t, size_t) **/ size_t ID3_FieldImpl::Get(unicode_t *buffer, size_t maxLength) const { size_t length = 0; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding()) && buffer != NULL && maxLength > 0) { String unicode = _text + '\0' + '\0'; const unicode_t* text = (unicode_t *) unicode.data(); if (NULL != text) { length = dami::min(maxLength, ucslen(text)); ::memcpy(buffer, text, length * 2); if (length < maxLength) { buffer[length] = NULL_UNICODE; } } } return length; } const unicode_t* ID3_FieldImpl::GetRawUnicodeText() const { const unicode_t* text = NULL; if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding())) { text = (unicode_t *)_text.data(); } return text; } size_t ID3_FieldImpl::Get(unicode_t *buffer, size_t maxLength, size_t itemNum) const { size_t length = 0; size_t total_items = this->GetNumTextItems(); if (this->GetType() == ID3FTY_TEXTSTRING && ID3TE_IS_DOUBLE_BYTE_ENC(this->GetEncoding()) && buffer != NULL && maxLength > 0 && itemNum < total_items) { String unicode = _text + '\0' + '\0'; const unicode_t *text = (unicode_t *) unicode.data(); for (size_t i = 0; i < itemNum; ++i) text += ucslen(text) + 1; if (text != NULL) { length = dami::min(maxLength, ucslen(text)); ::memcpy(buffer, text, length * 2); if (length < maxLength) buffer[length] = NULL_UNICODE; } } return length; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/flags.h000066400000000000000000000040221516712004000244730ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FLAGS_H_ #define _ID3LIB_FLAGS_H_ #include class ID3_Flags { public: typedef flags_t TYPE; ID3_Flags() : _f(0) { } virtual ~ID3_Flags() { } TYPE get() const { return _f; } bool test(TYPE f) const { return (this->get() & f) == f; } bool set(TYPE f) { bool r = (_f != f); _f = f; return r; } bool add(TYPE f) { return this->set(this->get() | f); } bool remove(TYPE f) { return this->set(this->get() & ~f); } bool clear() { return this->set(0); } bool set(TYPE f, bool b) { if (b) return this->add(f); return this->remove(f); } ID3_Flags &operator =(const ID3_Flags &f) { if (this != &f) this->set(f.get()); return *this; } private: TYPE _f; }; #endif /* _ID3LIB_FLAGS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame.cpp000066400000000000000000000162561516712004000250400ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "frame_impl.h" #include /** \class ID3_Frame frame.h id3/frame.h ** \brief The representative class of an id3v2 frame. ** ** id3lib defines frames in a funny way. Using some nice c++ conventions, ** ID3_FrameImpl class objects appear to be quite polymorphic; that is, they ** can take on many forms. The same ID3_FrameImpl class provides the ** facilities for the implementation of a complex APIC frame and for a simple ** text frame. ** ** @author Dirk Mahoney ** @version $Id$ ** @see ID3_Tag ** @see ID3_Field ** @see ID3_Err **/ /** Default constructor; accepts as a default parameter the type of frame ** to create. ** ** The parameter which will internally set the frame's structure. See ** SetID() for more details. ** ** @param id The type of frame to create ** @see ID3_FrameID ** @see SetID **/ ID3_Frame::ID3_Frame(ID3_FrameID id) : _impl(new ID3_FrameImpl(id)) { } ID3_Frame::ID3_Frame(const ID3_Frame &frame) : _impl(new ID3_FrameImpl(frame)) { } ID3_Frame::~ID3_Frame() { delete _impl; } /** Clears the frame of all data and resets the frame such that it can take ** on the form of any id3v2 frame that id3lib supports. ** ** @see ID3_Tag::Clear **/ void ID3_Frame::Clear() { _impl->Clear(); } /** Returns the type of frame that the object represents. ** ** Useful in conjunction with ID3_Tag::Find() method ** ** @returns The type, or id, of the frame ** @see ID3_Tag::Find **/ ID3_FrameID ID3_Frame::GetID() const { return _impl->GetID(); } /** Establishes the internal structure of an ID3_FrameImpl object so ** that it represents the id3v2 frame indicated by the parameter ** ** Given an ID3_FrameID (a list of which is found in <id3/field.h>), ** SetID() will structure the object according to the ** frame you wish to implement. ** ** Either using this call or via the constructor, this must be the first ** command performed on an ID3_FrameImpl object. ** ** \code ** myFrame.SetID(ID3FID_TITLE); ** \endcode ** ** @param id The type of frame this frame should be set to ** @see ID3_FrameID **/ bool ID3_Frame::SetID(ID3_FrameID id) { return _impl->SetID(id); } bool ID3_Frame::SetSpec(ID3_V2Spec spec) { return _impl->SetSpec(spec); } ID3_V2Spec ID3_Frame::GetSpec() const { return _impl->GetSpec(); } ID3_V2Spec ID3_Frame::MinSpec() const { return _impl->MinSpec(); } /** Returns a pointer to the frame's internal field indicated by the ** parameter. ** ** \code ** ID3_TextEnc enc; ** enc = (ID3_TextEnc) myFrame.GetField(ID3FN_TEXTENC)->Get(); ** \endcode ** ** @param name The name of the field to be retrieved ** @returns A reference to the desired field **/ ID3_Field *ID3_Frame::GetField(ID3_FieldID fieldName) const { return _impl->GetField(fieldName); } size_t ID3_Frame::NumFields() const { return _impl->NumFields(); } size_t ID3_Frame::Size() { return _impl->Size(); } bool ID3_Frame::HasChanged() const { return _impl->HasChanged(); } ID3_Frame &ID3_Frame::operator=(const ID3_Frame &rFrame) { if (this != &rFrame) { *_impl = rFrame; } return *this; } const char *ID3_Frame::GetDescription(ID3_FrameID id) { return ID3_FrameImpl::GetDescription(id); } const char *ID3_Frame::GetDescription() const { return _impl->GetDescription(); } const char *ID3_Frame::GetTextID() const { return _impl->GetTextID(); } bool ID3_Frame::Parse(ID3_Reader &reader) { return _impl->Parse(reader); } ID3_Err ID3_Frame::Render(ID3_Writer &writer) const { return _impl->Render(writer); } bool ID3_Frame::Contains(ID3_FieldID id) const { return _impl->Contains(id); } /** Sets the compression flag within the frame. When the compression flag is ** is set, compression will be attempted. However, the frame might not ** actually be compressed after it is rendered if the "compressed" data is ** no smaller than the "uncompressed" data. **/ bool ID3_Frame::SetCompression(bool b) { return _impl->SetCompression(b); } /** Returns whether or not the compression flag is set. After parsing a tag, ** this will indicate whether or not the frame was compressed. After ** rendering a tag, however, it does not actually indicate if the frame is ** compressed rendering. It only indicates whether or not compression was ** attempted. A frame will not be compressed, even whent the compression ** flag is set, if the "compressed" data is no smaller than the ** "uncompressed" data. **/ bool ID3_Frame::GetCompression() const { return _impl->GetCompression(); } size_t ID3_Frame::GetDataSize() const { return _impl->GetDataSize(); } bool ID3_Frame::SetEncryptionID(uchar id) { return _impl->SetEncryptionID(id); } uchar ID3_Frame::GetEncryptionID() const { return _impl->GetEncryptionID(); } bool ID3_Frame::SetGroupingID(uchar id) { return _impl->SetGroupingID(id); } uchar ID3_Frame::GetGroupingID() const { return _impl->GetGroupingID(); } namespace { class IteratorImpl : public ID3_Frame::Iterator { ID3_FrameImpl::iterator _cur; ID3_FrameImpl::iterator _end; public: IteratorImpl(ID3_FrameImpl &frame) : _cur(frame.begin()), _end(frame.end()) { } ID3_Field *GetNext() { ID3_Field *next = NULL; while (next == NULL && _cur != _end) { next = *_cur; ++_cur; } return next; } }; class ConstIteratorImpl : public ID3_Frame::ConstIterator { ID3_FrameImpl::const_iterator _cur; ID3_FrameImpl::const_iterator _end; public: ConstIteratorImpl(ID3_FrameImpl& frame) : _cur(frame.begin()), _end(frame.end()) { } const ID3_Field *GetNext() { ID3_Field *next = NULL; while (next == NULL && _cur != _end) { next = *_cur; ++_cur; } return next; } }; } ID3_Frame::Iterator *ID3_Frame::CreateIterator() { return new IteratorImpl(*_impl); } ID3_Frame::ConstIterator *ID3_Frame::CreateIterator() const { return new ConstIteratorImpl(*_impl); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame_def.h000066400000000000000000000034471516712004000253210ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FRAME_DEF_H_ #define _ID3LIB_FRAME_DEF_H_ #include struct ID3_FieldDef; class ID3_Frame; /* Structure used for defining how frames are defined internally. */ struct ID3_FrameDef { ID3_FrameID eID; char sShortTextID[3 + 1]; char sLongTextID[4 + 1]; ID3_V2Spec eFirstAppearance; ID3_V2Spec eLastAppearance; ID3_Frame *(*convert)(ID3_Frame *frame, ID3_V2Spec tospec); bool bTagDiscard; bool bFileDiscard; const ID3_FieldDef *aeFieldDefs; const char *sDescription; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame_impl.cpp000066400000000000000000000125601516712004000260530ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "frame_impl.h" #include "field_impl.h" #include "frame_def.h" #include "field_def.h" ID3_FrameImpl::ID3_FrameImpl(ID3_FrameID id) : _changed(false), _bitset(), _fields(), _encryption_id('\0'), _grouping_id('\0') { this->SetSpec(ID3V2_DEFAULT); this->SetID(id); } ID3_FrameImpl::ID3_FrameImpl(const ID3_FrameHeader &hdr) : _changed(false), _bitset(), _fields(), _hdr(hdr), _encryption_id('\0'), _grouping_id('\0') { this->_InitFields(); } ID3_FrameImpl::ID3_FrameImpl(const ID3_Frame& frame) : _changed(false), _bitset(), _fields(), _encryption_id('\0'), _grouping_id('\0') { *this = frame; } ID3_FrameImpl::~ID3_FrameImpl() { Clear(); } bool ID3_FrameImpl::_ClearFields() { for (iterator fi = _fields.begin(); fi != _fields.end(); ++fi) delete (ID3_FieldImpl*) *fi; _fields.clear(); _bitset.reset(); _changed = true; return true; } void ID3_FrameImpl::Clear() { this->_ClearFields(); _hdr.Clear(); _encryption_id = '\0'; _grouping_id = '\0'; } void ID3_FrameImpl::_InitFields() { const ID3_FrameDef *info = _hdr.GetFrameDef(); if (NULL == info) { // log this ID3_Field *fld = new ID3_FieldImpl(ID3_FieldDef::DEFAULT[0]); _fields.push_back(fld); _bitset.set(fld->GetID()); } else { for (size_t i = 0; info->aeFieldDefs[i]._id != ID3FN_NOFIELD; ++i) { ID3_Field *fld = new ID3_FieldImpl(info->aeFieldDefs[i]); _fields.push_back(fld); _bitset.set(fld->GetID()); } _changed = true; } } bool ID3_FrameImpl::SetID(ID3_FrameID id) { bool changed = (this->GetID() != id); if (changed) { this->_SetID(id); _changed = true; } return changed; } bool ID3_FrameImpl::_SetID(ID3_FrameID id) { bool changed = this->_ClearFields(); changed = _hdr.SetFrameID(id) || changed; this->_InitFields(); return changed; } bool ID3_FrameImpl::SetSpec(ID3_V2Spec spec) { return _hdr.SetSpec(spec); } ID3_V2Spec ID3_FrameImpl::GetSpec() const { return _hdr.GetSpec(); } ID3_Field* ID3_FrameImpl::GetField(ID3_FieldID fieldName) const { ID3_Field *field = NULL; if (this->Contains(fieldName)) { for (const_iterator fi = _fields.begin(); fi != _fields.end(); ++fi) { if ((*fi)->GetID() == fieldName) { field = *fi; break; } } } return field; } size_t ID3_FrameImpl::NumFields() const { return _fields.size(); } size_t ID3_FrameImpl::Size() { size_t bytesUsed = _hdr.Size(); if (this->GetEncryptionID()) bytesUsed++; if (this->GetGroupingID()) bytesUsed++; ID3_TextEnc enc = ID3TE_ISO8859_1; for (iterator fi = _fields.begin(); fi != _fields.end(); ++fi) { if (*fi && (*fi)->InScope(this->GetSpec())) { if ((*fi)->GetID() == ID3FN_TEXTENC) enc = (ID3_TextEnc) (*fi)->Get(); else (*fi)->SetEncoding(enc); bytesUsed += (*fi)->BinSize(); } } return bytesUsed; } bool ID3_FrameImpl::HasChanged() const { bool changed = _changed; for (const_iterator fi = _fields.begin(); fi != _fields.end(); ++fi) { if (*fi && (*fi)->InScope(this->GetSpec())) changed = (*fi)->HasChanged(); } return changed; } ID3_FrameImpl &ID3_FrameImpl::operator=(const ID3_Frame &rFrame) { ID3_FrameID eID = rFrame.GetID(); this->SetID(eID); ID3_Frame::ConstIterator *ri = rFrame.CreateIterator(); iterator li = this->begin(); while (li != this->end()) { ID3_Field *thisFld = *li++; const ID3_Field *thatFld = ri->GetNext(); if (thisFld != NULL && thatFld != NULL) *thisFld = *thatFld; } delete ri; this->SetEncryptionID(rFrame.GetEncryptionID()); this->SetGroupingID(rFrame.GetGroupingID()); this->SetCompression(rFrame.GetCompression()); this->SetSpec(rFrame.GetSpec()); _changed = false; return *this; } const char* ID3_FrameImpl::GetDescription(ID3_FrameID id) { ID3_FrameDef *myFrameDef = ID3_FindFrameDef(id); if (myFrameDef != NULL) return myFrameDef->sDescription; return NULL; } const char* ID3_FrameImpl::GetDescription() const { const ID3_FrameDef *def = _hdr.GetFrameDef(); if (def) return def->sDescription; return NULL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame_impl.h000066400000000000000000000112321516712004000255130ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FRAME_IMPL_H_ #define _ID3LIB_FRAME_IMPL_H_ #include #include "header_frame.h" #include #include class ID3_FrameImpl { typedef std::bitset Bitset; typedef std::vector Fields; public: typedef Fields::iterator iterator; typedef Fields::const_iterator const_iterator; public: ID3_FrameImpl(ID3_FrameID id = ID3FID_NOFRAME); ID3_FrameImpl(const ID3_FrameHeader&); ID3_FrameImpl(const ID3_Frame&); // Destructor. virtual ~ID3_FrameImpl(); void Clear(); bool SetID(ID3_FrameID id); ID3_FrameID GetID() const { return _hdr.GetFrameID(); } ID3_Field *GetField(ID3_FieldID name) const; size_t NumFields() const; const char *GetDescription() const; static const char *GetDescription(ID3_FrameID); const char *GetTextID() const { return _hdr.GetTextID(); } ID3_FrameImpl &operator =(const ID3_Frame &); bool HasChanged() const; bool Parse(ID3_Reader &); ID3_Err Render(ID3_Writer &) const; size_t Size(); bool Contains(ID3_FieldID fld) const { return _bitset.test(fld); } bool SetSpec(ID3_V2Spec); ID3_V2Spec GetSpec() const; ID3_V2Spec MinSpec() const; /** Sets the compression flag within the frame. When the compression flag is ** is set, compression will be attempted. However, the frame might not ** actually be compressed after it is rendered if the "compressed" data is ** no smaller than the "uncompressed" data. **/ bool SetCompression(bool b) { return _hdr.SetCompression(b); } /** Returns whether or not the compression flag is set. After parsing a tag, ** this will indicate whether or not the frame was compressed. After ** rendering a tag, however, it does not actually indicate if the frame is ** compressed rendering. It only indicates whether or not compression was ** attempted. A frame will not be compressed, even whent the compression ** flag is set, if the "compressed" data is no smaller than the ** "uncompressed" data. **/ bool GetCompression() const { return _hdr.GetCompression(); } size_t GetDataSize() const { return _hdr.GetDataSize(); } bool SetEncryptionID(uchar id) { bool changed = id != _encryption_id; _encryption_id = id; _changed = _changed || changed; _hdr.SetEncryption(true); return changed; } bool SetGroupingID(uchar id) { bool changed = id != _grouping_id; _grouping_id = id; _changed = _changed || changed; _hdr.SetGrouping(true); return changed; } uchar GetEncryptionID() const { return _encryption_id; } uchar GetGroupingID() const { return _grouping_id; } iterator begin() { return _fields.begin(); } iterator end() { return _fields.end(); } const_iterator begin() const { return _fields.begin(); } const_iterator end() const { return _fields.end(); } protected: bool _SetID(ID3_FrameID); bool _ClearFields(); void _InitFields(); void _InitFieldBits(); void _UpdateFieldDeps(); private: mutable bool _changed; // frame changed since last parse/render? Bitset _bitset; // which fields are present? Fields _fields; ID3_FrameHeader _hdr; uchar _encryption_id; // encryption id uchar _grouping_id; // grouping id }; #endif /* _ID3LIB_FRAME_IMPL_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame_parse.cpp000066400000000000000000000165711516712004000262320ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "frame_impl.h" #include using namespace dami; namespace { bool parseFields(ID3_Reader &rdr, ID3_FrameImpl &frame) { int iLoop; int iFields; io::ExitTrigger et(rdr); ID3_TextEnc enc = ID3TE_ISO8859_1; // set the default encoding ID3_V2Spec spec = frame.GetSpec(); size_t linked_fixed_size = 0; // set the default linkedsize /* Parse the frame's fields. */ iFields = frame.NumFields(); ID3D_NOTICE("ID3_FrameImpl::Parse(): num_fields = " << iFields); iLoop = 0; for (ID3_FrameImpl::iterator fi = frame.begin(); fi != frame.end(); ++fi) { ID3_Field *fp = *fi; ++iLoop; if (rdr.atEnd()) { /* There's no remaining data to parse! */ ID3D_WARNING("ID3_FrameImpl::Parse(): out of data at postion " << rdr.getCur()); if (iLoop == iFields) { /* If we are at the last field, (the 'data' field) it's apparently * an empty tag used for filling up padding, it's no problem * break will set the current 'cursor' to the right spot outside the for loop. */ break; } return false; } if (NULL == fp) { /* Ack! Why is the field NULL? Log this... */ ID3D_WARNING("ID3_FrameImpl::Parse(): field is null"); continue; } if (!fp->InScope(spec)) { ID3D_NOTICE("ID3_FrameImpl::Parse(): field is not in scope"); /* Continue with the rest of the fields. */ continue; } if (!fp->SetLinkedSize(linked_fixed_size)) { ID3D_NOTICE("ID3_FrameImpl::Parse(): field is empty sized"); /* Continue with the rest of the fields. */ continue; } ID3D_NOTICE("ID3_FrameImpl::Parse(): setting enc to " << enc); fp->SetEncoding(enc); ID3_Reader::pos_type beg = rdr.getCur(); et.setExitPos(beg); ID3D_NOTICE("ID3_FrameImpl::Parse(): parsing field, cur = " << beg); ID3D_NOTICE("ID3_FrameImpl::Parse(): parsing field, end = " << rdr.getEnd()); if (!fp->Parse(rdr) || rdr.getCur() == beg) { /* Nothing to parse! Ack! Parse error... */ ID3D_WARNING("ID3_FrameImpl::Parse(): no data parsed, bad parse"); return false; } if (fp->GetID() == ID3FN_TEXTENC) { enc = static_cast(fp->Get()); ID3D_NOTICE("ID3_FrameImpl::Parse(): found encoding = " << enc); } if (fp->HasFlag(ID3FF_HASLINKEDSIZE)) { /* Check whether it has a fixed size itself and is an integer and and no _linked_field. */ if (fp->GetType() == ID3FTY_INTEGER && fp->HasFixedSize() && fp->GetLinkedField() == ID3FN_NOFIELD) { switch (fp->GetID()) { case ID3FN_BITSSIZE: { uint32 _tmp_byte_size_ = fp->Get(); linked_fixed_size = 0; /* Round to whole bytes: 1 bit will become 1 byte, 7 bits will become 1 byte, 9 bits become 2 bytes, etc. */ for (; _tmp_byte_size_ > 0;) { if (_tmp_byte_size_ < 8 && _tmp_byte_size_ != 0) { ++linked_fixed_size; break; } else if (_tmp_byte_size_ >= 8) { ++linked_fixed_size; _tmp_byte_size_ -= 8; } } ID3D_NOTICE("ID3_FrameImpl::Parse(): found linked_fixed_size = " << linked_fixed_size); break; } case ID3FN_BYTESSIZE: { linked_fixed_size = static_cast(fp->Get()); ID3D_NOTICE("ID3_FrameImpl::Parse(): found linked_fixed_size = " << linked_fixed_size); break; } default: { /* Should never reach here, added to avoid compiler errors. */ break; } } } } } et.setExitPos(rdr.getCur()); return true; } }; bool ID3_FrameImpl::Parse(ID3_Reader &reader) { io::ExitTrigger et(reader); ID3D_NOTICE("ID3_FrameImpl::Parse(): reader.getBeg() = " << reader.getBeg()); ID3D_NOTICE("ID3_FrameImpl::Parse(): reader.getCur() = " << reader.getCur()); ID3D_NOTICE("ID3_FrameImpl::Parse(): reader.getEnd() = " << reader.getEnd()); ID3_Reader::pos_type beg = reader.getCur(); _hdr.SetSpec(this->GetSpec()); if (!_hdr.Parse(reader) || reader.getCur() == beg) { ID3D_WARNING("ID3_FrameImpl::Parse(): no header to parse"); return false; } ID3D_NOTICE("ID3_FrameImpl::Parse(): after hdr, getCur() = " << reader.getCur()); ID3D_NOTICE("ID3_FrameImpl::Parse(): found frame! id = " << _hdr.GetTextID()); /* Data is the part of the frame buffer that appears after the header. */ const size_t dataSize = _hdr.GetDataSize(); ID3D_NOTICE("ID3_FrameImpl::Parse(): dataSize = " << dataSize); if (reader.getEnd() < beg + dataSize) { ID3D_WARNING("ID3_FrameImpl::Parse(): not enough data to parse frame"); return false; } if (dataSize > 16777216) //Klenotic: The max frame size is 16MB according to http://www.id3.org/easy.html. A corrupted tag that reports a frame size of (-1) will crash the program. { ID3D_WARNING( "ID3_FrameImpl::Parse(): frame size too large" ); return false; } io::WindowedReader wr(reader, dataSize); ID3D_NOTICE("ID3_FrameImpl::Parse(): window getBeg() = " << wr.getBeg()); ID3D_NOTICE("ID3_FrameImpl::Parse(): window getCur() = " << wr.getCur()); ID3D_NOTICE("ID3_FrameImpl::Parse(): window getEnd() = " << wr.getEnd()); unsigned long origSize = 0; if (_hdr.GetCompression()) { origSize = io::readBENumber(reader, sizeof(uint32)); ID3D_NOTICE("ID3_FrameImpl::Parse(): frame is compressed, origSize = " << origSize); } if (_hdr.GetEncryption()) { char ch = wr.readChar(); this->SetEncryptionID(ch); ID3D_NOTICE("ID3_FrameImpl::Parse(): frame is encrypted, encryption_id = " << (int) ch); } if (_hdr.GetGrouping()) { char ch = wr.readChar(); this->SetGroupingID(ch); ID3D_NOTICE("ID3_FrameImpl::Parse(): frame is encrypted, grouping_id = " << (int) ch); } /* Set the type of frame based on the parsed header. */ this->_ClearFields(); this->_InitFields(); /* Expand out the data if it's compressed. */ if (!_hdr.GetCompression()) { parseFields(wr, *this); } else { io::CompressedReader csr(wr, origSize); parseFields(csr, *this); } et.setExitPos(wr.getCur()); _changed = false; return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/frame_render.cpp000066400000000000000000000117521516712004000263730ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "frame_impl.h" #include #include using namespace dami; namespace { ID3_Err renderFields(ID3_Writer &writer, const ID3_FrameImpl &frame) { ID3_Err err; ID3_TextEnc enc = ID3TE_ISO8859_1; for (ID3_FrameImpl::const_iterator fi = frame.begin(); fi != frame.end(); ++fi) { ID3_Field *fld = *fi; if (fld != NULL && fld->InScope(frame.GetSpec())) { if (fld->GetID() == ID3FN_TEXTENC) { enc = static_cast(fld->Get()); ID3D_NOTICE( "id3::v2::renderFields(): found encoding = " << enc ); } else { fld->SetEncoding(enc); } err = fld->Render(writer); if (err != ID3E_NoError) return err; } } return ID3E_NoError; } } ID3_V2Spec ID3_FrameImpl::MinSpec() const { ID3_V2Spec minSpec = ID3V2_EARLIEST; for (const_iterator cur = _fields.begin(); cur != _fields.end(); ++cur) { ID3_Field *field = *cur; if (!field) continue; ID3_V2Spec fieldSpec = field->MinSpec(); if (minSpec < fieldSpec) minSpec = fieldSpec; } return minSpec; } ID3_Err ID3_FrameImpl::Render(ID3_Writer& writer) const { /* Return immediately if we have no fields, which (usually) means we're * trying to render a frame which has been Cleared or hasn't been initialized */ if (!this->NumFields()) return ID3E_NoError; ID3_FrameHeader hdr; hdr.SetSpec(this->GetSpec()); /* 1. Write out the field data to the buffer, with the assumption that * we won't be decompressing, since this is the usual behavior */ String flds; io::StringWriter fldWriter(flds); size_t origSize = 0; if (!this->GetCompression()) { renderFields(fldWriter, *this); origSize = flds.size(); ID3D_NOTICE("ID3_FrameImpl::Render(): uncompressed fields"); } else { io::CompressedWriter cr(fldWriter); renderFields(cr, *this); cr.flush(); origSize = cr.getOrigSize(); ID3D_NOTICE("ID3_FrameImpl::Render(): compressed fields, orig size = " << origSize); } size_t fldSize = flds.size(); ID3D_NOTICE("ID3_FrameImpl::Render(): field size = " << fldSize); /* No need to not write empty frames, why would we not? * They can be used to fill up padding space which is * even recommended in the id3 spec. */ // if (fldSize == 0) // { // ID3D_WARNING("ID3_FrameImpl::Render(): no field data"); // return; // } /* Determine which flags need to be set. */ uchar eID = this->GetEncryptionID(), gID = this->GetGroupingID(); ID3_FrameID fid = this->GetID(); if (fid == ID3FID_NOFRAME) { const char *tid = this->GetTextID(); hdr.SetUnknownFrame(tid); } else { hdr.SetFrameID(fid); } hdr.SetEncryption(eID > 0); hdr.SetGrouping(gID > 0); hdr.SetCompression(origSize > fldSize); hdr.SetDataSize(fldSize + ((hdr.GetCompression() ? 4 : 0) + (hdr.GetEncryption() ? 1 : 0) + (hdr.GetGrouping() ? 1 : 0))); /* Write out the header. */ ID3_Err err = hdr.Render(writer); if (err != ID3E_NoError) return err; if (fldSize != 0) { /* No-man's land! Not part of the header, not part of the data. */ if (hdr.GetCompression()) { io::writeBENumber(writer, origSize, sizeof(uint32)); ID3D_NOTICE("ID3_FrameImpl::Render(): frame is compressed, wrote origSize = " << origSize); } if (hdr.GetEncryption()) { writer.writeChar(eID); ID3D_NOTICE("ID3_FrameImpl::Render(): frame is compressed, encryption id = " << eID); } if (hdr.GetGrouping()) { writer.writeChar(gID); ID3D_NOTICE("ID3_FrameImpl::Render(): frame is compressed, grouping id = " << gID); } /* Write the field data. */ writer.writeChars(flds.data(), fldSize); } _changed = false; return ID3E_NoError; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/globals.cpp000066400000000000000000000035471516712004000253700ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include #if defined HAVE_CONFIG_H # include #endif #ifdef _cplusplus extern "C" { #endif const char * const ID3LIB_NAME = _ID3LIB_NAME; const char * const ID3LIB_VERSION = _ID3LIB_VERSION; const char * const ID3LIB_FULL_NAME = _ID3LIB_FULLNAME; const int ID3LIB_MAJOR_VERSION = _ID3LIB_MAJOR_VERSION; const int ID3LIB_MINOR_VERSION = _ID3LIB_MINOR_VERSION; const int ID3LIB_PATCH_VERSION = _ID3LIB_PATCH_VERSION; const int ID3LIB_INTERFACE_AGE = _ID3LIB_INTERFACE_AGE; const int ID3LIB_BINARY_AGE = _ID3LIB_BINARY_AGE; #ifdef _cplusplus } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header.cpp000066400000000000000000000042321516712004000251650ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "header.h" #if defined HAVE_CONFIG_H # include #endif bool ID3_Header::SetSpec(ID3_V2Spec spec) { static ID3_Header::Info _spec_info[] = { // Warning, EXT SIZE are minimum sizes, they can be bigger // SIZEOF SIZEOF SIZEOF IS EXT EXT EXPERIM // FRID FRSZ FRFL HEADER SIZE BIT { 3, 3, 0, false, 0, false }, // ID3V2_2_0 { 3, 3, 0, true, 8, true }, // ID3V2_2_1 { 4, 4, 2, false, 10, false }, // ID3V2_3_0 { 4, 4, 2, false, 6, false } // ID3V2_4_0 }; bool changed = false; if (spec < ID3V2_EARLIEST || spec > ID3V2_LATEST) { changed = _spec != ID3V2_UNKNOWN; _spec = ID3V2_UNKNOWN; _info = NULL; } else { changed = _spec != spec; _spec = spec; _info = &_spec_info[_spec - ID3V2_EARLIEST]; } _changed = _changed || changed; return changed; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header.h000066400000000000000000000060421516712004000246330ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_HEADER_H_ #define _ID3LIB_HEADER_H_ #include #include "flags.h" class ID3_Reader; class ID3_Writer; class ID3_Header { public: struct Info { uchar frame_bytes_id; uchar frame_bytes_size; uchar frame_bytes_flags; bool is_extended; size_t extended_bytes; // including the extended header, so everything! bool is_experimental; }; ID3_Header() : _spec(ID3V2_UNKNOWN), _data_size(0), _changed(false) { this->Clear(); _changed = false; } virtual ~ID3_Header() { } virtual bool SetSpec(ID3_V2Spec); ID3_V2Spec GetSpec() const { return _spec; } bool SetDataSize(size_t size) { bool changed = size != _data_size; _changed = _changed || changed; _data_size = size; return changed; } size_t GetDataSize() const { return _data_size; } virtual bool Clear() { bool changed = this->SetDataSize(0); if (this->GetSpec() == ID3V2_UNKNOWN) { this->SetSpec(ID3V2_DEFAULT); changed = true; } changed = _flags.clear() || changed; _changed = changed || _changed; return changed; } virtual size_t Size() const = 0; virtual ID3_Err Render(ID3_Writer &) const = 0; virtual bool Parse(ID3_Reader &) = 0; ID3_Header &operator=(const ID3_Header &rhs) { if (this != &rhs) { this->SetSpec(rhs.GetSpec()); this->SetDataSize(rhs.GetSpec()); this->_flags = rhs._flags; } return *this; } protected: ID3_V2Spec _spec; // which version of the spec size_t _data_size; // how big is the data? ID3_Flags _flags; // header flags Info *_info; // header info w.r.t. id3v2 spec bool _changed; // has the header changed since parsing }; #endif /* _ID3LIB_HEADER_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header_frame.cpp000066400000000000000000000142331516712004000263410ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "header_frame.h" #include "frame_def.h" #include "field_def.h" #include "field_impl.h" #include #include using namespace dami; void ID3_FrameHeader::SetUnknownFrame(const char *id) { Clear(); int id_len = strlen(id); if (id_len > 4) return; _frame_def = new ID3_FrameDef; if (_frame_def == NULL) return; memset(_frame_def, 0, sizeof(ID3_FrameDef)); _frame_def->eID = ID3FID_NOFRAME; _frame_def->bTagDiscard = false; _frame_def->bFileDiscard = false; _frame_def->aeFieldDefs = ID3_FieldDef::DEFAULT; _frame_def->sDescription = NULL; if (id_len <= 3) strncpy(_frame_def->sShortTextID, id, 3); else strncpy(_frame_def->sLongTextID, id, 4); _dyn_frame_def = true; } bool ID3_FrameHeader::SetFrameID(ID3_FrameID id) { if (id == ID3FID_NOFRAME || id == this->GetFrameID()) return false; ID3_FrameDef *frame_def = ID3_FindFrameDef(id); if (frame_def == NULL) return false; _frame_def = frame_def; _flags.set(TAGALTER, _frame_def->bTagDiscard); _flags.set(FILEALTER, _frame_def->bFileDiscard); _changed = true; return true; } size_t ID3_FrameHeader::Size() const { if (!_info) return 0; return _info->frame_bytes_id + _info->frame_bytes_size + _info->frame_bytes_flags; } bool ID3_FrameHeader::Parse(ID3_Reader& reader) { ID3D_NOTICE("ID3_FrameHeader::Parse(): getCur() = " << reader.getCur()); io::ExitTrigger et(reader); if (!_info) return false; if (reader.getEnd() < reader.getCur() + 10) return false; String textID = io::readText(reader, _info->frame_bytes_id); ID3D_NOTICE("ID3_FrameHeader::Parse: textID = " << textID); ID3D_NOTICE("ID3_FrameHeader::Parse: getCur() = " << reader.getCur()); ID3_FrameID fid = ID3_FindFrameID(textID.c_str()); if (ID3FID_NOFRAME == fid) { this->SetUnknownFrame(textID.c_str()); ID3D_NOTICE("ID3_FrameHeader::Parse: unknown frame id"); } else { this->SetFrameID(fid); } /* Frame data size must be read as an * unsynchronized integer for ID3v2.4 tags! */ uint32 dataSize = 0; if (_spec == ID3V2_4_0) dataSize = io::readUInt28(reader); else dataSize = io::readBENumber(reader, _info->frame_bytes_size); ID3D_NOTICE("ID3_FrameHeader::Parse: dataSize = " << dataSize); ID3D_NOTICE("ID3_FrameHeader::Parse: getCur() = " << reader.getCur()); this->SetDataSize(dataSize); uint32 flags = io::readBENumber(reader, _info->frame_bytes_flags); _flags.add(flags); ID3D_NOTICE("ID3_FrameHeader::Parse: flags = " << flags); ID3D_NOTICE("ID3_FrameHeader::Parse: getCur() = " << reader.getCur()); et.setExitPos(reader.getCur()); return true; } ID3_Err ID3_FrameHeader::Render(ID3_Writer &writer) const { if (_frame_def == NULL) { ID3D_WARNING("ID3_FrameHeader::Render(): _frame_def is NULL!"); return ID3E_InvalidFrameID; } char *textID; if (_info->frame_bytes_id == strlen(_frame_def->sShortTextID)) textID = _frame_def->sShortTextID; else textID = _frame_def->sLongTextID; ID3D_NOTICE("ID3_FrameHeader::Render(): writing " << textID << ", " << (int) _info->frame_bytes_size << " bytes"); writer.writeChars((uchar *) textID, _info->frame_bytes_id); /* Frame data size must be written as an * unsynchronized integer for ID3v2.4 tags! */ if (_spec == ID3V2_4_0) io::writeUInt28(writer, _data_size); else io::writeBENumber(writer, _data_size, _info->frame_bytes_size); io::writeBENumber(writer, _flags.get(), _info->frame_bytes_flags); return ID3E_NoError; } const char *ID3_FrameHeader::GetTextID() const { char *textID = NULL; if (_info && _frame_def) { if (_info->frame_bytes_id == strlen(_frame_def->sShortTextID)) textID = _frame_def->sShortTextID; else textID = _frame_def->sLongTextID; } return (const char *) textID; } ID3_FrameHeader &ID3_FrameHeader::operator =(const ID3_FrameHeader &hdr) { if (this == &hdr) return *this; this->Clear(); this->ID3_Header::operator =(hdr); if (!hdr._dyn_frame_def) { _frame_def = hdr._frame_def; } else { _frame_def = new ID3_FrameDef; if (_frame_def == NULL) return *this; memset(_frame_def, 0, sizeof(ID3_FrameDef)); _frame_def->eID = hdr._frame_def->eID; _frame_def->bTagDiscard = hdr._frame_def->bTagDiscard; _frame_def->bFileDiscard = hdr._frame_def->bFileDiscard; _frame_def->aeFieldDefs = hdr._frame_def->aeFieldDefs; strcpy(_frame_def->sShortTextID, hdr._frame_def->sShortTextID); strcpy(_frame_def->sLongTextID, hdr._frame_def->sLongTextID); _dyn_frame_def = true; } return *this; } ID3_FrameID ID3_FrameHeader::GetFrameID() const { ID3_FrameID eID = ID3FID_NOFRAME; if (_frame_def != NULL) eID = _frame_def->eID; return eID; } const ID3_FrameDef *ID3_FrameHeader::GetFrameDef() const { return _frame_def; } bool ID3_FrameHeader::Clear() { bool changed = this->ID3_Header::Clear(); if (_dyn_frame_def) { delete _frame_def; _dyn_frame_def = false; changed = true; } if (_frame_def) { _frame_def = NULL; changed = true; } return changed; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header_frame.h000066400000000000000000000057031516712004000260100ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_HEADER_FRAME_H_ #define _ID3LIB_HEADER_FRAME_H_ #include "header.h" #include struct ID3_FrameDef; class ID3_FrameHeader : public ID3_Header { public: enum { TAGALTER = 1 << 15, FILEALTER = 1 << 14, READONLY = 1 << 13, COMPRESSION = 1 << 7, ENCRYPTION = 1 << 6, GROUPING = 1 << 5 }; ID3_FrameHeader() : _frame_def(NULL), _dyn_frame_def(false) { } virtual ~ID3_FrameHeader() { this->Clear(); } size_t Size() const; bool Parse(ID3_Reader &); ID3_Err Render(ID3_Writer &) const; bool SetFrameID(ID3_FrameID id); ID3_FrameID GetFrameID() const; const char *GetTextID() const; const ID3_FrameDef *GetFrameDef() const; bool Clear(); ID3_FrameHeader &operator=(const ID3_FrameHeader &); bool SetCompression(bool b) { return this->SetFlags(COMPRESSION, b); } bool SetEncryption(bool b) { return this->SetFlags(ENCRYPTION, b); } bool SetGrouping(bool b) { return this->SetFlags(GROUPING, b); } bool GetCompression() const { return _flags.test(COMPRESSION); } bool GetEncryption() const { return _flags.test(ENCRYPTION); } bool GetGrouping() const { return _flags.test(GROUPING); } bool GetReadOnly() const { return _flags.test(READONLY); } void SetUnknownFrame(const char*); protected: bool SetFlags(uint16 f, bool b) { bool changed = _flags.set(f, b); _changed = _changed || changed; return changed; } // following is moved to public due to bug unknownframes corrupting a tag // void SetUnknownFrame(const char*); private: ID3_FrameDef *_frame_def; bool _dyn_frame_def; }; #endif /* _ID3LIB_HEADER_FRAME_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header_tag.cpp000066400000000000000000000175471516712004000260350ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "header_tag.h" #include "spec.h" #include #include #include using namespace dami; const char * const ID3_TagHeader::ID = "ID3"; bool ID3_TagHeader::SetSpec(ID3_V2Spec spec) { bool changed = this->ID3_Header::SetSpec(spec); if (changed) { if (_info) { _flags.set(HEADER_FLAG_EXPERIMENTAL, _info->is_experimental); _flags.set(HEADER_FLAG_EXTENDED, _info->is_extended); } } return changed; } size_t ID3_TagHeader::Size() const { size_t bytesUsed = ID3_TagHeader::SIZE; if (_info && _info->is_extended) { bytesUsed += _info->extended_bytes; } return bytesUsed; } ID3_Err ID3_TagHeader::Render(ID3_Writer &writer) const { writer.writeChars((uchar *) ID, strlen(ID)); ID3_V2Spec spec2use = this->GetSpec(); // this is set in tag_file.cpp right before RenderV2ToFile writer.writeChar(ID3_V2SpecToVer(spec2use)); writer.writeChar(ID3_V2SpecToRev(spec2use)); /* Set the flags byte in the header. */ writer.writeChar(static_cast(_flags.get() & MASK8)); io::writeUInt28(writer, this->GetDataSize()); // now includes the extended header /* Now we render the extended header. */ if (_flags.test(HEADER_FLAG_EXTENDED)) { switch (spec2use) { case ID3V2_4_0: io::writeUInt28(writer, 6); // write 4 bytes of v2.4.0 ext header containing size '6' io::writeBENumber(writer, 1, 1); // write that it has only one flag byte (value '1') io::writeBENumber(writer, 0, 1); // write flag byte with value '0' break; case ID3V2_3_0: io::writeBENumber(writer, 6, sizeof(uint32)); for (size_t i = 0; i < 6; ++i) { if (writer.writeChar('\0') == ID3_Writer::END_OF_WRITER) break; } break; default: /* Can't reach here, but added to avoid compiler warnings. */ break; } } return ID3E_NoError; } bool ID3_TagHeader::Parse(ID3_Reader &reader) { io::ExitTrigger et(reader); if (!ID3_Tag::IsV2Tag(reader)) { ID3D_NOTICE("ID3_TagHeader::Parse(): not an id3v2 header"); return false; } uchar id[3]; reader.readChars(id, 3); /* The spec version is determined with the MAJOR and MINOR OFFSETs */ uchar major = reader.readChar(); uchar minor = reader.readChar(); this->SetSpec(ID3_VerRevToV2Spec(major, minor)); /* Get the flags at the appropriate offset. */ _flags.set(static_cast(reader.readChar())); /* Set the data size. */ this->SetDataSize(io::readUInt28(reader)); if (_flags.test(HEADER_FLAG_EXTENDED) && this->GetSpec() == ID3V2_2_1) { /* Couldn't find anything about this in the draft specifying 2.2.1 * -> http://www.id3.org/pipermail/id3v2/2000-April/000126.html */ _flags.set(HEADER_FLAG_EXTENDED, false); _info->extended_bytes = 0; // rest is checked at ParseExtended() } et.setExitPos(reader.getCur()); return true; } void ID3_TagHeader::ParseExtended(ID3_Reader &reader) { if (this->GetSpec() == ID3V2_3_0) { /* Extended header size $xx xx xx xx * Extended Flags $xx xx * Size of padding $xx xx xx xx */ /* Skip over header size, we are not using it anyway, we calculate it. */ reader.setCur(reader.getCur() + 4); // Extended header size // io::readBENumber(reader, 4); // Extended header size uint16 tmpval = io::readBENumber(reader, 2); //Extended Flags /* Skip over padding size, we are not using it anyway. */ reader.setCur(reader.getCur() + 4); // Size of padding // io::readBENumber(reader, 4); // Size of padding if (tmpval != 0) // There is only one flag defined in ID3V2_3_0: crc { /* Skip over CRC data, we are not using it anyway. */ reader.setCur(reader.getCur() + 4); // CRC // io::readBENumber(reader, 4); // CRC _info->extended_bytes = 14; } else { _info->extended_bytes = 10; } } if (this->GetSpec() == ID3V2_4_0) { /* Extended header size 4 * %0xxxxxxx * Number of flag bytes $01 * Extended Flags $xx */ uint16 i; uint16 extrabytes; io::readUInt28(reader); const int extflagbytes = reader.readChar(); // Number of flag bytes ID3_Flags *extflags[1] = { }; // ID3V2_4_0 has 1 flag byte, extflagbytes should be equal to 1 for (i = 0; i < extflagbytes; ++i) { extflags[i] = new ID3_Flags; extflags[i]->set(reader.readChar()); // Flags } extrabytes = 0; if (extflags[0]->test(EXT_HEADER_FLAG_BIT1)) { // ID3V2_4_0 ext header flag bit 1 *should* be 0 } if (extflags[0]->test(EXT_HEADER_FLAG_BIT2)) { // ID3V2_4_0 ext header flag bit 2 = Tag is an update /* Read size. */ extrabytes += 1; // add a byte for the char containing the extflagdatasize const int extheaderflagdatasize = reader.readChar(); extrabytes += extheaderflagdatasize; /* Set the cursor right; we are not parsing the data, no-one is using extended flags anyway */ reader.setCur(reader.getCur() + extheaderflagdatasize); // reader.readChars(buf, extheaderflagdatasize); // buf should be at least 127 bytes = max extended header flagdata size } if (extflags[0]->test(EXT_HEADER_FLAG_BIT3)) { // ID3V2_4_0 ext header flag bit 3 = CRC data present /* Read size. */ extrabytes += 1; // add a byte for the char containing the extflagdatasize const int extheaderflagdatasize = reader.readChar(); extrabytes += extheaderflagdatasize; /* Set the cursor right; we are not parsing the data, no-one is using extended flags anyway */ reader.setCur(reader.getCur() + extheaderflagdatasize); // reader.readChars(buf, extheaderflagdatasize); // buf should be at least 127 bytes = max extended header flagdata size } if (extflags[0]->test(EXT_HEADER_FLAG_BIT4)) { // ID3V2_4_0 ext header flag bit 4 = Tag restrictions /* Read size. */ extrabytes += 1; // add a byte for the char containing the extflagdatasize const int extheaderflagdatasize = reader.readChar(); extrabytes += extheaderflagdatasize; /* Set the cursor right; we are not parsing the data, no-one is using extended flags anyway */ reader.setCur(reader.getCur() + extheaderflagdatasize); // reader.readChars(buf, extheaderflagdatasize); // buf should be at least 127 bytes = max extended header flagdata size } _info->extended_bytes = 5 + extflagbytes + extrabytes; } /* A bit unorthodox, but since we are not using any of the extended header, but were merely * parsing it to get the cursor right, we delete it. Be Gone! */ _flags.set(HEADER_FLAG_EXTENDED, false); if (_info) { _data_size -= _info->extended_bytes; _info->extended_bytes = 0; } // else // there is a tag with a higher or lower version than supported } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/header_tag.h000066400000000000000000000071001516712004000254620ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_HEADER_TAG_H_ #define _ID3LIB_HEADER_TAG_H_ #include "header.h" class ID3_TagHeader : public ID3_Header { public: enum { HEADER_FLAG_UNSYNC = 1 << 7, HEADER_FLAG_EXTENDED = 1 << 6, HEADER_FLAG_EXPERIMENTAL = 1 << 5, HEADER_FLAG_FOOTER = 1 << 4 }; enum { EXT_HEADER_FLAG_BIT1 = 1 << 7, EXT_HEADER_FLAG_BIT2 = 1 << 6, EXT_HEADER_FLAG_BIT3 = 1 << 5, EXT_HEADER_FLAG_BIT4 = 1 << 4 }; ID3_TagHeader() : ID3_Header() { } ID3_TagHeader(const ID3_TagHeader &rhs) : ID3_Header() { *this = rhs; } virtual ~ID3_TagHeader() { } bool SetSpec(ID3_V2Spec); size_t Size() const; ID3_Err Render(ID3_Writer &) const; bool Parse(ID3_Reader &); void ParseExtended(ID3_Reader &); ID3_TagHeader &operator =(const ID3_TagHeader &hdr) { this->ID3_Header::operator =(hdr); return *this; } bool SetUnsync(bool b) { bool changed = _flags.set(HEADER_FLAG_UNSYNC, b); _changed = _changed || changed; return changed; } bool SetExtended(bool b) { bool changed = _flags.set(HEADER_FLAG_EXTENDED, b); _changed = _changed || changed; return changed; } bool SetExperimental(bool b) { bool changed = _flags.set(HEADER_FLAG_EXPERIMENTAL, b); _changed = _changed || changed; return changed; } bool SetFooter(bool b) { bool changed = _flags.set(HEADER_FLAG_FOOTER, b); _changed = _changed || changed; return changed; } bool GetUnsync() const { return _flags.test(HEADER_FLAG_UNSYNC); } bool GetExtended() const { return _flags.test(HEADER_FLAG_EXTENDED); } bool GetExperimental() const { return _flags.test(HEADER_FLAG_EXPERIMENTAL); } bool GetFooter() const { return _flags.test(HEADER_FLAG_FOOTER); } // id3v2 tag header signature: $49 44 33 MM mm GG ss ss ss ss // MM = major version (will never be 0xFF) // mm = minor version (will never be 0xFF) // ff = flags byte // ss = size bytes (less than $80) static const char *const ID; enum { ID_SIZE = 3, MAJOR_OFFSET = 3, MINOR_OFFSET = 4, FLAGS_OFFSET = 5, SIZE_OFFSET = 6, SIZE = 10 // does not include extented headers }; }; #endif /* _ID3LIB_HEADER_TAG_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/helpers.cpp000066400000000000000000000324211516712004000254000ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Lots of hacking added to this file by Scott Wheeler (scott@slackorama.net) // 11/02/2001 /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include #include #include "field_impl.h" #include "tag_impl.h" using namespace dami; String id3::v2::getString(const ID3_Frame* frame, ID3_FieldID fldName) { if (!frame) { return ""; } ID3_Field* fp = frame->GetField(fldName); if (!fp) { return ""; } ID3_TextEnc enc = fp->GetEncoding(); fp->SetEncoding(ID3TE_ISO8859_1); String text(fp->GetRawText(), fp->Size()); fp->SetEncoding(enc); return text; } String id3::v2::getStringAtIndex(const ID3_Frame *frame, ID3_FieldID fldName, size_t nIndex) { if (!frame) return ""; String text; ID3_FieldImpl *fp = (ID3_FieldImpl *) frame->GetField(fldName); if (fp && fp->GetNumTextItems() < nIndex) { ID3_TextEnc enc = fp->GetEncoding(); fp->SetEncoding(ID3TE_ISO8859_1); text = fp->GetTextItem(nIndex); fp->SetEncoding(enc); } return text; } size_t id3::v2::removeFrames(ID3_TagImpl& tag, ID3_FrameID id) { size_t numRemoved = 0; ID3_Frame* frame = NULL; while ((frame = tag.Find(id)) != NULL) { frame = tag.RemoveFrame(frame); delete frame; numRemoved++; } return numRemoved; } String id3::v2::getFrameText(const ID3_TagImpl& tag, ID3_FrameID id) { ID3_Frame* frame = tag.Find(id); return getString(frame, ID3FN_TEXT); } ID3_Frame* id3::v2::setFrameText(ID3_TagImpl& tag, ID3_FrameID id, String text) { ID3_Frame* frame = tag.Find(id); if (!frame) { frame = new ID3_Frame(id); if(!tag.AttachFrame(frame)) return NULL; } frame->GetField(ID3FN_TEXT)->Set(text.c_str()); return frame; } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasArtist(const ID3_TagImpl& tag) { ID3_Frame* fp = NULL; (fp = tag.Find(ID3FID_LEADARTIST)) || (fp = tag.Find(ID3FID_BAND)) || (fp = tag.Find(ID3FID_CONDUCTOR)) || (fp = tag.Find(ID3FID_COMPOSER)); return fp; } String id3::v2::getArtist(const ID3_TagImpl& tag) { ID3_Frame* frame = hasArtist(tag); return getString(frame, ID3FN_TEXT); } ID3_Frame* id3::v2::setArtist(ID3_TagImpl& tag, String text) { removeArtists(tag); return setFrameText(tag, ID3FID_LEADARTIST, text); } size_t id3::v2::removeArtists(ID3_TagImpl& tag) { size_t numRemoved = 0; ID3_Frame* frame = NULL; while ((frame = hasArtist(tag)) != NULL) { frame = tag.RemoveFrame(frame); delete frame; numRemoved++; } return numRemoved; } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasAlbum(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_ALBUM); return(frame); } String id3::v2::getAlbum(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_ALBUM); } ID3_Frame* id3::v2::setAlbum(ID3_TagImpl& tag, String text) { return setFrameText(tag, ID3FID_ALBUM, text); } size_t id3::v2::removeAlbums(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_ALBUM); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasTitle(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_TITLE); return(frame); } String id3::v2::getTitle(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_TITLE); } ID3_Frame* id3::v2::setTitle(ID3_TagImpl& tag, String text) { return setFrameText(tag, ID3FID_TITLE, text); } size_t id3::v2::removeTitles(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_TITLE); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasYear(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_YEAR); return(frame); } String id3::v2::getYear(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_YEAR); } ID3_Frame* id3::v2::setYear(ID3_TagImpl& tag, String text) { return setFrameText(tag, ID3FID_YEAR, text); } size_t id3::v2::removeYears(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_YEAR); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasV1Comment(const ID3_TagImpl& tag) { ID3_Frame* frame = NULL; (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC)) || (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, "" )) || (frame = tag.Find(ID3FID_COMMENT)); return(frame); } ID3_Frame* id3::v2::hasComment(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_COMMENT); return(frame); } String id3::v2::getV1Comment(const ID3_TagImpl& tag) { ID3_Frame* frame; (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC)) || (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, "" )) || (frame = tag.Find(ID3FID_COMMENT)); return getString(frame, ID3FN_TEXT); } String id3::v2::getComment(const ID3_TagImpl& tag, String desc) { ID3_Frame* frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, desc.c_str()); return getString(frame, ID3FN_TEXT); } ID3_Frame* id3::v2::setComment(ID3_TagImpl& tag, String text, String desc, String lang) { ID3D_NOTICE( "id3::v2::setComment: trying to find frame with description = " << desc ); ID3_Frame* frame = NULL; // See if there is already a comment with this description for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter) { frame = *iter; if (frame == NULL) { continue; } if (frame->GetID() == ID3FID_COMMENT) { String tmpDesc = getString(frame, ID3FN_DESCRIPTION); if (tmpDesc == desc) { ID3D_NOTICE( "id3::v2::setComment: found frame with description = " << desc ); break; } } frame = NULL; } if (frame == NULL) { ID3D_NOTICE( "id3::v2::setComment: creating new comment frame" ); frame = new ID3_Frame(ID3FID_COMMENT); if(!tag.AttachFrame(frame)) return NULL; } if (!frame) { ID3D_WARNING( "id3::v2::setComment: ack! no frame" ); } else { frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str()); frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str()); frame->GetField(ID3FN_TEXT)->Set(text.c_str()); } return frame; } // Remove all comments from the tag size_t id3::v2::removeAllComments(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_COMMENT); } // Remove all comments from the tag with the given description size_t id3::v2::removeComments(ID3_TagImpl& tag, String desc) { size_t numRemoved = 0; for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter) { ID3_Frame* frame = *iter; if (frame == NULL) { continue; } if (frame->GetID() == ID3FID_COMMENT) { // See if the description we have matches the description of the // current comment. If so, remove the comment String tmpDesc = getString(frame, ID3FN_DESCRIPTION); if (tmpDesc == desc) { frame = tag.RemoveFrame(frame); delete frame; numRemoved++; } } } return numRemoved; } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasTrack(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_TRACKNUM); return(frame); } String id3::v2::getTrack(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_TRACKNUM); } size_t id3::v2::getTrackNum(const ID3_TagImpl& tag) { String sTrack = getTrack(tag); return ::atoi(sTrack.c_str()); } ID3_Frame* id3::v2::setTrack(ID3_TagImpl& tag, uchar trk, uchar ttl) { ID3_Frame* frame = NULL; String track = toString((size_t)trk); if (ttl > 0) { track += "/"; track += toString((size_t)ttl); } setFrameText(tag, ID3FID_TRACKNUM, track); return frame; } size_t id3::v2::removeTracks(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_TRACKNUM); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasGenre(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_CONTENTTYPE); return(frame); } String id3::v2::getGenre(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_CONTENTTYPE); } size_t id3::v2::getGenreNum(const ID3_TagImpl& tag) { String sGenre = getGenre(tag); size_t ulGenre = 0xFF; size_t size = sGenre.size(); // If the genre string begins with "(ddd)", where "ddd" is a number, then // "ddd" is the genre number---get it size_t i = 0; if (i < size && size && sGenre[i] == '(') { ++i; while (i < size && isdigit(sGenre[i])) { ++i; } if (i < size && sGenre[i] == ')') { // if the genre number is greater than 255, its invalid. ulGenre = min(0xFF, atoi(&sGenre[1])); } } return ulGenre; } ID3_Frame* id3::v2::setGenre(ID3_TagImpl& tag, size_t genre) { String sGenre = "("; sGenre += toString(genre) + ")"; return setFrameText(tag, ID3FID_CONTENTTYPE, sGenre); } size_t id3::v2::removeGenres(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_CONTENTTYPE); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasLyrics(const ID3_TagImpl& tag) { ID3_Frame* frame = tag.Find(ID3FID_UNSYNCEDLYRICS); return(frame); } String id3::v2::getLyrics(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_UNSYNCEDLYRICS); } ID3_Frame* id3::v2::setLyrics(ID3_TagImpl& tag, String text, String desc, String lang) { ID3_Frame* frame = NULL; // See if there is already a comment with this description for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter) { frame = *iter; if (frame == NULL) { continue; } if (frame->GetID() == ID3FID_COMMENT) { String tmpDesc = getString(frame, ID3FN_DESCRIPTION); if (tmpDesc == desc) { break; } } frame = NULL; } if (frame == NULL) { frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS); if(!tag.AttachFrame(frame)) return NULL; } frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str()); frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str()); frame->GetField(ID3FN_TEXT)->Set(text.c_str()); return frame; } size_t id3::v2::removeLyrics(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_UNSYNCEDLYRICS); } String id3::v2::getLyricist(const ID3_TagImpl& tag) { return getFrameText(tag, ID3FID_LYRICIST); } ID3_Frame* id3::v2::setLyricist(ID3_TagImpl& tag, String text) { return setFrameText(tag, ID3FID_LYRICIST, text); } size_t id3::v2::removeLyricists(ID3_TagImpl& tag) { return removeFrames(tag, ID3FID_LYRICIST); } //////////////////////////////////////////////////////////// ID3_Frame* id3::v2::hasSyncLyrics(const ID3_TagImpl& tag, String lang, String desc) { ID3_Frame* frame=NULL; (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) || (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc)); return(frame); } ID3_Frame* id3::v2::setSyncLyrics(ID3_TagImpl& tag, BString data, ID3_TimeStampFormat format, String desc, String lang, ID3_ContentType type) { ID3_Frame* frame = NULL; // check if a SYLT frame of this language or descriptor already exists (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) || (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc)); if (!frame) { frame = new ID3_Frame(ID3FID_SYNCEDLYRICS); if(!tag.AttachFrame(frame)) return NULL; } frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str()); frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str()); frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format); frame->GetField(ID3FN_CONTENTTYPE)->Set(type); frame->GetField(ID3FN_DATA)->Set(data.data(), data.size()); return frame; } BString id3::v2::getSyncLyrics(const ID3_TagImpl &tag, String lang, String desc) { // check if a SYLT frame of this language or descriptor exists ID3_Frame *frame = NULL; (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) || (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc)) || (frame = tag.Find(ID3FID_SYNCEDLYRICS)); if (frame == NULL) return BString(); // get the lyrics size ID3_Field *fld = frame->GetField(ID3FN_DATA); return BString(reinterpret_cast(fld->GetRawBinary()), fld->Size()); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/000077500000000000000000000000001516712004000237075ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/container.h000066400000000000000000000052061516712004000260450ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_CONTAINER_H_ #define _ID3LIB_CONTAINER_H_ #include "globals.h" class ID3_ContainerImpl; class ID3_Frame; class ID3_Container { public: class Iterator { public: virtual ~Iterator() {}; virtual ID3_Frame *GetNext() = 0; }; class ConstIterator { public: virtual ~ConstIterator() {}; virtual const ID3_Frame *GetNext() = 0; }; protected: ID3_ContainerImpl *_impl; bool _own_impl; public: ID3_Container(); ID3_Container(ID3_ContainerImpl *impl); ID3_Container(const ID3_Container &container); virtual ~ID3_Container(); void Clear(); bool HasChanged() const; size_t Size() const; void AddFrame(const ID3_Frame &); void AddFrame(const ID3_Frame *); bool AttachFrame(ID3_Frame *); ID3_Frame *RemoveFrame(const ID3_Frame *); ID3_Frame *Find(ID3_FrameID) const; ID3_Frame *Find(ID3_FrameID, ID3_FieldID, uint32) const; ID3_Frame *Find(ID3_FrameID, ID3_FieldID, const char *) const; ID3_Frame *Find(ID3_FrameID, ID3_FieldID, const unicode_t *) const; size_t NumFrames() const; Iterator *CreateIterator(); ConstIterator *CreateIterator() const; ID3_Container &operator =(const ID3_Container &); ID3_V2Spec GetSpec() const; bool SetSpec(ID3_V2Spec); }; #endif /* _ID3LIB_CONTAINER_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/field.h000066400000000000000000000103111516712004000251370ustar00rootroot00000000000000// -*- C++ -*- // $Id$ /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FIELD_H_ #define _ID3LIB_FIELD_H_ #include "strings.h" #include "container.h" class ID3_Reader; class ID3_Writer; class ID3_Field : public ID3_Container { public: virtual void Clear() = 0; virtual size_t Size() const = 0; virtual size_t BinSize() const = 0; virtual size_t GetNumTextItems() const = 0; /* Integer field functions */ virtual ID3_Field &operator= (uint32 val) = 0; virtual void Set(uint32) = 0; virtual uint32 Get() const = 0; /* ASCII string field functions */ virtual ID3_Field &operator= (const char* s) = 0; virtual size_t Set(const char*) = 0; virtual size_t Get(char*, size_t) const = 0; virtual size_t Get(char*, size_t, size_t) const = 0; virtual const char *GetRawText() const = 0; virtual size_t Add(const char*) = 0; virtual dami::String GetText() const = 0; virtual size_t SetText(dami::String) = 0; /* Unicode string field functions */ virtual ID3_Field &operator= (const unicode_t* s) = 0; virtual size_t Set(const unicode_t*) = 0; virtual size_t Get(unicode_t *buffer, size_t) const = 0; virtual size_t Get(unicode_t *buffer, size_t, size_t) const = 0; virtual const unicode_t *GetRawUnicodeText() const = 0; virtual size_t Add(const unicode_t*) = 0; /* Binary field functions */ virtual size_t Set(const uchar *, size_t) = 0; virtual size_t Get(uchar *, size_t) const = 0; virtual const uchar *GetRawBinary() const = 0; virtual void FromFile(const char *) = 0; virtual void ToFile(const char *sInfo) const = 0; virtual dami::BString GetBinary() const = 0; /* Miscelaneous functions */ virtual ID3_Field &operator =(const ID3_Field &) = 0; virtual bool InScope(ID3_V2Spec spec) const = 0; virtual ID3_V2Spec MinSpec() const = 0; virtual ID3_V2Spec MaxSpec() const = 0; virtual ID3_FieldID GetID() const = 0; virtual ID3_FieldID GetLinkedField() const = 0; virtual ID3_FieldType GetType() const = 0; virtual bool SetEncoding(ID3_TextEnc enc) = 0; virtual bool SetLinkedSize(size_t newfixedsize) = 0; virtual bool HasFixedSize() = 0; virtual ID3_TextEnc GetEncoding() const = 0; virtual bool HasFlag(const flags_t flag) const = 0; virtual bool IsEncodable() const = 0; virtual ID3_Err Render(ID3_Writer &) const = 0; virtual bool Parse(ID3_Reader &) = 0; virtual bool HasChanged() const = 0; protected: /* To prevent public instantiation, the constructor is made protected */ ID3_Field() { }; virtual ~ID3_Field() { }; }; class ID3_FrameInfo { public: ID3_FrameInfo() {}; ~ID3_FrameInfo() {}; char *ShortName(ID3_FrameID frameid); char *LongName(ID3_FrameID frameid); const char *Description(ID3_FrameID frameid); int MaxFrameID(); int NumFields(ID3_FrameID frameid); ID3_FieldID FieldID(ID3_FrameID frameid, int fieldnum); ID3_FieldType FieldType(ID3_FrameID frameid, int fieldnum); size_t FieldSize(ID3_FrameID frameid, int fieldnum); flags_t FieldFlags(ID3_FrameID frameid, int fieldnum); }; #endif /* _ID3LIB_FIELD_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/frame.h000066400000000000000000000053521516712004000251570ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_FRAME_H_ #define _ID3LIB_FRAME_H_ #include "globals.h" class ID3_Field; class ID3_FrameImpl; class ID3_Reader; class ID3_Writer; class ID3_Frame { ID3_FrameImpl *_impl; public: class Iterator { public: virtual ~Iterator() {}; virtual ID3_Field *GetNext() = 0; }; class ConstIterator { public: virtual ~ConstIterator() {}; virtual const ID3_Field *GetNext() = 0; }; public: ID3_Frame(ID3_FrameID id = ID3FID_NOFRAME); ID3_Frame(const ID3_Frame &); virtual ~ID3_Frame(); void Clear(); bool SetID(ID3_FrameID id); ID3_FrameID GetID() const; ID3_Field *GetField(ID3_FieldID name) const; size_t NumFields() const; const char *GetDescription() const; static const char *GetDescription(ID3_FrameID); const char *GetTextID() const; ID3_Frame &operator =(const ID3_Frame &); bool HasChanged() const; bool Parse(ID3_Reader &); ID3_Err Render(ID3_Writer &) const; size_t Size(); bool Contains(ID3_FieldID fld) const; bool SetSpec(ID3_V2Spec); ID3_V2Spec GetSpec() const; ID3_V2Spec MinSpec() const; bool SetCompression(bool b); bool GetCompression() const; size_t GetDataSize() const; bool SetEncryptionID(uchar id); uchar GetEncryptionID() const; bool SetGroupingID(uchar id); uchar GetGroupingID() const; Iterator *CreateIterator(); ConstIterator *CreateIterator() const; }; #endif /* _ID3LIB_FRAME_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/globals.h000066400000000000000000000566001516712004000255120ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ /** This file defines common macros, types, constants, and enums used ** throughout id3lib. **/ #ifndef _ID3LIB_GLOBALS_H_ #define _ID3LIB_GLOBALS_H_ #include #include "sized_types.h" /* id3lib version. * we prefix variable declarations so they can * properly get exported in windows dlls. */ #ifdef WIN32 # define LINKOPTION_STATIC 1 //both for use and creation of static lib # define LINKOPTION_CREATE_DYNAMIC 2 //should only be used by prj/id3lib.dsp # define LINKOPTION_USE_DYNAMIC 3 //if your project links id3lib dynamic # ifndef ID3LIB_LINKOPTION # pragma message("*** NOTICE *** (not a real error)") # pragma message("* You should include a define in your project which reflect how you link the library") # pragma message("* If you use id3lib.lib or libprj/id3lib.dsp (you link static) you should add") # pragma message("* ID3LIB_LINKOPTION=1 to your preprocessor definitions of your project.") # pragma message("* If you use id3lib.dll (you link dynamic) you should add ID3LIB_LINKOPTION=3") # pragma message("* to your preprocessor definitions of your project.") # pragma message("***") # error read message above or win32.readme.first.txt # else # if (ID3LIB_LINKOPTION == LINKOPTION_CREATE_DYNAMIC) //used for creating a dynamic dll # define ID3_C_EXPORT extern __declspec(dllexport) # define ID3_CPP_EXPORT __declspec(dllexport) # define CCONV __stdcall // Added for VB & Delphi Compatibility - By FrogPrince Advised By Lothar # endif # if (ID3LIB_LINKOPTION == LINKOPTION_STATIC) //used for creating a static lib and using a static lib # define ID3_C_EXPORT # define ID3_CPP_EXPORT # define CCONV # endif # if (ID3LIB_LINKOPTION == LINKOPTION_USE_DYNAMIC) //used for those that do not link static and are using the dynamic dll by including a id3lib header # define ID3_C_EXPORT extern __declspec(dllimport) # define ID3_CPP_EXPORT __declspec(dllimport) //functions like these shouldn't be used by vb and delphi, # define CCONV __stdcall // Added for VB & Delphi Compatibility - By FrogPrince Advised By Lothar # endif # endif #else /* !WIN32 */ # define ID3_C_EXPORT # define ID3_CPP_EXPORT # define CCONV #endif /* !WIN32 */ #define ID3_C_VAR extern #ifndef __cplusplus typedef int bool; # define false (0) # define true (!false) #endif /* __cplusplus */ ID3_C_VAR const char * const ID3LIB_NAME; ID3_C_VAR const char * const ID3LIB_RELEASE; ID3_C_VAR const char * const ID3LIB_FULL_NAME; ID3_C_VAR const int ID3LIB_MAJOR_VERSION; ID3_C_VAR const int ID3LIB_MINOR_VERSION; ID3_C_VAR const int ID3LIB_PATCH_VERSION; ID3_C_VAR const int ID3LIB_INTERFACE_AGE; ID3_C_VAR const int ID3LIB_BINARY_AGE; #define ID3_TAGID "ID3" #define ID3_TAGIDSIZE (3) #define ID3_TAGHEADERSIZE (10) /** String used for the description field of a comment tag converted from an ** id3v1 tag to an id3v2 tag ** ** \sa #ID3V1_Tag **/ #define STR_V1_COMMENT_DESC "ID3v1 Comment" typedef unsigned char uchar; typedef long unsigned int luint; typedef uint16 unicode_t; typedef uint16 flags_t; #define NULL_UNICODE ((unicode_t) '\0') /* These macros are used to make the C and C++ declarations for enums and * structs have the same syntax. Basically, it allows C users to refer to an * enum or a struct without prepending enum/struct. */ #ifdef __cplusplus # define ID3_ENUM(E) enum E # define ID3_STRUCT(S) struct S #else # define ID3_ENUM(E) typedef enum _ ## E E; enum _ ## E # define ID3_STRUCT(S) typedef struct _ ## S S; struct _ ## S #endif /** \enum ID3_TextEnc ** Enumeration of the types of text encodings: ascii or unicode **/ ID3_ENUM(ID3_TextEnc) { ID3TE_NONE = -1, ID3TE_ISO8859_1, ID3TE_UTF16, ID3TE_UTF16BE, ID3TE_UTF8, ID3TE_NUMENCODINGS, }; #define ID3TE_IS_SINGLE_BYTE_ENC(enc) ((enc) == ID3TE_ISO8859_1 || (enc) == ID3TE_UTF8) #define ID3TE_IS_DOUBLE_BYTE_ENC(enc) ((enc) == ID3TE_UTF16 || (enc) == ID3TE_UTF16BE) /** Enumeration of the various id3 specifications **/ ID3_ENUM(ID3_V1Spec) { ID3V1_0 = 0, ID3V1_1, ID3V1_NUMSPECS }; ID3_ENUM(ID3_V2Spec) { ID3V2_UNKNOWN = -1, ID3V2_2_0 = 0, ID3V2_2_1, ID3V2_3_0, ID3V2_4_0, ID3V2_EARLIEST = ID3V2_2_0, ID3V2_LATEST = ID3V2_4_0, ID3V2_DEFAULT = ID3V2_3_0 }; /** The various types of tags that id3lib can handle **/ ID3_ENUM(ID3_TagType) { ID3TT_NONE = 0, /**< Represents an empty or non-existant tag */ ID3TT_ID3V1 = 1 << 0, /**< Represents an id3v1 or id3v1.1 tag */ ID3TT_ID3V2 = 1 << 1, /**< Represents an id3v2 tag */ ID3TT_LYRICS3 = 1 << 2, /**< Represents a Lyrics3 tag */ ID3TT_LYRICS3V2 = 1 << 3, /**< Represents a Lyrics3 v2.00 tag */ ID3TT_MUSICMATCH = 1 << 4, /**< Represents a MusicMatch tag */ /**< Represents a Lyrics3 tag (for backwards compatibility) */ ID3TT_LYRICS = ID3TT_LYRICS3, /** Represents both id3 tags: id3v1 and id3v2 */ ID3TT_ID3 = ID3TT_ID3V1 | ID3TT_ID3V2, /** Represents all possible types of tags */ ID3TT_ALL = ~ID3TT_NONE, /** Represents all tag types that can be prepended to a file */ ID3TT_PREPENDED = ID3TT_ID3V2, /** Represents all tag types that can be appended to a file */ ID3TT_APPENDED = ID3TT_ALL & ~ID3TT_ID3V2 }; /** ** Enumeration of the different types of fields in a frame. **/ ID3_ENUM(ID3_FieldID) { ID3FN_NOFIELD = 0, /**< No field */ ID3FN_TEXTENC, /**< Text encoding (unicode or ASCII) */ ID3FN_TEXT, /**< Text field */ ID3FN_URL, /**< A URL */ ID3FN_DATA, /**< Data field */ ID3FN_DESCRIPTION, /**< Description field */ ID3FN_OWNER, /**< Owner field */ ID3FN_EMAIL, /**< Email field */ ID3FN_RATING, /**< Rating field */ ID3FN_FILENAME, /**< Filename field */ ID3FN_LANGUAGE, /**< Language field */ ID3FN_PICTURETYPE, /**< Picture type field */ ID3FN_IMAGEFORMAT, /**< Image format field */ ID3FN_MIMETYPE, /**< Mimetype field */ ID3FN_COUNTER, /**< Counter field */ ID3FN_ID, /**< Identifier/Symbol field */ ID3FN_VOLUMEADJ, /**< Volume adjustment field */ ID3FN_NUMBITS, /**< Number of bits field */ ID3FN_NUMBER, /**< General Number, can be anything, as long it's an integer <= 32 bits */ ID3FN_VOLCHGRIGHT, /**< Volume chage on the right channel */ ID3FN_VOLCHGLEFT, /**< Volume chage on the left channel */ ID3FN_PEAKVOLRIGHT, /**< Peak volume on the right channel */ ID3FN_PEAKVOLLEFT, /**< Peak volume on the left channel */ ID3FN_TIMESTAMPFORMAT, /**< SYLT Timestamp Format */ ID3FN_CONTENTTYPE, /**< SYLT content type */ ID3FN_REVERBL, /**< Reverb Left */ ID3FN_REVERBR, /**< Reverb Right */ ID3FN_REVERBBOUNCESL, /**< Reverb Bounces Left */ ID3FN_REVERBBOUNCESR, /**< Reverb Bounces Right */ ID3FN_REVERBFEEDBACKL2L, /**< Reverb Feedback Left to Left */ ID3FN_REVERBFEEDBACKL2R, /**< Reverb Feedback Left to Right */ ID3FN_REVERBFEEDBACKR2R, /**< Reverb Feedback Right to Right */ ID3FN_REVERBFEEDBACKR2L, /**< Reverb Feedback Right to Left */ ID3FN_PREMIXL2R, /**< Premix Left to Right */ ID3FN_PREMIXR2L, /**< Premix Right to Left */ ID3FN_LENGTH, /**< Size field, can be bits, bytes, time etc */ ID3FN_FLAGS, /**< Flags field */ ID3FN_OFFSET, /**< Offset, can be bits, bytes, time etc */ ID3FN_PRICE, /**< Price Field, containing currency+amount */ ID3FN_8DATE, /**< Date Field, containing date as YYYYMMDD */ ID3FN_SELLER, /**< Seller */ ID3FN_DELIVERY, /**< Way of delivery field */ ID3FN_BITSSIZE, /**< contains the number of bits for other fields' fixed size */ ID3FN_BYTESSIZE, /**< contains the number of bytes for other fields' fixed size */ ID3FN_CHAPTERS, /**< Chapter ID list */ ID3FN_STARTTIME, /**< Chapter start offset in milliseconds */ ID3FN_ENDTIME, /**< Chapter end offset in milliseconds */ ID3FN_STARTOFFSET, /**< Chapter start offset in bytes */ ID3FN_ENDOFFSET, /**< Chapter end offset in bytes */ ID3FN_FRAMES, /**< Sub-frames */ ID3FN_LASTFIELDID /**< Last field placeholder */ }; /** ** Enumeration of the different types of frames recognized by id3lib **/ ID3_ENUM(ID3_FrameID) { /* ???? */ ID3FID_NOFRAME = 0, /**< No known frame */ /* AENC */ ID3FID_AUDIOCRYPTO, /**< Audio encryption */ /* APIC */ ID3FID_PICTURE, /**< Attached picture */ /* ASPI */ ID3FID_AUDIOSEEKPOINT, /**< Audio seek point index */ /* CHAP */ ID3FID_CHAPTER, /**< Chapter */ /* COMM */ ID3FID_COMMENT, /**< Comments */ /* COMR */ ID3FID_COMMERCIAL, /**< Commercial frame */ /* COMM */ ID3FID_TOC, /**< Table of contents */ /* ENCR */ ID3FID_CRYPTOREG, /**< Encryption method registration */ /* EQU2 */ ID3FID_EQUALIZATION2, /**< Equalisation (2) */ /* EQUA */ ID3FID_EQUALIZATION, /**< Equalization */ /* ETCO */ ID3FID_EVENTTIMING, /**< Event timing codes */ /* GEOB */ ID3FID_GENERALOBJECT, /**< General encapsulated object */ /* GRID */ ID3FID_GROUPINGREG, /**< Group identification registration */ /* IPLS */ ID3FID_INVOLVEDPEOPLE, /**< Involved people list */ /* LINK */ ID3FID_LINKEDINFO, /**< Linked information */ /* MCDI */ ID3FID_CDID, /**< Music CD identifier */ /* MLLT */ ID3FID_MPEGLOOKUP, /**< MPEG location lookup table */ /* MVIN */ ID3FID_MOVEMENT, /**< Movement number */ /* MVNM */ ID3FID_MOVEMENTNAME, /**< Movement name */ /* OWNE */ ID3FID_OWNERSHIP, /**< Ownership frame */ /* PRIV */ ID3FID_PRIVATE, /**< Private frame */ /* PCNT */ ID3FID_PLAYCOUNTER, /**< Play counter */ /* POPM */ ID3FID_POPULARIMETER, /**< Popularimeter */ /* POSS */ ID3FID_POSITIONSYNC, /**< Position synchronisation frame */ /* RBUF */ ID3FID_BUFFERSIZE, /**< Recommended buffer size */ /* RVA2 */ ID3FID_VOLUMEADJ2, /**< Relative volume adjustment (2) */ /* RVAD */ ID3FID_VOLUMEADJ, /**< Relative volume adjustment */ /* RVRB */ ID3FID_REVERB, /**< Reverb */ /* SEEK */ ID3FID_SEEKFRAME, /**< Seek frame */ /* SIGN */ ID3FID_SIGNATURE, /**< Signature frame */ /* SYLT */ ID3FID_SYNCEDLYRICS, /**< Synchronized lyric/text */ /* SYTC */ ID3FID_SYNCEDTEMPO, /**< Synchronized tempo codes */ /* TALB */ ID3FID_ALBUM, /**< Album/Movie/Show title */ /* TBPM */ ID3FID_BPM, /**< BPM (beats per minute) */ /* TCOM */ ID3FID_COMPOSER, /**< Composer */ /* TCON */ ID3FID_CONTENTTYPE, /**< Content type */ /* TCOP */ ID3FID_COPYRIGHT, /**< Copyright message */ /* TDAT */ ID3FID_DATE, /**< Date */ /* TDEN */ ID3FID_ENCODINGTIME, /**< Encoding time */ /* TDLY */ ID3FID_PLAYLISTDELAY, /**< Playlist delay */ /* TDOR */ ID3FID_ORIGRELEASETIME, /**< Original release time */ /* TDRC */ ID3FID_RECORDINGTIME, /**< Recording time */ /* TDRL */ ID3FID_RELEASETIME, /**< Release time */ /* TDTG */ ID3FID_TAGGINGTIME, /**< Tagging time */ /* TIPL */ ID3FID_INVOLVEDPEOPLE2, /**< Involved people list */ /* TENC */ ID3FID_ENCODEDBY, /**< Encoded by */ /* TEXT */ ID3FID_LYRICIST, /**< Lyricist/Text writer */ /* TFLT */ ID3FID_FILETYPE, /**< File type */ /* TIME */ ID3FID_TIME, /**< Time */ /* TIT1 */ ID3FID_CONTENTGROUP, /**< Content group description */ /* TIT2 */ ID3FID_TITLE, /**< Title/songname/content description */ /* TIT3 */ ID3FID_SUBTITLE, /**< Subtitle/Description refinement */ /* TKEY */ ID3FID_INITIALKEY, /**< Initial key */ /* TLAN */ ID3FID_LANGUAGE, /**< Language(s) */ /* TLEN */ ID3FID_SONGLEN, /**< Length */ /* TMCL */ ID3FID_MUSICIANCREDITLIST, /**< Musician credits list */ /* TMED */ ID3FID_MEDIATYPE, /**< Media type */ /* TMOO */ ID3FID_MOOD, /**< Mood */ /* TOAL */ ID3FID_ORIGALBUM, /**< Original album/movie/show title */ /* TOFN */ ID3FID_ORIGFILENAME, /**< Original filename */ /* TOLY */ ID3FID_ORIGLYRICIST, /**< Original lyricist(s)/text writer(s) */ /* TOPE */ ID3FID_ORIGARTIST, /**< Original artist(s)/performer(s) */ /* TORY */ ID3FID_ORIGYEAR, /**< Original release year */ /* TOWN */ ID3FID_FILEOWNER, /**< File owner/licensee */ /* TPE1 */ ID3FID_LEADARTIST, /**< Lead performer(s)/Soloist(s) */ /* TPE2 */ ID3FID_BAND, /**< Band/orchestra/accompaniment */ /* TPE3 */ ID3FID_CONDUCTOR, /**< Conductor/performer refinement */ /* TPE4 */ ID3FID_MIXARTIST, /**< Interpreted, remixed, or otherwise modified by */ /* TPOS */ ID3FID_PARTINSET, /**< Part of a set */ /* TPRO */ ID3FID_PRODUCEDNOTICE, /**< Produced notice */ /* TPUB */ ID3FID_PUBLISHER, /**< Publisher */ /* TRCK */ ID3FID_TRACKNUM, /**< Track number/Position in set */ /* TRDA */ ID3FID_RECORDINGDATES, /**< Recording dates */ /* TRSN */ ID3FID_NETRADIOSTATION, /**< Internet radio station name */ /* TRSO */ ID3FID_NETRADIOOWNER, /**< Internet radio station owner */ /* TSIZ */ ID3FID_SIZE, /**< Size */ /* TSO2 */ ID3FID_ALBUMARTISTSORTORDER, /**< Album artist sort order */ /* TSOA */ ID3FID_ALBUMSORTORDER, /**< Album sort order */ /* TSOC */ ID3FID_COMPOSERSORTORDER, /**< Composer sort order */ /* TSOP */ ID3FID_PERFORMERSORTORDER, /**< Performer sort order */ /* TSOT */ ID3FID_TITLESORTORDER, /**< Title sort order */ /* TSRC */ ID3FID_ISRC, /**< ISRC (international standard recording code) */ /* TSSE */ ID3FID_ENCODERSETTINGS, /**< Software/Hardware and settings used for encoding */ /* TSST */ ID3FID_SETSUBTITLE, /**< Set subtitle */ /* TXXX */ ID3FID_USERTEXT, /**< User defined text information */ /* TYER */ ID3FID_YEAR, /**< Year */ /* UFID */ ID3FID_UNIQUEFILEID, /**< Unique file identifier */ /* USER */ ID3FID_TERMSOFUSE, /**< Terms of use */ /* USLT */ ID3FID_UNSYNCEDLYRICS, /**< Unsynchronized lyric/text transcription */ /* WCOM */ ID3FID_WWWCOMMERCIALINFO, /**< Commercial information */ /* WCOP */ ID3FID_WWWCOPYRIGHT, /**< Copyright/Legal information */ /* WOAF */ ID3FID_WWWAUDIOFILE, /**< Official audio file webpage */ /* WOAR */ ID3FID_WWWARTIST, /**< Official artist/performer webpage */ /* WOAS */ ID3FID_WWWAUDIOSOURCE, /**< Official audio source webpage */ /* WORS */ ID3FID_WWWRADIOPAGE, /**< Official internet radio station homepage */ /* WPAY */ ID3FID_WWWPAYMENT, /**< Payment */ /* WPUB */ ID3FID_WWWPUBLISHER, /**< Official publisher webpage */ /* WXXX */ ID3FID_WWWUSER, /**< User defined URL link */ /* */ ID3FID_METACRYPTO, /**< Encrypted meta frame (id3v2.2.x) */ /* */ ID3FID_METACOMPRESSION, /**< Compressed meta frame (id3v2.2.1) */ /* >>>> */ ID3FID_LASTFRAMEID /**< Last field placeholder */ }; ID3_ENUM(ID3_V1Lengths) { ID3_V1_LEN = 128, ID3_V1_LEN_ID = 3, ID3_V1_LEN_TITLE = 30, ID3_V1_LEN_ARTIST = 30, ID3_V1_LEN_ALBUM = 30, ID3_V1_LEN_YEAR = 4, ID3_V1_LEN_COMMENT = 30, ID3_V1_LEN_GENRE = 1 }; ID3_ENUM(ID3_FieldFlags) { ID3FF_NONE = 0, ID3FF_CSTR = 1 << 0, /*null (according to encoding) terminated*/ ID3FF_LIST = 1 << 1, /*null (according to encoding) seperates listitems*/ ID3FF_NLIST = 1 << 2, /*null (according to encoding) seperates listitems, *preceded by one item count byte*/ ID3FF_ENCODABLE = 1 << 3, /*possible to encode in valid encodings, *if not set then string is encoded by ID3TE_ISO8859_1 */ ID3FF_HASLINKEDSIZE = 1 << 4 /*used together with _linked_field. *if _linked_field is NOT set, than this field contains *a size for other fields to use, if _linked_field is set, *than it's size comes from the last field which had this *flag but didn't have _linked_field set*/ }; /** Enumeration of the types of field types */ ID3_ENUM(ID3_FieldType) { ID3FTY_NONE = -1, ID3FTY_INTEGER = 0, ID3FTY_BINARY, ID3FTY_TEXTSTRING, ID3FTY_FRAMES, ID3FTY_NUMTYPES }; /** ** Predefined id3lib error types. **/ ID3_ENUM(ID3_Err) { ID3E_NoError = 0, /**< No error reported */ ID3E_NoData, /**< No data to parse */ ID3E_InvalidFrameID, /**< Invalid frame id */ ID3E_InvalidFrameSize, /**< Invalid frame size */ ID3E_UnknownFieldType, /**< Unknown field type */ ID3E_NoFile, /**< No file to parse */ ID3E_ReadOnly, /**< Attempting to write to a read-only file */ ID3E_InvalidTag, /**< Invalid Tag */ ID3E_zlibError /**< Error in compression/uncompression */ }; ID3_ENUM(ID3_ContentType) { ID3CT_OTHER = 0, ID3CT_LYRICS, ID3CT_TEXTTRANSCRIPTION, ID3CT_MOVEMENT, ID3CT_EVENTS, ID3CT_CHORD, ID3CT_TRIVIA }; ID3_ENUM(ID3_PictureType) { ID3PT_OTHER = 0, ID3PT_PNG32ICON = 1, // 32x32 pixels 'file icon' (PNG only) ID3PT_OTHERICON = 2, // Other file icon ID3PT_COVERFRONT = 3, // Cover (front) ID3PT_COVERBACK = 4, // Cover (back) ID3PT_LEAFLETPAGE = 5, // Leaflet page ID3PT_MEDIA = 6, // Media (e.g. lable side of CD) ID3PT_LEADARTIST = 7, // Lead artist/lead performer/soloist ID3PT_ARTIST = 8, // Artist/performer ID3PT_CONDUCTOR = 9, // Conductor ID3PT_BAND = 10, // Band/Orchestra ID3PT_COMPOSER = 11, // Composer ID3PT_LYRICIST = 12, // Lyricist/text writer ID3PT_REC_LOCATION = 13, // Recording Location ID3PT_RECORDING = 14, // During recording ID3PT_PERFORMANCE = 15, // During performance ID3PT_VIDEO = 16, // Movie/video screen capture ID3PT_FISH = 17, // A bright coloured fish ID3PT_ILLUSTRATION = 18, // Illustration ID3PT_ARTISTLOGO = 19, // Band/artist logotype ID3PT_PUBLISHERLOGO = 20 // Publisher/Studio logotype }; ID3_ENUM(ID3_TOCFlags) { ID3TF_NONE = 0, ID3TF_ORDERED = 1 << 0, /* chapters are in order */ ID3TF_TOPLEVEL = 1 << 1, /* does not have a parent */ }; ID3_ENUM(ID3_TimeStampFormat) { ID3TSF_FRAME = 1, ID3TSF_MS }; ID3_ENUM(MP3_BitRates) { MP3BITRATE_FALSE = -1, MP3BITRATE_NONE = 0, MP3BITRATE_8K = 8000, MP3BITRATE_16K = 16000, MP3BITRATE_24K = 24000, MP3BITRATE_32K = 32000, MP3BITRATE_40K = 40000, MP3BITRATE_48K = 48000, MP3BITRATE_56K = 56000, MP3BITRATE_64K = 64000, MP3BITRATE_80K = 80000, MP3BITRATE_96K = 96000, MP3BITRATE_112K = 112000, MP3BITRATE_128K = 128000, MP3BITRATE_144K = 144000, MP3BITRATE_160K = 160000, MP3BITRATE_176K = 176000, MP3BITRATE_192K = 192000, MP3BITRATE_224K = 224000, MP3BITRATE_256K = 256000, MP3BITRATE_288K = 288000, MP3BITRATE_320K = 320000, MP3BITRATE_352K = 352000, MP3BITRATE_384K = 384000, MP3BITRATE_416K = 416000, MP3BITRATE_448K = 448000 }; ID3_ENUM(Mpeg_Layers) { MPEGLAYER_FALSE = -1, MPEGLAYER_UNDEFINED, MPEGLAYER_III, MPEGLAYER_II, MPEGLAYER_I }; ID3_ENUM(Mpeg_Version) { MPEGVERSION_FALSE = -1, MPEGVERSION_2_5, MPEGVERSION_Reserved, MPEGVERSION_2, MPEGVERSION_1 }; ID3_ENUM(Mp3_Frequencies) { MP3FREQUENCIES_FALSE = -1, MP3FREQUENCIES_Reserved = 0, MP3FREQUENCIES_8000HZ = 8000, MP3FREQUENCIES_11025HZ = 11025, MP3FREQUENCIES_12000HZ = 12000, MP3FREQUENCIES_16000HZ = 16000, MP3FREQUENCIES_22050HZ = 22050, MP3FREQUENCIES_24000HZ = 24000, MP3FREQUENCIES_32000HZ = 32000, MP3FREQUENCIES_48000HZ = 48000, MP3FREQUENCIES_44100HZ = 44100, }; ID3_ENUM(Mp3_ChannelMode) { MP3CHANNELMODE_FALSE = -1, MP3CHANNELMODE_STEREO, MP3CHANNELMODE_JOINT_STEREO, MP3CHANNELMODE_DUAL_CHANNEL, MP3CHANNELMODE_SINGLE_CHANNEL }; ID3_ENUM(Mp3_ModeExt) { MP3MODEEXT_FALSE = -1, MP3MODEEXT_0, MP3MODEEXT_1, MP3MODEEXT_2, MP3MODEEXT_3 }; ID3_ENUM(Mp3_Emphasis) { MP3EMPHASIS_FALSE = -1, MP3EMPHASIS_NONE, MP3EMPHASIS_50_15MS, MP3EMPHASIS_Reserved, MP3EMPHASIS_CCIT_J17 }; ID3_ENUM(Mp3_Crc) { MP3CRC_ERROR_SIZE = -2, MP3CRC_MISMATCH = -1, MP3CRC_NONE = 0, MP3CRC_OK = 1 }; ID3_STRUCT(Mp3_Headerinfo) { Mpeg_Layers layer; Mpeg_Version version; MP3_BitRates bitrate; Mp3_ChannelMode channelmode; Mp3_ModeExt modeext; Mp3_Emphasis emphasis; Mp3_Crc crc; uint32 vbr_bitrate; // avg bitrate from xing header uint32 frequency; // samplerate uint32 framesize; uint32 frames; // nr of frames uint32 time; // nr of seconds in song uint32 datasize; // size from first sync byte till before the appended tags bool privatebit; bool copyrighted; bool original; }; #define MASK(bits) ((1 << (bits)) - 1) #define MASK1 MASK(1) #define MASK2 MASK(2) #define MASK3 MASK(3) #define MASK4 MASK(4) #define MASK5 MASK(5) #define MASK6 MASK(6) #define MASK7 MASK(7) #define MASK8 MASK(8) /* * The following is borrowed from glib.h (http://www.gtk.org) */ #ifdef WIN32 /* On native Win32, directory separator is the backslash, and search path * separator is the semicolon. */ # define ID3_DIR_SEPARATOR '\\' # define ID3_DIR_SEPARATOR_S "\\" # define ID3_SEARCHPATH_SEPARATOR ';' # define ID3_SEARCHPATH_SEPARATOR_S ";" #else /* !WIN32 */ # ifndef _EMX_ /* Unix */ # define ID3_DIR_SEPARATOR '/' # define ID3_DIR_SEPARATOR_S "/" # define ID3_SEARCHPATH_SEPARATOR ':' # define ID3_SEARCHPATH_SEPARATOR_S ":" # else /* EMX/OS2 */ # define ID3_DIR_SEPARATOR '/' # define ID3_DIR_SEPARATOR_S "/" # define ID3_SEARCHPATH_SEPARATOR ';' # define ID3_SEARCHPATH_SEPARATOR_S ";" # endif #endif /* !WIN32 */ #ifndef NULL # define NULL ((void*) 0) #endif #endif /* _ID3LIB_GLOBALS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/helpers.h000066400000000000000000000075751516712004000255400ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_HELPERS_H_ #define _ID3LIB_HELPERS_H_ #include "strings.h" #include "globals.h" class ID3_TagImpl; class ID3_Frame; namespace dami { namespace id3 { namespace v2 { String getString(const ID3_Frame *, ID3_FieldID); String getStringAtIndex(const ID3_Frame *, ID3_FieldID, size_t); String getFrameText(const ID3_TagImpl &, ID3_FrameID); ID3_Frame *setFrameText(ID3_TagImpl &, ID3_FrameID, String); size_t removeFrames(ID3_TagImpl &, ID3_FrameID); ID3_Frame *hasArtist(const ID3_TagImpl &); String getArtist(const ID3_TagImpl &); ID3_Frame *setArtist(ID3_TagImpl &, String); size_t removeArtists(ID3_TagImpl &); ID3_Frame *hasAlbum(const ID3_TagImpl &); String getAlbum(const ID3_TagImpl &); ID3_Frame *setAlbum(ID3_TagImpl &, String); size_t removeAlbums(ID3_TagImpl &); ID3_Frame *hasTitle(const ID3_TagImpl &); String getTitle(const ID3_TagImpl &); ID3_Frame *setTitle(ID3_TagImpl &, String); size_t removeTitles(ID3_TagImpl &); ID3_Frame *hasYear(const ID3_TagImpl &); String getYear(const ID3_TagImpl &); ID3_Frame *setYear(ID3_TagImpl &, String); size_t removeYears(ID3_TagImpl &); ID3_Frame *hasComment(const ID3_TagImpl &); String getComment(const ID3_TagImpl &, String desc); ID3_Frame *setComment(ID3_TagImpl &, String, String, String); size_t removeComments(ID3_TagImpl &, String); size_t removeAllComments(ID3_TagImpl &); ID3_Frame *hasV1Comment(const ID3_TagImpl &); String getV1Comment(const ID3_TagImpl &); ID3_Frame *hasTrack(const ID3_TagImpl &); String getTrack(const ID3_TagImpl &); size_t getTrackNum(const ID3_TagImpl &); ID3_Frame *setTrack(ID3_TagImpl &, uchar ucTrack, uchar ucTotal); size_t removeTracks(ID3_TagImpl &); ID3_Frame *hasGenre(const ID3_TagImpl &); String getGenre(const ID3_TagImpl &); size_t getGenreNum(const ID3_TagImpl &); ID3_Frame *setGenre(ID3_TagImpl &, size_t ucGenre); size_t removeGenres(ID3_TagImpl &); ID3_Frame *hasLyrics(const ID3_TagImpl &); String getLyrics(const ID3_TagImpl &); ID3_Frame *setLyrics(ID3_TagImpl &, String, String, String); size_t removeLyrics(ID3_TagImpl &); String getLyricist(const ID3_TagImpl &); ID3_Frame *setLyricist(ID3_TagImpl &, String); size_t removeLyricists(ID3_TagImpl &); ID3_Frame *hasSyncLyrics(const ID3_TagImpl &, String lang, String desc); ID3_Frame *setSyncLyrics(ID3_TagImpl &, BString, ID3_TimeStampFormat, String, String, ID3_ContentType); BString getSyncLyrics(const ID3_TagImpl &, String, String); }; }; }; #endif /* _ID3LIB_HELPERS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/io_decorators.h000066400000000000000000000143161516712004000267210ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_READER_DECORATORS_H_ #define _ID3LIB_READER_DECORATORS_H_ #include "readers.h" #include "io_helpers.h" #include "utils.h" namespace dami { namespace io { /** * Set a window on the buffer. Characters can only be read within this * window. */ class WindowedReader : public ID3_Reader { typedef ID3_Reader SUPER; ID3_Reader& _reader; pos_type _beg, _end; bool inWindow(pos_type cur) { return this->getBeg() <= cur && cur < this->getEnd(); } public: explicit WindowedReader(ID3_Reader& reader) : _reader(reader), _beg(reader.getBeg()), _end(reader.getEnd()) { ; } WindowedReader(ID3_Reader& reader, size_type size) : _reader(reader), _beg(reader.getBeg()), _end(reader.getEnd()) { this->setWindow(this->getCur(), size); } WindowedReader(ID3_Reader& reader, pos_type beg, size_type size) : _reader(reader), _beg(reader.getBeg()), _end(reader.getEnd()) { this->setWindow(beg, size); } void setWindow(pos_type beg, size_type size); pos_type setBeg(pos_type); pos_type setCur(pos_type cur) { return _reader.setCur(mid(this->getBeg(), cur, this->getEnd())); } pos_type setEnd(pos_type); pos_type getCur() { return _reader.getCur(); } pos_type getBeg() { return _beg; } pos_type getEnd() { return _end; } bool inWindow() { return this->inWindow(this->getCur()); } int_type readChar(); int_type peekChar(); size_type readChars(char_type buf[], size_type len); size_type readChars(char buf[], size_type len) { return this->readChars((char_type*) buf, len); } void close() { ; } }; class CharReader : public ID3_Reader { typedef ID3_Reader SUPER; protected: ID3_Reader& _reader; public: CharReader(ID3_Reader& reader) : _reader(reader) { } virtual ~CharReader() { ; } /** * Read \c len characters into the array \c buf. Since the stream needs * might have been unsynced, this function copies the characters one at a * time. */ size_type readChars(char_type buf[], size_type len); size_type readChars(char buf[], size_type len) { return this->readChars((char_type*) buf, len); } void close() { ; } int_type peekChar() { return _reader.peekChar(); } pos_type getBeg() { return _reader.getBeg(); } pos_type getCur() { return _reader.getCur(); } pos_type getEnd() { return _reader.getEnd(); } pos_type setCur(pos_type cur) { return _reader.setCur(cur); } }; class LineFeedReader : public CharReader { typedef CharReader SUPER; public: LineFeedReader(ID3_Reader& reader) : SUPER(reader) { ; } int_type readChar(); }; class UnsyncedReader : public CharReader { typedef CharReader SUPER; public: UnsyncedReader(ID3_Reader& reader) : SUPER(reader) { } int_type readChar(); }; class CompressedReader : public ID3_MemoryReader { char_type* _uncompressed; public: CompressedReader(ID3_Reader& reader, size_type newSize); virtual ~CompressedReader(); }; class UnsyncedWriter : public ID3_Writer { typedef ID3_Writer SUPER; ID3_Writer& _writer; int_type _last; size_type _numSyncs; public: UnsyncedWriter(ID3_Writer& writer) : _writer(writer), _last('\0'), _numSyncs(0) { ; } size_type getNumSyncs() const { return _numSyncs; } int_type writeChar(char_type ch); void flush(); /** * Write \c len characters into the array \c buf. Since the stream needs * might have been unsynced, this function copies the characters one at a * time. */ size_type writeChars(const char_type[], size_type len); size_type writeChars(const char buf[], size_type len) { return this->writeChars(reinterpret_cast(buf), len); } void close() { ; } pos_type getBeg() { return _writer.getBeg(); } pos_type getCur() { return _writer.getCur(); } pos_type getEnd() { return _writer.getEnd(); } }; class CompressedWriter : public ID3_Writer { typedef ID3_Writer SUPER; ID3_Writer& _writer; BString _data; size_type _origSize; public: explicit CompressedWriter(ID3_Writer& writer) : _writer(writer), _data(), _origSize(0) { ; } virtual ~CompressedWriter() { this->flush(); } size_type getOrigSize() const { return _origSize; } void flush(); size_type writeChars(const char_type buf[], size_type len); size_type writeChars(const char buf[], size_type len) { return this->writeChars(reinterpret_cast(buf), len); } pos_type getCur() { return _data.size(); } void close() { ; } }; }; }; #endif /* _ID3LIB_READER_DECORATORS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/io_helpers.h000066400000000000000000000055211516712004000262140ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_IO_HELPERS_H_ #define _ID3LIB_IO_HELPERS_H_ #include "strings.h" #include "reader.h" #include "writer.h" namespace dami { namespace io { /** **/ class ExitTrigger { ID3_Reader &_reader; ID3_Reader::pos_type _pos; bool _locked; public: ExitTrigger(ID3_Reader &rdr) : _reader(rdr), _pos(rdr.getCur()), _locked(true) { } ExitTrigger(ID3_Reader &rdr, ID3_Reader::pos_type pos) : _reader(rdr), _pos(pos), _locked(true) { } virtual ~ExitTrigger() { if (_locked) _reader.setCur(_pos); } void release() { _locked = false; } void update() { _pos = _reader.getCur(); } void setExitPos(ID3_Reader::pos_type pos) { _pos = pos; } }; String readString(ID3_Reader &); String readText(ID3_Reader &, size_t); String readUnicodeString(ID3_Reader &, ID3_TextEnc); String readUnicodeText(ID3_Reader &, size_t, ID3_TextEnc); BString readAllBinary(ID3_Reader &); BString readBinary(ID3_Reader &, size_t); uint32 readLENumber(ID3_Reader &, size_t); uint32 readBENumber(ID3_Reader &, size_t); String readTrailingSpaces(ID3_Reader &, size_t); uint32 readUInt28(ID3_Reader &); size_t writeString(ID3_Writer &, String); size_t writeText(ID3_Writer &, String); size_t writeUnicodeString(ID3_Writer &, String, ID3_TextEnc); size_t writeUnicodeText(ID3_Writer &, String, ID3_TextEnc); size_t writeBENumber(ID3_Writer &, uint32 val, size_t); size_t writeTrailingSpaces(ID3_Writer &, String, size_t); size_t writeUInt28(ID3_Writer &, uint32); }; }; #endif /* _ID3LIB_IO_HELPERS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/io_strings.h000066400000000000000000000144041516712004000262430ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_IO_STRINGS_H_ #define _ID3LIB_IO_STRINGS_H_ #include "strings.h" #include "reader.h" #include "writer.h" #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif namespace dami { namespace io { class StringReader : public ID3_Reader { const String& _string; pos_type _cur; public: StringReader(const String& string) : _string(string), _cur(0) { ; } virtual ~StringReader() { ; } virtual void close() { ; } virtual int_type peekChar() { if (!this->atEnd()) { return _string[_cur]; } return END_OF_READER; } /** Read up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters read into buf. **/ size_type readChars(char buf[], size_type len) { return this->readChars((char_type*) buf, len); } virtual size_type readChars(char_type buf[], size_type len) { size_type size = min((unsigned int)len, (unsigned int)(_string.size() - _cur)); _string.copy(reinterpret_cast(buf), size, _cur); _cur += size; return size; } virtual pos_type getCur() { return _cur; } virtual pos_type getBeg() { return 0; } virtual pos_type getEnd() { return _string.size(); } /** Set the value of the internal position for reading. **/ virtual pos_type setCur(pos_type pos) { pos_type end = this->getEnd(); _cur = (pos < end) ? pos : end; return _cur; } virtual bool atEnd() { return _cur >= _string.size(); } virtual size_type skipChars(size_type len) { size_type size = min((unsigned int)len, (unsigned int)(_string.size() - _cur)); _cur += size; return size; } }; class BStringReader : public ID3_Reader { const BString& _string; pos_type _cur; public: BStringReader(const BString& string) : _string(string), _cur(0) { ; } virtual ~BStringReader() { ; } virtual void close() { ; } virtual int_type peekChar() { if (!this->atEnd()) { return _string[_cur]; } return END_OF_READER; } /** Read up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters read into buf. **/ size_type readChars(char buf[], size_type len) { return this->readChars((char_type*) buf, len); } virtual size_type readChars(char_type buf[], size_type len) { size_type size = min((unsigned int)len, (unsigned int)(_string.size() - _cur)); _string.copy(reinterpret_cast(buf), size, _cur); _cur += size; return size; } virtual pos_type getCur() { return _cur; } virtual pos_type getBeg() { return 0; } virtual pos_type getEnd() { return _string.size(); } /** Set the value of the internal position for reading. **/ virtual pos_type setCur(pos_type pos) { pos_type end = this->getEnd(); _cur = (pos < end) ? pos : end; return _cur; } virtual bool atEnd() { return _cur >= _string.size(); } virtual size_type skipChars(size_type len) { size_type size = min((unsigned int)len,(unsigned int)( _string.size() - _cur)); _cur += size; return size; } }; class StringWriter : public ID3_Writer { String& _string; public: StringWriter(String& string) : _string(string) { ; } virtual ~StringWriter() { ; } void close() { ; } void flush() { ; } virtual size_type writeChars(const char buf[], size_type len) { _string.append(reinterpret_cast(buf), len); return len; } size_type writeChars(const char_type buf[], size_type len) { _string.append(reinterpret_cast(buf), len); return len; } pos_type getCur() { return _string.size(); } }; class BStringWriter : public ID3_Writer { BString& _string; public: BStringWriter(BString& string) : _string(string) { ; } virtual ~BStringWriter() { ; } void close() { ; } void flush() { ; } virtual size_type writeChars(const char buf[], size_type len) { _string.append(reinterpret_cast(buf), len); return len; } size_type writeChars(const char_type buf[], size_type len) { _string.append(reinterpret_cast(buf), len); return len; } pos_type getCur() { return _string.size(); } }; }; }; #endif /* _ID3LIB_IO_STRINGS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/misc_support.h000066400000000000000000000143251516712004000266140ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_MISC_SUPPORT_H_ #define _ID3LIB_MISC_SUPPORT_H_ #include "tag.h" char* ID3_GetString(const ID3_Frame *, ID3_FieldID); char* ID3_GetString(const ID3_Frame *, ID3_FieldID, size_t nItems); void ID3_FreeString(char *str); // defined in 'id3_misc_support.cpp' // these are 'convenience functions,' to make using the library easier for the // most common of operations char* ID3_GetArtist(const ID3_Tag*); ID3_Frame* ID3_AddArtist(ID3_Tag*, const char*, bool replace = false); size_t ID3_RemoveArtists(ID3_Tag*); char* ID3_GetAlbum(const ID3_Tag*); ID3_Frame* ID3_AddAlbum(ID3_Tag*, const char*, bool replace = false); size_t ID3_RemoveAlbums(ID3_Tag*); char* ID3_GetTitle(const ID3_Tag*); ID3_Frame* ID3_AddTitle(ID3_Tag*, const char*, bool replace = false); size_t ID3_RemoveTitles(ID3_Tag*); char* ID3_GetYear(const ID3_Tag*); ID3_Frame* ID3_AddYear(ID3_Tag*, const char*, bool replace = false); size_t ID3_RemoveYears(ID3_Tag*); char* ID3_GetComment(const ID3_Tag*, const char* desc = NULL); ID3_Frame* ID3_AddComment(ID3_Tag*, const char*, bool = false); ID3_Frame* ID3_AddComment(ID3_Tag*, const char*, const char*, bool = false); ID3_Frame* ID3_AddComment(ID3_Tag*, const char*, const char*, const char*, bool = false); size_t ID3_RemoveComments(ID3_Tag*, const char * = NULL); char* ID3_GetTrack(const ID3_Tag*); size_t ID3_GetTrackNum(const ID3_Tag*); //following routine courtesy of John George ID3_Frame* ID3_AddTrack(ID3_Tag*, uchar ucTrack, uchar ucTotal = 0, bool replace = false); size_t ID3_RemoveTracks(ID3_Tag*); char* ID3_GetGenre(const ID3_Tag*); size_t ID3_GetGenreNum(const ID3_Tag*); ID3_Frame* ID3_AddGenre(ID3_Tag*, size_t ucGenre, bool replace = false); //following routine courtesy of John George ID3_Frame* ID3_AddGenre(ID3_Tag*, const char *, bool replace = false); size_t ID3_RemoveGenres(ID3_Tag*); char* ID3_GetLyrics(const ID3_Tag*); ID3_Frame* ID3_AddLyrics(ID3_Tag*, const char*, bool = false); ID3_Frame* ID3_AddLyrics(ID3_Tag*, const char*, const char*, bool = false); ID3_Frame* ID3_AddLyrics(ID3_Tag*, const char*, const char*, const char*, bool = false); size_t ID3_RemoveLyrics(ID3_Tag*); char* ID3_GetLyricist(const ID3_Tag*); ID3_Frame* ID3_AddLyricist(ID3_Tag *, const char *, bool replace = false); size_t ID3_RemoveLyricist(ID3_Tag*); ID3_Frame* ID3_AddSyncLyrics(ID3_Tag*, const uchar*, size_t, ID3_TimeStampFormat, bool = false); ID3_Frame* ID3_AddSyncLyrics(ID3_Tag*, const uchar*, size_t, ID3_TimeStampFormat, const char *, bool = false); ID3_Frame* ID3_AddSyncLyrics(ID3_Tag*, const uchar*, size_t, ID3_TimeStampFormat, const char *, const char *, bool = false); ID3_Frame* ID3_AddSyncLyrics(ID3_Tag*, const uchar*, size_t, ID3_TimeStampFormat, const char *, const char *, ID3_ContentType, bool = false); ID3_Frame* ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *lang, const char *desc, char &stampformat, char &type, size_t &size); ID3_Frame* ID3_GetSyncLyrics(const ID3_Tag* tag, const char* lang, const char* desc, const uchar* &pData, size_t& size); //following routine courtesy of John George int ID3_GetPictureData(const ID3_Tag*, const char* TempPicPath); //following routine courtesy of John George char* ID3_GetPictureMimeType(const ID3_Tag*); //following routine courtesy of John George bool ID3_HasPicture(const ID3_Tag*); //following two routines courtesy of John George ID3_Frame* ID3_AddPicture(ID3_Tag*, const char* TempPicPath, const char* MimeType, bool replace = false); ID3_Frame* ID3_AddPicture(ID3_Tag*, const char* TempPicPath, const char* MimeType, ID3_PictureType pictype, const char* Description, bool replace = false); //following routine courtesy of John George size_t ID3_RemovePictures(ID3_Tag*); //following routine courtesy of John George size_t ID3_GetPictureDataOfPicType(ID3_Tag*, const char* TempPicPath, ID3_PictureType pictype); //following routine courtesy of John George char *ID3_GetMimeTypeOfPicType(ID3_Tag*, ID3_PictureType pictype); //following routine courtesy of John George char *ID3_GetDescriptionOfPicType(ID3_Tag*, ID3_PictureType pictype); //following routine courtesy of John George size_t ID3_RemovePictureType(ID3_Tag*, ID3_PictureType pictype); ID3_Frame* ID3_AddGenre(ID3_Tag* tag, size_t genreNum, char* genre, bool add_v1_genre_number = true, bool add_v1_genre_description = true, bool addRXorCR = false, bool replace = true); #endif /* _ID3LIB_MISC_SUPPORT_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/reader.h000066400000000000000000000077151516712004000253340ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_READER_H_ #define _ID3LIB_READER_H_ #include "globals.h" class ID3_Reader { public: typedef uint32 size_type; typedef uint8 char_type; typedef uint32 pos_type; typedef int32 off_type; typedef int16 int_type; static const int_type END_OF_READER; /** Close the reader. Any further actions on the reader should fail. **/ virtual void close() = 0; /** Return the beginning position in the reader. **/ virtual pos_type getBeg() { return static_cast(0); } /** Return the ending position in the reader. **/ virtual pos_type getEnd() { return static_cast(-1); } /** Return the current position in the reader. **/ virtual pos_type getCur() = 0; /** Set the value of the current position for reading. **/ virtual pos_type setCur(pos_type pos) = 0; /** Read a single character and advance the internal position. Note that the ** interal position may advance more than one byte for a single character ** read. Returns END_OF_READER if there isn't a character to read. **/ virtual int_type readChar() { if (this->atEnd()) { return END_OF_READER; } char_type ch; this->readChars(&ch, 1); return ch; } /** Return the next character to be read without advancing the internal ** position. Returns END_OF_READER if there isn't a character to read. **/ virtual int_type peekChar() = 0; /** Read up to \c len characters into buf and advance the internal position ** accordingly. Returns the number of characters read into buf. Note that ** the value returned may be less than the number of bytes that the internal ** position advances, due to multi-byte characters. **/ virtual size_type readChars(char_type buf[], size_type len) = 0; virtual size_type readChars(char buf[], size_type len) { return this->readChars(reinterpret_cast(buf), len); } /** Skip up to \c len chars in the stream and advance the internal position ** accordingly. Returns the number of characters actually skipped (may be ** less than requested). **/ virtual size_type skipChars(size_type len) { const size_type SIZE = 1024; char_type bytes[SIZE]; size_type remaining = len; while (!this->atEnd() && remaining > 0) { remaining -= this->readChars(bytes, (remaining < SIZE ? remaining : SIZE)); } return len - remaining; } virtual size_type remainingBytes() { pos_type end = this->getEnd(), cur = this->getCur(); if (end == pos_type(-1)) return size_type(-1); if (end >= cur) return end - cur; return 0; } virtual bool atEnd() { return this->getCur() >= this->getEnd(); } }; #endif /* _ID3LIB_READER_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/readers.h000066400000000000000000000106421516712004000255100ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_READERS_H_ #define _ID3LIB_READERS_H_ #include "streams.h" #include "reader.h" #include class ID3_IStreamReader : public ID3_Reader { istream& _stream; protected: istream& getReader() const { return _stream; } public: ID3_IStreamReader(istream& reader) : _stream(reader) { ; } virtual ~ID3_IStreamReader() { ; } virtual void close() { ; } virtual int_type peekChar() { return _stream.peek(); } /** Read up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters read into buf. **/ virtual size_type readChars(char buf[], size_type len) { return this->readChars(reinterpret_cast(buf), len); } virtual size_type readChars(char_type buf[], size_type len) { _stream.read((char *)buf, len); return _stream.gcount(); } virtual pos_type getBeg() { return 0; } virtual pos_type getCur() { return _stream.tellg(); } virtual pos_type getEnd() { pos_type cur = this->getCur(); _stream.seekg(0, ios::end); pos_type end = this->getCur(); this->setCur(cur); return end; } /** Set the value of the internal position for reading. **/ virtual pos_type setCur(pos_type pos) { _stream.seekg(pos); return pos; } }; class ID3_IFStreamReader : public ID3_IStreamReader { ifstream& _file; public: ID3_IFStreamReader(ifstream& reader) : ID3_IStreamReader(reader), _file(reader) { ; } virtual void close() { _file.close(); } }; class ID3_MemoryReader : public ID3_Reader { const char_type* _beg; const char_type* _cur; const char_type* _end; protected: void setBuffer(const char_type* buf, size_type size) { _beg = buf; _cur = buf; _end = buf + size; }; public: ID3_MemoryReader() { this->setBuffer(NULL, 0); } ID3_MemoryReader(const char_type* buf, size_type size) { this->setBuffer(buf, size); }; ID3_MemoryReader(const char* buf, size_type size) { this->setBuffer(reinterpret_cast(buf), size); }; virtual ~ID3_MemoryReader() { ; } virtual void close() { ; } virtual int_type peekChar() { if (!this->atEnd()) { return *_cur; } return END_OF_READER; } /** Read up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters read into buf. **/ virtual size_type readChars(char buf[], size_type len) { return this->readChars(reinterpret_cast(buf), len); } virtual size_type readChars(char_type buf[], size_type len) { size_type remaining = _end - _cur; size_type size = (remaining > len) ? len : remaining; ::memcpy(buf, _cur, size); _cur += size; return size; } virtual pos_type getCur() { return _cur - _beg; } virtual pos_type getBeg() { return _beg - _beg; } virtual pos_type getEnd() { return _end - _beg; } /** Set the value of the internal position for reading. **/ virtual pos_type setCur(pos_type pos) { pos_type end = this->getEnd(); size_type size = (pos < end) ? pos : end; _cur = _beg + size; return this->getCur(); } }; #endif /* _ID3LIB_READERS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/sized_types.h000066400000000000000000000051331516712004000264240ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags Copyright // 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ /** ** This file defines size-specific typedefs based on the macros defined in ** limits.h **/ #ifndef _SIZED_TYPES_H_ #define _SIZED_TYPES_H_ #include /* define our datatypes */ /* Define 8-bit types */ #if UCHAR_MAX == 0xff typedef unsigned char uint8; typedef signed char int8; #else #error This machine has no 8-bit type; report compiler, and the contents of your limits.h to the persons in the AUTHORS file #endif /* UCHAR_MAX == 0xff */ /* Define 16-bit types */ #if UINT_MAX == 0xffff typedef unsigned int uint16; typedef int int16; #elif USHRT_MAX == 0xffff typedef unsigned short uint16; typedef short int16; #else #error This machine has no 16-bit type; report compiler, and the contents of your limits.h to the persons in the AUTHORS file #endif /* UINT_MAX == 0xffff */ /* Define 32-bit types */ #if UINT_MAX == 0xfffffffful typedef unsigned int uint32; typedef int int32; #elif ULONG_MAX == 0xfffffffful typedef unsigned long uint32; typedef long int32; #elif USHRT_MAX == 0xfffffffful typedef unsigned short uint32; typedef short int32; #else #error This machine has no 32-bit type; report compiler, and the contents of your limits.h to the persons in the AUTHORS file #endif /* UINT_MAX == 0xfffffffful */ #endif /* _SIZED_TYPES_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/streams.h000066400000000000000000000030241516712004000255350ustar00rootroot00000000000000// id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 2002 Thijmen Klok /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef STREAMS_H_DEFINE #define STREAMS_H_DEFINE #include #include #include using std::ifstream; using std::ofstream; using std::fstream; using std::iostream; using std::ostream; using std::istream; using std::ios; using std::streamoff; #endif // STREAMS_H_DEFINE boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/strings.h000066400000000000000000000100041516712004000255440ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_STRINGS_H_ #define _ID3LIB_STRINGS_H_ #include #include #include #if (defined(__GNUC__) && (__GNUC__ >= 3) || (defined(_MSC_VER) && _MSC_VER > 1000)) namespace std { template<> struct char_traits { typedef unsigned char char_type; // Unsigned as wint_t in unsigned. typedef unsigned long int_type; typedef streampos pos_type; typedef streamoff off_type; typedef mbstate_t state_type; static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { for (size_t __i = 0; __i < __n; ++__i) if (!eq(__s1[__i], __s2[__i])) return lt(__s1[__i], __s2[__i]) ? -1 : 1; return 0; } static size_t length(const char_type* __s) { const char_type* __p = __s; while (__p) ++__p; return (__p - __s); } static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) if (*__p == __a) return __p; return 0; } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { for (char_type* __p = __s; __p < __s + __n; ++__p) assign(*__p, __a); return __s; } static char_type to_char_type(const int_type& __c) { return char_type(); } static int_type to_int_type(const char_type& __c) { return int_type(); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { return static_cast(-1); } static int_type not_eof(const int_type& __c) { return eq_int_type(__c, eof()) ? int_type(0) : __c; } }; }; // namespace std #endif namespace dami { typedef std::basic_string String; typedef std::basic_string BString; typedef std::basic_string WString; }; #endif /* _ID3LIB_STRINGS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/tag.h000066400000000000000000000054301516712004000246350ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_TAG_H_ #define _ID3LIB_TAG_H_ #include "container.h" #include "frame.h" #include "field.h" class ID3_Reader; class ID3_Writer; class ID3_TagImpl; class ID3_Tag : public ID3_Container { private: ID3_TagImpl *_impl; public: ID3_Tag(const char *name = NULL, flags_t = (flags_t) ID3TT_ALL); ID3_Tag(const ID3_Tag &tag); virtual ~ID3_Tag(); bool SetUnsync(bool); bool SetExtendedHeader(bool); bool SetExperimental(bool); bool GetUnsync() const; bool GetExtendedHeader() const; bool GetExperimental() const; bool SetPadding(bool); size_t Parse(const uchar *, size_t); bool Parse(ID3_Reader & reader); size_t Render(uchar *, ID3_TagType = ID3TT_ID3V2) const; size_t Render(ID3_Writer &, ID3_TagType = ID3TT_ID3V2) const; size_t Link(const char *fileInfo, flags_t = (flags_t) ID3TT_ALL); size_t Link(ID3_Reader &reader, flags_t = (flags_t) ID3TT_ALL); flags_t Update(flags_t = (flags_t) ID3TT_ALL); flags_t Strip(flags_t = (flags_t) ID3TT_ALL); size_t GetPrependedBytes() const; size_t GetAppendedBytes() const; size_t GetFileSize() const; const char *GetFileName() const; ID3_Err GetLastError(); const Mp3_Headerinfo *GetMp3HeaderInfo() const; ID3_Tag &operator =(const ID3_Tag &); bool HasTagType(ID3_TagType tt) const; static size_t IsV2Tag(const uchar *); static size_t IsV2Tag(ID3_Reader &); }; #endif /* _ID3LIB_TAG_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/utils.h000066400000000000000000000054651516712004000252320ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_UTILS_H_ #define _ID3LIB_UTILS_H_ #if defined HAVE_CONFIG_H # include #endif #include "streams.h" #include "globals.h" #include "strings.h" namespace dami { #ifdef MAXPATHLEN # define ID3_PATH_LENGTH (MAXPATHLEN + 1) #elif defined (PATH_MAX) # define ID3_PATH_LENGTH (PATH_MAX + 1) #else /* !MAXPATHLEN */ # define ID3_PATH_LENGTH (2048 + 1) #endif /* !MAXPATHLEN && !PATH_MAX */ #ifndef min template const T &min(const T &a, const T &b) { return (a < b) ? a : b; } #endif #ifndef max template const T &max(const T &a, const T &b) { return (b < a) ? a : b; } #endif #ifndef mid template const T &mid(const T &lo, const T &mid, const T &hi) { return max(lo, min(mid, hi)); } #endif #ifndef abs template T abs(const T &a) { return (a < T(0)) ? -a : a; } #endif size_t renderNumber(uchar *buffer, uint32 val, size_t size = sizeof(uint32)); String renderNumber(uint32 val, size_t size = sizeof(uint32)); String toString(uint32 val); WString toWString(const unicode_t[], size_t); size_t ucslen(const unicode_t *unicode); String convert(String data, ID3_TextEnc, ID3_TextEnc); /* File utils */ size_t getFileSize(fstream &); size_t getFileSize(ifstream &); size_t getFileSize(ofstream &); ID3_Err createFile(String, fstream &); ID3_Err openWritableFile(String, fstream &); ID3_Err openWritableFile(String, ofstream &); ID3_Err openReadableFile(String, fstream &); ID3_Err openReadableFile(String, ifstream &); }; #endif /* _ID3LIB_UTILS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/writer.h000066400000000000000000000066041516712004000254020ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_WRITER_H_ #define _ID3LIB_WRITER_H_ #include "globals.h" class ID3_Writer { public: typedef uint32 size_type; typedef uint8 char_type; typedef uint32 pos_type; typedef int32 off_type; typedef int16 int_type; static const int_type END_OF_WRITER; /** Close the writer. Any further actions on the writer should fail. **/ virtual void close() = 0; /** Flush the writer. **/ virtual void flush() = 0; /** Return the beginning position in the writer **/ virtual pos_type getBeg() { return static_cast(0); } /** Return the first position that can't be written to. A return value of ** -1 indicates no (reasonable) limit to the writer. **/ virtual pos_type getEnd() { return static_cast(-1); } /** Return the next position that will be written to */ virtual pos_type getCur() = 0; /** Return the number of bytes written **/ virtual size_type getSize() { return this->getCur() - this->getBeg(); } /** Return the maximum number of bytes that can be written **/ virtual size_type getMaxSize() { return this->getEnd() - this->getBeg(); } /** Write a single character and advance the internal position. Note that ** the interal position may advance more than one byte for a single ** character write. Returns END_OF_WRITER if there isn't a character to ** write. **/ virtual int_type writeChar(char_type ch) { if (this->atEnd()) { return END_OF_WRITER; } this->writeChars(&ch, 1); return ch; } /** Write up to \c len characters into buf and advance the internal position ** accordingly. Returns the number of characters write into buf. Note that ** the value returned may be less than the number of bytes that the internal ** position advances, due to multi-byte characters. **/ virtual size_type writeChars(const char_type buf[], size_type len) = 0; virtual size_type writeChars(const char buf[], size_type len) { return this->writeChars(reinterpret_cast(buf), len); } virtual bool atEnd() { return this->getCur() >= this->getEnd(); } }; #endif /* _ID3LIB_WRITER_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/id3/writers.h000066400000000000000000000117011516712004000255570ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_WRITERS_H_ #define _ID3LIB_WRITERS_H_ #include "writer.h" #include "streams.h" #include class ID3_OStreamWriter : public ID3_Writer { ostream& _stream; pos_type _beg; protected: ostream& getWriter() const { return _stream; } public: ID3_OStreamWriter(ostream& writer) : _stream(writer), _beg(_stream.tellp()) { ; } virtual ~ID3_OStreamWriter() { ; } virtual void close() { ; } virtual void flush() { _stream.flush(); } virtual int_type writeChar(char_type ch) { _stream.put(ch); return ch; } /** Write up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters write into buf. **/ virtual size_type writeChars(const char buf[], size_type len) { _stream.write(buf, len); return len; } virtual size_type writeChars(const char_type buf[], size_type len) { _stream.write(reinterpret_cast(buf), len); return len; } virtual pos_type getBeg() { return _beg; } virtual pos_type getCur() { return _stream.tellp(); } }; class ID3_OFStreamWriter : public ID3_OStreamWriter { ofstream& _file; public: ID3_OFStreamWriter(ofstream& writer) : ID3_OStreamWriter(writer), _file(writer) { ; } virtual void close() { _file.close(); } }; class ID3_IOStreamWriter : public ID3_Writer { iostream& _stream; pos_type _beg; protected: iostream& getWriter() const { return _stream; } public: ID3_IOStreamWriter(iostream& writer) : _stream(writer), _beg(_stream.tellp()) { ; } virtual ~ID3_IOStreamWriter() { ; } virtual void close() { ; } virtual void flush() { _stream.flush(); } virtual int_type writeChar(char_type ch) { _stream.put(ch); return ch; } /** Write up to \c len chars into buf and advance the internal position ** accordingly. Returns the number of characters write into buf. **/ virtual size_type writeChars(const char buf[], size_type len) { _stream.write(buf, len); return len; } virtual size_type writeChars(const char_type buf[], size_type len) { _stream.write(reinterpret_cast(buf), len); return len; } virtual pos_type getBeg() { return _beg; } virtual pos_type getCur() { return _stream.tellp(); } }; class ID3_FStreamWriter : public ID3_IOStreamWriter { fstream& _file; public: ID3_FStreamWriter(fstream& writer) : ID3_IOStreamWriter(writer), _file(writer) { ; } virtual void close() { _file.close(); } }; class ID3_MemoryWriter : public ID3_Writer { const char_type* _beg; /* */ char_type* _cur; const char_type* _end; protected: void setBuffer(char_type* buf, size_t size) { _beg = buf; _cur = buf; _end = buf + size; }; public: ID3_MemoryWriter() { this->setBuffer(NULL, 0); } ID3_MemoryWriter(char_type buf[], size_t size) { this->setBuffer(buf, size); } virtual ~ID3_MemoryWriter() { ; } virtual void close() { ; } virtual void flush() { ; } /** Write up to \c len chars from buf and advance the internal position ** accordingly. Returns the number of characters written from buf. **/ virtual size_type writeChars(const char buf[], size_type len) { return this->writeChars(reinterpret_cast(buf), len); } virtual size_type writeChars(const char_type buf[], size_type len) { size_type remaining = _end - _cur; size_type size = (remaining > len) ? len : remaining; ::memcpy(_cur, buf, size); _cur += size; return size; } virtual pos_type getCur() { return _cur - _beg; } virtual pos_type getBeg() { return _beg - _beg; } virtual pos_type getEnd() { return _end - _beg; } }; #endif /* _ID3LIB_WRITERS_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/io.cpp000066400000000000000000000027331516712004000243500ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include #include const ID3_Reader::int_type ID3_Reader::END_OF_READER = -1; const ID3_Writer::int_type ID3_Writer::END_OF_WRITER = -1; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/io_decorators.cpp000066400000000000000000000170631516712004000265770ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include #include "zlib.h" using namespace dami; void io::WindowedReader::setWindow(pos_type beg, size_type size) { ID3D_NOTICE("WindowedReader::setWindow() [beg, size] = [" << this->getBeg() << ", " << size << "]"); pos_type cur = this->getCur(); // reset the end marker so as to avoid errors this->setEnd(_reader.getEnd()); // set the beginning marker this->setBeg(beg); // since the characters might be more than a byte in size, we need to // manually get all the chars to set the window appropriately this->setCur(beg); ID3D_NOTICE("WindowedReader::setWindow(): after setCur(beg), cur = "<< this->getCur()); this->skipChars(size); ID3D_NOTICE("WindowedReader::setWindow(): after skipChars, cur = " << this->getCur()); this->setEnd(this->getCur()); ID3D_NOTICE("WindowedReader::setWindow() [beg, cur, end] = [" << this->getBeg() << ", " << this->getCur() << ", " << this->getEnd() << "]"); // reset the stream this->setCur(cur); } ID3_Reader::pos_type io::WindowedReader::setBeg(pos_type beg) { // make sure the position we want to set to isn't past the current // end position or the superclass's beginning position if (beg <= this->getEnd() && beg >= _reader.getBeg()) { _beg = beg; } else if (beg > this->getEnd()) { ID3D_WARNING("WindowedReader::setBeg() failed, [beg, _end] = " << beg << ", " << this->getEnd() << "]"); } else { ID3D_WARNING("WindowedReader::setBeg() failed, [beg, _beg] = " << beg << ", " << this->getBeg() << "]"); } return _beg; } ID3_Reader::pos_type io::WindowedReader::setEnd(pos_type end) { // make sure the position we want to set to isn't beforen the current // beginning position or the superclass's end position if (this->getBeg() <= end && end <= _reader.getEnd()) { _end = end; } else { ID3D_WARNING("WindowedReader::setEnd() failed, end = " << end); ID3D_WARNING("WindowedReader::setEnd() failed, beg = " << this->getBeg()); ID3D_WARNING("WindowedReader::setEnd() failed, super.end = " << _reader.getEnd()); } return _end; } ID3_Reader::int_type io::WindowedReader::readChar() { int_type ch = END_OF_READER; if (this->inWindow()) { ch = _reader.readChar(); } else { ID3D_WARNING("io::WindowedReader::readChar: not in window, " << "pos = " << this->getCur() << ", window = [" << this->getBeg() << ", " << this->getEnd() << "]"); } return ch; } ID3_Reader::int_type io::WindowedReader::peekChar() { int_type ch = END_OF_READER; if (this->inWindow()) { ch = _reader.peekChar(); } return ch; } ID3_Reader::size_type io::WindowedReader::readChars(char_type buf[], size_type len) { pos_type cur = this->getCur(); size_type size = 0; if (this->inWindow(cur)) { size = _reader.readChars(buf, min(len, _end - cur)); } return size; } ID3_Reader::size_type io::CharReader::readChars(char_type buf[], size_type len) { size_type numChars = 0; ID3D_NOTICE("CharReader::readChars(): len = " << len); for (; numChars < len; ++numChars) { if (this->atEnd()) break; char_type ch = this->readChar(); if (buf != NULL) buf[numChars] = ch; } ID3D_NOTICE("CharReader::readChars(): numChars = " << len); return numChars; } ID3_Reader::int_type io::LineFeedReader::readChar() { if (this->atEnd()) return END_OF_READER; char_type ch = _reader.readChar(); if (ch == 0x0D && this->peekChar() == 0x0A) { ID3D_NOTICE("LineFeedReader::readChar(): found CRLF at pos " << this->getCur()); ch = _reader.readChar(); } return ch; }; ID3_Reader::int_type io::UnsyncedReader::readChar() { if (this->atEnd()) return END_OF_READER; char_type ch = _reader.readChar(); if (ch == 0xFF && this->peekChar() == 0x00) { ID3D_NOTICE("UnsyncedReader::readChar(): found sync at pos " << this->getCur()); _reader.readChar(); } return ch; } io::CompressedReader::CompressedReader(ID3_Reader &reader, size_type newSize) : _uncompressed(new char_type[newSize]) { size_type oldSize = reader.remainingBytes(); BString binary = readBinary(reader, oldSize); if (::uncompress(_uncompressed, reinterpret_cast(&newSize), reinterpret_cast(binary.data()), oldSize) == Z_OK) { this->setBuffer(_uncompressed, newSize); } } io::CompressedReader::~CompressedReader() { delete [] _uncompressed; } ID3_Writer::int_type io::UnsyncedWriter::writeChar(char_type ch) { if (_last == 0xFF && (ch == 0x00 || ch >= 0xE0)) { _writer.writeChar('\0'); _numSyncs++; } _last = _writer.writeChar(ch); return _last; } void io::UnsyncedWriter::flush() { if (_last == 0xFF) { _last = _writer.writeChar('\0'); _numSyncs++; } _writer.flush(); } ID3_Writer::size_type io::UnsyncedWriter::writeChars(const char_type buf[], size_type len) { pos_type beg = this->getCur(); ID3D_NOTICE("UnsyncedWriter::writeChars(): len = " << len); for (size_t i = 0; i < len; ++i) { if (this->atEnd()) break; this->writeChar(buf[i]); } size_type numChars = this->getCur() - beg; ID3D_NOTICE("CharWriter::writeChars(): numChars = " << numChars); return numChars; } void io::CompressedWriter::flush() { if (_data.size() == 0) return; const char_type *data = reinterpret_cast(_data.data()); size_type dataSize = _data.size(); _origSize = dataSize; // The zlib documentation specifies that the destination size needs to // be an unsigned long at least 0.1% larger than the source buffer, // plus 12 bytes unsigned long newDataSize = dataSize + (dataSize / 10) + 12; char_type *newData = new char_type[newDataSize]; if (::compress(newData, &newDataSize, data, dataSize) != Z_OK) { // log this ID3D_WARNING("io::CompressedWriter: error compressing"); _writer.writeChars(data, dataSize); } else if (newDataSize < dataSize) { ID3D_NOTICE("io::CompressedWriter: compressed size = " << newDataSize << ", original size = " << dataSize); _writer.writeChars(newData, newDataSize); } else { ID3D_NOTICE("io::CompressedWriter: no compression!compressed size = " << newDataSize << ", original size = " << dataSize); _writer.writeChars(data, dataSize); } delete [] newData; _data.erase(); } ID3_Writer::size_type io::CompressedWriter::writeChars(const char_type buf[], size_type len) { ID3D_NOTICE("io::CompressedWriter: writing chars: " << len ); _data.append(buf, len); return len; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/io_helpers.cpp000066400000000000000000000231451516712004000260720ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include using namespace dami; String io::readString(ID3_Reader &reader) { String str; while (!reader.atEnd()) { ID3_Reader::char_type ch = reader.readChar(); if (ch == '\0') break; str += static_cast(ch); } return str; } String io::readText(ID3_Reader &reader, size_t len) { String str; str.reserve(len); const size_t SIZE = 1024; ID3_Reader::char_type buf[SIZE]; size_t remaining = len; while (remaining > 0 && !reader.atEnd()) { size_t numRead = reader.readChars(buf, min(remaining, SIZE)); remaining -= numRead; str.append(reinterpret_cast(buf), numRead); } return str; } namespace { bool isNull(unsigned char ch1, unsigned char ch2) { return ch1 == '\0' && ch2 == '\0'; } int isBOM(unsigned char ch1, unsigned char ch2) { // The following is taken from the following URL: // http://community.roxen.com/developers/idocs/rfc/rfc2781.html /* The Unicode Standard and ISO 10646 define the character "ZERO WIDTH NON-BREAKING SPACE" (0xFEFF), which is also known informally as "BYTE ORDER MARK" (abbreviated "BOM"). The latter name hints at a second possible usage of the character, in addition to its normal use as a genuine "ZERO WIDTH NON-BREAKING SPACE" within text. This usage, suggested by Unicode section 2.4 and ISO 10646 Annex F (informative), is to prepend a 0xFEFF character to a stream of Unicode characters as a "signature"; a receiver of such a serialized stream may then use the initial character both as a hint that the stream consists of Unicode characters and as a way to recognize the serialization order. In serialized UTF-16 prepended with such a signature, the order is big-endian if the first two octets are 0xFE followed by 0xFF; if they are 0xFF followed by 0xFE, the order is little-endian. Note that 0xFFFE is not a Unicode character, precisely to preserve the usefulness of 0xFEFF as a byte-order mark. */ if (ch1 == 0xFE && ch2 == 0xFF) return 1; else if (ch1 == 0xFF && ch2 == 0xFE) return -1; return 0; } bool readTwoChars(ID3_Reader &reader, ID3_Reader::char_type &ch1, ID3_Reader::char_type &ch2) { if (reader.atEnd()) return false; io::ExitTrigger et(reader); ch1 = reader.readChar(); if (reader.atEnd()) return false; et.release(); ch2 = reader.readChar(); return true; } } String io::readUnicodeString(ID3_Reader &reader, ID3_TextEnc enc) { //keeps reading until null char or at end of reader end String unicode; ID3_Reader::char_type ch1, ch2; if (!readTwoChars(reader, ch1, ch2) || isNull(ch1, ch2)) return unicode; int bom = isBOM(ch1, ch2); if (!bom) reader.setCur(reader.getCur() - 2); while (!reader.atEnd()) { if (!readTwoChars(reader, ch1, ch2) || isNull(ch1, ch2)) break; if (bom == 1 || (!bom && enc == ID3TE_UTF16BE)) { unicode += static_cast(ch1); unicode += static_cast(ch2); } else { unicode += static_cast(ch2); unicode += static_cast(ch1); } } return unicode; } String io::readUnicodeText(ID3_Reader &reader, size_t len, ID3_TextEnc enc) { String unicode; ID3_Reader::char_type ch1, ch2; if (!readTwoChars(reader, ch1, ch2)) return unicode; int bom = isBOM(ch1, ch2); if (!bom) reader.setCur(reader.getCur() - 2); else len -= 2; for (size_t i = 0; i < len; i += 2) { if (!readTwoChars(reader, ch1, ch2)) break; if (bom == 1 || (!bom && enc == ID3TE_UTF16BE)) { unicode += static_cast(ch1); unicode += static_cast(ch2); } else { unicode += static_cast(ch2); unicode += static_cast(ch1); } } return unicode; } BString io::readAllBinary(ID3_Reader &reader) { return readBinary(reader, reader.remainingBytes()); } BString io::readBinary(ID3_Reader &reader, size_t len) { BString binary; binary.reserve(len); size_t remaining = len; const size_t SIZE = 1024; ID3_Reader::char_type buf[SIZE]; while (!reader.atEnd() && remaining > 0) { size_t numRead = reader.readChars(buf, min(remaining, SIZE)); remaining -= numRead; binary.append(reinterpret_cast(buf), numRead); } return binary; } uint32 io::readLENumber(ID3_Reader &reader, size_t len) { uint32 val = 0; for (size_t i = 0; i < len; i++) { if (reader.atEnd()) break; val += (static_cast(0xFF & reader.readChar()) << (i * 8)); } return val; } uint32 io::readBENumber(ID3_Reader &reader, size_t len) { uint32 val = 0; for (ID3_Reader::size_type i = 0; i < len && !reader.atEnd(); ++i) { val *= 256; // 2^8 val += static_cast(0xFF & reader.readChar()); } return val; } String io::readTrailingSpaces(ID3_Reader &reader, size_t len) { io::WindowedReader wr(reader, len); String str; String spaces; str.reserve(len); spaces.reserve(len); while (!wr.atEnd()) { ID3_Reader::char_type ch = wr.readChar(); if (ch == '\0' || ch == ' ') { spaces += ch; } else { str += spaces + (char) ch; spaces.erase(); } } return str; } uint32 io::readUInt28(ID3_Reader &reader) { const unsigned short BITSUSED = 7; const uint32 MAXVAL = MASK(BITSUSED * sizeof(uint32)); uint32 val = 0; // For each byte of the first 4 bytes in the string... for (size_t i = 0; i < sizeof(uint32); ++i) { if (reader.atEnd()) break; // ...append the last 7 bits to the end of the temp integer... val = (val << BITSUSED) | (static_cast(reader.readChar()) & MASK(BITSUSED)); } // We should always parse 4 characters return min(val, MAXVAL); } size_t io::writeBENumber(ID3_Writer &writer, uint32 val, size_t len) { ID3_Writer::char_type bytes[sizeof(uint32)]; ID3_Writer::size_type size = min(len, sizeof(uint32)); renderNumber(bytes, val, size); return writer.writeChars(bytes, size); } size_t io::writeTrailingSpaces(ID3_Writer &writer, String buf, size_t len) { ID3_Writer::pos_type beg = writer.getCur(); ID3_Writer::size_type strLen = buf.size(); ID3_Writer::size_type size = min((unsigned int) len, (unsigned int) strLen); writer.writeChars(buf.data(), size); for (; size < len; ++size) writer.writeChar('\0'); return writer.getCur() - beg; } size_t io::writeUInt28(ID3_Writer &writer, uint32 val) { const unsigned short BITSUSED = 7; const uint32 MAXVAL = MASK(BITSUSED * sizeof(uint32)); uchar data[sizeof(uint32)]; val = min(val, MAXVAL); // This loop renders the value to the character buffer in reverse order, as // it is easy to extract the last 7 bits of an integer. This is why the // loop shifts the value of the integer by 7 bits for each iteration. for (size_t i = 0; i < sizeof(uint32); ++i) { // Extract the last BITSUSED bits from val and put it in its appropriate // place in the data buffer data[sizeof(uint32) - i - 1] = static_cast(val & MASK(BITSUSED)); // The last BITSUSED bits were extracted from the val. So shift it to the // right by that many bits for the next iteration val >>= BITSUSED; } // Should always render 4 bytes return writer.writeChars(data, sizeof(uint32)); } size_t io::writeString(ID3_Writer &writer, String data) { size_t size = writeText(writer, data); writer.writeChar('\0'); return size + 1; } size_t io::writeText(ID3_Writer &writer, String data) { ID3_Writer::pos_type beg = writer.getCur(); writer.writeChars(data.data(), data.size()); return writer.getCur() - beg; } size_t io::writeUnicodeString(ID3_Writer &writer, String data, ID3_TextEnc enc) { size_t size = writeUnicodeText(writer, data, enc); unicode_t null = NULL_UNICODE; writer.writeChars((const unsigned char *) &null, 2); return size + 2; } size_t io::writeUnicodeText(ID3_Writer &writer, String data, ID3_TextEnc enc) { ID3_Writer::pos_type beg = writer.getCur(); size_t size = (data.size() / 2) * 2; int is_bom = size ? isBOM(data[0], data[1]) : false; if (enc == ID3TE_UTF16 && !is_bom) { /* Write the BOM: 0xFEFF */ const unsigned char BOMch1 = 0xFE; const unsigned char BOMch2 = 0xFF; writer.writeChars(&BOMch2, 1); writer.writeChars(&BOMch1, 1); } for (size_t i = 0; i < size; i += 2) { if (i == 0 && enc != ID3TE_UTF16 && is_bom) { /* Skip unneeded leading BOM */ continue; } writer.writeChars(data.data() + i, 1); writer.writeChars(data.data() + i + 1, 1); } return writer.getCur() - beg; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/misc_support.cpp000066400000000000000000000561741516712004000265000ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include #include #include // using namespace dami; char *ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName) { if (frame == NULL) return NULL; char *text = NULL; ID3_Field *fld = frame->GetField(fldName); if (fld != NULL) { ID3_TextEnc enc = fld->GetEncoding(); fld->SetEncoding(ID3TE_ISO8859_1); size_t nText = fld->Size(); text = new char[nText + 1]; fld->Get(text, nText + 1); fld->SetEncoding(enc); } return text; } char *ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName, size_t nIndex) { char *text = NULL; if (NULL != frame) { size_t nText = frame->GetField(fldName)->Size(); text = new char[nText + 1]; frame->GetField(fldName)->Get(text, nText + 1, nIndex); } return text; } void ID3_FreeString(char *str) { if (str != NULL) delete [] str; } char *ID3_GetArtist(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sArtist = NULL; ID3_Frame *frame = NULL; if ((frame = tag->Find(ID3FID_LEADARTIST)) || (frame = tag->Find(ID3FID_BAND)) || (frame = tag->Find(ID3FID_CONDUCTOR)) || (frame = tag->Find(ID3FID_COMPOSER))) { sArtist = ID3_GetString(frame, ID3FN_TEXT); } return sArtist; } ID3_Frame *ID3_AddArtist(ID3_Tag *tag, const char *text, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (replace) ID3_RemoveArtists(tag); if (replace || (tag->Find(ID3FID_LEADARTIST) == NULL && tag->Find(ID3FID_BAND) == NULL && tag->Find(ID3FID_CONDUCTOR) == NULL && tag->Find(ID3FID_COMPOSER) == NULL)) { frame = new ID3_Frame(ID3FID_LEADARTIST); if (frame) { frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveArtists(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_LEADARTIST))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } while ((frame = tag->Find(ID3FID_BAND))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } while ((frame = tag->Find(ID3FID_CONDUCTOR))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } while ((frame = tag->Find(ID3FID_COMPOSER))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetAlbum(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sAlbum = NULL; ID3_Frame *frame = tag->Find(ID3FID_ALBUM); if (frame != NULL) sAlbum = ID3_GetString(frame, ID3FN_TEXT); return sAlbum; } ID3_Frame *ID3_AddAlbum(ID3_Tag *tag, const char *text, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (replace) ID3_RemoveAlbums(tag); if (replace || tag->Find(ID3FID_ALBUM) == NULL) { frame = new ID3_Frame(ID3FID_ALBUM); if (frame) { frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveAlbums(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_ALBUM))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetTitle(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sTitle = NULL; ID3_Frame *frame = tag->Find(ID3FID_TITLE); if (frame != NULL) sTitle = ID3_GetString(frame, ID3FN_TEXT); return sTitle; } ID3_Frame *ID3_AddTitle(ID3_Tag *tag, const char *text, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (replace) ID3_RemoveTitles(tag); if (replace || tag->Find(ID3FID_TITLE) == NULL) { frame = new ID3_Frame(ID3FID_TITLE); if (frame) { frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveTitles(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_TITLE))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetYear(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sYear = NULL; ID3_Frame *frame = tag->Find(ID3FID_YEAR); if (frame != NULL) sYear = ID3_GetString(frame, ID3FN_TEXT); return sYear; } ID3_Frame *ID3_AddYear(ID3_Tag *tag, const char *text, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (replace) ID3_RemoveYears(tag); if (replace || tag->Find(ID3FID_YEAR) == NULL) { frame = new ID3_Frame(ID3FID_YEAR); if (NULL != frame) { frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveYears(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_YEAR))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetComment(const ID3_Tag *tag, const char* desc) { if (NULL == tag) return NULL; char *comment = NULL; ID3_Frame *frame = NULL; if (desc) { frame = tag->Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, desc); } else { frame = tag->Find(ID3FID_COMMENT); if (frame == tag->Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC)) frame = tag->Find(ID3FID_COMMENT); } if (frame) comment = ID3_GetString(frame, ID3FN_TEXT); return comment; } ID3_Frame *ID3_AddComment(ID3_Tag *tag, const char *text, bool replace) { return ID3_AddComment(tag, text, "", replace); } ID3_Frame *ID3_AddComment(ID3_Tag *tag, const char *text, const char *desc, bool replace) { return ID3_AddComment(tag, text, desc, "XXX", replace); } ID3_Frame *ID3_AddComment(ID3_Tag *tag, const char *text, const char *desc, const char *lang, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && NULL != desc && strlen(text) > 0) { bool bAdd = true; if (replace) { ID3_RemoveComments(tag, desc); } else { // See if there is already a comment with this description ID3_Tag::Iterator *iter = tag->CreateIterator(); ID3_Frame *frame = NULL; while ((frame = iter->GetNext()) != NULL) { if (frame->GetID() == ID3FID_COMMENT) { char *tmp_desc = ID3_GetString(frame, ID3FN_DESCRIPTION); if (strcmp(tmp_desc, desc) == 0) bAdd = false; delete [] tmp_desc; if (!bAdd) break; } } delete iter; } if (bAdd) { frame = new ID3_Frame(ID3FID_COMMENT); if (NULL != frame) { frame->GetField(ID3FN_LANGUAGE)->Set(lang); frame->GetField(ID3FN_DESCRIPTION)->Set(desc); frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } // Remove all comments with the given description (remove all comments if // desc is NULL) size_t ID3_RemoveComments(ID3_Tag *tag, const char *desc) { size_t num_removed = 0; if (NULL == tag) return num_removed; ID3_Tag::Iterator *iter = tag->CreateIterator(); ID3_Frame *frame = NULL; while ((frame = iter->GetNext()) != NULL) { if (frame->GetID() == ID3FID_COMMENT) { bool remove = false; // A null description means remove all comments if (NULL == desc) { remove = true; } else { // See if the description we have matches the description of the // current comment. If so, set the "remove the comment" flag to true. char *tmp_desc = ID3_GetString(frame, ID3FN_DESCRIPTION); remove = (strcmp(tmp_desc, desc) == 0); delete [] tmp_desc; } if (remove) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } } } delete iter; return num_removed; } char *ID3_GetTrack(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sTrack = NULL; ID3_Frame *frame = tag->Find(ID3FID_TRACKNUM); if (frame != NULL) sTrack = ID3_GetString(frame, ID3FN_TEXT); return sTrack; } size_t ID3_GetTrackNum(const ID3_Tag *tag) { char *sTrack = ID3_GetTrack(tag); size_t nTrack = 0; if (NULL != sTrack) { nTrack = atoi(sTrack); delete [] sTrack; } return nTrack; } ID3_Frame *ID3_AddTrack(ID3_Tag *tag, uchar trk, uchar ttl, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && trk > 0) { if (replace) ID3_RemoveTracks(tag); if (replace || NULL == tag->Find(ID3FID_TRACKNUM)) { frame = new ID3_Frame(ID3FID_TRACKNUM); if (frame) { char *sTrack = NULL; if (0 == ttl) { sTrack = new char[4]; sprintf(sTrack, "%lu", (luint) trk); } else { sTrack = new char[8]; sprintf(sTrack, "%lu/%lu", (luint) trk, (luint) ttl); } frame->GetField(ID3FN_TEXT)->Set(sTrack); delete [] sTrack; if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } // following routine courtesy of John George int ID3_GetPictureData(const ID3_Tag *tag, const char *TempPicPath) { if (NULL == tag) return 0; ID3_Frame *frame = tag->Find(ID3FID_PICTURE); if (frame == NULL) return 0; ID3_Field *myField = frame->GetField(ID3FN_DATA); if (myField == NULL) return 0; myField->ToFile(TempPicPath); return (int) myField->Size(); } // following routine courtesy of John George char *ID3_GetPictureMimeType(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sPicMimetype = NULL; ID3_Frame *frame = tag->Find(ID3FID_PICTURE); if (frame != NULL) sPicMimetype = ID3_GetString(frame, ID3FN_MIMETYPE); return sPicMimetype; } // following routine courtesy of John George bool ID3_HasPicture(const ID3_Tag *tag) { if (NULL == tag) return false; ID3_Frame *frame = tag->Find(ID3FID_PICTURE); if (frame == NULL) return false; ID3_Field *myField = frame->GetField(ID3FN_DATA); if (myField != NULL) return true; else return false; } // following routine courtesy of John George ID3_Frame *ID3_AddPicture(ID3_Tag *tag, const char *TempPicPath, const char *MimeType, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag) { if (replace) ID3_RemovePictures(tag); if (replace || NULL == tag->Find(ID3FID_PICTURE)) { frame = new ID3_Frame(ID3FID_PICTURE); if (NULL != frame) { frame->GetField(ID3FN_DATA)->FromFile(TempPicPath); frame->GetField(ID3FN_MIMETYPE)->Set(MimeType); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } // following routine courtesy of John George size_t ID3_RemovePictures(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_PICTURE))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } // following routine courtesy of John George size_t ID3_RemovePictureType(ID3_Tag* tag, ID3_PictureType pictype) { size_t bremoved = 0; ID3_Frame *frame = NULL; if (NULL == tag) return bremoved; ID3_Tag::Iterator *iter = tag->CreateIterator(); while (NULL != (frame = iter->GetNext())) { if (frame->GetID() == ID3FID_PICTURE) { if (frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32) pictype) break; } } delete iter; if (NULL != frame) { frame = tag->RemoveFrame(frame); delete frame; bremoved = 1; } return bremoved; } // following routine courtesy of John George ID3_Frame *ID3_AddPicture(ID3_Tag *tag, const char *TempPicPath, const char *MimeType, ID3_PictureType pictype, const char *Description, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag) { if (replace) ID3_RemovePictureType(tag, pictype); if (replace || NULL == tag->Find(ID3FID_PICTURE, ID3FN_PICTURETYPE, (uint32)pictype)) { frame = new ID3_Frame(ID3FID_PICTURE); if (NULL != frame) { frame->GetField(ID3FN_DATA)->FromFile(TempPicPath); frame->GetField(ID3FN_MIMETYPE)->Set(MimeType); frame->GetField(ID3FN_PICTURETYPE)->Set((uint32)pictype); frame->GetField(ID3FN_DESCRIPTION)->Set(Description); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } // following routine courtesy of John George size_t ID3_GetPictureDataOfPicType(ID3_Tag *tag, const char *TempPicPath, ID3_PictureType pictype) { if (NULL == tag) return 0; ID3_Frame *frame = NULL; ID3_Tag::Iterator *iter = tag->CreateIterator(); while (NULL != (frame = iter->GetNext() )) { if(frame->GetID() == ID3FID_PICTURE) { if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32) pictype) break; } } delete iter; if (frame == NULL) return 0; ID3_Field *myField = frame->GetField(ID3FN_DATA); if (myField == NULL) return 0; myField->ToFile(TempPicPath); return (size_t) myField->Size(); } // following routine courtesy of John George char *ID3_GetMimeTypeOfPicType(ID3_Tag *tag, ID3_PictureType pictype) { if (NULL == tag) return NULL; char *sPicMimetype = NULL; ID3_Frame *frame = NULL; ID3_Tag::Iterator *iter = tag->CreateIterator(); while (NULL != (frame = iter->GetNext())) { if(frame->GetID() == ID3FID_PICTURE) { if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32) pictype) break; } } delete iter; if (frame != NULL) sPicMimetype = ID3_GetString(frame, ID3FN_MIMETYPE); return sPicMimetype; } // following routine courtesy of John George char *ID3_GetDescriptionOfPicType(ID3_Tag *tag, ID3_PictureType pictype) { if (NULL == tag) return NULL; char *sPicDescription = NULL; ID3_Frame *frame = NULL; ID3_Tag::Iterator *iter = tag->CreateIterator(); while (NULL != (frame = iter->GetNext())) { if(frame->GetID() == ID3FID_PICTURE) { if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype) break; } } delete iter; if (frame != NULL) sPicDescription = ID3_GetString(frame, ID3FN_DESCRIPTION); return sPicDescription; } size_t ID3_RemoveTracks(ID3_Tag* tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_TRACKNUM))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetGenre(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sGenre = NULL; ID3_Frame *frame = tag->Find(ID3FID_CONTENTTYPE); if (frame != NULL) sGenre = ID3_GetString(frame, ID3FN_TEXT); return sGenre; } size_t ID3_GetGenreNum(const ID3_Tag *tag) { char *sGenre = ID3_GetGenre(tag); size_t ulGenre = 0xFF; if (NULL == sGenre) return ulGenre; // If the genre string begins with "(ddd)", where "ddd" is a number, then // "ddd" is the genre number---get it if (sGenre[0] == '(') { char *pCur = &sGenre[1]; while (isdigit(*pCur)) pCur++; if (*pCur == ')') { // if the genre number is greater than 255, its invalid. ulGenre = dami::min(0xFF, atoi(&sGenre[1])); } } delete [] sGenre; return ulGenre; } // following routine courtesy of John George ID3_Frame *ID3_AddGenre(ID3_Tag *tag, const char *genre, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != genre && strlen(genre) > 0) { if (replace) ID3_RemoveGenres(tag); if (replace || NULL == tag->Find(ID3FID_CONTENTTYPE)) { frame = new ID3_Frame(ID3FID_CONTENTTYPE); if (NULL != frame) { frame->GetField(ID3FN_TEXT)->Set(genre); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } ID3_Frame *ID3_AddGenre(ID3_Tag *tag, size_t genreNum, bool replace) { if (0xFF != genreNum) { char sGenre[6]; sprintf(sGenre, "(%lu)", (luint) genreNum); return(ID3_AddGenre(tag, sGenre, replace)); } else { return(NULL); } } size_t ID3_RemoveGenres(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_CONTENTTYPE))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetLyrics(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sLyrics = NULL; ID3_Frame *frame = tag->Find(ID3FID_UNSYNCEDLYRICS); if (frame != NULL) sLyrics = ID3_GetString(frame, ID3FN_TEXT); return sLyrics; } ID3_Frame *ID3_AddLyrics(ID3_Tag *tag, const char *text, bool replace) { return ID3_AddLyrics(tag, text, "", replace); } ID3_Frame *ID3_AddLyrics(ID3_Tag *tag, const char *text, const char *desc, bool replace) { return ID3_AddLyrics(tag, text, desc, "XXX", replace); } ID3_Frame *ID3_AddLyrics(ID3_Tag *tag, const char *text, const char *desc, const char *lang, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && strlen(text) > 0) { if (replace) ID3_RemoveLyrics(tag); if (replace || tag->Find(ID3FID_UNSYNCEDLYRICS) == NULL) { frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS); if (NULL != frame) { frame->GetField(ID3FN_LANGUAGE)->Set(lang); frame->GetField(ID3FN_DESCRIPTION)->Set(desc); frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveLyrics(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_UNSYNCEDLYRICS))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } char *ID3_GetLyricist(const ID3_Tag *tag) { if (NULL == tag) return NULL; char *sLyricist = NULL; ID3_Frame *frame = tag->Find(ID3FID_LYRICIST); if (frame != NULL) sLyricist = ID3_GetString(frame, ID3FN_TEXT); return sLyricist; } ID3_Frame *ID3_AddLyricist(ID3_Tag *tag, const char *text, bool replace) { ID3_Frame *frame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (replace) ID3_RemoveLyricist(tag); if (replace || (tag->Find(ID3FID_LYRICIST) == NULL)) { frame = new ID3_Frame(ID3FID_LYRICIST); if (frame) { frame->GetField(ID3FN_TEXT)->Set(text); if (!tag->AttachFrame(frame)) return NULL; } } } return frame; } size_t ID3_RemoveLyricist(ID3_Tag *tag) { size_t num_removed = 0; ID3_Frame *frame = NULL; if (NULL == tag) return num_removed; while ((frame = tag->Find(ID3FID_LYRICIST))) { frame = tag->RemoveFrame(frame); delete frame; num_removed++; } return num_removed; } ID3_Frame *ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize, ID3_TimeStampFormat format, bool replace) { return ID3_AddSyncLyrics(tag, data, datasize, format, "", replace); } ID3_Frame *ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize, ID3_TimeStampFormat format, const char *desc, bool replace) { return ID3_AddSyncLyrics(tag, data, datasize, format, desc, "XXX", replace); } ID3_Frame *ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize, ID3_TimeStampFormat format, const char *desc, const char *lang, bool replace) { return ID3_AddSyncLyrics(tag, data, datasize, format, desc, lang, ID3CT_LYRICS, replace); } ID3_Frame *ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize, ID3_TimeStampFormat format, const char *desc, const char *lang, ID3_ContentType type, bool replace) { if (tag == NULL) return NULL; ID3_Frame *frame = NULL; // language and descriptor should be mandatory if ((lang == NULL) || (desc == NULL)) return NULL; // check if a SYLT frame of this language or descriptor already exists ID3_Frame *frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang); if (!frmExist) frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc); if (data != NULL) { if (replace && frmExist) { frmExist = tag->RemoveFrame (frmExist); delete frmExist; frmExist = NULL; } // if the frame still exist, cannot continue if (frmExist) return NULL; frame = new ID3_Frame(ID3FID_SYNCEDLYRICS); if (frame != NULL) { frame->GetField(ID3FN_LANGUAGE)->Set(lang); frame->GetField(ID3FN_DESCRIPTION)->Set(desc); frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format); frame->GetField(ID3FN_CONTENTTYPE)->Set(type); frame->GetField(ID3FN_DATA)->Set(data, datasize); if (!tag->AttachFrame(frame)) return NULL; } } return frame; } ID3_Frame *ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *desc, const char *lang, ID3_TimeStampFormat &format, ID3_ContentType &type, size_t &size) { // check if a SYLT frame of this language or descriptor exists ID3_Frame *frmExist = NULL; if (NULL != lang) { // search through language frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang); } else if (NULL != desc) { // search through descriptor frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc); } else { // both language and description not specified, search the first SYLT frame frmExist = tag->Find(ID3FID_SYNCEDLYRICS); } if (!frmExist) return NULL; // get the lyrics time stamp format format = static_cast(frmExist->GetField(ID3FN_TIMESTAMPFORMAT)->Get ()); // get the lyrics content type type = static_cast(frmExist->GetField(ID3FN_CONTENTTYPE)->Get ()); // get the lyrics size size = frmExist->GetField (ID3FN_DATA)->Size (); // return the frame pointer for further uses return frmExist; } ID3_Frame *ID3_GetSyncLyrics(const ID3_Tag *tag, const char *lang, const char *desc, const uchar *&pData, size_t &size) { // check if a SYLT frame of this language or descriptor exists ID3_Frame *frmExist = NULL; if (NULL != lang) { // search through language frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang); } else if (NULL != desc) { // search through descriptor frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc); } else { // both language and description not specified, search the first SYLT frame frmExist = tag->Find(ID3FID_SYNCEDLYRICS); } if (NULL == frmExist) return NULL; // get the lyrics size size = dami::min(size, frmExist->GetField(ID3FN_DATA)->Size()); // get the lyrics data pData = frmExist->GetField (ID3FN_DATA)->GetRawBinary(); // return the frame pointer for further uses return frmExist; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/mp3_header.h000066400000000000000000000066721516712004000254230ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _MP3_HEADER_H_ #define _MP3_HEADER_H_ #include class Mp3Info { public: Mp3Info() { _mp3_header_output = new Mp3_Headerinfo; }; ~Mp3Info() { this->Clean(); }; void Clean(); const Mp3_Headerinfo* GetMp3HeaderInfo() const { return _mp3_header_output; }; bool Parse(ID3_Reader&, size_t mp3size); Mpeg_Layers Layer() const { return _mp3_header_output->layer; }; Mpeg_Version Version() const { return _mp3_header_output->version; }; MP3_BitRates Bitrate() const { return _mp3_header_output->bitrate; }; Mp3_ChannelMode ChannelMode() const { return _mp3_header_output->channelmode; }; Mp3_ModeExt ModeExt() const { return _mp3_header_output->modeext; }; Mp3_Emphasis Emphasis() const { return _mp3_header_output->emphasis; }; Mp3_Crc Crc() const { return _mp3_header_output->crc; }; uint32 VbrBitrate() const { return _mp3_header_output->vbr_bitrate; }; uint32 Frequency() const { return _mp3_header_output->frequency; }; uint32 Framesize() const { return _mp3_header_output->framesize; }; uint32 Frames() const { return _mp3_header_output->frames; }; bool Private() const { return _mp3_header_output->privatebit; }; bool Copyrighted() const { return _mp3_header_output->copyrighted; }; bool Original() const { return _mp3_header_output->original; }; uint32 Seconds() const { return _mp3_header_output->time; }; uint32 DataSize() const { return _mp3_header_output->datasize; }; private: struct _mp3_header_internal //http://www.mp3-tech.org/programmer/frame_header.html { //byte 1 unsigned char frame_sync_a : 8; /* all bits should be set */ //byte 2 unsigned char protection_bit : 1; unsigned char layer : 2; unsigned char id : 2; unsigned char frame_sync_b : 3; /* all bits should be set */ //byte 3 unsigned char private_bit : 1; unsigned char padding_bit : 1; unsigned char frequency : 2; unsigned char bitrate_index : 4; //byte 4 unsigned char emphasis : 2; unsigned char original : 1; unsigned char copyright : 1; unsigned char mode_ext : 2;//only used in joint stereo unsigned char mode : 2; }; Mp3_Headerinfo* _mp3_header_output; }; //Info #endif /* _MP3_HEADER_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/mp3_parse.cpp000066400000000000000000000401611516712004000256270ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 2002, Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "mp3_header.h" #define FRAMES_FLAG 0x0001 #define BYTES_FLAG 0x0002 #define TOC_FLAG 0x0004 #define SCALE_FLAG 0x0008 static int ExtractI4(unsigned char *buf) { int x; // big endian extract x = buf[0]; x <<= 8; x |= buf[1]; x <<= 8; x |= buf[2]; x <<= 8; x |= buf[3]; return x; } uint32 fto_nearest_i(float f) { uint32 i; i = (uint32)f; if (i < f) { f -= i; if (f >= 0.5) return i+1; else return i; } else return i; } uint16 calcCRC(char *pFrame, size_t audiodatasize) { size_t icounter; int tmpchar, crcmask, tmpi; uint16 crc = 0xffff; for (icounter = 2; icounter < audiodatasize; ++icounter) { if (icounter != 4 && icounter != 5) //skip the 2 chars of the crc itself { crcmask = 1 << 8; tmpchar = pFrame[icounter]; while (crcmask >>= 1) { tmpi = crc & 0x8000; crc <<= 1; if (!tmpi ^ !(tmpchar & crcmask)) crc ^= 0x8005; } } } crc &= 0xffff; return crc; } void Mp3Info::Clean() { if (_mp3_header_output != NULL) delete _mp3_header_output; _mp3_header_output = NULL; } using namespace dami; bool Mp3Info::Parse(ID3_Reader& reader, size_t mp3size) { MP3_BitRates _mp3_bitrates[2][3][16] = { { { //MPEG 1, LAYER I MP3BITRATE_NONE, MP3BITRATE_32K, MP3BITRATE_64K, MP3BITRATE_96K, MP3BITRATE_128K, MP3BITRATE_160K, MP3BITRATE_192K, MP3BITRATE_224K, MP3BITRATE_256K, MP3BITRATE_288K, MP3BITRATE_320K, MP3BITRATE_352K, MP3BITRATE_384K, MP3BITRATE_416K, MP3BITRATE_448K, MP3BITRATE_FALSE }, { //MPEG 1, LAYER II MP3BITRATE_NONE, MP3BITRATE_32K, MP3BITRATE_48K, MP3BITRATE_56K, MP3BITRATE_64K, MP3BITRATE_80K, MP3BITRATE_96K, MP3BITRATE_112K, MP3BITRATE_128K, MP3BITRATE_160K, MP3BITRATE_192K, MP3BITRATE_224K, MP3BITRATE_256K, MP3BITRATE_320K, MP3BITRATE_384K, MP3BITRATE_FALSE }, { //MPEG 1, LAYER III MP3BITRATE_NONE, MP3BITRATE_32K, MP3BITRATE_40K, MP3BITRATE_48K, MP3BITRATE_56K, MP3BITRATE_64K, MP3BITRATE_80K, MP3BITRATE_96K, MP3BITRATE_112K, MP3BITRATE_128K, MP3BITRATE_160K, MP3BITRATE_192K, MP3BITRATE_224K, MP3BITRATE_256K, MP3BITRATE_320K, MP3BITRATE_FALSE } }, { { //MPEG 2 or 2.5, LAYER I MP3BITRATE_NONE, MP3BITRATE_32K, MP3BITRATE_48K, MP3BITRATE_56K, MP3BITRATE_64K, MP3BITRATE_80K, MP3BITRATE_96K, MP3BITRATE_112K, MP3BITRATE_128K, MP3BITRATE_144K, MP3BITRATE_160K, MP3BITRATE_176K, MP3BITRATE_192K, MP3BITRATE_224K, MP3BITRATE_256K, MP3BITRATE_FALSE }, { //MPEG 2 or 2.5, LAYER II MP3BITRATE_NONE, MP3BITRATE_8K, MP3BITRATE_16K, MP3BITRATE_24K, MP3BITRATE_32K, MP3BITRATE_40K, MP3BITRATE_48K, MP3BITRATE_56K, MP3BITRATE_64K, MP3BITRATE_80K, MP3BITRATE_96K, MP3BITRATE_112K, MP3BITRATE_128K, MP3BITRATE_144K, MP3BITRATE_160K, MP3BITRATE_FALSE }, { //MPEG 2 or 2.5, LAYER III MP3BITRATE_NONE, MP3BITRATE_8K, MP3BITRATE_16K, MP3BITRATE_24K, MP3BITRATE_32K, MP3BITRATE_40K, MP3BITRATE_48K, MP3BITRATE_56K, MP3BITRATE_64K, MP3BITRATE_80K, MP3BITRATE_96K, MP3BITRATE_112K, MP3BITRATE_128K, MP3BITRATE_144K, MP3BITRATE_160K, MP3BITRATE_FALSE } } }; Mp3_Frequencies _mp3_frequencies[4][4] = { { MP3FREQUENCIES_11025HZ, MP3FREQUENCIES_12000HZ, MP3FREQUENCIES_8000HZ,MP3FREQUENCIES_Reserved }, //MPEGVERSION_2_5 { MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved}, //MPEGVERSION_Reserved { MP3FREQUENCIES_22050HZ, MP3FREQUENCIES_24000HZ, MP3FREQUENCIES_16000HZ, MP3FREQUENCIES_Reserved }, //MPEGVERSION_2 { MP3FREQUENCIES_44100HZ, MP3FREQUENCIES_48000HZ, MP3FREQUENCIES_32000HZ, MP3FREQUENCIES_Reserved } //MPEGVERSION_1 }; _mp3_header_internal *_tmpheader = NULL; const size_t HEADERSIZE = 4;// char buf[HEADERSIZE+1]; //+1 to hold the \0 char ID3_Reader::pos_type beg = reader.getCur() ; ID3_Reader::pos_type end = beg + HEADERSIZE ; reader.setCur(beg); int bitrate_index; _mp3_header_output->layer = MPEGLAYER_FALSE; _mp3_header_output->version = MPEGVERSION_FALSE; _mp3_header_output->bitrate = MP3BITRATE_FALSE; _mp3_header_output->channelmode = MP3CHANNELMODE_FALSE; _mp3_header_output->modeext = MP3MODEEXT_FALSE; _mp3_header_output->emphasis = MP3EMPHASIS_FALSE; _mp3_header_output->crc = MP3CRC_MISMATCH; _mp3_header_output->frequency = 0; _mp3_header_output->framesize = 0; _mp3_header_output->frames = 0; _mp3_header_output->time = 0; _mp3_header_output->vbr_bitrate = 0; reader.readChars(buf, HEADERSIZE); buf[HEADERSIZE]='\0'; // copy the pointer to the struct if (((buf[0] & 0xFF) != 0xFF) || ((buf[1] & 0xE0) != 0xE0)) //first 11 bits should be 1 { // seek until the first 0xFF has been done in Parse() this->Clean(); return false; } _tmpheader = reinterpret_cast<_mp3_header_internal *>(buf); bitrate_index = 0; switch (_tmpheader->id) { case 3: _mp3_header_output->version = MPEGVERSION_1; bitrate_index = 0; break; case 2: _mp3_header_output->version = MPEGVERSION_2; bitrate_index = 1; break; case 1: this->Clean(); return false; //wouldn't know how to handle it case 0: _mp3_header_output->version = MPEGVERSION_2_5; bitrate_index = 1; break; default: this->Clean(); return false; }; switch (_tmpheader->layer) { case 3: _mp3_header_output->layer = MPEGLAYER_I; break; case 2: _mp3_header_output->layer = MPEGLAYER_II; break; case 1: _mp3_header_output->layer = MPEGLAYER_III; break; case 0: this->Clean(); return false; //wouldn't know how to handle it default: this->Clean(); return false; //how can two unsigned bits be something else?? }; // mpegversion, layer and bitrate are all valid _mp3_header_output->bitrate = _mp3_bitrates[bitrate_index][3-_tmpheader->layer][_tmpheader->bitrate_index]; if (_mp3_header_output->bitrate == MP3BITRATE_FALSE) { this->Clean(); return false; } _mp3_header_output->frequency = _mp3_frequencies[_tmpheader->id][_tmpheader->frequency]; if (_mp3_header_output->frequency == MP3FREQUENCIES_Reserved) { this->Clean(); return false; } _mp3_header_output->privatebit = (bool)_tmpheader->private_bit; _mp3_header_output->copyrighted = (bool)_tmpheader->copyright; _mp3_header_output->original = (bool)_tmpheader->original; _mp3_header_output->crc = (Mp3_Crc)!(bool)_tmpheader->protection_bit; switch (_tmpheader->mode) { case 3: _mp3_header_output->channelmode = MP3CHANNELMODE_SINGLE_CHANNEL; break; case 2: _mp3_header_output->channelmode = MP3CHANNELMODE_DUAL_CHANNEL; break; case 1: _mp3_header_output->channelmode = MP3CHANNELMODE_JOINT_STEREO; break; case 0: _mp3_header_output->channelmode = MP3CHANNELMODE_STEREO; break; default: this->Clean(); return false; //wouldn't know how to handle it } if (_mp3_header_output->channelmode == MP3CHANNELMODE_JOINT_STEREO) { // these have a different meaning for different layers, better give them a generic name in the enum switch (_tmpheader->mode_ext) { case 3: _mp3_header_output->modeext = MP3MODEEXT_3; break; case 2: _mp3_header_output->modeext = MP3MODEEXT_2; break; case 1: _mp3_header_output->modeext = MP3MODEEXT_1; break; case 0: _mp3_header_output->modeext = MP3MODEEXT_0; break; default: this->Clean(); return false; //wouldn't know how to handle it } } else //it's valid to have a valid false one in this case, since it's only used with joint stereo _mp3_header_output->modeext = MP3MODEEXT_FALSE; switch (_tmpheader->emphasis) { case 3: _mp3_header_output->emphasis = MP3EMPHASIS_CCIT_J17; break; case 2: _mp3_header_output->emphasis = MP3EMPHASIS_Reserved; break; case 1: _mp3_header_output->emphasis = MP3EMPHASIS_50_15MS; break; case 0: _mp3_header_output->emphasis = MP3EMPHASIS_NONE; break; default: this->Clean(); return false; //wouldn't know how to handle it } //http://www.mp3-tech.org/programmer/frame_header.html if (_mp3_header_output->bitrate != MP3BITRATE_NONE && _mp3_header_output->frequency > 0) { switch(_mp3_header_output->layer) { case MPEGLAYER_I: // Layer 1 _mp3_header_output->framesize = 4 * (12 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0)); break; case MPEGLAYER_II: // Layer 2 _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0); break; case MPEGLAYER_III: // Layer 3 if(_mp3_header_output->version == MPEGVERSION_2_5) _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0); //Mpeg1 else _mp3_header_output->framesize = 72000 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0); //Mpeg2 + Mpeg2.5 break; case MPEGLAYER_FALSE: case MPEGLAYER_UNDEFINED: _mp3_header_output->framesize = 0; //unable to determine break; } // if (_mp3_header_output->layer == MPEGLAYER_I) // _mp3_header_output->framesize = fto_nearest_i((float)((48 * (float)_mp3_header_output->bitrate) / _mp3_header_output->frequency)) + (_tmpheader->padding_bit ? 4 : 0); // else // _mp3_header_output->framesize = fto_nearest_i((float)((144 * (float)_mp3_header_output->bitrate) / _mp3_header_output->frequency)) + (_tmpheader->padding_bit ? 1 : 0); } else _mp3_header_output->framesize = 0; //unable to determine const size_t CRCSIZE = 2; size_t sideinfo_len; if (_mp3_header_output->version == MPEGVERSION_1) /* MPEG 1 */ sideinfo_len = (_mp3_header_output->channelmode == MP3CHANNELMODE_SINGLE_CHANNEL) ? 4 + 17 : 4 + 32; else /* MPEG 2 */ sideinfo_len = (_mp3_header_output->channelmode == MP3CHANNELMODE_SINGLE_CHANNEL) ? 4 + 9 : 4 + 17; int vbr_header_offest = beg + sideinfo_len; int vbr_frames = 0; sideinfo_len += 2; // add two for the crc itself if ((_mp3_header_output->crc == MP3CRC_OK) && mp3size < sideinfo_len) _mp3_header_output->crc = MP3CRC_ERROR_SIZE; if (_mp3_header_output->crc == MP3CRC_OK) { char audiodata[38 + 1]; //+1 to hold the 0 char uint16 crc16; uint16 crcstored; _mp3_header_output->crc = MP3CRC_MISMATCH; //as a starting point, we assume the worst reader.setCur(beg); reader.readChars(audiodata, sideinfo_len); audiodata[sideinfo_len] = '\0'; crc16 = calcCRC(audiodata, sideinfo_len); beg = end; end = beg + CRCSIZE; reader.setCur(beg); crcstored = (uint16)io::readBENumber(reader, CRCSIZE); // a mismatch doesn't mean the file is unusable // it has just some bits in the wrong place if (crcstored == crc16) _mp3_header_output->crc = MP3CRC_OK; } // read xing/vbr header if present // derived from code in vbrheadersdk.zip // from http://www.xingtech.com/developer/mp3/ const size_t VBR_HEADER_MIN_SIZE = 8; // "xing" + flags are fixed const size_t VBR_HEADER_MAX_SIZE = 120; // frames, bytes, toc and scale are optional if (mp3size >= vbr_header_offest + VBR_HEADER_MIN_SIZE) { char vbrheaderdata[VBR_HEADER_MAX_SIZE+1]; //+1 to hold the 0 char unsigned char *pvbrdata = (unsigned char *)vbrheaderdata; // get fixed part of vbr header // and check if valid beg = vbr_header_offest; reader.setCur(beg); reader.readChars(vbrheaderdata, VBR_HEADER_MIN_SIZE); vbrheaderdata[VBR_HEADER_MIN_SIZE] = '\0'; if (pvbrdata[0] == 'X' && pvbrdata[1] == 'i' && pvbrdata[2] == 'n' && pvbrdata[3] == 'g') { pvbrdata += 4; // get vbr flags int vbr_flags = ExtractI4(pvbrdata); pvbrdata += 4; // read entire vbr header size_t vbr_header_size = VBR_HEADER_MIN_SIZE + ((vbr_flags & FRAMES_FLAG)? 4:0) + ((vbr_flags & BYTES_FLAG)? 4:0) + ((vbr_flags & TOC_FLAG)? 100:0) + ((vbr_flags & SCALE_FLAG)? 4:0); if (mp3size >= vbr_header_offest + vbr_header_size) { reader.readChars(&vbrheaderdata[VBR_HEADER_MIN_SIZE], vbr_header_size - VBR_HEADER_MIN_SIZE); vbrheaderdata[vbr_header_size] = '\0'; // get frames, bytes, toc and scale int vbr_filesize = 0; if (vbr_flags & FRAMES_FLAG) { vbr_frames = ExtractI4(pvbrdata); pvbrdata +=4; } if (vbr_flags & BYTES_FLAG) { vbr_filesize = ExtractI4(pvbrdata); pvbrdata +=4; } if (vbr_flags & TOC_FLAG) { // seek offsets // we are not using // for(i=0;i<100;i++) seek_offsets[i] = pvbrdata[i]; pvbrdata +=100; } if (vbr_flags & SCALE_FLAG) { pvbrdata +=4; } if (vbr_frames > 0) { _mp3_header_output->vbr_bitrate = (((vbr_filesize!=0) ? vbr_filesize : mp3size) / vbr_frames) * _mp3_header_output->frequency / 144; _mp3_header_output->vbr_bitrate -= _mp3_header_output->vbr_bitrate%1000; // round the bitrate: } } } } if (_mp3_header_output->framesize > 0 && mp3size >= _mp3_header_output->framesize) // this means bitrate is not none too { if (vbr_frames == 0) _mp3_header_output->frames = fto_nearest_i((float)mp3size / _mp3_header_output->framesize); else _mp3_header_output->frames = vbr_frames; // bitrate becomes byterate (per second) if divided by 8 if (_mp3_header_output->vbr_bitrate == 0) _mp3_header_output->time = fto_nearest_i( (float)mp3size / (_mp3_header_output->bitrate / 8) ); else _mp3_header_output->time = fto_nearest_i( (float)mp3size / (_mp3_header_output->vbr_bitrate / 8) ); } else { _mp3_header_output->frames = 0; _mp3_header_output->time = 0; } //if we got to here it's okay _mp3_header_output->datasize = reader.getEnd() - reader.getBeg(); return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/spec.cpp000066400000000000000000000043231516712004000246700ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "spec.h" ID3_V2Spec ID3_VerRevToV2Spec(uchar ver, uchar rev) { ID3_V2Spec spec = ID3V2_UNKNOWN; if (2 == ver) { if (0 == rev) spec = ID3V2_2_0; else if (1 == rev) spec = ID3V2_2_1; } else if (3 == ver) { if (0 == rev) spec = ID3V2_3_0; } else if (4 == ver) { if (0 == rev) spec = ID3V2_4_0; } return spec; } uchar ID3_V2SpecToVer(ID3_V2Spec spec) { uchar ver = 0; switch (spec) { case ID3V2_2_0: case ID3V2_2_1: ver = 2; break; case ID3V2_3_0: ver = 3; break; case ID3V2_4_0: ver = 4; break; default: break; } return ver; } uchar ID3_V2SpecToRev(ID3_V2Spec spec) { uchar rev = 0; switch (spec) { case ID3V2_4_0: rev = 0; break; case ID3V2_3_0: rev = 0; break; case ID3V2_2_1: rev = 1; break; case ID3V2_2_0: rev = 0; break; default: break; } return rev; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/spec.h000066400000000000000000000030051516712004000243310ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_SPEC_H_ #define _ID3LIB_SPEC_H_ #include ID3_V2Spec ID3_VerRevToV2Spec(uchar ver, uchar rev); uchar ID3_V2SpecToVer(ID3_V2Spec spec); uchar ID3_V2SpecToRev(ID3_V2Spec spec); #endif /* _ID3LIB_SPEC_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag.cpp000066400000000000000000000461431516712004000245170ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include #include using namespace dami; /** \mainpage id3lib Library Documentation ** ** \section tutorial Quick Tutorial ** ** This tutorial will quickly get you up and running with id3lib. ** ** \subsection download Downloading id3lib ** ** First, id3lib must be a part of your development environment. The latest ** files can always be downloaded from the id3lib homepage. ** ** \subsection include Preparing your source code ** ** To use the basic functionality of id3lib in your C++ code, a single ** \c #include is necessary. ** ** \code ** #include ** \endcode ** ** There are other files that must be included to access more advanced ** functionality, but this will do most of the core functionality. ** ** In straight C the \c #include is slightly different: ** ** \code ** #include ** \endcode ** ** \subsection creation Creating a tag ** ** Almost all functionality occurs via an ID3_Tag object. An ID3_Tag object ** basically encapsulates two things: a collection of ID3_Frame objects and ** file information. The goal is to populate an ID3_Tag object with ID3_Frame ** objects, and the easiest way to do this is to associate the tag with a ** file. This is done primarily via the ID3_Tag constructor, like so: ** ** \code ** ID3_Tag myTag("song.mp3"); ** \endcode ** ** This constructor links, or associates, the object \c myTag with the file ** "song.mp3". In doing so, the tagging information from "song.mp3" is parsed ** and added to \c myTag. This association can also be accomplished by creating ** an empty tag and making an explicit call to Link(). ** ** \code ** ID3_Tag myTag; ** myTag.Link("song.mp3"); ** \endcode ** ** This is similar to the interface in straight C, where the tag creation and ** tag link must be done separately: ** ** \code ** ID3Tag *myTag = ID3Tag_New(); ** ID3Tag_Link(myTag, "song.mp3"); ** \endcode ** ** The default behavior of Link() is to parse all possible tagging information ** and convert it into ID3v2 frames. The tagging information parsed can be ** limited to a particular type (or types) of tag by passing an ID3_TagType ** (or combination of ID3_TagTypes). For example, to read only the ID3v1 ** tag, pass in the constant ID3TT_ID3V1. ** ** \code ** myTag.Link("song.mp3", ID3TT_ID3V1); ** \endcode ** ** The C equivalent is this: ** ** \code ** ID3Tag_LinkWithFlags(myTag, "song.mp3", ID3TT_ID3V1); ** \endcode ** ** Another example would be to read in all tags that could possibly appear at ** the end of the file. Here are the C++ and C examples: ** ** \code ** myTag.Link("song.mp3", ID3TT_ID3V1 | ID3TT_LYRICS3V2 | ID3TT_MUSICMATCH); // C++ ** ID3Tag_LinkWithFlags(myTag, "song.mp3", ID3TT_ID3V1 | ID3TT_LYRICS3V2 | ID3TT_MUSICMATCH); // C ** \endcode ** ** \section accessing Accessing the Tag Data ** ** After linking with a file, the object \c myTag now contains some or all of ** the tagging information present in the file "song.mp3", represented as ** ID3v2 frames. How can that information be accessed? There are a variety of ** ways to do this. One is to iterate through all the frames in the tag. ** ** \code ** // use an std::auto_ptr here to handle object cleanup automatically ** ID3_Tag::Iterator* iter = myTag.CreateIterator(); ** ID3_Frame* myFrame = NULL; ** while (NULL != (myFrame = iter->GetNext())) ** { ** // do something with myFrame ** } ** delete iter; ** \endcode ** ** Another way to access tagging information is by searching for specific ** frames using the Find() method. For example, the album frame can be found ** in the following manner: ** ** \code ** ID3_Frame* myFrame = myTag.Find(ID3FID_ALBUM); ** if (NULL != myFrame) ** { ** // do something with myFrame ** } ** \endcode ** ** The Find() method can be used to search for frames with specific ** information. For example, the following code can be used to find the frame ** with the title "Nirvana". ** ** \code ** ID3_Frame* myFrame = myTag.Find(ID3FID_TITLE, ID3FN_TEXT, "Nirvana"))); ** if (NULL != myFrame) ** { ** // do something with myFrame ** } ** \endcode ** ** As indicated, the Find() method will return a NULL pointer if no such frame ** can be found. If more than one frame meets the search criteria, subsequent ** calls to Find() with the same parameters will return the other matching ** frames. The Find() method is guaranteed to return all matching frames ** before it wraps around to return the first matching frame. ** ** All ID3_Frame objects are comprised of a collection of ID3_Field objects. ** These fields can represent text, numbers, or binary data. As with frames, ** fields can be accessed in a variety of manners. The fields of a frame ** can be iterated over in much the same manner of the frames of a tag. ** ** \code ** // use an std::auto_ptr here to handle object cleanup automatically ** ID3_Frame::Iterator* iter = myFrame->CreateIterator(); ** ID3_Field* myField = NULL; ** while (NULL != (myField = iter->GetNext())) ** { ** // do something with myField ** } ** delete iter; ** \endcode ** ** If you know which field type you're looking for, you can access it ** directly. ** ** \code ** ID3_Field* myField = myFrame->GetField(ID3FN_TEXT); ** while (NULL != myField) ** { ** // do something with myField ** } ** \endcode ** ** Note: The ID3_FrameInfo class provides information about the frame types known ** to id3lib. ** ** The ID3_Field represents a single piece of data within an ID3v2 frame. As ** mentioned, an ID3_Field can represent three possible types of ** data: integers, binary data, and text strings. The type of a particular ** field object is immutable; it is determined at the time of its construction ** (almost always when a frame is constructed) and can't be changed. If in ** doubt, the field type can be accessed through its GetType() method. ** ** Having an ID3_Field object isn't much use if you cannot access and/or ** alter its data. Luckily, the id3lib API provides overloaded \c Set and ** \c Get methods for all data types. ** ** If the field is an integer, the following methods can be used to access ** the data. ** ** \code ** uint32 val = myField->Get(); ** myField->Set(5); ** (*myField) = 10; ** \endcode ** ** All text data is accessed in a slightly different manner. The following ** code example best illustrates these differences. ** ** \code ** // for ascii strings ** char str1[1024]; ** const char* p1 = "My String"; ** const char* p2 = "My Other String"; ** ** myField->Set(p1); ** (*myField) = p2; // equivalent to Set ** ** myField->Get(str1, 1024); // copies up to 1024 bytes of the field data into str1 ** p1 = myField->GetRawText(); // returns a pointer to the internal string ** \endcode ** ** Binary data is similar to text data, except that its base type is a pointer ** to an unsigned, rather than a signed, char. ** ** \code ** // for binary strings ** uchar data[1024]; ** const uchar *p1 = getBinaryData(); // not an id3lib function ** size_t size = getBinarySize(); // not an id3lib function ** ** myField->Set(p1, size); ** ** myField->Get(data, 1024); // copies up to 1024 bytes of the field data into str1 ** p1 = myField->GetRawBinary(); // returns a pointer to the internal string ** \endcode ** ** \section updating Updating the Tag ** ** When you're ready to save your changes back to the file, a single call to ** Update() is sufficient. ** ** \code ** tag.Update(); ** \endcode ** **/ /** \class ID3_Tag tag.h id3/tag.h ** \brief The representative class of an id3 tag. ** ** The ID3_Tag is, at its simplest, a container for ID3v2 frames. At its ** most complicated, it's a kitchen-sink, monolithic "catch-all" class for ** handling almost every task associated with creating, parsing, rendering, ** and manipulating digital audio data using id3lib. ** ** This simple \c #include does it all. In order to read an existing tag, do ** the following: ** ** \code ** ID3_Tag myTag; ** myTag.Link("something.mp3"); ** \endcode ** ** That is all there is to it. Now all you have to do is use the Find() ** method to locate the frames you are interested in is the following: ** ** \code ** ID3_Frame* myFrame = myTag.Find(ID3FID_TITLE); ** if (NULL != myFrame) ** { ** const char* title = myFrame->GetField(ID3FN_TEXT)->GetText(); ** cout << "Title: " << title << endl; ** } ** \endcode ** ** This code snippet locates the ID3FID_TITLE frame and displays the ** text field. ** ** When using the ID3_Tag::Link() method, you automatically gain access to any ** ID3v1/1.1, ID3v2, Lyrics3 v2.0, and MusicMatch tags present in the file. ** The class will automaticaly parse and convert any of these foreign tag ** formats into ID3v2 tags. Also, id3lib will correctly parse any correctly ** formatted 'CDM' frames from the unreleased ID3v2 2.01 draft specification. ** ** \author Dirk Mahoney ** \version $Id$ ** \sa ID3_Frame ** \sa ID3_Field ** \sa ID3_Err **/ /** Default constructor; it can accept an optional filename as a parameter. ** ** If this file exists, it will be opened and all id3lib-supported tags will ** be parsed and converted to ID3v2 if necessary. After the conversion, the ** file will remain unchanged, and will continue to do so until you use the ** Update() method on the tag (if you choose to Update() at all). ** ** \param name The filename of the mp3 file to link to **/ ID3_Tag::ID3_Tag(const char *name, flags_t flags) : ID3_Container(new ID3_TagImpl(name, flags)) { _impl = (ID3_TagImpl *) ID3_Container::_impl; } /** Standard copy constructor. ** ** \param tag What is copied into this tag **/ ID3_Tag::ID3_Tag(const ID3_Tag &tag) : ID3_Container(new ID3_TagImpl(tag)) { _impl = (ID3_TagImpl *) ID3_Container::_impl; } ID3_Tag::~ID3_Tag() { delete _impl; } /** Turns unsynchronization on or off, dependant on the value of the boolean ** parameter. ** ** If you call this method with 'false' as the parameter, the ** binary tag will not be unsync'ed, regardless of whether the tag should ** be. This option is useful when the file is only going to be used by ** ID3v2-compliant software. See the ID3v2 standard document for futher ** details on unsync. ** ** Be default, tags are created without unsync. ** ** \code ** myTag.SetUnsync(false); ** \endcode ** ** \param bSync Whether the tag should be unsynchronized **/ bool ID3_Tag::SetUnsync(bool b) { return _impl->SetUnsync(b); } /** Turns extended header rendering on or off, dependant on the value of the ** boolean parameter. ** ** This option is currently ignored as id3lib doesn't yet create extended ** headers. This option only applies when rendering tags for ID3v2 versions ** that support extended headers. ** ** \code ** myTag.SetExtendedHeader(true); ** \endcode ** ** \param bExt Whether to render an extended header **/ bool ID3_Tag::SetExtendedHeader(bool ext) { return _impl->SetExtended(ext); } /** Turns padding on or off, dependant on the value of the boolean ** parameter. ** ** When using ID3v2 tags in association with files, id3lib can optionally ** add padding to the tags to ensure minmal file write times when updating ** the tag in the future. ** ** When the padding option is switched on, id3lib automatically creates ** padding according to the 'ID3v2 Programming Guidelines'. Specifically, ** enough padding will be added to round out the entire file (song plus ** tag) to an even multiple of 2K. Padding will only be created when the ** tag is attached to a file and that file is not empty (aside from a ** pre-existing tag). ** ** id3lib's addition to the guidelines for padding, is that if frames are ** removed from a pre-existing tag (or the tag simply shrinks because of ** other reasons), the new tag will continue to stay the same size as the ** old tag (with padding making the difference of course) until such time as ** the padding is greater than 4K. When this happens, the padding will be ** reduced and the new tag will be smaller than the old. ** ** By default, padding is switched on. ** ** \code ** myTag.SetPadding(false); ** \endcode ** ** \param bPad Whether or not render the tag with padding. **/ bool ID3_Tag::SetPadding(bool pad) { return _impl->SetPadding(pad); } bool ID3_Tag::SetExperimental(bool exp) { return _impl->SetExperimental(exp); } bool ID3_Tag::GetUnsync() const { return _impl->GetUnsync(); } bool ID3_Tag::GetExtendedHeader() const { return _impl->GetExtended(); } bool ID3_Tag::GetExperimental() const { return _impl->GetExperimental(); } bool ID3_Tag::Parse(ID3_Reader& reader) { return id3::v2::parse(*_impl, reader); } size_t ID3_Tag::Parse(const uchar* buffer, size_t bytes) { ID3_MemoryReader mr(buffer, bytes); ID3_Reader::pos_type beg = mr.getCur(); id3::v2::parse(*_impl, mr); return mr.getEnd() - beg; } /** Renders the tag and writes it to the attached file; the type of tag ** rendered can be specified as a parameter. The default is to update only ** the ID3v2 tag. See the ID3_TagType enumeration for the constants that ** can be used. ** ** Make sure the rendering parameters are set before calling the method. ** See the Link documentation for an example of this method in use. ** ** \sa ID3_TagType ** \sa Link ** \param tt The type of tag to update. **/ /** Renders a binary image of the tag into the supplied buffer. ** ** See Size() for an example. This method returns the actual number of the ** bytes of the buffer used to store the tag. This will be no more than the ** size of the buffer itself, because Size() over estimates the required ** buffer size when padding is enabled. ** ** Before calling this method, it is advisable to call HasChanged() first as ** this will let you know whether you should bother rendering the tag. ** ** @see ID3_IsTagHeader ** @see ID3_Tag#HasChanged ** @return The actual number of the bytes of the buffer used to store the ** tag ** @param buffer The buffer that will contain the rendered tag. **/ size_t ID3_Tag::Render(uchar* buffer, ID3_TagType tt) const { ID3_MemoryWriter mw(buffer, -1); return this->Render(mw, tt); } size_t ID3_Tag::Render(ID3_Writer& writer, ID3_TagType tt) const { ID3_Writer::pos_type beg = writer.getCur(); if (ID3TT_ID3V2 & tt) { ID3_Err err = id3::v2::render(writer, *this); if (err != ID3E_NoError) _impl->SetLastError(err); } else if (ID3TT_ID3V1 & tt) { id3::v1::render(writer, *this); } return writer.getCur() - beg; } /** Attaches a file to the tag, parses the file, and adds any tag information ** found in the file to the tag. ** ** Use this method if you created your ID3_Tag object without supplying a ** parameter to the constructor (maybe you created an array of ID3_Tag ** pointers). This is the preferred method of interacting with files, since ** id3lib can automatically do things like parse foreign tag formats and ** handle padding when linked to a file. When a tag is linked to a file, you ** do not need to use the Size(), Render(const uchar*, size_t), or ** Parse(ID3_Reader&) methods or the IsV2Tag(ID3_Reader&) static function-- ** id3lib will take care of those details for you. The single parameter is a ** pointer to a file name. ** ** Link returns the size of the the ID3v2 tag (if any) that begins the file. ** ** \code ** ID3_Tag myTag; ** myTag.Link("mysong.mp3"); ** ** // do whatever we want with the tag ** // ... ** ** // setup all our rendering parameters ** myTag->SetUnsync(false); ** myTag->SetExtendedHeader(true); ** myTag->SetPadding(true); ** ** // write any changes to the file ** myTag->Update() ** ** \endcode ** ** @see IsV2Tag ** @param fileInfo The filename of the file to link to. **/ size_t ID3_Tag::Link(const char *fileInfo, flags_t flags) { return _impl->Link(fileInfo, flags); } /** ** Same as above, but takes a ID3_Reader as argument. */ size_t ID3_Tag::Link(ID3_Reader &reader, flags_t flags) { return _impl->Link(reader, flags); } flags_t ID3_Tag::Update(flags_t flags) { return _impl->Update(flags); } /** ** Get's the mp3 Info like bitrate, mpeg version, etc. ** Can be run after Link() ** **/ const Mp3_Headerinfo* ID3_Tag::GetMp3HeaderInfo() const { return _impl->GetMp3HeaderInfo(); } /** ** Returns the last error ** Can be run after Link() and Update() ** Will be reset to ID3E_NoError after being called for. ** **/ ID3_Err ID3_Tag::GetLastError() { return _impl->GetLastError(); } /** Strips the tag(s) from the attached file. The type of tag stripped ** can be specified as a parameter. The default is to strip all tag types. ** ** \param tt The type of tag to strip ** \sa ID3_TagType **/ flags_t ID3_Tag::Strip(flags_t flags) { return _impl->Strip(flags); } size_t ID3_Tag::GetPrependedBytes() const { return _impl->GetPrependedBytes(); } size_t ID3_Tag::GetAppendedBytes() const { return _impl->GetAppendedBytes(); } size_t ID3_Tag::GetFileSize() const { return _impl->GetFileSize(); } const char* ID3_Tag::GetFileName() const { return _impl->GetFileName().c_str(); } ID3_Tag& ID3_Tag::operator=( const ID3_Tag &rTag ) { if (this != &rTag) { *_impl = rTag; } return *this; } bool ID3_Tag::HasTagType(ID3_TagType tt) const { return _impl->HasTagType(tt); } /** Analyses a buffer to determine if we have a valid ID3v2 tag header. ** If so, return the total number of bytes (including the header) to ** read so we get all of the tag **/ size_t ID3_Tag::IsV2Tag(const uchar* const data) { ID3_MemoryReader mr(data, ID3_TagHeader::SIZE); return ID3_TagImpl::IsV2Tag(mr); } size_t ID3_Tag::IsV2Tag(ID3_Reader& reader) { return ID3_TagImpl::IsV2Tag(reader); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_file.cpp000066400000000000000000000276411516712004000255200ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include #include using namespace dami; #if !defined HAVE_MKSTEMP # include #endif #if defined HAVE_UNISTD_H # include #endif #if defined HAVE_SYS_STAT_H # include #endif #if defined _WIN32 # include static int truncate(const char *path, size_t length) { int result = -1; HANDLE fh; fh = ::CreateFileA(path, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != fh) { SetFilePointer(fh, length, NULL, FILE_BEGIN); SetEndOfFile(fh); CloseHandle(fh); result = 0; } return result; } #elif defined(macintosh) static int truncate(const char *path, size_t length) { /* Not implemented on the Mac. */ return -1; } #endif size_t ID3_TagImpl::Link(const char *fileInfo, flags_t tag_types) { _tags_to_parse.set(tag_types); if (NULL == fileInfo) return 0; _file_name = fileInfo; _changed = true; this->ParseFile(); return this->GetPrependedBytes(); } /* Used for streaming: */ size_t ID3_TagImpl::Link(ID3_Reader &reader, flags_t tag_types) { _tags_to_parse.set(tag_types); _file_name = ""; _changed = true; this->ParseReader(reader); return this->GetPrependedBytes(); } size_t RenderV1ToFile(ID3_TagImpl &tag, fstream &file) { if (!file) return 0; // Heck no, this is stupid. If we do not read in an initial V1(.1) // header then we are constantly appending new V1(.1) headers. Files // can get very big that way if we never overwrite the old ones. // if (ID3_V1_LEN > tag.GetAppendedBytes()) - Daniel Hazelbaker if (ID3_V1_LEN > tag.GetFileSize()) { file.seekp(0, ios::end); } else { // We want to check if there is already an id3v1 tag, so we can write over // it. First, seek to the beginning of any possible id3v1 tag file.seekg(0-ID3_V1_LEN, ios::end); char sID[ID3_V1_LEN_ID]; // Read in the TAG characters file.read(sID, ID3_V1_LEN_ID); // If those three characters are TAG, then there's a preexisting id3v1 tag, // so we should set the file cursor so we can overwrite it with a new tag. // Otherwise, set the cursor to the end of the file so we can append on // the new tag. if (memcmp(sID, "TAG", ID3_V1_LEN_ID) == 0) file.seekp(0 - ID3_V1_LEN, ios::end); else file.seekp(0, ios::end); } ID3_IOStreamWriter out(file); id3::v1::render(out, tag); return ID3_V1_LEN; } size_t RenderV2ToFile(const ID3_TagImpl &tag, fstream &file) { ID3_Err err = ID3E_NoError; ID3D_NOTICE( "RenderV2ToFile: starting" ); if (!file) { ID3D_WARNING("RenderV2ToFile: error in file"); return 0; } String tagString; io::StringWriter writer(tagString); err = id3::v2::render(writer, tag); if (err != ID3E_NoError) return (size_t) err; // impossible size, will make caller be able to set _last_error ID3D_NOTICE( "RenderV2ToFile: rendered v2" ); const char *tagData = tagString.data(); size_t tagSize = tagString.size(); // if the new tag fits perfectly within the old and the old one // actually existed (ie this isn't the first tag this file has had) if ((!tag.GetPrependedBytes() && !ID3_GetDataSize(tag)) || (tagSize == tag.GetPrependedBytes())) { file.seekp(0, ios::beg); file.write(tagData, tagSize); } else { String filename = tag.GetFileName(); String sTmpSuffix = ".XXXXXX"; if (filename.size() + sTmpSuffix.size() >= ID3_PATH_LENGTH) { /* TODO: log this */ return (size_t)ID3E_NoFile; } char sTempFile[ID3_PATH_LENGTH] = { 0 }; strncpy(sTempFile, filename.c_str(), ID3_PATH_LENGTH - 1); strncat(sTempFile, sTmpSuffix.c_str(), ID3_PATH_LENGTH - strlen(sTempFile) - 1); #if ((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) // This section is for Windows folk && gcc 3.x folk fstream tmpOut; err = createFile(sTempFile, tmpOut); if (err != ID3E_NoError) { tmpOut.close(); remove(sTempFile); return (size_t) err; // impossible size, will make caller be able to set _last_error } tmpOut.write(tagData, tagSize); file.seekg(tag.GetPrependedBytes(), ios::beg); char tmpBuffer[BUFSIZ]; while (!file.eof()) { file.read(tmpBuffer, BUFSIZ); size_t nBytes = file.gcount(); tmpOut.write(tmpBuffer, nBytes); } #else // ((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) // else we gotta make a temp file, copy the tag into it, copy the // rest of the old file after the tag, delete the old file, rename // this new file to the old file's name and update the handle int fd = mkstemp(sTempFile); if (fd < 0) { remove(sTempFile); return (size_t) ID3E_NoFile; // impossible size, will make caller be able to set _last_error } ofstream tmpOut(fd); if (!tmpOut) { tmpOut.close(); remove(sTempFile); /* TODO: log this */ return (size_t) ID3E_ReadOnly; //impossible size, will make caller be able to set _last_error } tmpOut.write(tagData, tagSize); file.seekg(tag.GetPrependedBytes(), ios::beg); uchar tmpBuffer[BUFSIZ]; while (file) { file.read(tmpBuffer, BUFSIZ); size_t nBytes = file.gcount(); tmpOut.write(tmpBuffer, nBytes); } close(fd); // closes the file #endif // ((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) tmpOut.close(); file.close(); // the following sets the permissions of the new file // to be the same as the original #if defined(HAVE_SYS_STAT_H) struct stat fileStat; if(stat(filename.c_str(), &fileStat) == 0) { #endif // defined(HAVE_SYS_STAT_H) remove(filename.c_str()); rename(sTempFile, filename.c_str()); #if defined(HAVE_SYS_STAT_H) chmod(filename.c_str(), fileStat.st_mode); } #endif // defined(HAVE_SYS_STAT_H) file.clear(); // to clear the eof mark err = openWritableFile(filename, file); if (err != ID3E_NoError) { return (size_t) err; // impossible size, will make caller be able to set _last_error } } return tagSize; } flags_t ID3_TagImpl::Update(flags_t ulTagFlag) { flags_t tags = ID3TT_NONE; fstream file; String filename = this->GetFileName(); _last_error = openWritableFile(filename, file); _file_size = getFileSize(file); if (_last_error == ID3E_NoFile) _last_error = createFile(filename, file); if (_last_error == ID3E_ReadOnly) return tags; if ((ulTagFlag & ID3TT_ID3V2) && this->HasChanged()) { ID3_V2Spec spec2use; if (this->UserUpdatedSpec) spec2use = this->GetSpec() < ID3V2_3_0 ? ID3V2_LATEST : this->GetSpec(); // if the spec is too old, upgrade anyway. And never use experimental ones else spec2use = ID3V2_LATEST; // write ID3V2_LATEST as default this->SetSpec(spec2use); this->checkFrames(); _prepended_bytes = RenderV2ToFile(*this, file); if (_prepended_bytes < 17) // 17 = minimal tag size, errors should not be higher numbered than 16 { // must be an error _last_error = (ID3_Err)_prepended_bytes; _prepended_bytes = 0; } if (_prepended_bytes) tags |= ID3TT_ID3V2; } if ((ulTagFlag & ID3TT_ID3V1) && (!this->HasTagType(ID3TT_ID3V1) || this->HasChanged())) { size_t tag_bytes = RenderV1ToFile(*this, file); if (tag_bytes) { // only add the tag_bytes if there wasn't an id3v1 tag before if (! _file_tags.test(ID3TT_ID3V1)) _appended_bytes += tag_bytes; tags |= ID3TT_ID3V1; } } _changed = false; _file_tags.add(tags); _file_size = getFileSize(file); file.close(); return tags; } flags_t ID3_TagImpl::Strip(flags_t ulTagFlag) { flags_t ulTags = ID3TT_NONE; const size_t data_size = ID3_GetDataSize(*this); // First remove the v2 tag, if requested if (ulTagFlag & ID3TT_PREPENDED & _file_tags.get()) { fstream file; _last_error = openWritableFile(this->GetFileName(), file); if (ID3E_NoError != _last_error) return ulTags; _file_size = getFileSize(file); // We will remove the id3v2 tag in place: since it comes at the beginning // of the file, we'll effectively move all the data that comes after the // tag back n bytes, where n is the size of the id3v2 tag. Once we've // copied the data, we'll truncate the file. file.seekg(this->GetPrependedBytes(), ios::beg); uchar aucBuffer[BUFSIZ]; // The nBytesRemaining variable indicates how many bytes are to be copied size_t nBytesToCopy = data_size; // Here we increase the nBytesToCopy by the size of any tags that appear // at the end of the file if we don't want to strip them if (!(ulTagFlag & ID3TT_APPENDED)) nBytesToCopy += this->GetAppendedBytes(); // The nBytesRemaining variable indicates how many bytes are left to be // moved in the actual file. // The nBytesCopied variable keeps track of how many actual bytes were // copied (or moved) so far. size_t nBytesRemaining = nBytesToCopy, nBytesCopied = 0; while (!file.eof()) { size_t nBytesToRead = min((unsigned int)(nBytesRemaining - nBytesCopied), (unsigned int)BUFSIZ); file.read((char *)aucBuffer, nBytesToRead); size_t nBytesRead = file.gcount(); if (nBytesRead != nBytesToRead) { // TODO: log this //cerr << "--- attempted to write " << nBytesRead << " bytes, " // << "only wrote " << nBytesWritten << endl; } if (nBytesRead > 0) { long offset = nBytesRead + this->GetPrependedBytes(); file.seekp(-offset, ios::cur); file.write((char *)aucBuffer, nBytesRead); file.seekg(this->GetPrependedBytes(), ios::cur); nBytesCopied += nBytesRead; } if (nBytesCopied == nBytesToCopy || nBytesToRead < BUFSIZ) break; } file.close(); } size_t nNewFileSize = data_size; if ((_file_tags.get() & ID3TT_APPENDED) && (ulTagFlag & ID3TT_APPENDED)) { ulTags |= _file_tags.get() & ID3TT_APPENDED; } else { // if we're not stripping the appended tags, be sure to increase the file // size by those bytes nNewFileSize += this->GetAppendedBytes(); } if ((ulTagFlag & ID3TT_PREPENDED) && (_file_tags.get() & ID3TT_PREPENDED)) { // If we're stripping the ID3v2 tag, there's no need to adjust the new // file size, since it doesn't account for the ID3v2 tag size ulTags |= _file_tags.get() & ID3TT_PREPENDED; } else { // add the original prepended tag size since we don't want to delete it, // and the new file size represents the file size _not_ counting the ID3v2 // tag nNewFileSize += this->GetPrependedBytes(); } if (ulTags && (truncate(_file_name.c_str(), nNewFileSize) == -1)) { /* TODO: log this */ _last_error = ID3E_NoFile; return 0; } _prepended_bytes = (ulTags & ID3TT_PREPENDED) ? 0 : _prepended_bytes; _appended_bytes = (ulTags & ID3TT_APPENDED) ? 0 : _appended_bytes; _file_size = data_size + _prepended_bytes + _appended_bytes; _changed = _file_tags.remove(ulTags) || _changed; return ulTags; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_impl.cpp000066400000000000000000000133641516712004000255370ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_SYS_PARAM_H # include #endif #include "tag_impl.h" #include using namespace dami; size_t ID3_TagImpl::IsV2Tag(ID3_Reader &reader) { io::ExitTrigger et(reader); size_t tagSize = 0; String id = io::readText(reader, ID3_TagHeader::ID_SIZE); String ver = io::readText(reader, 2); /* Read flags byte. */ reader.readChar(); String size = io::readText(reader, 4); if (id == ID3_TagHeader::ID && (uchar) ver [0] < 0xFF && (uchar) ver [1] < 0xFF && (uchar) size[0] < 0x80 && (uchar) size[1] < 0x80 && (uchar) size[2] < 0x80 && (uchar) size[3] < 0x80) { io::StringReader sr(size); tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE; } else if (id != ID3_TagHeader::ID) ID3D_NOTICE( "*** IsV2Tag: Not an id3v2 tag header" ); else if ((uchar) ver[0] >= 0xFF) ID3D_NOTICE( "*** IsV2Tag: Major offset" ); else if ((uchar) ver[1] >= 0xFF) ID3D_NOTICE( "*** ISV2Tag: Minor offset" ); else if ((uchar) size[0] >= 0x80) ID3D_NOTICE( "*** ISV2Tag: 1st size offset" ); else if ((uchar) size[1] >= 0x80) ID3D_NOTICE( "*** ISV2Tag: 2nd size offset" ); else if ((uchar) size[2] >= 0x80) ID3D_NOTICE( "*** ISV2Tag: 3rd size offset" ); else if ((uchar) size[3] >= 0x80) ID3D_NOTICE( "*** ISV2Tag: 4th size offset" ); else ID3D_NOTICE( "*** shouldn't get here!" ); return tagSize; } ID3_TagImpl::ID3_TagImpl(const char *name, flags_t flags) : _file_name(), _file_size(0), _prepended_bytes(0), _appended_bytes(0), _is_file_writable(false), _mp3_info(NULL) // need to do this before this->Clear() { this->Clear(); if (name) { this->Link(name, flags); } } ID3_TagImpl::ID3_TagImpl(const ID3_Tag &tag) : _file_name(), _file_size(0), _prepended_bytes(0), _appended_bytes(0), _is_file_writable(false), _mp3_info(NULL) // need to do this before this->Clear() { *this = tag; } ID3_TagImpl::~ID3_TagImpl() { this->Clear(); } void ID3_TagImpl::Clear() { ID3_ContainerImpl::Clear(); _is_padded = true; _hdr.Clear(); _hdr.SetSpec(ID3V2_DEFAULT); _tags_to_parse.clear(); if (_mp3_info) { delete _mp3_info; // Also deletes _mp3_header _mp3_info = NULL; } _file_name = ""; _last_error = ID3E_NoError; _changed = true; } ID3_Err ID3_TagImpl::GetLastError() { ID3_Err err = _last_error; _last_error = ID3E_NoError; return err; } bool ID3_TagImpl::SetSpec(ID3_V2Spec spec) { bool changed = _hdr.SetSpec(spec); ID3_ContainerImpl::SetSpec(spec); _changed = _changed || changed; return changed; } ID3_V2Spec ID3_TagImpl::GetSpec() const { return _hdr.GetSpec(); } bool ID3_TagImpl::SetUnsync(bool b) { bool changed = _hdr.SetUnsync(b); _changed = changed || _changed; return changed; } bool ID3_TagImpl::SetExtended(bool ext) { bool changed = _hdr.SetExtended(ext); _changed = changed || _changed; return changed; } bool ID3_TagImpl::SetExperimental(bool exp) { bool changed = _hdr.SetExperimental(exp); _changed = changed || _changed; return changed; } bool ID3_TagImpl::GetUnsync() const { return _hdr.GetUnsync(); } bool ID3_TagImpl::GetExtended() const { return _hdr.GetExtended(); } bool ID3_TagImpl::GetExperimental() const { return _hdr.GetExperimental(); } bool ID3_TagImpl::GetFooter() const { return _hdr.GetFooter(); } size_t ID3_TagImpl::GetExtendedBytes() const { /* Returns the number of bytes this lib will write, is only called by id3::v2::render. */ if (this->GetExtended()) { if (this->GetSpec() == ID3V2_4_0) return 6; // minimal ID3v2.4 ext header size else if (this->GetSpec() == ID3V2_3_0) return 10; // minimal ID3v2.3 ext header size else return 0; // not implemented } return 0; } bool ID3_TagImpl::SetPadding(bool pad) { bool changed = (_is_padded != pad); _changed = changed || _changed; if (changed) _is_padded = pad; return changed; } ID3_TagImpl &ID3_TagImpl::operator=(const ID3_Tag &rTag) { this->Clear(); this->SetSpec(rTag.GetSpec()); this->SetUnsync(rTag.GetUnsync()); this->SetExtended(rTag.GetExtendedHeader()); this->SetExperimental(rTag.GetExperimental()); ID3_Tag::ConstIterator *iter = rTag.CreateIterator(); const ID3_Frame *frame = NULL; while (NULL != (frame = iter->GetNext())) { this->AttachFrame(new ID3_Frame(*frame)); } delete iter; return *this; } size_t ID3_GetDataSize(const ID3_TagImpl &tag) { return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_impl.h000066400000000000000000000107751516712004000252070ustar00rootroot00000000000000// -*- C++ -*- // $Id$ // id3lib: a software library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #ifndef _ID3LIB_TAG_IMPL_H_ #define _ID3LIB_TAG_IMPL_H_ #include #include "container_impl.h" #include "header_tag.h" #include "mp3_header.h" class ID3_Reader; class ID3_Writer; namespace dami { namespace id3 { namespace v1 { bool parse(ID3_TagImpl&, ID3_Reader&); void render(ID3_Writer&, const ID3_TagImpl&); }; namespace v2 { bool parse(ID3_TagImpl& tag, ID3_Reader& rdr); ID3_Err render(ID3_Writer& writer, const ID3_TagImpl& tag); }; }; namespace lyr3 { namespace v1 { bool parse(ID3_TagImpl&, ID3_Reader&); }; namespace v2 { bool parse(ID3_TagImpl&, ID3_Reader&); }; }; namespace mm { bool parse(ID3_TagImpl&, ID3_Reader&); }; }; class ID3_TagImpl : public ID3_ContainerImpl { public: ID3_TagImpl(const char *name = NULL, flags_t = (flags_t) ID3TT_ALL); ID3_TagImpl(const ID3_Tag &tag); virtual ~ID3_TagImpl(); void Clear(); size_t Size() const; bool SetUnsync(bool); bool SetExtended(bool); bool SetExperimental(bool); bool SetPadding(bool); bool GetUnsync() const; bool GetExtended() const; bool GetExperimental() const; bool GetFooter() const; size_t GetExtendedBytes() const; size_t Link(const char *fileInfo, flags_t = (flags_t) ID3TT_ALL); size_t Link(ID3_Reader &reader, flags_t = (flags_t) ID3TT_ALL); flags_t Update(flags_t = (flags_t) ID3TT_ALL); flags_t Strip(flags_t = (flags_t) ID3TT_ALL); size_t GetPrependedBytes() const { return _prepended_bytes; } size_t GetAppendedBytes() const { return _appended_bytes; } size_t GetFileSize() const { return _file_size; } const dami::String &GetFileName() const { return _file_name; } ID3_TagImpl &operator =(const ID3_Tag &); bool HasTagType(ID3_TagType tt) const { return _file_tags.test(tt); } ID3_V2Spec GetSpec() const; bool SetSpec(ID3_V2Spec); static size_t IsV2Tag(ID3_Reader &); ID3_Err GetLastError(); void SetLastError(ID3_Err err) { _last_error = err; } const Mp3_Headerinfo *GetMp3HeaderInfo() const { if (_mp3_info) return _mp3_info->GetMp3HeaderInfo(); else return NULL; } /* Deprecated! */ size_t PaddingSize(size_t) const; protected: void ParseFile(); void ParseReader(ID3_Reader &reader); private: ID3_TagHeader _hdr; // information relevant to the tag header bool _is_padded; // add padding to tags? mutable bool _changed; // has tag changed since last parse or render? // file-related member variables dami::String _file_name; // name of the file we are linked to size_t _file_size; // the size of the file (without any tag(s)) size_t _prepended_bytes; // number of tag bytes at start of file size_t _appended_bytes; // number of tag bytes at end of file bool _is_file_writable; // is the associated file (via Link) writable? ID3_Flags _tags_to_parse; // which tag types should attempt to be parsed ID3_Flags _file_tags; // which tag types does the file contain Mp3Info *_mp3_info; // class used to retrieve _mp3_header ID3_Err _last_error; //storage place for last error }; size_t ID3_GetDataSize(const ID3_TagImpl &); #endif /* _ID3LIB_TAG_IMPL_H_ */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_parse.cpp000066400000000000000000000246221516712004000257070ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include using namespace dami; bool id3::v2::parse(ID3_TagImpl& tag, ID3_Reader& reader) { ID3_Reader::pos_type beg = reader.getCur(); io::ExitTrigger et(reader); ID3_TagHeader hdr; io::WindowedReader wr(reader, ID3_TagHeader::SIZE); if (!hdr.Parse(wr) || wr.getCur() == beg) { ID3D_NOTICE("id3::v2::parse(): parsing header failes"); return false; } if (hdr.GetExtended()) { hdr.ParseExtended(reader); } tag.SetSpec(hdr.GetSpec()); size_t dataSize = hdr.GetDataSize(); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): dataSize = " << dataSize); wr.setWindow(wr.getCur(), dataSize); et.setExitPos(wr.getEnd()); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): data window beg = " << wr.getBeg()); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): data window cur = " << wr.getCur()); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): data window end = " << wr.getEnd()); tag.SetExtended(hdr.GetExtended()); if (!hdr.GetUnsync()) { tag.SetUnsync(false); parseFrames(tag, wr); } else { /* The buffer has been unsynced. It will have to be resynced to be * readable. This has to be done a character at a time. * * The original reader may be reading in characters from a file. Doing * this a character at a time is quite slow. To improve performance, read * in the entire buffer into a string, then create an UnsyncedReader from * the string. * * It might be better to implement a BufferedReader so that the details * of this can be abstracted away behind a class. */ tag.SetUnsync(true); BString raw = io::readAllBinary(wr); io::BStringReader bsr(raw); io::UnsyncedReader ur(bsr); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): unsync beg = " << ur.getBeg()); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): unsync cur = " << ur.getCur()); ID3D_NOTICE("ID3_TagImpl::Parse(ID3_Reader&): unsync end = " << ur.getEnd()); /* Now read the UnsyncedReader into another string, and parse the frames * from the string. This is done so that 1. the unsynced reader is * unsynced exactly once, removing the possibility of multiple unsyncings * of the same string, and 2) so that calls to readChars aren't done a * character at a time for every call. */ BString synced = io::readAllBinary(ur); io::BStringReader sr(synced); parseFrames(tag, sr); } return true; } void ID3_TagImpl::ParseFile() { ifstream file; if (ID3E_NoError != openReadableFile(this->GetFileName(), file)) { /* Log this... */ return; } ID3_IFStreamReader ifsr(file); ParseReader(ifsr); file.close(); } /* Used for streaming media. */ void ID3_TagImpl::ParseReader(ID3_Reader &reader) { size_t bytes_till_sync; io::WindowedReader wr(reader); wr.setBeg(wr.getCur()); _file_tags.clear(); _file_size = reader.getEnd(); ID3_Reader::pos_type beg = wr.getBeg(); ID3_Reader::pos_type cur = wr.getCur(); ID3_Reader::pos_type end = wr.getEnd(); ID3_Reader::pos_type last = cur; if (_tags_to_parse.test(ID3TT_ID3V2)) { do { last = cur; /* Parse tags at the beginning of the file first... */ if (id3::v2::parse(*this, wr)) { _file_tags.add(ID3TT_ID3V2); } cur = wr.getCur(); wr.setBeg(cur); } while (!wr.atEnd() && cur > last); } /* Add silly padding outside the tag to _prepended_bytes */ if (!wr.atEnd() && wr.peekChar() == '\0') { ID3D_NOTICE("ID3_TagImpl::ParseReader(): found padding outside tag"); do { last = cur; cur = wr.getCur() + 1; wr.setBeg(cur); wr.setCur(cur); } while (!wr.atEnd() && cur > last && wr.peekChar() == '\0'); } if (!wr.atEnd() && _file_size - (cur - beg) > 4 && wr.peekChar() == 255) { /* Unfortunatly, this is necessary for finding an invalid padding. */ wr.setCur(cur + 1); // cur is known by peekChar if (wr.readChar() == '\0' && wr.readChar() == '\0' && wr.peekChar() == '\0') { /* Three empty bytes found, enough for me, this is stupid padding */ cur += 3; // those are now already read in (excluding the peekChar, since it will be added by do{}) do { last = cur; cur = wr.getCur() + 1; wr.setBeg(cur); wr.setCur(cur); } while (!wr.atEnd() && cur > last && wr.peekChar() == '\0'); } else { wr.setCur(cur); } } _prepended_bytes = cur - beg; /* Go looking for the first sync byte to add to bytes_till_sync * by not adding it to _prepended_bytes, we preserve this 'unknown' data. * The routine's only effect is helping the lib to find things as bitrate etc. */ beg = wr.getBeg(); if (!wr.atEnd() && wr.peekChar() != 0xFF) // no sync byte, so, either this is not followed by a mp3 file or it's a fLaC file, or an encapsulating format, better check it { ID3D_NOTICE("ID3_TagImpl::ParseReader(): Didn't find mp3 sync byte"); if ((_file_size - (cur - beg)) >= 4) { /* There is room to search for some kind of ID. */ unsigned char buf[5]; wr.readChars(buf, 4); buf[4] = '\0'; /* Check for RIFF (an encapsulating format) ID. */ if (strncmp((char *) buf, "RIFF", 4) == 0 || strncmp((char *) buf, "RIFX", 4) == 0) { /* Next 4 bytes are RIFF size, skip them. */ cur = wr.getCur() + 4; wr.setCur(cur); /* Loop until first possible sync byte. */ if (!wr.atEnd() && wr.peekChar() != 0xFF) { do { last = cur; cur = wr.getCur() + 1; wr.setCur(cur); } while (!wr.atEnd() && cur > last && wr.peekChar() != 0xFF); } } else if (strncmp((char *) buf, "fLaC", 4) == 0) { /* A FLAC file, no need looking for a sync byte. */ beg = cur; } else { /* Since we set the cursor 4 bytes ahead for looking for RIFF, RIFX or fLaC, better set it back * but peekChar already checked the first one, so we add one. */ cur = cur + 1; wr.setCur(cur); /* Go looking for a sync byte. */ if (!wr.atEnd() && wr.peekChar() != 0xFF) //no sync byte, we have an unknown byte { do { last = cur; cur = wr.getCur() + 1; wr.setCur(cur); } while (!wr.atEnd() && cur > last && wr.peekChar() != 0xFF); } } } // if ((_file_size - (cur - beg)) >= 4) else { /* remaining size is smaller than 4 bytes, can't be useful, but leave it for now. */ beg = cur; // file.close(); // return; } } bytes_till_sync = cur - beg; cur = wr.setCur(end); if (_file_size > _prepended_bytes) { do { last = cur; ID3D_NOTICE("ID3_TagImpl::ParseReader(): beg = " << wr.getBeg()); ID3D_NOTICE("ID3_TagImpl::ParseReader(): cur = " << wr.getCur()); ID3D_NOTICE("ID3_TagImpl::ParseReader(): end = " << wr.getEnd()); /* ...then the tags at the end */ ID3D_NOTICE("ID3_TagImpl::ParseReader(): musicmatch? cur = " << wr.getCur()); if (_tags_to_parse.test(ID3TT_MUSICMATCH) && mm::parse(*this, wr)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): musicmatch! cur = " << wr.getCur()); _file_tags.add(ID3TT_MUSICMATCH); wr.setEnd(wr.getCur()); } ID3D_NOTICE("ID3_TagImpl::ParseReader(): lyr3v1? cur = " << wr.getCur()); if (_tags_to_parse.test(ID3TT_LYRICS3) && lyr3::v1::parse(*this, wr)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): lyr3v1! cur = " << wr.getCur()); _file_tags.add(ID3TT_LYRICS3); wr.setEnd(wr.getCur()); } ID3D_NOTICE("ID3_TagImpl::ParseReader(): lyr3v2? cur = " << wr.getCur()); if (_tags_to_parse.test(ID3TT_LYRICS3V2) && lyr3::v2::parse(*this, wr)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): lyr3v2! cur = " << wr.getCur()); _file_tags.add(ID3TT_LYRICS3V2); cur = wr.getCur(); wr.setCur(wr.getEnd());//set to end to seek id3v1 tag /* Check for id3v1 tag and set End accordingly */ ID3D_NOTICE("ID3_TagImpl::ParseReader(): id3v1? cur = " << wr.getCur()); if (_tags_to_parse.test(ID3TT_ID3V1) && id3::v1::parse(*this, wr)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): id3v1! cur = " << wr.getCur()); _file_tags.add(ID3TT_ID3V1); } wr.setCur(cur); wr.setEnd(cur); } ID3D_NOTICE("ID3_TagImpl::ParseReader(): id3v1? cur = " << wr.getCur()); if (_tags_to_parse.test(ID3TT_ID3V1) && id3::v1::parse(*this, wr)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): id3v1! cur = " << wr.getCur()); wr.setEnd(wr.getCur()); _file_tags.add(ID3TT_ID3V1); } cur = wr.getCur(); } while (cur != last); _appended_bytes = end - cur; /* Now get the mp3 header. */ size_t mp3_core_size = (_file_size - _appended_bytes) - (_prepended_bytes + bytes_till_sync); if (mp3_core_size >= 4) { /* It has at least the size for a mp3 header (a mp3 header is 4 bytes). */ wr.setBeg(_prepended_bytes + bytes_till_sync); wr.setCur(_prepended_bytes + bytes_till_sync); wr.setEnd(_file_size - _appended_bytes); _mp3_info = new Mp3Info; ID3D_NOTICE("ID3_TagImpl::ParseReader(): mp3header? cur = " << wr.getCur()); if (_mp3_info->Parse(wr, mp3_core_size)) { ID3D_NOTICE("ID3_TagImpl::ParseReader(): mp3header! cur = " << wr.getCur()); } else { delete _mp3_info; _mp3_info = NULL; } } } else { this->SetPadding(false); // no need to pad an empty file } } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_parse_lyrics3.cpp000066400000000000000000000210211516712004000273450ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include #include using namespace dami; namespace { uint32 readIntegerString(ID3_Reader &reader, size_t numBytes) { uint32 val = 0; for (size_t i = 0; i < numBytes && isdigit(reader.peekChar()); ++i) { val = (val * 10) + (reader.readChar() - '0'); } ID3D_NOTICE( "readIntegerString: val = " << val ); return val; } bool isTimeStamp(ID3_Reader &reader) { ID3_Reader::pos_type cur = reader.getCur(); if (reader.getEnd() < cur + 7) return false; bool its = ('[' == reader.readChar() && isdigit(reader.readChar()) && isdigit(reader.readChar()) && ':' == reader.readChar() && isdigit(reader.readChar()) && isdigit(reader.readChar()) && ']' == reader.readChar()); reader.setCur(cur); if (its) ID3D_NOTICE( "isTimeStamp(): found timestamp, cur = " << reader.getCur() ); return its; } uint32 readTimeStamp(ID3_Reader &reader) { reader.skipChars(1); size_t sec = readIntegerString(reader, 2) * 60; reader.skipChars(1); sec += readIntegerString(reader, 2); reader.skipChars(1); ID3D_NOTICE( "readTimeStamp(): timestamp = " << sec ); return sec * 1000; } bool findText(ID3_Reader &reader, String text) { if (text.empty()) return true; size_t index = 0; while (!reader.atEnd()) { ID3_Reader::char_type ch = reader.readChar(); if (ch == text[index]) index++; else if (ch == text[0]) index = 1; else index = 0; if (index == text.size()) { reader.setCur(reader.getCur() - index); ID3D_NOTICE( "findText: found \"" << text << "\" at " << reader.getCur() ); break; } } return !reader.atEnd(); } void lyrics3ToSylt(ID3_Reader &reader, ID3_Writer &writer) { while (!reader.atEnd()) { bool lf = false; size_t ms = 0; size_t count = 0; while (isTimeStamp(reader)) { // For now, just skip over multiple time stamps if (count++ > 0) readTimeStamp(reader); else ms = readTimeStamp(reader); } while (!reader.atEnd() && !isTimeStamp(reader)) { ID3_Reader::char_type ch = reader.readChar(); if (0x0A == ch && (reader.atEnd() || isTimeStamp(reader))) { lf = true; break; } else { writer.writeChar(ch); } } // put synch identifier writer.writeChar('\0'); // put timestamp ID3D_NOTICE( "lyrics3toSylt: ms = " << ms ); io::writeBENumber(writer, ms, sizeof(uint32)); if (lf) { ID3D_NOTICE( "lyrics3toSylt: adding lf" ); // put the LF writer.writeChar(0x0A); } } } }; bool lyr3::v1::parse(ID3_TagImpl &tag, ID3_Reader &reader) { io::ExitTrigger et(reader); ID3_Reader::pos_type end = reader.getCur(); if (end < reader.getBeg() + 9 + 128) { ID3D_NOTICE( "id3::v1::parse: bailing, not enough bytes to parse, pos = " << end ); return false; } reader.setCur(end - (9 + 128)); if (io::readText(reader, 9) != "LYRICSEND" || io::readText(reader, 3) != "TAG") { return false; } // we have a Lyrics3 v1.00 tag if (end < reader.getBeg() + 11 + 9 + 128) { // the file size isn't large enough to actually hold lyrics ID3D_WARNING( "id3::v1::parse: not enough data to parse lyrics3" ); return false; } // reserve enough space for lyrics3 + id3v1 tag size_t window = end - reader.getBeg(); size_t lyrDataSize = min(window, 11 + 5100 + 9 + 128); reader.setCur(end - lyrDataSize); io::WindowedReader wr(reader, lyrDataSize - (9 + 128)); if (!findText(wr, "LYRICSBEGIN")) { ID3D_WARNING( "id3::v1::parse: couldn't find LYRICSBEGIN, bailing" ); return false; } et.setExitPos(wr.getCur()); wr.skipChars(11); wr.setBeg(wr.getCur()); io::LineFeedReader lfr(wr); String lyrics = io::readText(lfr, wr.remainingBytes()); id3::v2::setLyrics(tag, lyrics, "Converted from Lyrics3 v1.00", "XXX"); return true; } //bool parse(TagImpl& tag, ID3_Reader& reader) bool lyr3::v2::parse(ID3_TagImpl &tag, ID3_Reader &reader) { io::ExitTrigger et(reader); ID3_Reader::pos_type end = reader.getCur(); if (end < reader.getBeg() + 6 + 9 + 128) { ID3D_NOTICE( "lyr3::v2::parse: bailing, not enough bytes to parse, pos = " << reader.getCur() ); return false; } reader.setCur(end - (6 + 9 + 128)); ID3_Reader::pos_type beg = reader.getCur(); uint32 lyrSize = readIntegerString(reader, 6); if (reader.getCur() < beg + 6) { ID3D_NOTICE( "lyr3::v2::parse: couldn't find numeric string, lyrSize = " << lyrSize ); return false; } if (io::readText(reader, 9) != "LYRICS200" || io::readText(reader, 3) != "TAG") { return false; } if (end < reader.getBeg() + lyrSize + 6 + 9 + 128) { ID3D_WARNING( "lyr3::v2::parse: not enough data to parse tag, lyrSize = " << lyrSize ); return false; } reader.setCur(end - (lyrSize + 6 + 9 + 128)); io::WindowedReader wr(reader); wr.setWindow(wr.getCur(), lyrSize); beg = wr.getCur(); if (io::readText(wr, 11) != "LYRICSBEGIN") { // not a lyrics v2.00 tag ID3D_WARNING( "lyr3::v2::parse: couldn't find LYRICSBEGIN, bailing" ); return false; } bool has_time_stamps = false; while (!wr.atEnd()) { String fldName = io::readText(wr, 3); uint32 fldSize = readIntegerString(wr, 5); ID3D_NOTICE( "lyr3::v2::parse: fldName = " << fldName ); ID3D_NOTICE( "lyr3::v2::parse: fldSize = " << fldSize ); String fldData; io::WindowedReader wr2(wr, fldSize); io::LineFeedReader lfr(wr2); fldData = io::readText(lfr, fldSize); ID3D_NOTICE( "lyr3::v2::parse: fldData = \"" << fldData << "\"" ); // the IND field if (fldName == "IND") { has_time_stamps = (fldData.size() > 1 && fldData[1] == '1'); } // the TITLE field else if (fldName == "ETT" && !id3::v2::hasTitle(tag)) { //tag.setTitle(fldData); id3::v2::setTitle(tag, fldData); } // the ARTIST field else if (fldName == "EAR" && !id3::v2::hasArtist(tag)) { //tag.setArtist(fldData); id3::v2::setArtist(tag, fldData); } // the ALBUM field else if (fldName == "EAL" && !id3::v2::hasAlbum(tag)) { //tag.setAlbum(fldData); id3::v2::setAlbum(tag, fldData); } // the Lyrics/Music AUTHOR field else if (fldName == "AUT") { //tag.setAuthor(fldData); id3::v2::setLyricist(tag, fldData); } // the INFORMATION field else if (fldName == "INF") { //tag.setInfo(fldData); id3::v2::setComment(tag, fldData, "Lyrics3 v2.00 INF", "XXX"); } // the LYRICS field else if (fldName == "LYR") { // if already found an INF field, use it as description String desc = "Converted from Lyrics3 v2.00"; //tag.setLyrics(fldData); if (!has_time_stamps) { id3::v2::setLyrics(tag, fldData, desc, "XXX"); } else { // converts from lyrics3 to SYLT in-place io::StringReader sr(fldData); ID3D_NOTICE( "lyr3::v2::parse: determining synced lyrics" ); BString sylt; io::BStringWriter sw(sylt); lyrics3ToSylt(sr, sw); id3::v2::setSyncLyrics(tag, sylt, ID3TSF_MS, desc, "XXX", ID3CT_LYRICS); ID3D_NOTICE( "lyr3::v2::parse: determined synced lyrics" ); } } else if (fldName == "IMG") { // currently unsupported ID3D_WARNING( "lyr3::v2::parse: IMG field unsupported" ); } else { ID3D_WARNING( "lyr3::v2::parse: undefined field id: " << fldName ); } } et.setExitPos(beg); return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_parse_musicmatch.cpp000066400000000000000000000242151516712004000301220ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #if defined HAVE_CONFIG_H # include #endif #include "tag_impl.h" using namespace dami; namespace { uint32 readSeconds(ID3_Reader& reader, size_t len) { io::ExitTrigger et(reader); io::WindowedReader wr(reader, len); uint32 seconds = 0; uint32 cur = 0; while (!wr.atEnd()) { ID3_Reader::char_type ch = wr.readChar(); if (':' == ch) { seconds += 60 * cur; cur = 0; } else if (!isdigit(ch)) { return 0; } else { cur = cur * 10 + (ch - '0'); } } et.release(); return seconds + cur; } ID3_Frame* readTextFrame(ID3_Reader& reader, ID3_FrameID id, const String desc = "") { uint32 size = io::readLENumber(reader, 2); ID3D_NOTICE( "readTextFrame: size = " << size ); if (size == 0) { return NULL; } String text; if (ID3FID_SONGLEN != id) { io::LineFeedReader lfr(reader); text = io::readText(lfr, size); ID3D_NOTICE( "readTextFrame: text = " << text ); } else { text = toString(readSeconds(reader, size) * 1000); ID3D_NOTICE( "readTextFrame: songlen = " << text ); } ID3_Frame* frame = new ID3_Frame(id); if (frame) { if (frame->Contains(ID3FN_TEXT)) { frame->GetField(ID3FN_TEXT)->Set(text.c_str()); } else if (frame->Contains(ID3FN_URL)) { frame->GetField(ID3FN_URL)->Set(text.c_str()); } if (frame->Contains(ID3FN_LANGUAGE)) { frame->GetField(ID3FN_LANGUAGE)->Set("XXX"); } if (frame->Contains(ID3FN_DESCRIPTION)) { frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str()); } } return frame; } }; bool mm::parse(ID3_TagImpl& tag, ID3_Reader& rdr) { io::ExitTrigger et(rdr); ID3_Reader::pos_type end = rdr.getCur(); if (end < rdr.getBeg() + 48) { ID3D_NOTICE( "mm::parse: bailing, not enough bytes to parse, pos = " << end ); return false; } rdr.setCur(end - 48); String version; { if (io::readText(rdr, 32) != "Brava Software Inc. ") { ID3D_NOTICE( "mm::parse: bailing, couldn't find footer" ); return false; } version = io::readText(rdr, 4); if (version.size() != 4 || !isdigit(version[0]) || version[1] != '.' || !isdigit(version[2]) || !isdigit(version[3])) { ID3D_WARNING( "mm::parse: bailing, nonstandard version = " << version ); return false; } } ID3_Reader::pos_type beg = rdr.setCur(end - 48); et.setExitPos(beg); if (end < 68) { ID3D_NOTICE( "mm::parse: bailing, not enough bytes to parse offsets, pos = " << end ); return false; } rdr.setCur(end - 68); io::WindowedReader dataWindow(rdr); dataWindow.setEnd(rdr.getCur()); uint32 offsets[5]; io::WindowedReader offsetWindow(rdr, 20); for (size_t i = 0; i < 5; ++i) { offsets[i] = io::readLENumber(rdr, sizeof(uint32)); } size_t metadataSize = 0; if (version <= "3.00") { // All MusicMatch tags up to and including version 3.0 had metadata // sections exactly 7868 bytes in length. metadataSize = 7868; } else { // MusicMatch tags after version 3.0 had three possible lengths for their // metadata sections. We can determine which it was by searching for // the version section signature that should precede the metadata section // by exactly 256 bytes. size_t possibleSizes[] = { 8132, 8004, 7936 }; for (size_t i = 0; i < sizeof(possibleSizes)/sizeof(size_t); ++i) { dataWindow.setCur(dataWindow.getEnd()); // Our offset will be exactly 256 bytes prior to our potential metadata // section size_t offset = possibleSizes[i] + 256; if (dataWindow.getCur() < offset) { // if our filesize is less than the offset, then it can't possibly // be the correct offset, so try again. continue; } dataWindow.setCur(dataWindow.getCur() - offset); // now read in the signature to see if it's a match if (io::readText(dataWindow, 8) == "18273645") { metadataSize = possibleSizes[i]; break; } } } if (0 == metadataSize) { // if we didn't establish a size for the metadata, then something is // wrong. probably should log this. ID3D_WARNING( "mm::parse: bailing, couldn't find meta data signature, end = " << end ); return false; } // parse the offset pointers to determine the actual sizes of all the // sections size_t sectionSizes[5]; size_t tagSize = metadataSize; // we already know the size of the last section sectionSizes[4] = metadataSize; size_t lastOffset = 0; for (int i = 0; i < 5; i++) { size_t thisOffset = offsets[i]; //ASSERT(thisOffset > lastOffset); if (i > 0) { size_t sectionSize = thisOffset - lastOffset; sectionSizes[i-1] = sectionSize; tagSize += sectionSize; } lastOffset = thisOffset; } // now check to see that our tag size is reasonable if (dataWindow.getEnd() < tagSize) { // Ack! The tag size doesn't jive with the tag's ending position in // the file. Bail! ID3D_WARNING( "mm::parse: bailing, tag size is too big, tag size = " << tagSize << ", end = " << end ); return false; } dataWindow.setBeg(dataWindow.getEnd() - tagSize); dataWindow.setCur(dataWindow.getBeg()); // Now calculate the adjusted offsets offsets[0] = dataWindow.getBeg(); for (size_t i = 0; i < 4; ++i) { offsets[i+1] = offsets[i] + sectionSizes[i]; } // now check for a tag header and adjust the tag_beg pointer appropriately if (dataWindow.getBeg() >= 256) { rdr.setCur(dataWindow.getBeg() - 256); if (io::readText(rdr, 8) == "18273645") { et.setExitPos(rdr.getCur() - 8); } else { et.setExitPos(dataWindow.getBeg()); } dataWindow.setCur(dataWindow.getBeg()); } // Now parse the various sections... // Parse the image extension at offset 0 dataWindow.setCur(offsets[0]); String imgExt = io::readTrailingSpaces(dataWindow, 4); // Parse the image binary at offset 1 dataWindow.setCur(offsets[1]); uint32 imgSize = io::readLENumber(dataWindow, 4); if (imgSize == 0) { // no image binary. don't do anything. } else { io::WindowedReader imgWindow(dataWindow, imgSize); if (imgWindow.getEnd() < imgWindow.getBeg() + imgSize) { // Ack! The image size given extends beyond the next offset! This is // not good... log? } else { BString imgData = io::readAllBinary(imgWindow); ID3_Frame* frame = new ID3_Frame(ID3FID_PICTURE); if (frame) { String mimetype("image/"); mimetype += imgExt; frame->GetField(ID3FN_MIMETYPE)->Set(mimetype.c_str()); frame->GetField(ID3FN_IMAGEFORMAT)->Set(""); frame->GetField(ID3FN_PICTURETYPE)->Set(static_cast(0)); frame->GetField(ID3FN_DESCRIPTION)->Set(""); frame->GetField(ID3FN_DATA)->Set(reinterpret_cast(imgData.data()), imgData.size()); tag.AttachFrame(frame); } } } //file.seekg(offsets[2]); //file.seekg(offsets[3]); dataWindow.setCur(offsets[4]); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_TITLE)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_ALBUM)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_LEADARTIST)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_CONTENTTYPE)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Tempo")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Mood")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Situation")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Preference")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_SONGLEN)); // The next 12 bytes can be ignored. The first 8 represent the // creation date as a 64 bit floating point number. The last 4 are // for a play counter. dataWindow.skipChars(12); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Path")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Serial")); // 2 bytes for track uint32 trkNum = io::readLENumber(dataWindow, 2); if (trkNum > 0) { String trkStr = toString(trkNum); ID3_Frame* frame = new ID3_Frame(ID3FID_TRACKNUM); if (frame) { frame->GetField(ID3FN_TEXT)->Set(trkStr.c_str()); tag.AttachFrame(frame); } } tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Notes")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_Bio")); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_UNSYNCEDLYRICS)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_WWWARTIST)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_WWWCOMMERCIALINFO)); tag.AttachFrame(readTextFrame(dataWindow, ID3FID_COMMENT, "MusicMatch_ArtistEmail")); // email? return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_parse_v1.cpp000066400000000000000000000132401516712004000263070ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include using namespace dami; bool id3::v1::parse(ID3_TagImpl &tag, ID3_Reader &reader) { io::ExitTrigger et(reader); ID3_Reader::pos_type end = reader.getCur(); /* Position ourselves at 128 bytes from the current position. */ if (end < reader.getBeg() + ID3_V1_LEN) { ID3D_NOTICE( "id3::v1::parse: not enough bytes to parse, pos = " << end ); return false; } reader.setCur(end - ID3_V1_LEN); ID3_Reader::pos_type beg = reader.getCur(); if (end != beg + ID3_V1_LEN) { ID3D_WARNING( "id3::v1::parse: failed to reposition " << ID3_V1_LEN << " bytes" ); return false; } /* Read the next 128 bytes. */ String field = io::readText(reader, ID3_V1_LEN_ID); /* Check to see if it was a tag. */ if (field != "TAG") return false; et.setExitPos(beg); /* Guess so, let's start checking the v2 tag for frames which are the * equivalent of the v1 fields. When we come across a v1 field that has * no current equivalent v2 frame, we create the frame, copy the data * from the v1 frame and attach it to the tag. */ ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The title field. */ String title = io::readTrailingSpaces(reader, ID3_V1_LEN_TITLE); field = id3::v2::getTitle(tag); if (title.size() > 0 && (field.size() == 0 || field == "")) id3::v2::setTitle(tag, title); ID3D_NOTICE("id3::v1::parse: title = \"" << title << "\""); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The artist field. */ String artist = io::readTrailingSpaces(reader, ID3_V1_LEN_ARTIST); field = id3::v2::getArtist(tag); if (artist.size() > 0 && (field.size() == 0 || field == "")) id3::v2::setArtist(tag, artist); ID3D_NOTICE("id3::v1::parse: artist = \"" << artist << "\""); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The album field. */ String album = io::readTrailingSpaces(reader, ID3_V1_LEN_ALBUM); field = id3::v2::getAlbum(tag); if (album.size() > 0 && (field.size() == 0 || field == "")) id3::v2::setAlbum(tag, album); ID3D_NOTICE("id3::v1::parse: album = \"" << title << "\""); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The year field. */ String year = io::readTrailingSpaces(reader, ID3_V1_LEN_YEAR); field = id3::v2::getYear(tag); if (year.size() > 0 && (field.size() == 0 || field == "")) id3::v2::setYear(tag, year); ID3D_NOTICE("id3::v1::parse: year = \"" << year << "\""); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The comment and track fields. */ String comment = io::readTrailingSpaces(reader, ID3_V1_LEN_COMMENT - 2); /* Fixes bug for when tracknumber is 0x20. */ BString trackno = io::readBinary(reader, ID3_V1_LEN_COMMENT - 28); if (trackno[0] == '\0') { if (trackno[1] != '\0') { /* We've got a track number. */ size_t track = trackno[1]; field = id3::v2::getTrack(tag); if (field.size() == 0 || field == "00") id3::v2::setTrack(tag, track, 0); ID3D_NOTICE("id3::v1::parse: track = \"" << track << "\""); ID3D_NOTICE("id3::v1::parse: comment length = \"" << comment.length() << "\""); } } else { // trackno[0] != '\0' const int paddingsize = (ID3_V1_LEN_COMMENT - 2) - comment.size(); const char *padding = " "; // 28 spaces if ((trackno[1] == '\0' || trackno[1] == 0x20) && trackno[0] != 0x20) { /* If there used to be spaces they are gone now, we need to rebuild them. */ comment.append(padding, paddingsize); comment.append((const char *) trackno.data(), 1); } else if (trackno[1] != '\0' && trackno[1] != 0x20) { /* If there used to be spaces they are gone now, we need to rebuild them. */ comment.append(padding, paddingsize); comment.append((const char *) trackno.data(), 2); } } ID3D_NOTICE( "id3::v1::parse: comment = \"" << comment << "\"" ); if (comment.size() > 0) id3::v2::setComment(tag, comment, STR_V1_COMMENT_DESC, "XXX"); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); /* The genre field. */ uchar genre = reader.readChar(); field = id3::v2::getGenre(tag); if (genre != 0xFF && (field.size() == 0 || field == "")) id3::v2::setGenre(tag, genre); ID3D_NOTICE("id3::v1::parse: genre = \"" << (int) genre << "\""); ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg); return true; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/tag_render.cpp000066400000000000000000000136011516712004000260470ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include "tag_impl.h" #include #include #if defined HAVE_SYS_PARAM_H # include #endif #define ID3_PADMULTIPLE (2048) #define ID3_PADMAX (4096) using namespace dami; void id3::v1::render(ID3_Writer &writer, const ID3_TagImpl &tag) { writer.writeChars("TAG", 3); io::writeTrailingSpaces(writer, id3::v2::getTitle(tag), ID3_V1_LEN_TITLE); io::writeTrailingSpaces(writer, id3::v2::getArtist(tag), ID3_V1_LEN_ARTIST); io::writeTrailingSpaces(writer, id3::v2::getAlbum(tag), ID3_V1_LEN_ALBUM); io::writeTrailingSpaces(writer, id3::v2::getYear(tag), ID3_V1_LEN_YEAR); size_t track = id3::v2::getTrackNum(tag); String comment = id3::v2::getV1Comment(tag); if (track > 0) { io::writeTrailingSpaces(writer, comment, ID3_V1_LEN_COMMENT - 2); writer.writeChar('\0'); writer.writeChar((char) track); } else { io::writeTrailingSpaces(writer, comment, ID3_V1_LEN_COMMENT); } writer.writeChar((char) id3::v2::getGenreNum(tag)); } ID3_Err id3::v2::render(ID3_Writer &writer, const ID3_TagImpl &tag) { /* There has to be at least one frame for there to be a tag... */ ID3_Err err = ID3E_NoError; if (tag.NumFrames() == 0) { ID3D_WARNING("id3::v2::render(): no frames to render"); return ID3E_NoData; } ID3_V2Spec spec = tag.MinSpec(); if (tag.GetSpec() > spec) spec = tag.GetSpec(); ID3D_NOTICE("id3::v2::render(): rendering"); ID3_TagHeader hdr; hdr.SetSpec(spec); hdr.SetExtended(tag.GetExtended()); hdr.SetExperimental(tag.GetExperimental()); hdr.SetFooter(tag.GetFooter()); /* Set up the encryption and grouping IDs. */ /* ... */ String frms; io::StringWriter frmWriter(frms); if (!tag.GetUnsync()) { ID3D_NOTICE("id3::v2::render(): rendering frames"); err = renderFrames(frmWriter, tag); if (err != ID3E_NoError) return err; hdr.SetUnsync(false); } else { ID3D_NOTICE("id3::v2::render(): rendering unsynced frames"); io::UnsyncedWriter uw(frmWriter); err = renderFrames(uw, tag); if (err != ID3E_NoError) return err; uw.flush(); ID3D_NOTICE("id3::v2::render(): numsyncs = " << uw.getNumSyncs()); hdr.SetUnsync(uw.getNumSyncs() > 0); } size_t frmSize = frms.size(); if (frmSize == 0) { ID3D_WARNING("id3::v2::render(): rendered frame size is 0 bytes"); return ID3E_InvalidFrameSize; } /* Zero the remainder of the buffer so that our padding bytes are zero. */ luint nPadding = tag.PaddingSize(frmSize); ID3D_NOTICE("id3::v2::render(): padding size = " << nPadding); hdr.SetDataSize(frmSize + tag.GetExtendedBytes() + nPadding); err = hdr.Render(writer); if (err != ID3E_NoError) return err; writer.writeChars(frms.data(), frms.size()); for (size_t i = 0; i < nPadding; ++i) { if (writer.writeChar('\0') == ID3_Writer::END_OF_WRITER) { break; } } return ID3E_NoError; } size_t ID3_TagImpl::Size() const { if (this->NumFrames() == 0) return 0; ID3_V2Spec spec = this->MinSpec(); if (this->GetSpec() > spec) spec = this->GetSpec(); ID3_TagHeader hdr; hdr.SetSpec(spec); size_t bytesUsed = hdr.Size(); size_t frameBytes = ID3_ContainerImpl::Size(); if (!frameBytes) return 0; bytesUsed += frameBytes; /* Add 30% for sync. */ bytesUsed += bytesUsed / 3; /* Add padding and another ID3_PADMULTIPLE bytes * to be safe in case the above guess was too low. */ bytesUsed += this->PaddingSize(bytesUsed) + ID3_PADMULTIPLE; return bytesUsed; } size_t ID3_TagImpl::PaddingSize(size_t curSize) const { luint newSize = 0; /* If padding is switched off. */ if (!_is_padded) return 0; /* If the old tag was large enough to hold the new tag, then we will simply * pad out the difference - that way the new tag can be written without * shuffling the rest of the song file around. */ if ((this->GetPrependedBytes()-ID3_TagHeader::SIZE > 0) && (this->GetPrependedBytes()-ID3_TagHeader::SIZE >= curSize) && (this->GetPrependedBytes()-ID3_TagHeader::SIZE - curSize) < ID3_PADMAX) { newSize = this->GetPrependedBytes() - ID3_TagHeader::SIZE; } else { luint tempSize = curSize + ID3_GetDataSize(*this) + this->GetAppendedBytes() + ID3_TagHeader::SIZE; /* This method of automatic padding rounds the COMPLETE FILE up to the * nearest 2K. If the file will already be an even multiple of 2K (with * the tag included) then we just add another 2K of padding. */ tempSize = ((tempSize / ID3_PADMULTIPLE) + 1) * ID3_PADMULTIPLE; /* The size of the new tag is the new filesize minus the audio data. */ newSize = tempSize - ID3_GetDataSize(*this) - this->GetAppendedBytes () - ID3_TagHeader::SIZE; } return newSize - curSize; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3/utils.cpp000066400000000000000000000176661516712004000251140ustar00rootroot00000000000000// $Id$ // id3lib: a C++ library for creating and manipulating id3v1/v2 tags // Copyright 1999, 2000 Scott Thomas Haug /* This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The id3lib authors encourage improvements and optimisations to be sent to * the id3lib coordinator. Please see the README file for details on where to * send such submissions. See the AUTHORS file for a list of people who have * contributed to id3lib. See the ChangeLog file for a list of changes to * id3lib. These files are distributed with id3lib at * http://download.sourceforge.net/id3lib/ */ #include #if (defined(__GNUC__) && __GNUC__ == 2) # define NOCREATE ios::nocreate #else # if defined(macintosh) //not sure if this is still needed # define toascii(X) (X) //not sure if this is still needed # endif //not sure if this is still needed # define NOCREATE ((std::ios_base::openmode)0) #endif #include /* Check if we have all unicodes */ #if defined HAVE_ICONV_H # if (defined(ID3_ICONV_FORMAT_UTF16BE) && defined(ID3_ICONV_FORMAT_UTF16) && defined(ID3_ICONV_FORMAT_UTF8) && defined(ID3_ICONV_FORMAT_ASCII)) # include # include # else # undef HAVE_ICONV_H # endif #endif using namespace dami; /* Converts an ASCII string into a Unicode one */ dami::String mbstoucs(dami::String data) { size_t size = data.size(); dami::String unicode(size * 2, '\0'); for (size_t i = 0; i < size; ++i) { unicode[i * 2 + 1] = toascii(data[i]); } return unicode; } /* Converts a Unicode string into ASCII */ dami::String ucstombs(dami::String data) { size_t size = data.size() / 2; dami::String ascii(size, '\0'); for (size_t i = 0; i < size; ++i) { ascii[i] = toascii(data[i * 2 + 1]); } return ascii; } dami::String oldconvert(dami::String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc) { dami::String target; if (ID3TE_IS_SINGLE_BYTE_ENC(sourceEnc) && ID3TE_IS_DOUBLE_BYTE_ENC(targetEnc)) target = mbstoucs(data); else if (ID3TE_IS_DOUBLE_BYTE_ENC(sourceEnc) && ID3TE_IS_SINGLE_BYTE_ENC(targetEnc)) target = ucstombs(data); return target; } size_t dami::renderNumber(uchar *buffer, uint32 val, size_t size) { uint32 num = val; for (size_t i = 0; i < size; i++) { buffer[size - i - 1] = (uchar) (num & MASK8); num >>= 8; } return size; } String dami::renderNumber(uint32 val, size_t size) { String str(size, '\0'); uint32 num = val; for (size_t i = 0; i < size; i++) { str[size - i - 1] = (uchar) (num & MASK8); num >>= 8; } return str; } #if defined(HAVE_ICONV_H) namespace { String convert_i(iconv_t cd, String source) { String target; size_t source_size = source.size(); #if defined(ID3LIB_ICONV_OLDSTYLE) const char *source_str = source.data(); #else char *source_str = new char[source.size() + 1]; source.copy(source_str, String::npos); source_str[source.length()] = 0; #endif #define ID3LIB_BUFSIZ 1024 char buf[ID3LIB_BUFSIZ]; char *target_str = buf; size_t target_size = ID3LIB_BUFSIZ; do { errno = 0; size_t nconv = iconv(cd, &source_str, &source_size, &target_str, &target_size); if (nconv == (size_t) -1 && errno != EINVAL && errno != E2BIG) { /* errno is probably EILSEQ here, which means either an invalid * byte sequence or a valid but unconvertible byte sequence. */ #if !defined(ID3LIB_ICONV_OLDSTYLE) delete [] source_str; #endif return target; } target.append(buf, ID3LIB_BUFSIZ - target_size); target_str = buf; target_size = ID3LIB_BUFSIZ; } while (source_size > 0); #if !defined(ID3LIB_ICONV_OLDSTYLE) delete [] source_str; #endif return target; } const char *getFormat(ID3_TextEnc enc) { const char *format = NULL; switch (enc) { case ID3TE_ISO8859_1: format = ID3_ICONV_FORMAT_ASCII; break; case ID3TE_UTF16: format = ID3_ICONV_FORMAT_UTF16; break; case ID3TE_UTF16BE: format = ID3_ICONV_FORMAT_UTF16BE; break; case ID3TE_UTF8: format = ID3_ICONV_FORMAT_UTF8; break; default: break; } return format; } } #endif String dami::convert(String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc) { String target; if ((sourceEnc != targetEnc) && (data.size() > 0)) { #if !defined HAVE_ICONV_H target = oldconvert(data, sourceEnc, targetEnc); #else const char *targetFormat = getFormat(targetEnc); const char *sourceFormat = getFormat(sourceEnc); iconv_t cd = iconv_open(targetFormat, sourceFormat); if (cd != (iconv_t) -1) { target = convert_i(cd, data); if (target.size() == 0) { /* Try without iconv. */ target = oldconvert(data, sourceEnc, targetEnc); } } else { target = oldconvert(data, sourceEnc, targetEnc); } iconv_close (cd); #endif } return target; } size_t dami::ucslen(const unicode_t *unicode) { if (unicode == NULL) return 0; for (size_t size = 0; true; size++) { if (unicode[size] == NULL_UNICODE) return size; } return 0; } namespace { bool exists(String name) { ifstream file(name.c_str(), NOCREATE); return file.is_open() != 0; } }; ID3_Err dami::createFile(String name, fstream &file) { if (file.is_open()) file.close(); file.open(name.c_str(), ios::in | ios::out | ios::binary | ios::trunc); if (!file) return ID3E_ReadOnly; return ID3E_NoError; } size_t dami::getFileSize(fstream &file) { size_t size = 0; if (file.is_open()) { streamoff curpos = file.tellg(); file.seekg(0, ios::end); size = file.tellg(); file.seekg(curpos); } return size; } size_t dami::getFileSize(ifstream &file) { size_t size = 0; if (file.is_open()) { streamoff curpos = file.tellg(); file.seekg(0, ios::end); size = file.tellg(); file.seekg(curpos); } return size; } size_t dami::getFileSize(ofstream &file) { size_t size = 0; if (file.is_open()) { streamoff curpos = file.tellp(); file.seekp(0, ios::end); size = file.tellp(); file.seekp(curpos); } return size; } ID3_Err dami::openWritableFile(String name, fstream &file) { if (!exists(name)) return ID3E_NoFile; if (file.is_open()) file.close(); file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE); if (!file) return ID3E_ReadOnly; return ID3E_NoError; } ID3_Err dami::openWritableFile(String name, ofstream &file) { if (!exists(name)) return ID3E_NoFile; if (file.is_open()) file.close(); file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE); if (!file) return ID3E_ReadOnly; return ID3E_NoError; } ID3_Err dami::openReadableFile(String name, fstream &file) { if (file.is_open()) file.close(); file.open(name.c_str(), ios::in | ios::binary | NOCREATE); if (!file) return ID3E_NoFile; return ID3E_NoError; } ID3_Err dami::openReadableFile(String name, ifstream &file) { if (file.is_open()) file.close(); file.open(name.c_str(), ios::in | ios::binary | NOCREATE); if (!file) return ID3E_NoFile; return ID3E_NoError; } String dami::toString(uint32 val) { if (val == 0) return "0"; String text; while (val > 0) { String tmp; char ch = (val % 10) + '0'; tmp += ch; text = tmp + text; val /= 10; } return text; } WString dami::toWString(const unicode_t buf[], size_t len) { WString str; str.reserve(len); for (size_t i = 0; i < len; ++i) { str += static_cast(buf[i]); } return str; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3v2.cpp000066400000000000000000001543001516712004000242070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "id3v2.h" using namespace smooth::IO; const String &BoCA::TaggerID3v2::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ ID3v2 Tagger \ 1.0 \ id3v2-tag \ tagger \ \ MPEG 1 Audio Layer 3 \ mp3 \ \ \ ID3v2 \ \ \ \ ISO-8859-1 \ UTF-8 \ UTF-16LE \ UTF-16BE \ \ \ \ \ "; return componentSpecs; } const String BoCA::TaggerID3v2::ConfigID = "Tags"; const String BoCA::TaggerID3v2::genres[192] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alt. Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta Rap", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop", "Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout", "Downtempo", "Dub", "EBM", "Eclectic", "Electro", "Electroclash", "Emo", "Experimental", "Garage", "Global", "IDM", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield", "Lounge", "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance", "Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical", "Audiobook", "Audio Theatre", "Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient" }; BoCA::TaggerID3v2::TaggerID3v2() { textEncoding = ID3TE_NONE; } BoCA::TaggerID3v2::~TaggerID3v2() { } Error BoCA::TaggerID3v2::RenderBuffer(Buffer &buffer, const Track &track) { ID3_Tag tag; RenderContainer(tag, track); tag.SetPadding(false); /* ID3Lib versions used in many Linux distributions are buggy * and return less than the actually used tag size here. * * Round to the next multiple of 2048 to compensate for that. */ buffer.Resize(((tag.Size() / 2048) + 1) * 2048); Int size = tag.Render(buffer, ID3TT_ID3V2); buffer.Resize(size); return Success(); } Error BoCA::TaggerID3v2::ParseBuffer(const Buffer &buffer, Track &track) { ID3_Tag tag; tag.Parse(buffer, buffer.Size()); ParseContainer(tag, track); return Success(); } Error BoCA::TaggerID3v2::ParseStreamInfo(const String &fileName, Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Look for ID3v2 tag. */ if (in.InputString(3) == "ID3" && in.InputNumber(1) <= 4) { /* Skip minor version and flags. */ in.InputNumber(1); in.InputNumber(1); /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); in.Seek(0); Buffer buffer(tagSize + 10); in.InputData(buffer, buffer.Size()); return ParseBuffer(buffer, track); } return Error(); } Error BoCA::TaggerID3v2::UpdateStreamInfo(const String &fileName, const Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Check for RIFF or AIFF files. */ String magic = in.InputString(4); if (magic == "RIFF" || magic == "FORM") { in.Close(); return UpdateChunkedFileTag(fileName, track); } in.Seek(0); /* Look for ID3v2 tag. */ if (in.InputString(3) == "ID3" && in.InputNumber(1) <= 4) { /* Skip minor version and flags. */ in.InputNumber(1); in.InputNumber(1); /* Read tag size as a 4 byte unsynchronized integer. */ Int tagSize = (in.InputNumber(1) << 21) + (in.InputNumber(1) << 14) + (in.InputNumber(1) << 7) + (in.InputNumber(1) ); /* Skip the tag. */ in.RelSeek(tagSize); } else { in.Seek(0); } /* Copy to temporary file and write tag. */ OutStream out(STREAM_FILE, fileName.Append(".temp"), OS_REPLACE); if (out.GetLastError() == IO_ERROR_OK) { Buffer buffer; RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); buffer.Resize(128 * 1024); for (Int64 i = in.GetPos(); i < in.Size(); i += buffer.Size()) { Int bytes = Math::Min(in.Size() - i, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); } in.Close(); out.Close(); File(fileName).Delete(); File(fileName.Append(".temp")).Move(fileName); return Success(); } return Error(); } Error BoCA::TaggerID3v2::UpdateChunkedFileTag(const String &fileName, const Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Read RIFF chunk. */ Bool error = False; String riff = in.InputString(4); if (riff != "RIFF" && riff != "RF64" && riff != "FORM") return Error(); /* Create output file. */ OutStream out(STREAM_FILE, fileName.Append(".temp"), OS_REPLACE); UnsignedInt32 rSize = riff != "FORM" ? in.InputNumber(4) : in.InputNumberRaw(4); UnsignedInt32 rFormat = in.InputNumber(4); out.OutputString(riff); if (riff != "FORM") out.OutputNumber(rSize, 4); else out.OutputNumberRaw(rSize, 4); out.OutputNumber(rFormat, 4); Int64 dSize = -1; Buffer buffer(131072); while (!error) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ String chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) (riff != "FORM" ? in.InputNumber(4) : in.InputNumberRaw(4)); if ((riff != "FORM" && chunk == "id3 ") || (riff == "FORM" && chunk == "ID3 ")) { /* Skip ID3 chunk. */ if (!in.RelSeek(cSize + cSize % 2)) error = True; continue; } out.OutputString(chunk); if (riff != "FORM") out.OutputNumber(cSize, 4); else out.OutputNumberRaw(cSize, 4); if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(-16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) error = True; if (dSize >= 0) cSize = dSize; } /* Write chunk data to output file. */ cSize += cSize % 2; while (!error && cSize > 0) { Int64 bytes = Math::Min(cSize, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); cSize -= bytes; } } /* Write new metadata. */ if (!error) { /* Write ID3 chunk. */ buffer.Resize(0); RenderBuffer(buffer, track); if (riff != "FORM") out.OutputString("id3 "); else out.OutputString("ID3 "); Int size = buffer.Size(); if (riff != "FORM") out.OutputNumber(size, 4); else out.OutputNumberRaw(size, 4); out.OutputData(buffer, size); /* Update file size. */ UnsignedInt64 fileSize = out.GetPos() - 8; rSize = Math::Min(0xFFFFFFFF, fileSize); out.Seek(4); if (riff != "FORM") out.OutputNumber(rSize, 4); else out.OutputNumberRaw(rSize, 4); } /* Clean up. */ in.Close(); out.Close(); if (error) { File(fileName.Append(".temp")).Delete(); return Error(); } File(fileName).Delete(); File(fileName.Append(".temp")).Move(fileName); return Success(); } Int BoCA::TaggerID3v2::RenderContainer(ID3_Container &container, const Track &track, Bool isChapter) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroID3v2", False); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool writeMCDI = currentConfig->GetIntValue(ConfigID, "WriteMCDI", True); Bool preserveReplayGain = currentConfig->GetIntValue(ConfigID, "PreserveReplayGain", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToID3v2 = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToID3v2", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Set text encoding. */ textEncodingID = currentConfig->GetStringValue(ConfigID, "ID3v2Encoding", "UTF-16LE"); if (textEncodingID == "UTF-8") textEncoding = ID3TE_UTF8; else if (textEncodingID == "ISO-8859-1") textEncoding = ID3TE_ISO8859_1; else if (textEncodingID == "UTF-16" || textEncodingID == "UCS-2" || textEncodingID == "UTF-16LE" || textEncodingID == "UCS-2LE") textEncoding = ID3TE_UTF16; else if (textEncodingID == "UTF-16BE" || textEncodingID == "UCS-2BE") textEncoding = ID3TE_UTF16BE; /* Set ID3v2 version according to encoding. */ if (textEncodingID == "UTF-16BE" || textEncodingID == "UTF-8") container.SetSpec(ID3V2_4_0); else container.SetSpec(ID3V2_3_0); /* Save basic information. */ Info info = track.GetInfo(); if (info.artist != NIL) { ID3_Frame frame(ID3FID_LEADARTIST); SetStringField(frame, ID3FN_TEXT, info.artist); container.AddFrame(frame); } if (info.title != NIL) { ID3_Frame frame(ID3FID_TITLE); SetStringField(frame, ID3FN_TEXT, info.title); container.AddFrame(frame); } if (info.album != NIL) { ID3_Frame frame(ID3FID_ALBUM); SetStringField(frame, ID3FN_TEXT, info.album); container.AddFrame(frame); } if (info.genre != NIL) { ID3_Frame frame(ID3FID_CONTENTTYPE); SetStringField(frame, ID3FN_TEXT, info.genre); container.AddFrame(frame); } if (info.label != NIL) { ID3_Frame frame(ID3FID_PUBLISHER); SetStringField(frame, ID3FN_TEXT, info.label); container.AddFrame(frame); } if (info.isrc != NIL) { ID3_Frame frame(ID3FID_ISRC); SetStringField(frame, ID3FN_TEXT, info.isrc); container.AddFrame(frame); } if (info.year > 0) { ID3_Frame frame; if (container.GetSpec() == ID3V2_4_0) frame = ID3_Frame(ID3FID_RECORDINGTIME); else frame = ID3_Frame(ID3FID_YEAR); SetStringField(frame, ID3FN_TEXT, String::FromInt(info.year)); container.AddFrame(frame); } if (info.track > 0) { String trackString = String(prependZero && info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track)); if (info.numTracks > 0) trackString.Append("/").Append(prependZero && info.numTracks < 10 ? "0" : NIL).Append(String::FromInt(info.numTracks)); { ID3_Frame frame(ID3FID_TRACKNUM); SetStringField(frame, ID3FN_TEXT, trackString); container.AddFrame(frame); } } if (info.disc > 0) { String discString = String(prependZero && info.disc < 10 ? "0" : NIL).Append(String::FromInt(info.disc)); if (info.numDiscs > 0) discString.Append("/").Append(prependZero && info.numDiscs < 10 ? "0" : NIL).Append(String::FromInt(info.numDiscs)); { ID3_Frame frame(ID3FID_PARTINSET); SetStringField(frame, ID3FN_TEXT, discString); container.AddFrame(frame); } } if (info.rating >= 0) { Int rating = Math::Max(1, Math::Min(255, Math::Round(info.rating * 254 / 100.0) + 1)); { ID3_Frame frame(ID3FID_POPULARIMETER); SetStringField(frame, ID3FN_EMAIL, "rating@freac.org"); SetIntegerField(frame, ID3FN_RATING, rating); container.AddFrame(frame); } } /* Save comment. */ if ((info.comment != NIL && !replaceExistingComments) || (!isChapter && defaultComment != NIL)) { ID3_Frame frame(ID3FID_COMMENT); SetStringField(frame, ID3FN_LANGUAGE, "eng"); // iTunes recognizes comments only if language is set to English if (info.comment != NIL && !replaceExistingComments) SetStringField(frame, ID3FN_TEXT, info.comment, False); else SetStringField(frame, ID3FN_TEXT, defaultComment); container.AddFrame(frame); } /* Set band to album artist if only album artist is filled. */ if (info.HasOtherInfo(INFO_ALBUMARTIST) && !info.HasOtherInfo(INFO_BAND)) { info.SetOtherInfo(INFO_BAND, info.GetOtherInfo(INFO_ALBUMARTIST)); info.SetOtherInfo(INFO_ALBUMARTIST, NIL); } /* Save other text info. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "Album Artist"); container.AddFrame(frame); } else if (key == INFO_CONTENTGROUP) { ID3_Frame frame(ID3FID_CONTENTGROUP); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SUBTITLE) { ID3_Frame frame(ID3FID_SUBTITLE); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_BAND) { ID3_Frame frame(ID3FID_BAND); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_CONDUCTOR) { ID3_Frame frame(ID3FID_CONDUCTOR); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_REMIXER) { ID3_Frame frame(ID3FID_MIXARTIST); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_COMPOSER) { ID3_Frame frame(ID3FID_COMPOSER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_LYRICIST) { ID3_Frame frame(ID3FID_LYRICIST); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_PRODUCER) { Bool add = False; ID3_Frame *frame = container.Find(ID3FID_INVOLVEDPEOPLE); if (!frame) { add = True; frame = new ID3_Frame(ID3FID_INVOLVEDPEOPLE); } AddStringListItem(*frame, ID3FN_TEXT, "producer"); AddStringListItem(*frame, ID3FN_TEXT, value); if (add) container.AddFrame(frame); } else if (key == INFO_ORIG_ARTIST) { ID3_Frame frame(ID3FID_ORIGARTIST); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_ORIG_ALBUM) { ID3_Frame frame(ID3FID_ORIGALBUM); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_ORIG_LYRICIST) { ID3_Frame frame(ID3FID_ORIGLYRICIST); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_ORIG_YEAR) { ID3_Frame frame; if (container.GetSpec() == ID3V2_4_0) frame = ID3_Frame(ID3FID_ORIGRELEASETIME); else frame = ID3_Frame(ID3FID_ORIGYEAR); SetStringField(frame, ID3FN_TEXT, String::FromInt(info.year)); container.AddFrame(frame); } else if (key == INFO_MOVEMENT) { if (info.HasOtherInfo(INFO_MOVEMENTTOTAL)) value.Append("/").Append(info.GetOtherInfo(INFO_MOVEMENTTOTAL)); { ID3_Frame frame(ID3FID_MOVEMENT); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } } else if (key == INFO_MOVEMENTNAME) { ID3_Frame frame(ID3FID_MOVEMENTNAME); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_BPM) { ID3_Frame frame(ID3FID_BPM); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_INITIALKEY) { ID3_Frame frame(ID3FID_INITIALKEY); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_COPYRIGHT) { ID3_Frame frame(ID3FID_COPYRIGHT); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_MEDIATYPE) { ID3_Frame frame(ID3FID_MEDIATYPE); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_CATALOGNUMBER) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "CATALOGNUMBER"); container.AddFrame(frame); } else if (key == INFO_BARCODE) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "BARCODE"); container.AddFrame(frame); } else if (key == INFO_DISCSUBTITLE) { ID3_Frame frame(ID3FID_SETSUBTITLE); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_LYRICS) { ID3_Frame frame(ID3FID_UNSYNCEDLYRICS); SetStringField(frame, ID3FN_TEXT, value, False); SetStringField(frame, ID3FN_LANGUAGE, "und"); container.AddFrame(frame); } else if (key == INFO_SCRIPT) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "SCRIPT"); container.AddFrame(frame); } else if (key == INFO_RADIOSTATION) { ID3_Frame frame(ID3FID_NETRADIOSTATION); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_RADIOOWNER) { ID3_Frame frame(ID3FID_NETRADIOOWNER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SORT_ARTIST) { ID3_Frame frame(ID3FID_PERFORMERSORTORDER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SORT_ALBUM) { ID3_Frame frame(ID3FID_ALBUMSORTORDER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SORT_ALBUMARTIST) { ID3_Frame frame(ID3FID_ALBUMARTISTSORTORDER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SORT_COMPOSER) { ID3_Frame frame(ID3FID_COMPOSERSORTORDER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_SORT_TITLE) { ID3_Frame frame(ID3FID_TITLESORTORDER); SetStringField(frame, ID3FN_TEXT, value); container.AddFrame(frame); } else if (key == INFO_USERTEXT) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value.Tail(value.Length() - value.Find(":|:") - 3)); SetStringField(frame, ID3FN_DESCRIPTION, value.Head(value.Find(":|:"))); container.AddFrame(frame); } else if (key == INFO_WEB_ARTIST) { ID3_Frame frame(ID3FID_WWWARTIST); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_PUBLISHER) { ID3_Frame frame(ID3FID_WWWPUBLISHER); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_RADIO) { ID3_Frame frame(ID3FID_WWWRADIOPAGE); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_SOURCE) { ID3_Frame frame(ID3FID_WWWAUDIOSOURCE); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_COPYRIGHT) { ID3_Frame frame(ID3FID_WWWCOPYRIGHT); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_COMMERCIAL) { ID3_Frame frame(ID3FID_WWWCOMMERCIALINFO); SetStringField(frame, ID3FN_URL, value); container.AddFrame(frame); } else if (key == INFO_WEB_USERURL) { ID3_Frame frame(ID3FID_WWWUSER); SetStringField(frame, ID3FN_URL, value.Tail(value.Length() - value.Find(":|:") - 3)); SetStringField(frame, ID3FN_DESCRIPTION, value.Head(value.Find(":|:"))); container.AddFrame(frame); } else if (key == INFO_ASIN) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "ASIN"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_ARTISTID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Artist Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_ALBUMID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Album Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_ALBUMARTISTID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Album Artist Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_WORKID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Work Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_DISCID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Disc Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_TRACKID) { ID3_Frame frame(ID3FID_UNIQUEFILEID); Buffer buffer(value.Length()); memcpy(buffer, value.ConvertTo("ISO-8859-1"), value.Length()); SetStringField(frame, ID3FN_OWNER, "http://musicbrainz.org"); SetBinaryField(frame, ID3FN_DATA, buffer); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_ORIGINALARTISTID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Original Artist Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_ORIGINALALBUMID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Original Album Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_RELEASEGROUPID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Release Group Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_RELEASETRACKID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Release Track Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_TRMID) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz TRM Id"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_RELEASETYPE) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Album Type"); container.AddFrame(frame); } else if (key == INFO_MUSICBRAINZ_RELEASESTATUS) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Album Status"); container.AddFrame(frame); } else if (key == INFO_RELEASECOUNTRY) { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, value); SetStringField(frame, ID3FN_DESCRIPTION, "MusicBrainz Album Release Country"); container.AddFrame(frame); } } /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, info.track_gain); SetStringField(frame, ID3FN_DESCRIPTION, "replaygain_track_gain"); container.AddFrame(frame); } { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, info.track_peak); SetStringField(frame, ID3FN_DESCRIPTION, "replaygain_track_peak"); container.AddFrame(frame); } } if (info.album_gain != NIL && info.album_peak != NIL) { { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, info.album_gain); SetStringField(frame, ID3FN_DESCRIPTION, "replaygain_album_gain"); container.AddFrame(frame); } { ID3_Frame frame(ID3FID_USERTEXT); SetStringField(frame, ID3FN_TEXT, info.album_peak); SetStringField(frame, ID3FN_DESCRIPTION, "replaygain_album_peak"); container.AddFrame(frame); } } } /* Save CD table of contents. */ if (writeMCDI && info.mcdi.IsValid() && !isChapter) { ID3_Frame frame_mcdi(ID3FID_CDID); SetBinaryField(frame_mcdi, ID3FN_DATA, info.mcdi.GetData()); container.AddFrame(frame_mcdi); } /* Save encoder version. */ if (!isChapter) { Application *app = Application::Get(); ID3_Frame frame(ID3FID_ENCODERSETTINGS); SetStringField(frame, ID3FN_TEXT, app->getClientName.Call().Append(" ").Append(app->getClientVersion.Call())); container.AddFrame(frame); } /* Save album art. */ if (albumArtWriteToTags && albumArtWriteToID3v2) { foreach (const Picture &picInfo, track.pictures) { ID3_Frame frame_picture(ID3FID_PICTURE); /* Set the description field and try to stay compatible with * iTunes which expects it to be in a single byte encoding. */ if (picInfo.description != NIL) { String savedEncodingID = textEncodingID; ID3_TextEnc savedEncoding = textEncoding; if (textEncodingID != "UTF-8" && !String::IsUnicode(picInfo.description)) { textEncodingID = "ISO-8859-1"; textEncoding = ID3TE_ISO8859_1; } SetStringField(frame_picture, ID3FN_DESCRIPTION, picInfo.description); textEncodingID = savedEncodingID; textEncoding = savedEncoding; } /* Set picture data. */ if (picInfo.mime != NIL) SetStringField(frame_picture, ID3FN_MIMETYPE, picInfo.mime); SetIntegerField(frame_picture, ID3FN_PICTURETYPE, picInfo.type); SetBinaryField(frame_picture, ID3FN_DATA, picInfo.data); container.AddFrame(frame_picture); } } /* Save chapters. */ if (!isChapter && track.tracks.Length() > 0 && writeChapters) { /* Write TOC frame. */ ID3_Frame frame_toc(ID3FID_TOC); SetStringField(frame_toc, ID3FN_ID, String("toc")); SetIntegerField(frame_toc, ID3FN_FLAGS, ID3TF_TOPLEVEL | ID3TF_ORDERED); for (Int i = 0; i < track.tracks.Length(); i++) { frame_toc.GetField(ID3FN_CHAPTERS)->Add((char *) String("chp").Append(String::FromInt(i))); } container.AddFrame(frame_toc); /* Write chapter frames. */ Int64 offset = 0; for (Int i = 0; i < track.tracks.Length(); i++) { const Track &chapterTrack = track.tracks.GetNth(i); const Format &chapterFormat = chapterTrack.GetFormat(); ID3_Frame frame_chapter(ID3FID_CHAPTER); SetStringField(frame_chapter, ID3FN_ID, String("chp").Append(String::FromInt(i))); SetIntegerField(frame_chapter, ID3FN_STARTTIME, Float(offset) * 1000.0 / chapterFormat.rate); if (chapterTrack.length >= 0) SetIntegerField(frame_chapter, ID3FN_ENDTIME, Float(offset + chapterTrack.length) * 1000.0 / chapterFormat.rate); else if (chapterTrack.approxLength >= 0) SetIntegerField(frame_chapter, ID3FN_ENDTIME, Float(offset + chapterTrack.approxLength) * 1000.0 / chapterFormat.rate); /* Render individual chapter information. */ RenderContainer(*frame_chapter.GetField(ID3FN_FRAMES), chapterTrack, True); container.AddFrame(frame_chapter); if (chapterTrack.length >= 0) offset += chapterTrack.length; else if (chapterTrack.approxLength >= 0) offset += chapterTrack.approxLength; } } return Success(); } Int BoCA::TaggerID3v2::ParseContainer(const ID3_Container &container, Track &track) { const Config *currentConfig = GetConfiguration(); Info info = track.GetInfo(); /* Parse individual comment items. */ ID3_Container::ConstIterator *iterator = container.CreateIterator(); Bool haveChapters = False; String overDriveMarkers; for (UnsignedInt i = 0; i < container.NumFrames(); i++) { const ID3_Frame &frame = *iterator->GetNext(); if (frame.GetID() == ID3FID_LEADARTIST) info.artist = GetStringField(frame, ID3FN_TEXT); else if (frame.GetID() == ID3FID_TITLE) info.title = GetStringField(frame, ID3FN_TEXT); else if (frame.GetID() == ID3FID_ALBUM) info.album = GetStringField(frame, ID3FN_TEXT); else if (frame.GetID() == ID3FID_YEAR) info.year = GetStringField(frame, ID3FN_TEXT).ToInt(); else if (frame.GetID() == ID3FID_RECORDINGTIME) info.year = GetStringField(frame, ID3FN_TEXT).Head(4).ToInt(); else if (frame.GetID() == ID3FID_COMMENT) info.comment = GetStringField(frame, ID3FN_TEXT, False); else if (frame.GetID() == ID3FID_PUBLISHER) info.label = GetStringField(frame, ID3FN_TEXT); else if (frame.GetID() == ID3FID_ISRC) { if (Info::IsISRC(GetStringField(frame, ID3FN_TEXT))) info.isrc = GetStringField(frame, ID3FN_TEXT); } else if (frame.GetID() == ID3FID_CONTENTGROUP) info.SetOtherInfo(INFO_CONTENTGROUP, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_SUBTITLE) info.SetOtherInfo(INFO_SUBTITLE, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_BAND) info.SetOtherInfo(INFO_BAND, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_CONDUCTOR) info.SetOtherInfo(INFO_CONDUCTOR, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_MIXARTIST) info.SetOtherInfo(INFO_REMIXER, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_COMPOSER) info.SetOtherInfo(INFO_COMPOSER, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_LYRICIST) info.SetOtherInfo(INFO_LYRICIST, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_INVOLVEDPEOPLE || frame.GetID() == ID3FID_INVOLVEDPEOPLE2) { const Array &list = GetStringListField(frame, ID3FN_TEXT); for (Int i = 0; i < list.Length(); i += 2) { String description = list.GetNth(i); String value = list.GetNth(i + 1); if (value == NIL) continue; if (description.ToLower() == "producer") info.SetOtherInfo(INFO_PRODUCER, value); } } else if (frame.GetID() == ID3FID_ORIGARTIST) info.SetOtherInfo(INFO_ORIG_ARTIST, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ORIGALBUM) info.SetOtherInfo(INFO_ORIG_ALBUM, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ORIGLYRICIST) info.SetOtherInfo(INFO_ORIG_LYRICIST, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ORIGYEAR) info.SetOtherInfo(INFO_ORIG_YEAR, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ORIGRELEASETIME) info.SetOtherInfo(INFO_ORIG_YEAR, GetStringField(frame, ID3FN_TEXT).Head(4)); else if (frame.GetID() == ID3FID_MOVEMENT) { String movementString = GetStringField(frame, ID3FN_TEXT); info.SetOtherInfo(INFO_MOVEMENT, String::FromInt(movementString.ToInt())); if (movementString.Contains("/")) info.SetOtherInfo(INFO_MOVEMENTTOTAL, movementString.Tail(movementString.Length() - movementString.Find("/") - 1)); } else if (frame.GetID() == ID3FID_MOVEMENTNAME) info.SetOtherInfo(INFO_MOVEMENTNAME, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_BPM) { if (GetStringField(frame, ID3FN_TEXT).ToInt() > 0) info.SetOtherInfo(INFO_BPM, GetStringField(frame, ID3FN_TEXT)); } else if (frame.GetID() == ID3FID_INITIALKEY) info.SetOtherInfo(INFO_INITIALKEY, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_COPYRIGHT) info.SetOtherInfo(INFO_COPYRIGHT, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_MEDIATYPE) info.SetOtherInfo(INFO_MEDIATYPE, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_SETSUBTITLE) info.SetOtherInfo(INFO_DISCSUBTITLE, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_UNSYNCEDLYRICS) info.SetOtherInfo(INFO_LYRICS, GetStringField(frame, ID3FN_TEXT, False)); else if (frame.GetID() == ID3FID_NETRADIOSTATION) info.SetOtherInfo(INFO_RADIOSTATION, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_NETRADIOOWNER) info.SetOtherInfo(INFO_RADIOOWNER, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_PERFORMERSORTORDER) info.SetOtherInfo(INFO_SORT_ARTIST, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ALBUMSORTORDER) info.SetOtherInfo(INFO_SORT_ALBUM, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_ALBUMARTISTSORTORDER) info.SetOtherInfo(INFO_SORT_ALBUMARTIST, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_COMPOSERSORTORDER) info.SetOtherInfo(INFO_SORT_COMPOSER, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_TITLESORTORDER) info.SetOtherInfo(INFO_SORT_TITLE, GetStringField(frame, ID3FN_TEXT)); else if (frame.GetID() == ID3FID_WWWARTIST) info.SetOtherInfo(INFO_WEB_ARTIST, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWPUBLISHER) info.SetOtherInfo(INFO_WEB_PUBLISHER, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWRADIOPAGE) info.SetOtherInfo(INFO_WEB_RADIO, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWAUDIOSOURCE) info.SetOtherInfo(INFO_WEB_SOURCE, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWCOPYRIGHT) info.SetOtherInfo(INFO_WEB_COPYRIGHT, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWCOMMERCIALINFO) info.SetOtherInfo(INFO_WEB_COMMERCIAL, GetStringField(frame, ID3FN_URL)); else if (frame.GetID() == ID3FID_WWWUSER) { String description = GetStringField(frame, ID3FN_DESCRIPTION); String value = GetStringField(frame, ID3FN_URL); if (value == NIL) continue; info.other.Add(String(INFO_WEB_USERURL).Append(":").Append(description).Append(":|:").Append(value)); } else if (frame.GetID() == ID3FID_TRACKNUM) { String trackString = GetStringField(frame, ID3FN_TEXT); info.track = trackString.ToInt(); if (trackString.Contains("/")) info.numTracks = trackString.Tail(trackString.Length() - trackString.Find("/") - 1).ToInt(); } else if (frame.GetID() == ID3FID_PARTINSET) { String discString = GetStringField(frame, ID3FN_TEXT); info.disc = discString.ToInt(); if (discString.Contains("/")) info.numDiscs = discString.Tail(discString.Length() - discString.Find("/") - 1).ToInt(); } else if (frame.GetID() == ID3FID_POPULARIMETER) { Int rating = GetIntegerField(frame, ID3FN_RATING); if (rating > 0) info.rating = Math::Max(0, Math::Min(100, Math::Round((rating - 1) * 100 / 254.0))); } else if (frame.GetID() == ID3FID_USERTEXT) { String description = GetStringField(frame, ID3FN_DESCRIPTION); String value = GetStringField(frame, ID3FN_TEXT); if (value == NIL) continue; if (description.ToLower() == "album artist") info.SetOtherInfo(INFO_ALBUMARTIST, value); else if (description.ToLower() == "catalognumber") info.SetOtherInfo(INFO_CATALOGNUMBER, value); else if (description.ToLower() == "barcode") info.SetOtherInfo(INFO_BARCODE, value); else if (description.ToLower() == "script") info.SetOtherInfo(INFO_SCRIPT, value); else if (description.ToLower() == "asin") info.SetOtherInfo(INFO_ASIN, value); else if (description.ToLower().StartsWith("musicbrainz")) { if (description.ToLower() == "musicbrainz artist id") info.SetOtherInfo(INFO_MUSICBRAINZ_ARTISTID, value); else if (description.ToLower() == "musicbrainz album id") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMID, value); else if (description.ToLower() == "musicbrainz album artist id") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMARTISTID, value); else if (description.ToLower() == "musicbrainz work id") info.SetOtherInfo(INFO_MUSICBRAINZ_WORKID, value); else if (description.ToLower() == "musicbrainz disc id") info.SetOtherInfo(INFO_MUSICBRAINZ_DISCID, value); else if (description.ToLower() == "musicbrainz original artist id") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALARTISTID, value); else if (description.ToLower() == "musicbrainz original album id") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALALBUMID, value); else if (description.ToLower() == "musicbrainz release group id") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASEGROUPID, value); else if (description.ToLower() == "musicbrainz release track id") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETRACKID, value); else if (description.ToLower() == "musicbrainz trm id") info.SetOtherInfo(INFO_MUSICBRAINZ_TRMID, value); else if (description.ToLower() == "musicbrainz album type") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETYPE, value); else if (description.ToLower() == "musicbrainz album status") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASESTATUS, value); else if (description.ToLower() == "musicbrainz album release country") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); } else if (description.ToLower().StartsWith("replaygain")) { if (description.ToLower() == "replaygain_track_gain") info.track_gain = value; else if (description.ToLower() == "replaygain_track_peak") info.track_peak = value; else if (description.ToLower() == "replaygain_album_gain") info.album_gain = value; else if (description.ToLower() == "replaygain_album_peak") info.album_peak = value; } else if (description.ToLower() == "cuesheet") { if (currentConfig->GetIntValue(ConfigID, "ReadEmbeddedCueSheets", True)) { String::OutputFormat outputFormat("UTF-8"); /* Output cuesheet to temporary file. */ String cuesheet = value.Replace("\r\n", "\n"); String cueFile = S::System::System::GetTempDirectory().Append("cuesheet_temp_").Append(String::FromInt(track.fileName.ComputeCRC32())).Append(".cue"); OutStream out(STREAM_FILE, cueFile, OS_REPLACE); /* Write UTF-8 BOM. */ if (value[0] != 0xFEFF) out.OutputNumberRaw(0xEFBBBF, 3); /* Write cuesheet line by line. */ const Array &lines = cuesheet.Explode("\n"); out.OutputLine(String("FILE \"").Append(track.fileName).Append("\" WAVE")); foreach (const String &line, lines) { if (!line.Trim().StartsWith("FILE")) out.OutputLine(line); } out.Close(); /* Get cue sheet stream info. */ AS::Registry &boca = AS::Registry::Get(); AS::DecoderComponent *decoder = (AS::DecoderComponent *) boca.CreateComponentByID("cuesheet-dec"); if (decoder != NIL) { Track cueTrack; Config *cueConfig = Config::Copy(GetConfiguration()); cueConfig->SetIntValue("Tags", "ReadChapters", False); cueConfig->SetIntValue("Tags", "ReadEmbeddedCueSheets", False); cueConfig->SetIntValue("CueSheet", "ReadInformationTags", True); cueConfig->SetIntValue("CueSheet", "PreferCueSheets", True); cueConfig->SetIntValue("CueSheet", "LookForAlternativeFiles", False); cueConfig->SetIntValue("CueSheet", "IgnoreErrors", False); decoder->SetConfiguration(cueConfig); decoder->GetStreamInfo(cueFile, cueTrack); boca.DeleteComponent(decoder); Config::Free(cueConfig); if (cueTrack.tracks.Length() > 0) track.tracks = cueTrack.tracks; } File(cueFile).Delete(); } } else if (description == "OverDrive MediaMarkers") { /* Save OverDrive markers to process as chapters further down. */ overDriveMarkers = value; } else info.other.Add(String(INFO_USERTEXT).Append(":").Append(description).Append(":|:").Append(value)); } else if (frame.GetID() == ID3FID_UNIQUEFILEID) { String owner = GetStringField(frame, ID3FN_OWNER); if (owner == "http://musicbrainz.org") { Buffer buffer; GetBinaryField(frame, ID3FN_DATA, buffer); buffer.Resize(buffer.Size() + 1); buffer[buffer.Size() - 1] = 0; info.SetOtherInfo(INFO_MUSICBRAINZ_TRACKID, (char *) (UnsignedByte *) buffer); } } else if (frame.GetID() == ID3FID_CONTENTTYPE) { String s_genre = GetStringField(frame, ID3FN_TEXT); String genreID; if (s_genre[0] == '(') { for (Int j = 1; j < s_genre.Length(); j++) { if (s_genre[j] == ')') break; genreID[j - 1] = s_genre[j]; } } if (genreID == NIL) info.genre = s_genre; else if (s_genre.Length() > genreID.Length() + 2) info.genre = s_genre.Tail(s_genre.Length() - genreID.Length() - 2); else info.genre = GetID3CategoryName(genreID.ToInt()); } else if (frame.GetID() == ID3FID_CDID) { Buffer data; GetBinaryField(frame, ID3FN_DATA, data); /* Use a heuristic to detect if this is a valid binary MCDI * field or the commonly used track offset string. */ Bool binary = False; for (Int i = 0; i < data.Size(); i++) { if (data[i] > 0 && data[i] < 0x20) { binary = True; break; } } if (binary) { /* Check validity of MCDI data and assign. */ MCDI mcdi(data); if (mcdi.IsValid()) info.mcdi.SetData(data); } else { /* Found offset string. */ for (Int i = 0; i < data.Size() / 2; i++) { info.offsets[i] = ((short *) (UnsignedByte *) data)[i]; if (info.offsets[i] == 0) break; } } } else if (frame.GetID() == ID3FID_PICTURE && currentConfig->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { Picture picture; Buffer buffer; GetBinaryField(frame, ID3FN_DATA, buffer); picture.description = GetStringField(frame, ID3FN_DESCRIPTION); picture.type = GetIntegerField(frame, ID3FN_PICTURETYPE); picture.mime = GetStringField(frame, ID3FN_MIMETYPE); picture.data = buffer; if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } } else if (frame.GetID() == ID3FID_CHAPTER) { /* Chapters are processed further down. */ haveChapters = True; } } /* Set album artist to band if only band is filled. */ if (info.HasOtherInfo(INFO_BAND) && !info.HasOtherInfo(INFO_ALBUMARTIST)) { info.SetOtherInfo(INFO_ALBUMARTIST, info.GetOtherInfo(INFO_BAND)); info.SetOtherInfo(INFO_BAND, NIL); } /* Set artist to album artist if artist is not filled. */ if (info.artist == NIL) info.artist = info.GetOtherInfo(INFO_ALBUMARTIST); /* Remove sub-tracks if main track has a track number. */ if (info.track > 0) track.tracks.RemoveAll(); track.SetInfo(info); delete iterator; /* Read chapters. */ if (haveChapters && currentConfig->GetIntValue(ConfigID, "ReadChapters", True) && (!currentConfig->GetIntValue(ConfigID, "PreferCueSheetsToChapters", True) || track.tracks.Length() == 0)) { track.tracks.RemoveAll(); Int chapterCount = 0; Array chapterIDs; iterator = container.CreateIterator(); for (UnsignedInt i = 0; i < container.NumFrames(); i++) { const ID3_Frame &frame = *iterator->GetNext(); if (frame.GetID() == ID3FID_TOC) { /* Respect first toplevel TOC only. */ if (chapterIDs.Length() == 0 && GetIntegerField(frame, ID3FN_FLAGS) & ID3TF_TOPLEVEL) { ID3_Field *chapters = frame.GetField(ID3FN_CHAPTERS); Buffer buffer(1024); for (UnsignedInt i = 0; i < chapters->GetNumTextItems(); i++) { buffer.Zero(); chapters->Get(buffer, buffer.Size(), i); String chapterID; chapterID.ImportFrom("ISO-8859-1", buffer); chapterIDs.Add(chapterID, chapterID.ComputeCRC32()); } } } else if (frame.GetID() == ID3FID_CHAPTER) { const Format &format = track.GetFormat(); /* Fill track data. */ Track rTrack; rTrack.fileName = track.fileName; rTrack.pictures = track.pictures; rTrack.sampleOffset = Math::Round(Float( frame.GetField(ID3FN_STARTTIME)->Get()) / 1000.0 * format.rate); rTrack.length = Math::Round(Float(frame.GetField(ID3FN_ENDTIME)->Get() - frame.GetField(ID3FN_STARTTIME)->Get()) / 1000.0 * format.rate); if (track.length > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * rTrack.length); else if (track.approxLength > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * rTrack.length); else rTrack.fileSize = rTrack.length * format.channels * (format.bits / 8); rTrack.SetFormat(format); /* Set track number and parent track info. */ Info info = track.GetInfo(); info.track = ++chapterCount; rTrack.SetInfo(info); /* Parse individual chapter information. */ ParseContainer(*frame.GetField(ID3FN_FRAMES), rTrack); /* Add track to track list. */ track.tracks.Add(rTrack, GetStringField(frame, ID3FN_ID).ComputeCRC32()); } } delete iterator; /* Ignore chapters that are not listed in TOC. */ if (chapterIDs.Length() > 0) { for (Int i = track.tracks.Length() - 1; i >= 0; i--) { if (chapterIDs.Get(track.tracks.GetNthIndex(i)) == NIL) track.tracks.RemoveNth(i); } } /* Discard chapters if their number does not match TOC. */ if (track.tracks.Length() != chapterIDs.Length()) { track.tracks.RemoveAll(); } } /* Read OverDrive MediaMarkers. */ if (!haveChapters && overDriveMarkers != NIL && currentConfig->GetIntValue(ConfigID, "ReadChapters", True) && (!currentConfig->GetIntValue(ConfigID, "PreferCueSheetsToChapters", True) || track.tracks.Length() == 0)) { track.tracks.RemoveAll(); if (!overDriveMarkers.StartsWith("").Append(overDriveMarkers); XML::Document doc; const char *xml = overDriveMarkers.ConvertTo("UTF-8"); if (doc.ParseMemory(xml, strlen(xml)) == Success()) { XML::Node *root = doc.GetRootNode(); const Format &format = track.GetFormat(); Int chapterCount = 0; for (Int i = 0; i < root->GetNOfNodes(); i++) { XML::Node *marker = root->GetNthNode(i); if (marker->GetName() != "Marker") continue; String chapterName; String chapterTime; if (XML::Node *name = marker->GetNodeByName("Name")) chapterName = name->GetContent().Trim(); if (XML::Node *time = marker->GetNodeByName("Time")) chapterTime = time->GetContent().Trim(); chapterCount++; /* Fill track data. */ Track rTrack; rTrack.fileName = track.fileName; rTrack.pictures = track.pictures; Array chapterTimes = chapterTime.Explode(":"); if (chapterTimes.Length() == 2) chapterTimes.InsertAtPos(0, "00"); rTrack.sampleOffset = chapterTimes.GetNth(0).ToInt() * 60 * 60 * format.rate; rTrack.sampleOffset += chapterTimes.GetNth(1).ToInt() * 60 * format.rate; rTrack.sampleOffset += Math::Round(chapterTimes.GetNth(2).ToFloat() * format.rate); if (track.length > 0) rTrack.length = track.length - rTrack.sampleOffset; else if (track.approxLength > 0) rTrack.approxLength = track.approxLength - rTrack.sampleOffset; if (track.length > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * rTrack.length); else if (track.approxLength > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * rTrack.length); else rTrack.fileSize = rTrack.length * format.channels * (format.bits / 8); rTrack.SetFormat(format); /* Set track title. */ Info info = track.GetInfo(); info.title = chapterName; info.track = chapterCount; rTrack.SetInfo(info); /* Update previous track length. */ if (chapterCount > 1) { Track &pTrack = track.tracks.GetReference(chapterCount - 1); pTrack.length = rTrack.sampleOffset - pTrack.sampleOffset; if (track.length > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * pTrack.length); else if (track.approxLength > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * pTrack.length); else pTrack.fileSize = pTrack.length * format.channels * (format.bits / 8); } /* Add track to track list. */ track.tracks.Add(rTrack); } } } return Success(); } String BoCA::TaggerID3v2::GetStringField(const ID3_Frame &frame, ID3_FieldID fieldType, Bool trim) { if (!frame.Contains(fieldType)) return NIL; ID3_Field *field = frame.GetField(fieldType); ID3_TextEnc encoding = ID3TE_ISO8859_1; if (field->IsEncodable()) encoding = (ID3_TextEnc) GetIntegerField(frame, ID3FN_TEXTENC); String result; if (encoding == ID3TE_ISO8859_1 || encoding == ID3TE_UTF8) { Buffer aBuffer(field->Size() + 1); aBuffer.Zero(); field->Get(aBuffer, field->Size()); if (encoding == ID3TE_ISO8859_1) result.ImportFrom("ISO-8859-1", aBuffer); else if (encoding == ID3TE_UTF8) result.ImportFrom("UTF-8", aBuffer); } else if (encoding == ID3TE_UTF16 || encoding == ID3TE_UTF16BE) { Buffer wBuffer(field->Size() + 1); wBuffer.Zero(); field->Get((unicode_t *) (wchar_t *) wBuffer, field->Size()); result.ImportFrom("UTF-16BE", (char *) (wchar_t *) wBuffer); } return trim ? result.Trim() : result; } Int BoCA::TaggerID3v2::SetStringField(ID3_Frame &frame, ID3_FieldID fieldType, const String &value, Bool trim) { String string = trim ? value.Trim() : value; if (!frame.Contains(fieldType) || string == NIL) return Error(); ID3_Field *field = frame.GetField(fieldType); ID3_TextEnc encoding = ID3TE_ISO8859_1; if (field->IsEncodable()) { encoding = textEncoding; SetIntegerField(frame, ID3FN_TEXTENC, textEncoding); } field->SetEncoding(encoding); if (encoding == ID3TE_UTF16) field->Set((unicode_t *) string.ConvertTo("UTF-16LE")); else if (encoding == ID3TE_UTF16BE) field->Set((unicode_t *) string.ConvertTo("UTF-16BE")); else if (encoding == ID3TE_ISO8859_1) field->Set((char *) string.ConvertTo("ISO-8859-1")); else field->Set((char *) string.ConvertTo(textEncodingID)); return Success(); } Array BoCA::TaggerID3v2::GetStringListField(const ID3_Frame &frame, ID3_FieldID fieldType, Bool trim) { if (!frame.Contains(fieldType)) return Array(); ID3_Field *field = frame.GetField(fieldType); ID3_TextEnc encoding = (ID3_TextEnc) GetIntegerField(frame, ID3FN_TEXTENC); Int num = field->GetNumTextItems(); Array result; if (encoding == ID3TE_ISO8859_1 || encoding == ID3TE_UTF8) { Buffer aBuffer(field->Size() + 1); aBuffer.Zero(); for (Int i = 0; i < num; i++) { field->Get(aBuffer, field->Size(), i); String string; if (encoding == ID3TE_ISO8859_1) string.ImportFrom("ISO-8859-1", aBuffer); else if (encoding == ID3TE_UTF8) string.ImportFrom("UTF-8", aBuffer); result.Add(trim ? string.Trim() : string); } } else if (encoding == ID3TE_UTF16 || encoding == ID3TE_UTF16BE) { Buffer wBuffer(field->Size() + 1); wBuffer.Zero(); for (Int i = 0; i < num; i++) { field->Get((unicode_t *) (wchar_t *) wBuffer, field->Size(), i); String string; string.ImportFrom("UTF-16BE", (char *) (wchar_t *) wBuffer); result.Add(trim ? string.Trim() : string); } } return result; } Int BoCA::TaggerID3v2::AddStringListItem(ID3_Frame &frame, ID3_FieldID fieldType, const String &value, Bool trim) { String string = trim ? value.Trim() : value; if (!frame.Contains(fieldType) || string == NIL) return Error(); SetIntegerField(frame, ID3FN_TEXTENC, textEncoding); ID3_Field *field = frame.GetField(fieldType); field->SetEncoding(textEncoding); if (textEncoding == ID3TE_UTF16) field->Add((unicode_t *) string.ConvertTo("UTF-16LE")); else if (textEncoding == ID3TE_UTF16BE) field->Add((unicode_t *) string.ConvertTo("UTF-16BE")); else field->Add((char *) string.ConvertTo(textEncodingID)); return Success(); } Int BoCA::TaggerID3v2::GetIntegerField(const ID3_Frame &frame, ID3_FieldID fieldType) { if (!frame.Contains(fieldType)) return -1; ID3_Field *field = frame.GetField(fieldType); return field->Get(); } Int BoCA::TaggerID3v2::SetIntegerField(ID3_Frame &frame, ID3_FieldID fieldType, Int value) { if (!frame.Contains(fieldType)) return Error(); ID3_Field *field = frame.GetField(fieldType); field->Set(value); return Success(); } Int BoCA::TaggerID3v2::GetBinaryField(const ID3_Frame &frame, ID3_FieldID fieldType, Buffer &buffer) { if (!frame.Contains(fieldType)) return Error(); ID3_Field *field = frame.GetField(fieldType); buffer.Resize(field->Size()); field->Get(buffer, buffer.Size()); return Success(); } Int BoCA::TaggerID3v2::SetBinaryField(ID3_Frame &frame, ID3_FieldID fieldType, const Buffer &data) { if (!frame.Contains(fieldType) || data.Size() == 0) return Error(); ID3_Field *field = frame.GetField(fieldType); field->Set(data, data.Size()); return Success(); } const String &BoCA::TaggerID3v2::GetID3CategoryName(UnsignedInt id) { static const String empty; if (id > 191) return empty; else return genres[id]; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/id3v2.h000066400000000000000000000041621516712004000236540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include BoCA_BEGIN_COMPONENT(TaggerID3v2) namespace BoCA { class TaggerID3v2 : public CS::TaggerComponent { private: static const String ConfigID; static const String genres[192]; String textEncodingID; ID3_TextEnc textEncoding; Int ParseContainer(const ID3_Container &, Track &); Int RenderContainer(ID3_Container &, const Track &, Bool = False); String GetStringField(const ID3_Frame &, ID3_FieldID, Bool = True); Int SetStringField(ID3_Frame &, ID3_FieldID, const String &, Bool = True); Array GetStringListField(const ID3_Frame &, ID3_FieldID, Bool = True); Int AddStringListItem(ID3_Frame &, ID3_FieldID, const String &, Bool = True); Int GetIntegerField(const ID3_Frame &, ID3_FieldID); Int SetIntegerField(ID3_Frame &, ID3_FieldID, Int); Int GetBinaryField(const ID3_Frame &, ID3_FieldID, Buffer &); Int SetBinaryField(ID3_Frame &, ID3_FieldID, const Buffer &); Error UpdateChunkedFileTag(const String &, const Track &); static const String &GetID3CategoryName(UnsignedInt); public: static const String &GetComponentSpecs(); TaggerID3v2(); ~TaggerID3v2(); Error ParseBuffer(const Buffer &, Track &); Error ParseStreamInfo(const String &, Track &); Error RenderBuffer(Buffer &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerID3v2) BoCA_END_COMPONENT(TaggerID3v2) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/000077500000000000000000000000001516712004000235115ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/Makefile000066400000000000000000000007161516712004000251550ustar00rootroot00000000000000BOCA_PATH = ../../../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options OBJECTS = adler32.o compress.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o TARGET = libz.a CCOPTS = -I"$(SRCDIR)" AR = ar ifneq ($(BUILD_WIN32),True) CCOPTS += -fPIC endif all: $(TARGET) $(TARGET): $(OBJECTS) $(AR) rs $@ $(OBJECTS) clean: rm -f $(TARGET) $(OBJECTS) .c.o: $(CC) $(CCOPTS) $(CFLAGS) -c $< -o $@ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/adler32.c000066400000000000000000000115441516712004000251160ustar00rootroot00000000000000/* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-2011, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" #define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* use NO_DIVIDE if your processor does not do division in hardware -- try it both ways to see which is faster */ #ifdef NO_DIVIDE /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 (thank you to John Reiser for pointing this out) */ # define CHOP(a) \ do { \ unsigned long tmp = a >> 16; \ a &= 0xffffUL; \ a += (tmp << 4) - tmp; \ } while (0) # define MOD28(a) \ do { \ CHOP(a); \ if (a >= BASE) a -= BASE; \ } while (0) # define MOD(a) \ do { \ CHOP(a); \ MOD28(a); \ } while (0) # define MOD63(a) \ do { /* this assumes a is not negative */ \ z_off64_t tmp = a >> 32; \ a &= 0xffffffffL; \ a += (tmp << 8) - (tmp << 5) + tmp; \ tmp = a >> 16; \ a &= 0xffffL; \ a += (tmp << 4) - tmp; \ tmp = a >> 16; \ a &= 0xffffL; \ a += (tmp << 4) - tmp; \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE # define MOD28(a) a %= BASE # define MOD63(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { unsigned long sum2; unsigned n; /* split Adler-32 into component sums */ sum2 = (adler >> 16) & 0xffff; adler &= 0xffff; /* in case user likes doing a byte at a time, keep it fast */ if (len == 1) { adler += buf[0]; if (adler >= BASE) adler -= BASE; sum2 += adler; if (sum2 >= BASE) sum2 -= BASE; return adler | (sum2 << 16); } /* initial Adler-32 value (deferred check for len == 1 speed) */ if (buf == Z_NULL) return 1L; /* in case short lengths are provided, keep it somewhat fast */ if (len < 16) { while (len--) { adler += *buf++; sum2 += adler; } if (adler >= BASE) adler -= BASE; MOD28(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX; n = NMAX / 16; /* NMAX is divisible by 16 */ do { DO16(buf); /* 16 sums unrolled */ buf += 16; } while (--n); MOD(adler); MOD(sum2); } /* do remaining bytes (less than NMAX, still just one modulo) */ if (len) { /* avoid modulos if none remaining */ while (len >= 16) { len -= 16; DO16(buf); buf += 16; } while (len--) { adler += *buf++; sum2 += adler; } MOD(adler); MOD(sum2); } /* return recombined sums */ return adler | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { return adler32_z(adler, buf, len); } /* ========================================================================= */ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { unsigned long sum1; unsigned long sum2; unsigned rem; /* for negative len, return invalid adler32 as a clue for debugging */ if (len2 < 0) return 0xffffffffUL; /* the derivation of this formula is left as an exercise for the reader */ MOD63(len2); /* assumes len2 >= 0 */ rem = (unsigned)len2; sum1 = adler1 & 0xffff; sum2 = rem * sum1; MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 >= BASE) sum1 -= BASE; if (sum1 >= BASE) sum1 -= BASE; if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { return adler32_combine_(adler1, adler2, len2); } uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { return adler32_combine_(adler1, adler2, len2); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/compress.c000066400000000000000000000050651516712004000255160ustar00rootroot00000000000000/* compress.c -- compress a memory buffer * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; uLong left; left = *destLen; *destLen = 0; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; err = deflateInit(&stream, level); if (err != Z_OK) return err; stream.next_out = dest; stream.avail_out = 0; stream.next_in = (z_const Bytef *)source; stream.avail_in = 0; do { if (stream.avail_out == 0) { stream.avail_out = left > (uLong)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; sourceLen -= stream.avail_in; } err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); } while (err == Z_OK); *destLen = stream.total_out; deflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err; } /* =========================================================================== */ int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } /* =========================================================================== If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ uLong ZEXPORT compressBound(uLong sourceLen) { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/crc32.c000066400000000000000000000755651516712004000246130ustar00rootroot00000000000000/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2022 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * This interleaved implementation of a CRC makes use of pipelined multiple * arithmetic-logic units, commonly found in modern CPU cores. It is due to * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. */ /* @(#) $Id$ */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). MAKECRCH can be #defined to write out crc32.h. A main() routine is also produced, so that this one source file can be compiled to an executable. */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ /* A CRC of a message is computed on N braids of words in the message, where each word consists of W bytes (4 or 8). If N is 3, for example, then three running sparse CRCs are calculated respectively on each braid, at these indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... This is done starting at a word boundary, and continues until as many blocks of N * W bytes as are available have been processed. The results are combined into a single CRC at the end. For this code, N must be in the range 1..6 and W must be 4 or 8. The upper limit on N can be increased if desired by adding more #if blocks, extending the patterns apparent in the code. In addition, crc32.h would need to be regenerated, if the maximum N value is increased. N and W are chosen empirically by benchmarking the execution time on a given processor. The choices for N and W below were based on testing on Intel Kaby Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 Octeon II processors. The Intel, AMD, and ARM processors were all fastest with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. They were all tested with either gcc or clang, all using the -O3 optimization level. Your mileage may vary. */ /* Define N */ #ifdef Z_TESTN # define N Z_TESTN #else # define N 5 #endif #if N < 1 || N > 6 # error N must be in 1..6 #endif /* z_crc_t must be at least 32 bits. z_word_t must be at least as long as z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and that bytes are eight bits. */ /* Define W and the associated z_word_t type. If W is not defined, then a braided calculation is not used, and the associated tables and code are not compiled. */ #ifdef Z_TESTW # if Z_TESTW-1 != -1 # define W Z_TESTW # endif #else # ifdef MAKECRCH # define W 8 /* required for MAKECRCH */ # else # if defined(__x86_64__) || defined(__aarch64__) # define W 8 # else # define W 4 # endif # endif #endif #ifdef W # if W == 8 && defined(Z_U8) typedef Z_U8 z_word_t; # elif defined(Z_U4) # undef W # define W 4 typedef Z_U4 z_word_t; # else # undef W # endif #endif /* If available, use the ARM processor CRC32 instruction. */ #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 # define ARMCRC32 #endif #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) /* Swap the bytes in a z_word_t to convert between little and big endian. Any self-respecting compiler will optimize this to a single machine byte-swap instruction, if one is available. This assumes that word_t is either 32 bits or 64 bits. */ local z_word_t byte_swap(z_word_t word) { # if W == 8 return (word & 0xff00000000000000) >> 56 | (word & 0xff000000000000) >> 40 | (word & 0xff0000000000) >> 24 | (word & 0xff00000000) >> 8 | (word & 0xff000000) << 8 | (word & 0xff0000) << 24 | (word & 0xff00) << 40 | (word & 0xff) << 56; # else /* W == 4 */ return (word & 0xff000000) >> 24 | (word & 0xff0000) >> 8 | (word & 0xff00) << 8 | (word & 0xff) << 24; # endif } #endif #ifdef DYNAMIC_CRC_TABLE /* ========================================================================= * Table of powers of x for combining CRC-32s, filled in by make_crc_table() * below. */ local z_crc_t FAR x2n_table[32]; #else /* ========================================================================= * Tables for byte-wise and braided CRC-32 calculations, and a table of powers * of x for combining CRC-32s, all made by make_crc_table(). */ # include "crc32.h" #endif /* CRC polynomial. */ #define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ /* Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, reflected. For speed, this requires that a not be zero. */ local z_crc_t multmodp(z_crc_t a, z_crc_t b) { z_crc_t m, p; m = (z_crc_t)1 << 31; p = 0; for (;;) { if (a & m) { p ^= b; if ((a & (m - 1)) == 0) break; } m >>= 1; b = b & 1 ? (b >> 1) ^ POLY : b >> 1; } return p; } /* Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been initialized. */ local z_crc_t x2nmodp(z_off64_t n, unsigned k) { z_crc_t p; p = (z_crc_t)1 << 31; /* x^0 == 1 */ while (n) { if (n & 1) p = multmodp(x2n_table[k & 31], p); n >>= 1; k++; } return p; } #ifdef DYNAMIC_CRC_TABLE /* ========================================================================= * Build the tables for byte-wise and braided CRC-32 calculations, and a table * of powers of x for combining CRC-32s. */ local z_crc_t FAR crc_table[256]; #ifdef W local z_word_t FAR crc_big_table[256]; local z_crc_t FAR crc_braid_table[W][256]; local z_word_t FAR crc_braid_big_table[W][256]; local void braid(z_crc_t [][256], z_word_t [][256], int, int); #endif #ifdef MAKECRCH local void write_table(FILE *, const z_crc_t FAR *, int); local void write_table32hi(FILE *, const z_word_t FAR *, int); local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ /* Define a once() function depending on the availability of atomics. If this is compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in multiple threads, and if atomics are not available, then get_crc_table() must be called to initialize the tables and must return before any threads are allowed to compute or combine CRCs. */ /* Definition of once functionality. */ typedef struct once_s once_t; /* Check for the availability of atomics. */ #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ !defined(__STDC_NO_ATOMICS__) #include /* Structure for once(), which must be initialized with ONCE_INIT. */ struct once_s { atomic_flag begun; atomic_int done; }; #define ONCE_INIT {ATOMIC_FLAG_INIT, 0} /* Run the provided init() function exactly once, even if multiple threads invoke once() at the same time. The state must be a once_t initialized with ONCE_INIT. */ local void once(once_t *state, void (*init)(void)) { if (!atomic_load(&state->done)) { if (atomic_flag_test_and_set(&state->begun)) while (!atomic_load(&state->done)) ; else { init(); atomic_store(&state->done, 1); } } } #else /* no atomics */ /* Structure for once(), which must be initialized with ONCE_INIT. */ struct once_s { volatile int begun; volatile int done; }; #define ONCE_INIT {0, 0} /* Test and set. Alas, not atomic, but tries to minimize the period of vulnerability. */ local int test_and_set(int volatile *flag) { int was; was = *flag; *flag = 1; return was; } /* Run the provided init() function once. This is not thread-safe. */ local void once(once_t *state, void (*init)(void)) { if (!state->done) { if (test_and_set(&state->begun)) while (!state->done) ; else { init(); state->done = 1; } } } #endif /* State for once(). */ local once_t made = ONCE_INIT; /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. */ local void make_crc_table(void) { unsigned i, j, n; z_crc_t p; /* initialize the CRC of bytes tables */ for (i = 0; i < 256; i++) { p = i; for (j = 0; j < 8; j++) p = p & 1 ? (p >> 1) ^ POLY : p >> 1; crc_table[i] = p; #ifdef W crc_big_table[i] = byte_swap(p); #endif } /* initialize the x^2^n mod p(x) table */ p = (z_crc_t)1 << 30; /* x^1 */ x2n_table[0] = p; for (n = 1; n < 32; n++) x2n_table[n] = p = multmodp(p, p); #ifdef W /* initialize the braiding tables -- needs x2n_table[] */ braid(crc_braid_table, crc_braid_big_table, N, W); #endif #ifdef MAKECRCH { /* The crc32.h header file contains tables for both 32-bit and 64-bit z_word_t's, and so requires a 64-bit type be available. In that case, z_word_t must be defined to be 64-bits. This code then also generates and writes out the tables for the case that z_word_t is 32 bits. */ #if !defined(W) || W != 8 # error Need a 64-bit integer type in order to generate crc32.h. #endif FILE *out; int k, n; z_crc_t ltl[8][256]; z_word_t big[8][256]; out = fopen("crc32.h", "w"); if (out == NULL) return; /* write out little-endian CRC table to crc32.h */ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n" " * Generated automatically by crc32.c\n */\n" "\n" "local const z_crc_t FAR crc_table[] = {\n" " "); write_table(out, crc_table, 256); fprintf(out, "};\n"); /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ fprintf(out, "\n" "#ifdef W\n" "\n" "#if W == 8\n" "\n" "local const z_word_t FAR crc_big_table[] = {\n" " "); write_table64(out, crc_big_table, 256); fprintf(out, "};\n"); /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ fprintf(out, "\n" "#else /* W == 4 */\n" "\n" "local const z_word_t FAR crc_big_table[] = {\n" " "); write_table32hi(out, crc_big_table, 256); fprintf(out, "};\n" "\n" "#endif\n"); /* write out braid tables for each value of N */ for (n = 1; n <= 6; n++) { fprintf(out, "\n" "#if N == %d\n", n); /* compute braid tables for this N and 64-bit word_t */ braid(ltl, big, n, 8); /* write out braid tables for 64-bit z_word_t to crc32.h */ fprintf(out, "\n" "#if W == 8\n" "\n" "local const z_crc_t FAR crc_braid_table[][256] = {\n"); for (k = 0; k < 8; k++) { fprintf(out, " {"); write_table(out, ltl[k], 256); fprintf(out, "}%s", k < 7 ? ",\n" : ""); } fprintf(out, "};\n" "\n" "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); for (k = 0; k < 8; k++) { fprintf(out, " {"); write_table64(out, big[k], 256); fprintf(out, "}%s", k < 7 ? ",\n" : ""); } fprintf(out, "};\n"); /* compute braid tables for this N and 32-bit word_t */ braid(ltl, big, n, 4); /* write out braid tables for 32-bit z_word_t to crc32.h */ fprintf(out, "\n" "#else /* W == 4 */\n" "\n" "local const z_crc_t FAR crc_braid_table[][256] = {\n"); for (k = 0; k < 4; k++) { fprintf(out, " {"); write_table(out, ltl[k], 256); fprintf(out, "}%s", k < 3 ? ",\n" : ""); } fprintf(out, "};\n" "\n" "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); for (k = 0; k < 4; k++) { fprintf(out, " {"); write_table32hi(out, big[k], 256); fprintf(out, "}%s", k < 3 ? ",\n" : ""); } fprintf(out, "};\n" "\n" "#endif\n" "\n" "#endif\n"); } fprintf(out, "\n" "#endif\n"); /* write out zeros operator table to crc32.h */ fprintf(out, "\n" "local const z_crc_t FAR x2n_table[] = {\n" " "); write_table(out, x2n_table, 32); fprintf(out, "};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH /* Write the 32-bit values in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ local void write_table(FILE *out, const z_crc_t FAR *table, int k) { int n; for (n = 0; n < k; n++) fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", (unsigned long)(table[n]), n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); } /* Write the high 32-bits of each value in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", (unsigned long)(table[n] >> 32), n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); } /* Write the 64-bit values in table[0..k-1] to out, three per line in hexadecimal separated by commas. This assumes that if there is a 64-bit type, then there is also a long long integer type, and it is at least 64 bits. If not, then the type cast and format string can be adjusted accordingly. */ local void write_table64(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", (unsigned long long)(table[n]), n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); } /* Actually do the deed. */ int main(void) { make_crc_table(); return 0; } #endif /* MAKECRCH */ #ifdef W /* Generate the little and big-endian braid tables for the given n and z_word_t size w. Each array must have room for w blocks of 256 elements. */ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { int k; z_crc_t i, p, q; for (k = 0; k < w; k++) { p = x2nmodp((n * w + 3 - k) << 3, 0); ltl[k][0] = 0; big[w - 1 - k][0] = 0; for (i = 1; i < 256; i++) { ltl[k][i] = q = multmodp(i << 24, p); big[w - 1 - k][i] = byte_swap(q); } } } #endif #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32(), and to force the * generation of the CRC tables in a threaded application. */ const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ return (const z_crc_t FAR *)crc_table; } /* ========================================================================= * Use ARM machine instructions if available. This will compute the CRC about * ten times faster than the braided calculation. This code does not check for * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will * only be defined if the compilation specifies an ARM processor architecture * that has the instructions. For example, compiling with -march=armv8.1-a or * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 * instructions. */ #ifdef ARMCRC32 /* Constants empirically determined to maximize speed. These values are from measurements on a Cortex-A57. Your mileage may vary. */ #define Z_BATCH 3990 /* number of words in a batch */ #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ #define Z_BATCH_MIN 800 /* fewest words in a final batch */ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z_size_t len) { z_crc_t val; z_word_t crc1, crc2; const z_word_t *word; z_word_t val0, val1, val2; z_size_t last, last2, i; z_size_t num; /* Return initial CRC, if requested. */ if (buf == Z_NULL) return 0; #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ crc = (~crc) & 0xffffffff; /* Compute the CRC up to a word boundary. */ while (len && ((z_size_t)buf & 7) != 0) { len--; val = *buf++; __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); } /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ word = (z_word_t const *)buf; num = len >> 3; len &= 7; /* Do three interleaved CRCs to realize the throughput of one crc32x instruction per cycle. Each CRC is calculated on Z_BATCH words. The three CRCs are combined into a single CRC after each set of batches. */ while (num >= 3 * Z_BATCH) { crc1 = 0; crc2 = 0; for (i = 0; i < Z_BATCH; i++) { val0 = word[i]; val1 = word[i + Z_BATCH]; val2 = word[i + 2 * Z_BATCH]; __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); } word += 3 * Z_BATCH; num -= 3 * Z_BATCH; crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; } /* Do one last smaller batch with the remaining words, if there are enough to pay for the combination of CRCs. */ last = num / 3; if (last >= Z_BATCH_MIN) { last2 = last << 1; crc1 = 0; crc2 = 0; for (i = 0; i < last; i++) { val0 = word[i]; val1 = word[i + last]; val2 = word[i + last2]; __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); } word += 3 * last; num -= 3 * last; val = x2nmodp(last, 6); crc = multmodp(val, crc) ^ crc1; crc = multmodp(val, crc) ^ crc2; } /* Compute the CRC on any remaining words. */ for (i = 0; i < num; i++) { val0 = word[i]; __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); } word += num; /* Complete the CRC on any remaining bytes. */ buf = (const unsigned char FAR *)word; while (len) { len--; val = *buf++; __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); } /* Return the CRC, post-conditioned. */ return crc ^ 0xffffffff; } #else #ifdef W /* Return the CRC of the W bytes in the word_t data, taking the least-significant byte of the word as the first byte of data, without any pre or post conditioning. This is used to combine the CRCs of each braid. */ local z_crc_t crc_word(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data >> 8) ^ crc_table[data & 0xff]; return (z_crc_t)data; } local z_word_t crc_word_big(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data << 8) ^ crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; return data; } #endif /* ========================================================================= */ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z_size_t len) { /* Return initial CRC, if requested. */ if (buf == Z_NULL) return 0; #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ crc = (~crc) & 0xffffffff; #ifdef W /* If provided enough bytes, do a braided CRC calculation. */ if (len >= N * W + W - 1) { z_size_t blks; z_word_t const *words; unsigned endian; int k; /* Compute the CRC up to a z_word_t boundary. */ while (len && ((z_size_t)buf & (W - 1)) != 0) { len--; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; } /* Compute the CRC on as many N z_word_t blocks as are available. */ blks = len / (N * W); len -= blks * N * W; words = (z_word_t const *)buf; /* Do endian check at execution time instead of compile time, since ARM processors can change the endianness at execution time. If the compiler knows what the endianness will be, it can optimize out the check and the unused branch. */ endian = 1; if (*(unsigned char *)&endian) { /* Little endian. */ z_crc_t crc0; z_word_t word0; #if N > 1 z_crc_t crc1; z_word_t word1; #if N > 2 z_crc_t crc2; z_word_t word2; #if N > 3 z_crc_t crc3; z_word_t word3; #if N > 4 z_crc_t crc4; z_word_t word4; #if N > 5 z_crc_t crc5; z_word_t word5; #endif #endif #endif #endif #endif /* Initialize the CRC for each braid. */ crc0 = crc; #if N > 1 crc1 = 0; #if N > 2 crc2 = 0; #if N > 3 crc3 = 0; #if N > 4 crc4 = 0; #if N > 5 crc5 = 0; #endif #endif #endif #endif #endif /* Process the first blks-1 blocks, computing the CRCs on each braid independently. */ while (--blks) { /* Load the word for each braid into registers. */ word0 = crc0 ^ words[0]; #if N > 1 word1 = crc1 ^ words[1]; #if N > 2 word2 = crc2 ^ words[2]; #if N > 3 word3 = crc3 ^ words[3]; #if N > 4 word4 = crc4 ^ words[4]; #if N > 5 word5 = crc5 ^ words[5]; #endif #endif #endif #endif #endif words += N; /* Compute and update the CRC for each word. The loop should get unrolled. */ crc0 = crc_braid_table[0][word0 & 0xff]; #if N > 1 crc1 = crc_braid_table[0][word1 & 0xff]; #if N > 2 crc2 = crc_braid_table[0][word2 & 0xff]; #if N > 3 crc3 = crc_braid_table[0][word3 & 0xff]; #if N > 4 crc4 = crc_braid_table[0][word4 & 0xff]; #if N > 5 crc5 = crc_braid_table[0][word5 & 0xff]; #endif #endif #endif #endif #endif for (k = 1; k < W; k++) { crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; #if N > 1 crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; #if N > 2 crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; #if N > 3 crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; #if N > 4 crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; #if N > 5 crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; #endif #endif #endif #endif #endif } } /* Process the last block, combining the CRCs of the N braids at the same time. */ crc = crc_word(crc0 ^ words[0]); #if N > 1 crc = crc_word(crc1 ^ words[1] ^ crc); #if N > 2 crc = crc_word(crc2 ^ words[2] ^ crc); #if N > 3 crc = crc_word(crc3 ^ words[3] ^ crc); #if N > 4 crc = crc_word(crc4 ^ words[4] ^ crc); #if N > 5 crc = crc_word(crc5 ^ words[5] ^ crc); #endif #endif #endif #endif #endif words += N; } else { /* Big endian. */ z_word_t crc0, word0, comb; #if N > 1 z_word_t crc1, word1; #if N > 2 z_word_t crc2, word2; #if N > 3 z_word_t crc3, word3; #if N > 4 z_word_t crc4, word4; #if N > 5 z_word_t crc5, word5; #endif #endif #endif #endif #endif /* Initialize the CRC for each braid. */ crc0 = byte_swap(crc); #if N > 1 crc1 = 0; #if N > 2 crc2 = 0; #if N > 3 crc3 = 0; #if N > 4 crc4 = 0; #if N > 5 crc5 = 0; #endif #endif #endif #endif #endif /* Process the first blks-1 blocks, computing the CRCs on each braid independently. */ while (--blks) { /* Load the word for each braid into registers. */ word0 = crc0 ^ words[0]; #if N > 1 word1 = crc1 ^ words[1]; #if N > 2 word2 = crc2 ^ words[2]; #if N > 3 word3 = crc3 ^ words[3]; #if N > 4 word4 = crc4 ^ words[4]; #if N > 5 word5 = crc5 ^ words[5]; #endif #endif #endif #endif #endif words += N; /* Compute and update the CRC for each word. The loop should get unrolled. */ crc0 = crc_braid_big_table[0][word0 & 0xff]; #if N > 1 crc1 = crc_braid_big_table[0][word1 & 0xff]; #if N > 2 crc2 = crc_braid_big_table[0][word2 & 0xff]; #if N > 3 crc3 = crc_braid_big_table[0][word3 & 0xff]; #if N > 4 crc4 = crc_braid_big_table[0][word4 & 0xff]; #if N > 5 crc5 = crc_braid_big_table[0][word5 & 0xff]; #endif #endif #endif #endif #endif for (k = 1; k < W; k++) { crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; #if N > 1 crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; #if N > 2 crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; #if N > 3 crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; #if N > 4 crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; #if N > 5 crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; #endif #endif #endif #endif #endif } } /* Process the last block, combining the CRCs of the N braids at the same time. */ comb = crc_word_big(crc0 ^ words[0]); #if N > 1 comb = crc_word_big(crc1 ^ words[1] ^ comb); #if N > 2 comb = crc_word_big(crc2 ^ words[2] ^ comb); #if N > 3 comb = crc_word_big(crc3 ^ words[3] ^ comb); #if N > 4 comb = crc_word_big(crc4 ^ words[4] ^ comb); #if N > 5 comb = crc_word_big(crc5 ^ words[5] ^ comb); #endif #endif #endif #endif #endif words += N; crc = byte_swap(comb); } /* Update the pointer to the remaining bytes to process. */ buf = (unsigned char const *)words; } #endif /* W */ /* Complete the computation of the CRC on any remaining bytes. */ while (len >= 8) { len -= 8; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; } while (len) { len--; crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; } /* Return the CRC, post-conditioned. */ return crc ^ 0xffffffff; } #endif /* ========================================================================= */ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len) { return crc32_z(crc, buf, len); } /* ========================================================================= */ uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); } /* ========================================================================= */ uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { return crc32_combine64(crc1, crc2, (z_off64_t)len2); } /* ========================================================================= */ uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ return x2nmodp(len2, 3); } /* ========================================================================= */ uLong ZEXPORT crc32_combine_gen(z_off_t len2) { return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/crc32.h000066400000000000000000022036051516712004000246060ustar00rootroot00000000000000/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const z_crc_t FAR crc_table[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; #ifdef W #if W == 8 local const z_word_t FAR crc_big_table[] = { 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, 0x8def022d00000000}; #else /* W == 4 */ local const z_word_t FAR crc_big_table[] = { 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, 0x8def022d}; #endif #if N == 1 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6}, {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30}, {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc}, {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c}, {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1}, {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed}, {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72}, {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, 0x8def022d00000000}, {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, 0x72fd249300000000}, {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, 0xed3498be00000000}, {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, 0xf10605de00000000}, {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, 0x8cc764ca00000000}, {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, 0xccabc4e400000000}, {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, 0x304a369200000000}, {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, 0xe6064b2600000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1}, {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed}, {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72}, {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, 0x8def022d}, {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, 0x72fd2493}, {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, 0xed3498be}, {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, 0xf10605de}}; #endif #endif #if N == 2 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, 0x0d7139d7}, {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, 0x1c53e98a}, {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, 0x3f88e851}, {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, 0x3dee8ca6}, {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, 0x36197165}, {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, 0x1a3b93aa}, {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, 0xe147d714}, {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, 0x494f0c4b}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, 0x4b0c4f4900000000}, {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, 0x14d747e100000000}, {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, 0xaa933b1a00000000}, {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, 0x6571193600000000}, {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, 0xa68cee3d00000000}, {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, 0x51e8883f00000000}, {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, 0x8ae9531c00000000}, {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, 0xd739710d00000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6}, {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30}, {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc}, {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, 0x8cc764ca}, {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, 0xccabc4e4}, {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, 0x304a3692}, {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, 0xe6064b26}}; #endif #endif #if N == 3 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, 0x09cd8551}, {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, 0x7bc97a0c}, {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, 0x7851a2ca}, {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, 0x566b6848}, {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, 0xd8ac6b35}, {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, 0xa140efa8}, {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, 0x917cd6a1}, {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, 0x18ba364e}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, 0x4e36ba1800000000}, {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, 0xa1d67c9100000000}, {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, 0xa8ef40a100000000}, {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, 0x356bacd800000000}, {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, 0x48686b5600000000}, {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, 0xcaa2517800000000}, {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, 0x0c7ac97b00000000}, {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, 0x5185cd0900000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, 0x36197165}, {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, 0x1a3b93aa}, {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, 0xe147d714}, {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, 0x494f0c4b}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, 0x4b0c4f49}, {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, 0x14d747e1}, {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, 0xaa933b1a}, {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, 0x65711936}}; #endif #endif #if N == 4 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, 0xe3c45916}, {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, 0xa7520488}, {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, 0x3522e9e4}, {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, 0x97411e28}, {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, 0x93c7a00b}, {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, 0xce5f968d}, {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, 0x3e721277}, {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, 0x1c65ace7}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, 0xe7ac651c00000000}, {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, 0x7712723e00000000}, {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, 0x8d965fce00000000}, {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, 0x0ba0c79300000000}, {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, 0x281e419700000000}, {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, 0xe4e9223500000000}, {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, 0x880452a700000000}, {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, 0x1659c4e300000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, 0x0d7139d7}, {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, 0x1c53e98a}, {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, 0x3f88e851}, {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, 0x3dee8ca6}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, 0xa68cee3d}, {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, 0x51e8883f}, {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, 0x8ae9531c}, {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, 0xd739710d}}; #endif #endif #if N == 5 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, 0xe9947565}, {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, 0xf7d05006}, {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, 0xb2075b94}, {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, 0xba50bcb9}, {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, 0x808abcf4}, {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, 0xefdb3f95}, {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, 0x0e2fbf43}, {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, 0xf4377108}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, 0x087137f400000000}, {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, 0x43bf2f0e00000000}, {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, 0x953fdbef00000000}, {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, 0xf4bc8a8000000000}, {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, 0xb9bc50ba00000000}, {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, 0x945b07b200000000}, {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, 0x0650d0f700000000}, {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, 0x657594e900000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, 0xd8ac6b35}, {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, 0xa140efa8}, {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, 0x917cd6a1}, {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, 0x18ba364e}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, 0x4e36ba18}, {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, 0xa1d67c91}, {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, 0xa8ef40a1}, {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, 0x356bacd8}}; #endif #endif #if N == 6 #if W == 8 local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, 0x8568a0a8}, {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, 0x0d907052}, {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, 0xfd1a6c8a}, {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, 0x7895f01a}, {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, 0x9239b848}, {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, 0xeb36d3cc}, {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, 0x38e5f3c5}, {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, 0x3d3101a2}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, 0xa201313d00000000}, {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, 0xc5f3e53800000000}, {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, 0xccd336eb00000000}, {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, 0x48b8399200000000}, {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, 0x1af0957800000000}, {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, 0x8a6c1afd00000000}, {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, 0x5270900d00000000}, {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, 0xa8a0688500000000}}; #else /* W == 4 */ local const z_crc_t FAR crc_braid_table[][256] = { {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, 0x09cd8551}, {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, 0x7bc97a0c}, {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, 0x7851a2ca}, {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, 0x566b6848}}; local const z_word_t FAR crc_braid_big_table[][256] = { {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, 0x48686b56}, {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, 0xcaa25178}, {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, 0x0c7ac97b}, {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, 0x5185cd09}}; #endif #endif #endif local const z_crc_t FAR x2n_table[] = { 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, 0xc40ba6d0, 0xc4e22c3c}; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/deflate.c000066400000000000000000002375031516712004000252730ustar00rootroot00000000000000/* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in http://tools.ietf.org/html/rfc1951 * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ /* @(#) $Id$ */ #include "deflate.h" const char deflate_copyright[] = " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func)(deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ local block_state deflate_stored(deflate_state *s, int flush); local block_state deflate_fast(deflate_state *s, int flush); #ifndef FASTEST local block_state deflate_slow(deflate_state *s, int flush); #endif local block_state deflate_rle(deflate_state *s, int flush); local block_state deflate_huff(deflate_state *s, int flush); /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ #define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to UPDATE_HASH are made with consecutive input * characters, so that a running hash key can be computed from the previous * key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. * IN assertion: all calls to INSERT_STRING are made with consecutive input * characters and the first MIN_MATCH bytes of str are valid (except for * the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ do { \ s->head[s->hash_size - 1] = NIL; \ zmemzero((Bytef *)s->head, \ (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ } while (0) /* =========================================================================== * Slide the hash table when sliding the window down (could be avoided with 32 * bit values at the expense of memory usage). We slide even when level == 0 to * keep the hash table consistent if we switch back to level > 0 later. */ #if defined(__has_feature) # if __has_feature(memory_sanitizer) __attribute__((no_sanitize("memory"))) # endif #endif local void slide_hash(deflate_state *s) { unsigned n, m; Posf *p; uInt wsize = s->w_size; n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m - wsize : NIL); } while (--n); n = wsize; #ifndef FASTEST p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m - wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); #endif } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; zmemcpy(buf, strm->next_in, len); if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, buf, len); } #ifdef GZIP else if (strm->state->wrap == 2) { strm->adler = crc32(strm->adler, buf, len); } #endif strm->next_in += len; strm->total_in += len; return len; } /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(deflate_state *s) { unsigned n; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (sizeof(int) <= 2) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ more--; } } /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (s->strstart >= wsize + MAX_DIST(s)) { zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; if (s->insert > s->strstart) s->insert = s->strstart; slide_hash(s); more += wsize; } if (s->strm->avail_in == 0) break; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead + s->insert >= MIN_MATCH) { uInt str = s->strstart - s->insert; s->ins_h = s->window[str]; UPDATE_HASH(s, s->ins_h, s->window[str + 1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif while (s->insert) { UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); #ifndef FASTEST s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif s->head[s->ins_h] = (Pos)str; str++; s->insert--; if (s->lookahead + s->insert < MIN_MATCH) break; } } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); /* If the WIN_INIT bytes after the end of the current data have never been * written, then zero those bytes in order to avoid memory check reports of * the use of uninitialized (or uninitialised as Julian writes) bytes by * the longest match routines. Update the high water mark for the next * time through here. WIN_INIT is set to MAX_MATCH since the longest match * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. */ if (s->high_water < s->window_size) { ulg curr = s->strstart + (ulg)(s->lookahead); ulg init; if (s->high_water < curr) { /* Previous high water mark below current data -- zero WIN_INIT * bytes or up to end of window, whichever is less. */ init = s->window_size - curr; if (init > WIN_INIT) init = WIN_INIT; zmemzero(s->window + curr, (unsigned)init); s->high_water = curr + init; } else if (s->high_water < (ulg)curr + WIN_INIT) { /* High water mark at or above current data, but below current data * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up * to end of window, whichever is less. */ init = (ulg)curr + WIN_INIT - s->high_water; if (init > s->window_size - s->high_water) init = s->window_size - s->high_water; zmemzero(s->window + s->high_water, (unsigned)init); s->high_water += init; } } Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "not enough room for search"); } /* ========================================================================= */ int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size) { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size) { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; if (windowBits < -15) return Z_STREAM_ERROR; windowBits = -windowBits; } #ifdef GZIP else if (windowBits > 15) { wrap = 2; /* write gzip wrapper instead */ windowBits -= 16; } #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->status = INIT_STATE; /* to pass state test in deflateReset() */ s->wrap = wrap; s->gzhead = Z_NULL; s->w_bits = (uInt)windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = (uInt)memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->high_water = 0; /* nothing written to s->window yet */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ /* We overlay pending_buf and sym_buf. This works since the average size * for length/distance pairs over any compressed block is assured to be 31 * bits or less. * * Analysis: The longest fixed codes are a length code of 8 bits plus 5 * extra bits, for lengths 131 to 257. The longest fixed distance codes are * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest * possible fixed-codes length/distance pair is then 31 bits total. * * sym_buf starts one-fourth of the way into pending_buf. So there are * three bytes in sym_buf for every four bytes in pending_buf. Each symbol * in sym_buf is three bytes -- two for the distance and one for the * literal/length. As each symbol is consumed, the pointer to the next * sym_buf value to read moves forward three bytes. From that symbol, up to * 31 bits are written to pending_buf. The closest the written pending_buf * bits gets to the next sym_buf symbol to read is just before the last * code is written. At that time, 31*(n - 2) bits have been written, just * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 * symbols are written.) The closest the writing gets to what is unread is * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and * can range from 128 to 32768. * * Therefore, at a minimum, there are 142 bits of space between what is * written and what is read in the overlain buffers, so the symbols cannot * be overwritten by the compressed data. That space is actually 139 bits, * due to the three-bit fixed-code block header. * * That covers the case where either Z_FIXED is specified, forcing fixed * codes, or when the use of fixed codes is chosen, because that choice * results in a smaller compressed block than dynamic codes. That latter * condition then assures that the above analysis also covers all dynamic * blocks. A dynamic-code block will only be chosen to be emitted if it has * fewer bits than a fixed-code block would for the same set of symbols. * Therefore its average symbol length is assured to be less than 31. So * the compressed data for a dynamic block also cannot overwrite the * symbols from which it is being constructed. */ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; strm->msg = ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } #ifdef LIT_MEM s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); s->l_buf = s->pending_buf + (s->lit_bufsize << 2); s->sym_end = s->lit_bufsize - 1; #else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; #endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= * Check for a valid deflate stream state. Return 0 if ok, 1 if not. */ local int deflateStateCheck(z_streamp strm) { deflate_state *s; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) return 1; s = strm->state; if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && #ifdef GZIP s->status != GZIP_STATE && #endif s->status != EXTRA_STATE && s->status != NAME_STATE && s->status != COMMENT_STATE && s->status != HCRC_STATE && s->status != BUSY_STATE && s->status != FINISH_STATE)) return 1; return 0; } /* ========================================================================= */ int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength) { deflate_state *s; uInt str, n; int wrap; unsigned avail; z_const unsigned char *next; if (deflateStateCheck(strm) || dictionary == Z_NULL) return Z_STREAM_ERROR; s = strm->state; wrap = s->wrap; if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) return Z_STREAM_ERROR; /* when using zlib wrappers, compute Adler-32 for provided dictionary */ if (wrap == 1) strm->adler = adler32(strm->adler, dictionary, dictLength); s->wrap = 0; /* avoid computing Adler-32 in read_buf */ /* if dictionary would fill window, just replace the history */ if (dictLength >= s->w_size) { if (wrap == 0) { /* already empty otherwise */ CLEAR_HASH(s); s->strstart = 0; s->block_start = 0L; s->insert = 0; } dictionary += dictLength - s->w_size; /* use the tail */ dictLength = s->w_size; } /* insert dictionary into window and hash */ avail = strm->avail_in; next = strm->next_in; strm->avail_in = dictLength; strm->next_in = (z_const Bytef *)dictionary; fill_window(s); while (s->lookahead >= MIN_MATCH) { str = s->strstart; n = s->lookahead - (MIN_MATCH-1); do { UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); #ifndef FASTEST s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif s->head[s->ins_h] = (Pos)str; str++; } while (--n); s->strstart = str; s->lookahead = MIN_MATCH-1; fill_window(s); } s->strstart += s->lookahead; s->block_start = (long)s->strstart; s->insert = s->lookahead; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; strm->next_in = next; strm->avail_in = avail; s->wrap = wrap; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, uInt *dictLength) { deflate_state *s; uInt len; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; len = s->strstart + s->lookahead; if (len > s->w_size) len = s->w_size; if (dictionary != Z_NULL && len) zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); if (dictLength != Z_NULL) *dictLength = len; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateResetKeep(z_streamp strm) { deflate_state *s; if (deflateStateCheck(strm)) { return Z_STREAM_ERROR; } strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } s->status = #ifdef GZIP s->wrap == 2 ? GZIP_STATE : #endif INIT_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); s->last_flush = -2; _tr_init(s); return Z_OK; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init(deflate_state *s) { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->insert = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; } /* ========================================================================= */ int ZEXPORT deflateReset(z_streamp strm) { int ret; ret = deflateResetKeep(strm); if (ret == Z_OK) lm_init(strm->state); return ret; } /* ========================================================================= */ int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { if (deflateStateCheck(strm) || strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; if (bits != Z_NULL) *bits = strm->state->bi_valid; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; #ifdef LIT_MEM if (bits < 0 || bits > 16 || (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; #else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; #endif do { put = Buf_size - s->bi_valid; if (put > bits) put = bits; s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); s->bi_valid += put; _tr_flush_bits(s); value >>= put; bits -= put; } while (bits); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { deflate_state *s; compress_func func; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2) { /* Flush the last buffer: */ int err = deflate(strm, Z_BLOCK); if (err == Z_STREAM_ERROR) return err; if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) return Z_BUF_ERROR; } if (s->level != level) { if (s->level == 0 && s->matches != 0) { if (s->matches == 1) slide_hash(s); else CLEAR_HASH(s); s->matches = 0; } s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain) { deflate_state *s; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; s->good_match = (uInt)good_length; s->max_lazy_match = (uInt)max_lazy; s->nice_match = nice_length; s->max_chain_length = (uInt)max_chain; return Z_OK; } /* ========================================================================= * For the default windowBits of 15 and memLevel of 8, this function returns a * close to exact, as well as small, upper bound on the compressed size. This * is an expansion of ~0.03%, plus a small constant. * * For any setting other than those defaults for windowBits and memLevel, one * of two worst case bounds is returned. This is at most an expansion of ~4% or * ~13%, plus a small constant. * * Both the 0.03% and 4% derive from the overhead of stored blocks. The first * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second * is for stored blocks of 127 bytes (the worst case memLevel == 1). The * expansion results from five bytes of header for each stored block. * * The larger expansion of 13% results from a window size less than or equal to * the symbols buffer size (windowBits <= memLevel + 7). In that case some of * the data being compressed may have slid out of the sliding window, impeding * a stored block from being emitted. Then the only choice is a fixed or * dynamic block, where a fixed block limits the maximum expansion to 9 bits * per 8-bit byte, plus 10 bits for every block. The smallest block size for * which this can occur is 255 (memLevel == 2). * * Shifts are used to approximate divisions, for speed. */ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { deflate_state *s; uLong fixedlen, storelen, wraplen; /* upper bound for fixed blocks with 9-bit literals and length 255 (memLevel == 2, which is the lowest that may not use stored blocks) -- ~13% overhead plus a small constant */ fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + (sourceLen >> 9) + 4; /* upper bound for stored blocks with length 127 (memLevel == 1) -- ~4% overhead plus a small constant */ storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7; /* if can't get parameters, return larger bound plus a zlib wrapper */ if (deflateStateCheck(strm)) return (fixedlen > storelen ? fixedlen : storelen) + 6; /* compute wrapper length */ s = strm->state; switch (s->wrap) { case 0: /* raw deflate */ wraplen = 0; break; case 1: /* zlib wrapper */ wraplen = 6 + (s->strstart ? 4 : 0); break; #ifdef GZIP case 2: /* gzip wrapper */ wraplen = 18; if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ Bytef *str; if (s->gzhead->extra != Z_NULL) wraplen += 2 + s->gzhead->extra_len; str = s->gzhead->name; if (str != Z_NULL) do { wraplen++; } while (*str++); str = s->gzhead->comment; if (str != Z_NULL) do { wraplen++; } while (*str++); if (s->gzhead->hcrc) wraplen += 2; } break; #endif default: /* for compiler happiness */ wraplen = 6; } /* if not default parameters, return one of the conservative bounds */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + wraplen; /* default settings: return tight bound for that case -- ~0.03% overhead plus a small constant */ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB(deflate_state *s, uInt b) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output, except for * some deflate_stored() output, goes through this function so some * applications may wish to modify it to avoid allocating a large * strm->next_out buffer and copying into it. (See also read_buf()). */ local void flush_pending(z_streamp strm) { unsigned len; deflate_state *s = strm->state; _tr_flush_bits(s); len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; s->pending_out += len; strm->total_out += len; strm->avail_out -= len; s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } /* =========================================================================== * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. */ #define HCRC_UPDATE(beg) \ do { \ if (s->gzhead->hcrc && s->pending > (beg)) \ strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ s->pending - (beg)); \ } while (0) /* ========================================================================= */ int ZEXPORT deflate(z_streamp strm, int flush) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || (strm->avail_in != 0 && strm->next_in == Z_NULL) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); old_flush = s->last_flush; s->last_flush = flush; /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Write the header */ if (s->status == INIT_STATE && s->wrap == 0) s->status = BUSY_STATE; if (s->status == INIT_STATE) { /* zlib header */ uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) level_flags = 0; else if (s->level < 6) level_flags = 1; else if (s->level == 6) level_flags = 2; else level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = adler32(0L, Z_NULL, 0); s->status = BUSY_STATE; /* Compression must start with an empty pending buffer */ flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } } #ifdef GZIP if (s->status == GZIP_STATE) { /* gzip header */ strm->adler = crc32(0L, Z_NULL, 0); put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); if (s->gzhead == Z_NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, OS_CODE); s->status = BUSY_STATE; /* Compression must start with an empty pending buffer */ flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } } else { put_byte(s, (s->gzhead->text ? 1 : 0) + (s->gzhead->hcrc ? 2 : 0) + (s->gzhead->extra == Z_NULL ? 0 : 4) + (s->gzhead->name == Z_NULL ? 0 : 8) + (s->gzhead->comment == Z_NULL ? 0 : 16) ); put_byte(s, (Byte)(s->gzhead->time & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); if (s->gzhead->extra != Z_NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } if (s->gzhead->hcrc) strm->adler = crc32(strm->adler, s->pending_buf, s->pending); s->gzindex = 0; s->status = EXTRA_STATE; } } if (s->status == EXTRA_STATE) { if (s->gzhead->extra != Z_NULL) { ulg beg = s->pending; /* start of bytes to update crc */ uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; while (s->pending + left > s->pending_buf_size) { uInt copy = s->pending_buf_size - s->pending; zmemcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy); s->pending = s->pending_buf_size; HCRC_UPDATE(beg); s->gzindex += copy; flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } beg = 0; left -= copy; } zmemcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left); s->pending += left; HCRC_UPDATE(beg); s->gzindex = 0; } s->status = NAME_STATE; } if (s->status == NAME_STATE) { if (s->gzhead->name != Z_NULL) { ulg beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { HCRC_UPDATE(beg); flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } beg = 0; } val = s->gzhead->name[s->gzindex++]; put_byte(s, val); } while (val != 0); HCRC_UPDATE(beg); s->gzindex = 0; } s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { if (s->gzhead->comment != Z_NULL) { ulg beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { HCRC_UPDATE(beg); flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } beg = 0; } val = s->gzhead->comment[s->gzindex++]; put_byte(s, val); } while (val != 0); HCRC_UPDATE(beg); } s->status = HCRC_STATE; } if (s->status == HCRC_STATE) { if (s->gzhead->hcrc) { if (s->pending + 2 > s->pending_buf_size) { flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } } put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); strm->adler = crc32(0L, Z_NULL, 0); } s->status = BUSY_STATE; /* Compression must start with an empty pending buffer */ flush_pending(strm); if (s->pending != 0) { s->last_flush = -1; return Z_OK; } } #endif /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = s->level == 0 ? deflate_stored(s, flush) : s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ if (s->lookahead == 0) { s->strstart = 0; s->block_start = 0L; s->insert = 0; } } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; /* Write the trailer */ #ifdef GZIP if (s->wrap == 2) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); put_byte(s, (Byte)(strm->total_in & 0xff)); put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); } else #endif { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int ZEXPORT deflateEnd(z_streamp strm) { int status; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; status = strm->state->status; /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { #ifdef MAXSEG_64K (void)dest; (void)source; return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; if (deflateStateCheck(source) || dest == Z_NULL) { return Z_STREAM_ERROR; } ss = source->state; zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); #ifdef LIT_MEM ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); #else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; #endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif /* MAXSEG_64K */ } #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = (int)s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan + best_len - 1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len - 1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2. Note that the checks below * for insufficient lookahead only occur occasionally for performance * reasons. Therefore uninitialized memory will be accessed, and * conditional jumps will be made that depend on those values. * However the length of the match is limited to the lookahead, so * the output of deflate is not affected by the uninitialized values. */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match + best_len - 1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart + 3, + 5, up to strstart + 257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && *(ushf*)(scan += 2) == *(ushf*)(match += 2) && *(ushf*)(scan += 2) == *(ushf*)(match += 2) && *(ushf*)(scan += 2) == *(ushf*)(match += 2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window + strstart + 257 */ Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend - scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len - 1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len - 1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart + 258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan + best_len - 1); #else scan_end1 = scan[best_len - 1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } #else /* FASTEST */ /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ local uInt longest_match(deflate_state *s, IPos cur_match) { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ register Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Return failure if the match length is less than 2: */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; /* The check at best_len - 1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match += 2; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart + 258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); if (len < MIN_MATCH) return MIN_MATCH - 1; s->match_start = cur_match; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #endif /* FASTEST */ #ifdef ZLIB_DEBUG #define EQUAL 0 /* result of memcmp for equal strings */ /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ Bytef *back = s->window + (int)match, *here = s->window + start; IPos len = length; if (match == (IPos)-1) { /* match starts one byte before the current window -- just compare the subsequent length-1 bytes */ back++; here++; len--; } if (zmemcmp(back, here, len) != EQUAL) { fprintf(stderr, " start %u, match %d, length %d\n", start, (int)match, length); do { fprintf(stderr, "(%02x %02x)", *back++, *here++); } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start - match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* ZLIB_DEBUG */ /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, last) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, last) { \ FLUSH_BLOCK_ONLY(s, last); \ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } /* Maximum stored block length in deflate format (not including header). */ #define MAX_STORED 65535 /* Minimum of a and b. */ #define MIN(a, b) ((a) > (b) ? (b) : (a)) /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * * In case deflateParams() is used to later switch to a non-zero compression * level, s->matches (otherwise unused when storing) keeps track of the number * of hash table slides to perform. If s->matches is 1, then one hash table * slide will be done when switching. If s->matches is 2, the maximum value * allowed here, then the hash table will be cleared, since two or more slides * is the same as a clear. * * deflate_stored() is written to minimize the number of times an input byte is * copied. It is most efficient with large input and output buffers, which * maximizes the opportunities to have a single copy from next_in to next_out. */ local block_state deflate_stored(deflate_state *s, int flush) { /* Smallest worthy block size when not flushing or finishing. By default * this is 32K. This can be as small as 507 bytes for memLevel == 1. For * large input and output buffers, the stored block size will be larger. */ unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); /* Copy as many min_block or larger stored blocks directly to next_out as * possible. If flushing, copy the remaining available input to next_out as * stored blocks, if there is enough space. */ unsigned len, left, have, last = 0; unsigned used = s->strm->avail_in; do { /* Set len to the maximum size block that we can copy directly with the * available input data and output space. Set left to how much of that * would be copied from what's left in the window. */ len = MAX_STORED; /* maximum deflate stored block length */ have = (s->bi_valid + 42) >> 3; /* number of header bytes */ if (s->strm->avail_out < have) /* need room for header */ break; /* maximum stored block length that will fit in avail_out: */ have = s->strm->avail_out - have; left = s->strstart - s->block_start; /* bytes left in window */ if (len > (ulg)left + s->strm->avail_in) len = left + s->strm->avail_in; /* limit len to the input */ if (len > have) len = have; /* limit len to the output */ /* If the stored block would be less than min_block in length, or if * unable to copy all of the available input when flushing, then try * copying to the window and the pending buffer instead. Also don't * write an empty block when flushing -- deflate() does that. */ if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || len != left + s->strm->avail_in)) break; /* Make a dummy stored block in pending to get the header bytes, * including any pending bits. This also updates the debugging counts. */ last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ s->pending_buf[s->pending - 4] = len; s->pending_buf[s->pending - 3] = len >> 8; s->pending_buf[s->pending - 2] = ~len; s->pending_buf[s->pending - 1] = ~len >> 8; /* Write the stored block header bytes. */ flush_pending(s->strm); #ifdef ZLIB_DEBUG /* Update debugging counts for the data about to be copied. */ s->compressed_len += len << 3; s->bits_sent += len << 3; #endif /* Copy uncompressed bytes from the window to next_out. */ if (left) { if (left > len) left = len; zmemcpy(s->strm->next_out, s->window + s->block_start, left); s->strm->next_out += left; s->strm->avail_out -= left; s->strm->total_out += left; s->block_start += left; len -= left; } /* Copy uncompressed bytes directly from next_in to next_out, updating * the check value. */ if (len) { read_buf(s->strm, s->strm->next_out, len); s->strm->next_out += len; s->strm->avail_out -= len; s->strm->total_out += len; } } while (last == 0); /* Update the sliding window with the last s->w_size bytes of the copied * data, or append all of the copied data to the existing window if less * than s->w_size bytes were copied. Also update the number of bytes to * insert in the hash tables, in the event that deflateParams() switches to * a non-zero compression level. */ used -= s->strm->avail_in; /* number of input bytes directly copied */ if (used) { /* If any input was used, then no unused input remains in the window, * therefore s->block_start == s->strstart. */ if (used >= s->w_size) { /* supplant the previous history */ s->matches = 2; /* clear hash */ zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); s->strstart = s->w_size; s->insert = s->strstart; } else { if (s->window_size - s->strstart <= used) { /* Slide the window down. */ s->strstart -= s->w_size; zmemcpy(s->window, s->window + s->w_size, s->strstart); if (s->matches < 2) s->matches++; /* add a pending slide_hash() */ if (s->insert > s->strstart) s->insert = s->strstart; } zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); s->strstart += used; s->insert += MIN(used, s->w_size - s->insert); } s->block_start = s->strstart; } if (s->high_water < s->strstart) s->high_water = s->strstart; /* If the last block was written to next_out, then done. */ if (last) return finish_done; /* If flushing and all input has been consumed, then done. */ if (flush != Z_NO_FLUSH && flush != Z_FINISH && s->strm->avail_in == 0 && (long)s->strstart == s->block_start) return block_done; /* Fill the window with any remaining input. */ have = s->window_size - s->strstart; if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { /* Slide the window down. */ s->block_start -= s->w_size; s->strstart -= s->w_size; zmemcpy(s->window, s->window + s->w_size, s->strstart); if (s->matches < 2) s->matches++; /* add a pending slide_hash() */ have += s->w_size; /* more space now */ if (s->insert > s->strstart) s->insert = s->strstart; } if (have > s->strm->avail_in) have = s->strm->avail_in; if (have) { read_buf(s->strm, s->window + s->strstart, have); s->strstart += have; s->insert += MIN(have, s->w_size - s->insert); } if (s->high_water < s->strstart) s->high_water = s->strstart; /* There was not enough avail_out to write a complete worthy or flushed * stored block to next_out. Write a stored block to pending instead, if we * have enough input for a worthy block, or if flushing and there is enough * room for the remaining input as a stored block in the pending buffer. */ have = (s->bi_valid + 42) >> 3; /* number of header bytes */ /* maximum stored block length that will fit in pending: */ have = MIN(s->pending_buf_size - have, MAX_STORED); min_block = MIN(have, s->w_size); left = s->strstart - s->block_start; if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) { len = MIN(left, have); last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0; _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); s->block_start += len; flush_pending(s->strm); } /* We've done all we can with the available input and output. */ return last ? finish_started : need_more; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(deflate_state *s, int flush) { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart + 2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else #endif { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->sym_next) FLUSH_BLOCK(s, 0); return block_done; } #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(deflate_state *s, int flush) { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart + 2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) #endif )) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart - 1, s->prev_match, s->prev_length); _tr_tally_dist(s, s->strstart - 1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. * strstart - 1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length - 1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart - 1])); _tr_tally_lit(s, s->window[s->strstart - 1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart - 1])); _tr_tally_lit(s, s->window[s->strstart - 1], bflush); s->match_available = 0; } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->sym_next) FLUSH_BLOCK(s, 0); return block_done; } #endif /* FASTEST */ /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ local block_state deflate_rle(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the longest run, plus one for the unrolled loop. */ if (s->lookahead <= MAX_MATCH) { fill_window(s); if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* See how many times the previous byte repeats */ s->match_length = 0; if (s->lookahead >= MIN_MATCH && s->strstart > 0) { scan = s->window + s->strstart - 1; prev = *scan; if (prev == *++scan && prev == *++scan && prev == *++scan) { strend = s->window + s->strstart + MAX_MATCH; do { } while (prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && scan < strend); s->match_length = MAX_MATCH - (uInt)(strend - scan); if (s->match_length > s->lookahead) s->match_length = s->lookahead; } Assert(scan <= s->window + (uInt)(s->window_size - 1), "wild scan"); } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->strstart - 1, s->match_length); _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; s->strstart += s->match_length; s->match_length = 0; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } s->insert = 0; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->sym_next) FLUSH_BLOCK(s, 0); return block_done; } /* =========================================================================== * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ local block_state deflate_huff(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we have a literal to write. */ if (s->lookahead == 0) { fill_window(s); if (s->lookahead == 0) { if (flush == Z_NO_FLUSH) return need_more; break; /* flush the current block */ } } /* Output a literal byte */ s->match_length = 0; Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } s->insert = 0; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->sym_next) FLUSH_BLOCK(s, 0); return block_done; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/deflate.h000066400000000000000000000333311516712004000252710ustar00rootroot00000000000000/* deflate.h -- internal compression state * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef DEFLATE_H #define DEFLATE_H #include "zutil.h" /* define NO_GZIP when compiling if you want to disable gzip header and trailer creation by deflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP # define GZIP #endif /* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at the cost of a larger memory footprint */ /* #define LIT_MEM */ /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define Buf_size 16 /* size of bit buffer in bi_buf */ #define INIT_STATE 42 /* zlib header -> BUSY_STATE */ #ifdef GZIP # define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ #endif #define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ #define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ #define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ #define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ #define BUSY_STATE 113 /* deflate -> FINISH_STATE */ #define FINISH_STATE 666 /* stream complete */ /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ const static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ ulg pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ ulg gzindex; /* where in extra, name, or comment */ Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to suppress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ #ifdef LIT_MEM # define LIT_BUFS 5 ushf *d_buf; /* buffer for distances */ uchf *l_buf; /* buffer for literals/lengths */ #else # define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ #endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ uInt insert; /* bytes at end of window left to insert */ #ifdef ZLIB_DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ ulg high_water; /* High water mark offset in window for initialized bytes -- bytes above * this are set to zero in order to avoid memory check warnings when * longest match routines access bytes past the input. This is then * updated to the new high water mark. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ #define WIN_INIT MAX_MATCH /* Number of bytes after end of data in window to initialize in order to avoid memory checker errors from longest match routines */ /* in trees.c */ void ZLIB_INTERNAL _tr_init(deflate_state *s); int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, ulg stored_len, int last); void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); void ZLIB_INTERNAL _tr_align(deflate_state *s); void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, ulg stored_len, int last); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef ZLIB_DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch ZLIB_INTERNAL _length_code[]; extern uch ZLIB_INTERNAL _dist_code[]; #else extern const uch ZLIB_INTERNAL _length_code[]; extern const uch ZLIB_INTERNAL _dist_code[]; #endif #ifdef LIT_MEM # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->sym_next] = 0; \ s->l_buf[s->sym_next++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->sym_next == s->sym_end); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (uch)(length); \ ush dist = (ush)(distance); \ s->d_buf[s->sym_next] = dist; \ s->l_buf[s->sym_next++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } #else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ s->sym_buf[s->sym_next++] = 0; \ s->sym_buf[s->sym_next++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->sym_next == s->sym_end); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (uch)(length); \ ush dist = (ush)(distance); \ s->sym_buf[s->sym_next++] = (uch)dist; \ s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ s->sym_buf[s->sym_next++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } #endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/gzguts.h000066400000000000000000000150241516712004000252070ustar00rootroot00000000000000/* gzguts.h -- zlib internal header definitions for gz* operations * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #ifdef _LARGEFILE64_SOURCE # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif # undef _FILE_OFFSET_BITS # undef _TIME_BITS #endif #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL #endif #include #include "zlib.h" #ifdef STDC # include # include # include #endif #ifndef _POSIX_SOURCE # define _POSIX_SOURCE #endif #include #ifdef _WIN32 # include #endif #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) # include #endif #if defined(_WIN32) # define WIDECHAR #endif #ifdef WINAPI_FAMILY # define open _open # define read _read # define write _write # define close _close #endif #ifdef NO_DEFLATE /* for compatibility with old definition */ # define NO_GZCOMPRESS #endif #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) # define vsnprintf _vsnprintf # endif # endif # endif # ifdef __SASC # define NO_vsnprintf # endif # ifdef VMS # define NO_vsnprintf # endif # ifdef __OS400__ # define NO_vsnprintf # endif # ifdef __MVS__ # define NO_vsnprintf # endif #endif /* unlike snprintf (which is required in C99), _snprintf does not guarantee null termination of the result -- however this is only used in gzlib.c where the result is assured to fit in the space provided */ #if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf #endif #ifndef local # define local static #endif /* since "static" is used to mean two completely different things in C, we define "local" for the non-static meaning of "static", for readability (compile with -Dlocal if your debugger can't find static symbols) */ /* gz* functions always use library allocation functions */ #ifndef STDC extern voidp malloc(uInt size); extern void free(voidpf ptr); #endif /* get errno and strerror definition */ #if defined UNDER_CE # include # define zstrerror() gz_strwinerror((DWORD)GetLastError()) #else # ifndef NO_STRERROR # include # define zstrerror() strerror(errno) # else # define zstrerror() "stdio error (consult errno)" # endif #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); #endif /* default memLevel */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default i/o buffer size -- double this for output when reading (this and twice this must be able to fit in an unsigned type) */ #define GZBUFSIZE 8192 /* gzip modes, also provide a little integrity check on the passed structure */ #define GZ_NONE 0 #define GZ_READ 7247 #define GZ_WRITE 31153 #define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ /* values for gz_state how */ #define LOOK 0 /* look for a gzip header */ #define COPY 1 /* copy input directly */ #define GZIP 2 /* decompress a gzip stream */ /* internal gzip file state data structure */ typedef struct { /* exposed contents for gzgetc() macro */ struct gzFile_s x; /* "x" for exposed */ /* x.have: number of bytes available at x.next */ /* x.next: next output data to deliver or write */ /* x.pos: current position in uncompressed data */ /* used for both reading and writing */ int mode; /* see gzip modes above */ int fd; /* file descriptor */ char *path; /* path or fd for error messages */ unsigned size; /* buffer size, zero if not allocated yet */ unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned char *in; /* input buffer (double-sized when writing) */ unsigned char *out; /* output buffer (double-sized when reading) */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ int how; /* 0: get header, 1: copy, 2: decompress */ z_off64_t start; /* where the gzip data started, for rewinding */ int eof; /* true if end of input file reached */ int past; /* true if read requested past end */ /* just for writing */ int level; /* compression level */ int strategy; /* compression strategy */ int reset; /* true if a reset is pending after a Z_FINISH */ /* seek request */ z_off64_t skip; /* amount to skip (already rewound if backwards) */ int seek; /* true if seek request pending */ /* error information */ int err; /* error code */ char *msg; /* error message */ /* zlib inflate or deflate stream */ z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; typedef gz_state FAR *gz_statep; /* shared functions */ void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); #if defined UNDER_CE char ZLIB_INTERNAL *gz_strwinerror(DWORD error); #endif /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ unsigned ZLIB_INTERNAL gz_intmax(void); #define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/infback.c000066400000000000000000000542151516712004000252610ustar00rootroot00000000000000/* infback.c -- inflate using a call-back interface * Copyright (C) 1995-2022 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* This code is largely copied from inflate.c. Normally either infback.o or inflate.o would be linked into an application--not both. The interface with inffast.c is retained so that optimized assembler-coded versions of inflate_fast() can be used with either inflate.c or infback.c. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size) { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->dmax = 32768U; state->wbits = (uInt)windowBits; state->wsize = 1U << windowBits; state->window = window; state->wnext = 0; state->whave = 0; state->sane = 1; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \ have = in(in_desc, &next); \ if (have == 0) { \ next = Z_NULL; \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ #define PULLBYTE() \ do { \ PULL(); \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \ put = state->window; \ left = state->wsize; \ state->whave = left; \ if (out(out_desc, put, left)) { \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* strm provides the memory allocation functions and window buffer on input, and provides information on the unused input on return. For Z_DATA_ERROR returns, strm will also provide an error message. in() and out() are the call-back input and output functions. When inflateBack() needs more input, it calls in(). When inflateBack() has filled the window with output, or when it completes with data in the window, it calls out() to write out the data. The application must not change the provided input until in() is called again or inflateBack() returns. The application must not change the window/output buffer until inflateBack() returns. in() and out() are called with a descriptor parameter provided in the inflateBack() call. This parameter can be a structure that provides the information required to do the read or write, as well as accumulated information on the input and output such as totals and check values. in() should return zero on failure. out() should return non-zero on failure. If either in() or out() fails, than inflateBack() returns a Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it was in() or out() that caused in the error. Otherwise, inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format error, or Z_MEM_ERROR if it could not allocate memory for the state. inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* Reset the state */ strm->msg = Z_NULL; state->mode = TYPE; state->last = 0; state->whave = 0; next = strm->next_in; have = next != Z_NULL ? strm->avail_in : 0; hold = 0; bits = 0; put = state->window; left = state->wsize; /* Inflate until end of block marked as last */ for (;;) switch (state->mode) { case TYPE: /* determine and dispatch block type */ if (state->last) { BYTEBITS(); state->mode = DONE; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: /* get and verify stored block length */ BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ while (state->length != 0) { copy = state->length; PULL(); ROOM(); if (copy > have) copy = have; if (copy > left) copy = left; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: /* get dynamic table entries descriptor */ NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = (unsigned)(state->lens[state->have - 1]); copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; /* fallthrough */ case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); if (state->whave < state->wsize) state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; } /* get a literal, length, or end-of-block code */ for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); state->length = (unsigned)here.val; /* process literal */ if (here.op == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; } /* process end of block */ if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); /* get distance code */ for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; /* get distance extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { ROOM(); copy = state->wsize - state->offset; if (copy < left) { from = put + copy; copy = left - copy; } else { from = put - state->offset; copy = left; } if (copy > state->length) copy = state->length; state->length -= copy; left -= copy; do { *put++ = *from++; } while (--copy); } while (state->length != 0); break; case DONE: /* inflate stream terminated properly */ ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; default: /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } /* Write leftover output and return unused input */ inf_leave: if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left) && ret == Z_STREAM_END) ret = Z_BUF_ERROR; } strm->next_in = next; strm->avail_in = have; return ret; } int ZEXPORT inflateBackEnd(z_streamp strm) { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inffast.c000066400000000000000000000311741516712004000253150ustar00rootroot00000000000000/* inffast.c -- fast decoding * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef ASMINF # pragma message("Assembler code may have bugs -- use at your own risk") #else /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code const *here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in; last = in + (strm->avail_in - 5); out = strm->next_out; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT dmax = state->dmax; #endif wsize = state->wsize; whave = state->whave; wnext = state->wnext; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (1U << state->lenbits) - 1; dmask = (1U << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(*in++) << bits; bits += 8; hold += (unsigned long)(*in++) << bits; bits += 8; } here = lcode + (hold & lmask); dolen: op = (unsigned)(here->bits); hold >>= op; bits -= op; op = (unsigned)(here->op); if (op == 0) { /* literal */ Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here->val)); *out++ = (unsigned char)(here->val); } else if (op & 16) { /* length base */ len = (unsigned)(here->val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(*in++) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(*in++) << bits; bits += 8; hold += (unsigned long)(*in++) << bits; bits += 8; } here = dcode + (hold & dmask); dodist: op = (unsigned)(here->bits); hold >>= op; bits -= op; op = (unsigned)(here->op); if (op & 16) { /* distance base */ dist = (unsigned)(here->val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(*in++) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(*in++) << bits; bits += 8; } } dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { *out++ = 0; } while (--len); continue; } len -= op - whave; do { *out++ = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { *out++ = *from++; } while (--len); continue; } #endif } from = window; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } } else if (wnext < op) { /* wrap around window */ from += wsize + wnext - op; op -= wnext; if (op < len) { /* some from end of window */ len -= op; do { *out++ = *from++; } while (--op); from = window; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += wnext - op; if (op < len) { /* some from window */ len -= op; do { *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { *out++ = *from++; *out++ = *from++; *out++ = *from++; len -= 3; } if (len) { *out++ = *from++; if (len > 1) *out++ = *from++; } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ *out++ = *from++; *out++ = *from++; *out++ = *from++; len -= 3; } while (len > 2); if (len) { *out++ = *from++; if (len > 1) *out++ = *from++; } } } else if ((op & 64) == 0) { /* 2nd level distance code */ here = dcode + here->val + (hold & ((1U << op) - 1)); goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ here = lcode + here->val + (hold & ((1U << op) - 1)); goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (1U << bits) - 1; /* update state and return */ strm->next_in = in; strm->next_out = out; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and wnext == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* !ASMINF */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inffast.h000066400000000000000000000006461516712004000253220ustar00rootroot00000000000000/* inffast.h -- header to use inffast.c * Copyright (C) 1995-2003, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inffixed.h000066400000000000000000000142741516712004000254660ustar00rootroot00000000000000 /* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of this library and is subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inflate.c000066400000000000000000001543371516712004000253140ustar00rootroot00000000000000/* inflate.c -- zlib decompression * Copyright (C) 1995-2022 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * Change history: * * 1.2.beta0 24 Nov 2002 * - First version -- complete rewrite of inflate to simplify code, avoid * creation of window when not needed, minimize use of window when it is * needed, make inffast.c even faster, implement gzip decoding, and to * improve code readability and style over the previous zlib inflate code * * 1.2.beta1 25 Nov 2002 * - Use pointers for available input and output checking in inffast.c * - Remove input and output counters in inffast.c * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 * - Remove unnecessary second byte pull from length extra in inffast.c * - Unroll direct copy to three copies per loop in inffast.c * * 1.2.beta2 4 Dec 2002 * - Change external routine names to reduce potential conflicts * - Correct filename to inffixed.h for fixed tables in inflate.c * - Make hbuf[] unsigned char to match parameter type in inflate.c * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) * to avoid negation problem on Alphas (64 bit) in inflate.c * * 1.2.beta3 22 Dec 2002 * - Add comments on state->bits assertion in inffast.c * - Add comments on op field in inftrees.h * - Fix bug in reuse of allocated window after inflateReset() * - Remove bit fields--back to byte structure for speed * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths * - Change post-increments to pre-increments in inflate_fast(), PPC biased? * - Add compile time option, POSTINC, to use post-increments instead (Intel?) * - Make MATCH copy in inflate() much faster for when inflate_fast() not used * - Use local copies of stream next and avail values, as well as local bit * buffer and bit count in inflate()--for speed when inflate_fast() not used * * 1.2.beta4 1 Jan 2003 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings * - Move a comment on output buffer sizes from inffast.c to inflate.c * - Add comments in inffast.c to introduce the inflate_fast() routine * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed * - Pull out common wnext == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new * source file infback.c to provide a call-back interface to inflate for * programs like gzip and unzip -- uses window as output buffer to avoid * window copying * * 1.2.beta5 1 Jan 2003 * - Improved inflateBack() interface to allow the caller to provide initial * input in strm. * - Fixed stored blocks bug in inflateBack() * * 1.2.beta6 4 Jan 2003 * - Added comments in inffast.c on effectiveness of POSTINC * - Typecasting all around to reduce compiler warnings * - Changed loops from while (1) or do {} while (1) to for (;;), again to * make compilers happy * - Changed type of window in inflateBackInit() to unsigned char * * * 1.2.beta7 27 Jan 2003 * - Changed many types to unsigned or unsigned short to avoid warnings * - Added inflateCopy() function * * 1.2.0 9 Mar 2003 * - Changed inflateBack() interface to provide separate opaque descriptors * for the in() and out() functions * - Changed inflateBack() argument and in_func typedef to swap the length * and buffer address return values for the input function * - Check next_in and next_out for Z_NULL on entry to inflate() * * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED # endif #endif local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) return 1; state = (struct inflate_state FAR *)strm->state; if (state == Z_NULL || state->strm != strm || state->mode < HEAD || state->mode > SYNC) return 1; return 0; } int ZEXPORT inflateResetKeep(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; if (state->wrap) /* to support ill-conceived Java test suite */ strm->adler = state->wrap & 1; state->mode = HEAD; state->last = 0; state->havedict = 0; state->flags = -1; state->dmax = 32768U; state->head = Z_NULL; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflateReset(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->wsize = 0; state->whave = 0; state->wnext = 0; return inflateResetKeep(strm); } int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { int wrap; struct inflate_state FAR *state; /* get the state */ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* extract wrap request from windowBits parameter */ if (windowBits < 0) { if (windowBits < -15) return Z_STREAM_ERROR; wrap = 0; windowBits = -windowBits; } else { wrap = (windowBits >> 4) + 5; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } /* set number of window bits, free window if different */ if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR; if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { ZFREE(strm, state->window); state->window = Z_NULL; } /* update state and reset the rest of it */ state->wrap = wrap; state->wbits = (unsigned)windowBits; return inflateReset(strm); } int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, int stream_size) { int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->strm = strm; state->window = Z_NULL; state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); strm->state = Z_NULL; } return ret; } int ZEXPORT inflateInit_(z_streamp strm, const char *version, int stream_size) { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; if (bits == 0) return Z_OK; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; state->bits = 0; return Z_OK; } if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; state->hold += (unsigned)value << state->bits; state->bits += (uInt)bits; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } #ifdef MAKEFIXED #include /* Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also defines BUILDFIXED, so the tables are built on the fly. makefixed() writes those tables to stdout, which would be piped to inffixed.h. A small program can simply call makefixed to do this: void makefixed(void); int main(void) { makefixed(); return 0; } Then that can be linked with zlib built with MAKEFIXED defined and run: a.out > inffixed.h */ void makefixed(void) { unsigned low, size; struct inflate_state state; fixedtables(&state); puts(" /* inffixed.h -- table for decoding fixed codes"); puts(" * Generated automatically by makefixed()."); puts(" */"); puts(""); puts(" /* WARNING: this file should *not* be used by applications."); puts(" It is part of the implementation of this library and is"); puts(" subject to change. Applications should only use zlib.h."); puts(" */"); puts(""); size = 1U << 9; printf(" static const code lenfix[%u] = {", size); low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); size = 1U << 5; printf("\n static const code distfix[%u] = {", size); low = 0; for (;;) { if ((low % 6) == 0) printf("\n "); printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); } #endif /* MAKEFIXED */ /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { struct inflate_state FAR *state; unsigned dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; state->wnext = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ if (copy >= state->wsize) { zmemcpy(state->window, end - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; zmemcpy(state->window + state->wnext, end - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, end - copy, copy); state->wnext = copy; state->whave = state->wsize; } else { state->wnext += dist; if (state->wnext == state->wsize) state->wnext = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE_CHECK(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(z_streamp strm, int flush) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (inflateStateCheck(strm) || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ if (state->wbits == 0) state->wbits = 15; state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; if (len > 15 || len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } state->dmax = 1U << len; state->flags = 0; /* indicate zlib header */ Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); if ((state->flags & 0x0200) && (state->wrap & 4)) CRC2(state->check, hold); INITBITS(); state->mode = TIME; /* fallthrough */ case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; if ((state->flags & 0x0200) && (state->wrap & 4)) CRC4(state->check, hold); INITBITS(); state->mode = OS; /* fallthrough */ case OS: NEEDBITS(16); if (state->head != Z_NULL) { state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } if ((state->flags & 0x0200) && (state->wrap & 4)) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; /* fallthrough */ case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; if ((state->flags & 0x0200) && (state->wrap & 4)) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; /* fallthrough */ case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && state->head->extra != Z_NULL && (len = state->head->extra_len - state->length) < state->head->extra_max) { zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->length = 0; state->mode = NAME; /* fallthrough */ case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) state->head->name[state->length++] = (Bytef)len; } while (len && copy < have); if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; /* fallthrough */ case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) state->head->comment[state->length++] = (Bytef)len; } while (len && copy < have); if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; /* fallthrough */ case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if ((state->wrap & 4) && hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } if (state->head != Z_NULL) { state->head->hcrc = (int)((state->flags >> 9) & 1); state->head->done = 1; } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = ZSWAP32(hold); INITBITS(); state->mode = DICT; /* fallthrough */ case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; /* fallthrough */ case TYPE: if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; /* fallthrough */ case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN_; /* decode codes */ if (flush == Z_TREES) { DROPBITS(2); goto inf_leave; } break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY_; if (flush == Z_TREES) goto inf_leave; /* fallthrough */ case COPY_: state->mode = COPY; /* fallthrough */ case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; /* fallthrough */ case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; /* fallthrough */ case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (const code FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (const code FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN_; if (flush == Z_TREES) goto inf_leave; /* fallthrough */ case LEN_: state->mode = LEN; /* fallthrough */ case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); if (state->mode == TYPE) state->back = -1; break; } state->back = 0; for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; state->length = (unsigned)here.val; if ((int)(here.op) == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); state->mode = LIT; break; } if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->back = -1; state->mode = TYPE; break; } if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; /* fallthrough */ case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); state->was = state->length; state->mode = DIST; /* fallthrough */ case DIST: for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; /* fallthrough */ case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; /* fallthrough */ case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR Trace((stderr, "inflate.c too far\n")); copy -= state->whave; if (copy > state->length) copy = state->length; if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = 0; } while (--copy); if (state->length == 0) state->mode = LEN; break; #endif } if (copy > state->wnext) { copy -= state->wnext; from = state->window + (state->wsize - copy); } else from = state->window + (state->wnext - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE_CHECK(state->check, put - out, out); out = left; if ((state->wrap & 4) && ( #ifdef GUNZIP state->flags ? hold : #endif ZSWAP32(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; /* fallthrough */ case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; /* fallthrough */ case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: /* fallthrough */ default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (out != strm->avail_out && state->mode < BAD && (state->mode < CHECK || flush != Z_FINISH))) if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE_CHECK(state->check, strm->next_out - out, out); strm->data_type = (int)state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, uInt *dictLength) { struct inflate_state FAR *state; /* check state */ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* copy dictionary */ if (state->whave && dictionary != Z_NULL) { zmemcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); zmemcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); } if (dictLength != Z_NULL) *dictLength = state->whave; return Z_OK; } int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength) { struct inflate_state FAR *state; unsigned long dictid; int ret; /* check state */ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary identifier */ if (state->mode == DICT) { dictid = adler32(0L, Z_NULL, 0); dictid = adler32(dictid, dictionary, dictLength); if (dictid != state->check) return Z_DATA_ERROR; } /* copy dictionary to window using updatewindow(), which will amend the existing dictionary if appropriate */ ret = updatewindow(strm, dictionary + dictLength, dictLength); if (ret) { state->mode = MEM; return Z_MEM_ERROR; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { struct inflate_state FAR *state; /* check state */ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; /* save header structure */ state->head = head; head->done = 0; return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, unsigned len) { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(z_streamp strm) { unsigned len; /* number of bytes to look at or looked at */ int flags; /* temporary to save header status */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; if (state->flags == -1) state->wrap = 0; /* if no header yet, treat as raw */ else state->wrap &= ~4; /* no point in computing a check value now */ flags = state->flags; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->flags = flags; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; unsigned wsize; /* check input */ if (inflateStateCheck(source) || dest == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) { wsize = 1U << state->wbits; zmemcpy(window, state->window, wsize); } copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; } int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR state->sane = !subvert; return Z_OK; #else (void)subvert; state->sane = 1; return Z_DATA_ERROR; #endif } int ZEXPORT inflateValidate(z_streamp strm, int check) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (check && state->wrap) state->wrap |= 4; else state->wrap &= ~4; return Z_OK; } long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return -(1L << 16); state = (struct inflate_state FAR *)strm->state; return (long)(((unsigned long)((long)state->back)) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return (unsigned long)-1; state = (struct inflate_state FAR *)strm->state; return (unsigned long)(state->next - state->codes); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inflate.h000066400000000000000000000150331516712004000253060ustar00rootroot00000000000000/* inflate.h -- internal inflate state definition * Copyright (C) 1995-2019 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP # define GUNZIP #endif /* Possible inflate modes between inflate() calls */ typedef enum { HEAD = 16180, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY_, /* i/o: same as COPY below, but only first time in */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN_, /* i: same as LEN below, but only first time in */ LEN, /* i: waiting for length/lit/eob code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ LENGTH, /* i: waiting for 32-bit length (gzip) */ DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to BAD or MEM on error -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) or (raw) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE (raw) -> TYPEDO Read deflate blocks: TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK STORED -> COPY_ -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN_ LEN_ -> LEN Read deflate codes in fixed or dynamic block: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* State maintained between inflate() calls -- approximately 7K bytes, not including the allocated sliding window, which is up to 32K bytes. */ struct inflate_state { z_streamp strm; /* pointer back to this zlib stream */ inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip, bit 2 true to validate check value */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags, 0 if zlib, or -1 if raw or no header yet */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ int sane; /* if false, allow invalid distance too far */ int back; /* bits back of last unprocessed length/lit */ unsigned was; /* initial length of match */ }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inftrees.c000066400000000000000000000313401516712004000254750ustar00rootroot00000000000000/* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work) { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ unsigned match; /* use base and extra for symbol >= match */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)1; here.val = (unsigned short)0; *(*table)++ = here; /* make a table to force an error */ *(*table)++ = here; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked for LENS and DIST tables against the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in the initial root table size constants. See the comments in inftrees.h for more information. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ match = 20; break; case LENS: base = lbase; extra = lext; match = 257; break; default: /* DISTS */ base = dbase; extra = dext; match = 0; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = 1U << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ here.bits = (unsigned char)(len - drop); if (work[sym] + 1U < match) { here.op = (unsigned char)0; here.val = work[sym]; } else if (work[sym] >= match) { here.op = (unsigned char)(extra[work[sym] - match]); here.val = base[work[sym] - match]; } else { here.op = (unsigned char)(32 + 64); /* end of block */ here.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = 1U << (len - drop); fill = 1U << curr; min = fill; /* save offset to next table */ do { fill -= incr; next[(huff >> drop) + fill] = here; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += min; /* here min is 1 << curr */ /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += 1U << curr; if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* fill in remaining table entry if code is incomplete (guaranteed to have at most one remaining entry, since if the code is incomplete, the maximum code length that was allowed to get this far is one bit) */ if (huff != 0) { here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)(len - drop); here.val = (unsigned short)0; next[huff] = here; } /* set return parameters */ *table += used; *bits = root; return 0; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/inftrees.h000066400000000000000000000055501516712004000255060ustar00rootroot00000000000000/* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2005, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Structure for decoding tables. Each entry provides either the information needed to do the operation requested by the code that indexed that table entry, or it provides a pointer to another table that indexes more bits of the code. op indicates whether the entry is a pointer to another table, a literal, a length or distance, an end-of-block, or an invalid code. For a table pointer, the low four bits of op is the number of index bits of that table. For a length or distance, the low four bits of op is the number of extra bits to get after the code. bits is the number of bits in this code or part of the code to drop off of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of the dynamic table. The maximum number of code structures is 1444, which is the sum of 852 for literal/length codes and 592 for distance codes. These values were found by exhaustive searches using the program examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes returns 852, and "enough 30 6 15" for distance codes returns 592. The initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ #define ENOUGH_LENS 852 #define ENOUGH_DISTS 592 #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) /* Type of code to build for inflate_table() */ typedef enum { CODES, LENS, DISTS } codetype; int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work); boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/trees.c000066400000000000000000001177511516712004000250130ustar00rootroot00000000000000/* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* @(#) $Id$ */ /* #define GEN_TREES_H */ #include "deflate.h" #ifdef ZLIB_DEBUG # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ /* =========================================================================== * Local data. These are initialized only once. */ #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ uch _dist_code[DIST_CODE_LEN]; /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ uch _length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else # include "trees.h" #endif /* GEN_TREES_H */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; #ifdef NO_INIT_GLOBAL_POINTERS # define TCONST #else # define TCONST const #endif local TCONST static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local TCONST static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local TCONST static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(unsigned code, int len) { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(deflate_state *s) { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(deflate_state *s) { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef ZLIB_DEBUG s->bits_sent = (s->bits_sent + 7) & ~7; #endif } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ unsigned code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { code = (code + bl_count[bits - 1]) << 1; next_code[bits] = (ush)code; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, "inconsistent bit counts"); Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); for (n = 0; n <= max_code; n++) { int len = tree[n].Len; if (len == 0) continue; /* Now reverse the bits */ tree[n].Code = (ush)bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); } } #ifdef GEN_TREES_H local void gen_trees_header(void); #endif #ifndef ZLIB_DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* !ZLIB_DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef ZLIB_DEBUG local void send_bits(deflate_state *s, int value, int length) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (ush)value << s->bi_valid; put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= (ush)value << s->bi_valid; s->bi_valid += length; } } #else /* !ZLIB_DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = (int)value;\ s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (ush)(value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* ZLIB_DEBUG */ /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. */ local void tr_static_init(void) { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ #ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; #endif /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1 << extra_lbits[code]); n++) { _length_code[length++] = (uch)code; } } Assert (length == 256, "tr_static_init: length != 256"); /* Note that the length 255 (match length 258) can be represented * in two different ways: code 284 + 5 bits or code 285, so we * overwrite length_code[255] to use the best encoding: */ _length_code[length - 1] = (uch)code; /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1 << extra_dbits[code]); n++) { _dist_code[dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: dist != 256"); dist >>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { _dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256 + dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; # ifdef GEN_TREES_H gen_trees_header(); # endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } /* =========================================================================== * Generate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef ZLIB_DEBUG # include # endif # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width) - 1 ? ",\n" : ", ")) void gen_trees_header(void) { FILE *header = fopen("trees.h", "w"); int i; Assert (header != NULL, "Can't open trees.h"); fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); for (i = 0; i < L_CODES+2; i++) { fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); } fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } fprintf(header, "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); } fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); for (i = 0; i < LENGTH_CODES; i++) { fprintf(header, "%1u%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); } fprintf(header, "local const int base_dist[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "%5u%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); } fclose(header); } #endif /* GEN_TREES_H */ /* =========================================================================== * Initialize a new block. */ local void init_block(deflate_state *s) { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->sym_next = s->matches = 0; } /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL _tr_init(deflate_state *s) { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; #ifdef ZLIB_DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(deflate_state *s, ct_data *tree, int k) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n - base]; f = tree[n].Freq; s->opt_len += (ulg)f * (unsigned)(bits + xbits); if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); } if (overflow == 0) return; Tracev((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length - 1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } #ifdef DUMP_BL_TREE # include #endif /* =========================================================================== * Construct one Huffman tree and assigns the code bit strings and lengths. * Update the total bit length for the current block. * IN assertion: the field freq is set for all tree elements. * OUT assertions: the fields len and code are set to the optimal bit length * and corresponding code. The length opt_len is updated; static_len is * also updated if stree is not null. The field max_code is set. */ local void build_tree(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code + 1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n + 1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code + 1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n + 1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(deflate_state *s) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except the * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes - 1, 5); send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, ulg stored_len, int last) { send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ bi_windup(s); /* align on byte boundary */ put_short(s, (ush)stored_len); put_short(s, (ush)~stored_len); if (stored_len) zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); s->pending += stored_len; #ifdef ZLIB_DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; s->bits_sent += 2*16; s->bits_sent += stored_len << 3; #endif } /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { bi_flush(s); } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */ void ZLIB_INTERNAL _tr_align(deflate_state *s) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef ZLIB_DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { #ifdef LIT_MEM dist = s->d_buf[sx]; lc = s->l_buf[sx++]; #else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; #endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; send_code(s, code + LITERALS + 1, ltree); /* send length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= (unsigned)base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check for no overlay of pending_buf on needed symbols */ #ifdef LIT_MEM Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); #else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); #endif } while (sx < s->sym_next); send_code(s, END_BLOCK, ltree); } /* =========================================================================== * Check if the data type is TEXT or BINARY, using the following algorithm: * - TEXT if the two conditions below are satisfied: * a) There are no non-portable control characters belonging to the * "block list" (0..6, 14..25, 28..31). * b) There is at least one printable character belonging to the * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). * - BINARY otherwise. * - The following partially-portable control characters form a * "gray list" that is ignored in this detection algorithm: * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */ local int detect_data_type(deflate_state *s) { /* block_mask is the bit mask of block-listed bytes * set bits 0..6, 14..25, and 28..31 * 0xf3ffc07f = binary 11110011111111111100000001111111 */ unsigned long block_mask = 0xf3ffc07fUL; int n; /* Check for non-textual ("block-listed") bytes. */ for (n = 0; n <= 31; n++, block_mask >>= 1) if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) return Z_BINARY; /* Check for textual ("allow-listed") bytes. */ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) return Z_TEXT; for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) return Z_TEXT; /* There are no "block-listed" or "allow-listed" bytes: * this stream either is empty or has tolerated ("gray-listed") bytes only. */ return Z_BINARY; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and write out the encoded block. */ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, ulg stored_len, int last) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is binary or text */ if (s->strm->data_type == Z_UNKNOWN) s->strm->data_type = detect_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = (s->opt_len + 3 + 7) >> 3; static_lenb = (s->static_len + 3 + 7) >> 3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->sym_next / 3)); #ifndef FORCE_STATIC if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) #endif opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len + 4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, last); } else if (static_lenb == opt_lenb) { send_bits(s, (STATIC_TREES<<1) + last, 3); compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); #ifdef ZLIB_DEBUG s->compressed_len += 3 + s->static_len; #endif } else { send_bits(s, (DYN_TREES<<1) + last, 3); send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, max_blindex + 1); compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); #ifdef ZLIB_DEBUG s->compressed_len += 3 + s->opt_len; #endif } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ init_block(s); if (last) { bi_windup(s); #ifdef ZLIB_DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, s->compressed_len - 7*last)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { #ifdef LIT_MEM s->d_buf[s->sym_next] = (ush)dist; s->l_buf[s->sym_next++] = (uch)lc; #else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; #endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } return (s->sym_next == s->sym_end); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/trees.h000066400000000000000000000204301516712004000250030ustar00rootroot00000000000000/* header created automatically with -DGEN_TREES_H */ local const ct_data static_ltree[L_CODES+2] = { {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} }; local const ct_data static_dtree[D_CODES] = { {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} }; const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 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, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; local const int base_length[LENGTH_CODES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; local const int base_dist[D_CODES] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/uncompr.c000066400000000000000000000055371516712004000253520ustar00rootroot00000000000000/* uncompr.c -- decompress a memory buffer * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Decompresses the source buffer into the destination buffer. *sourceLen is the byte length of the source buffer. Upon entry, *destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, *destLen is the size of the decompressed data and *sourceLen is the number of source bytes consumed. Upon return, source + *sourceLen points to the first unused input byte. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. */ int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; uLong len, left; Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ len = *sourceLen; if (*destLen) { left = *destLen; *destLen = 0; } else { left = 1; dest = buf; } stream.next_in = (z_const Bytef *)source; stream.avail_in = 0; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; err = inflateInit(&stream); if (err != Z_OK) return err; stream.next_out = dest; stream.avail_out = 0; do { if (stream.avail_out == 0) { stream.avail_out = left > (uLong)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { stream.avail_in = len > (uLong)max ? max : (uInt)len; len -= stream.avail_in; } err = inflate(&stream, Z_NO_FLUSH); } while (err == Z_OK); *sourceLen -= len + stream.avail_in; if (dest != buf) *destLen = stream.total_out; else if (stream.total_out && err == Z_BUF_ERROR) left = 1; inflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err == Z_NEED_DICT ? Z_DATA_ERROR : err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : err; } int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { return uncompress2(dest, destLen, source, &sourceLen); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/zconf.h000066400000000000000000000401641516712004000250060ustar00rootroot00000000000000/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. * Even better than compiling with -DZ_PREFIX would be to use configure to set * this permanently in zconf.h using "./configure --zprefix". */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET /* all linked symbols and init macros */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align # define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block # define _tr_tally z__tr_tally # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 # define adler32_z z_adler32_z # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 # define crc32_combine_gen z_crc32_combine_gen # define crc32_combine_gen64 z_crc32_combine_gen64 # define crc32_combine_op z_crc32_combine_op # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd # define deflateGetDictionary z_deflateGetDictionary # define deflateInit z_deflateInit # define deflateInit2 z_deflateInit2 # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams # define deflatePending z_deflatePending # define deflatePrime z_deflatePrime # define deflateReset z_deflateReset # define deflateResetKeep z_deflateResetKeep # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table # ifndef Z_SOLO # define gz_error z_gz_error # define gz_intmax z_gz_intmax # define gz_strwinerror z_gz_strwinerror # define gzbuffer z_gzbuffer # define gzclearerr z_gzclearerr # define gzclose z_gzclose # define gzclose_r z_gzclose_r # define gzclose_w z_gzclose_w # define gzdirect z_gzdirect # define gzdopen z_gzdopen # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush # define gzfread z_gzfread # define gzfwrite z_gzfwrite # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets # define gzoffset z_gzoffset # define gzoffset64 z_gzoffset64 # define gzopen z_gzopen # define gzopen64 z_gzopen64 # ifdef _WIN32 # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread # define gzrewind z_gzrewind # define gzseek z_gzseek # define gzseek64 z_gzseek64 # define gzsetparams z_gzsetparams # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc # define gzvprintf z_gzvprintf # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd # define inflateBackInit z_inflateBackInit # define inflateBackInit_ z_inflateBackInit_ # define inflateCodesUsed z_inflateCodesUsed # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd # define inflateGetDictionary z_inflateGetDictionary # define inflateGetHeader z_inflateGetHeader # define inflateInit z_inflateInit # define inflateInit2 z_inflateInit2 # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateResetKeep z_inflateResetKeep # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine # define inflateValidate z_inflateValidate # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress # define uncompress2 z_uncompress2 # endif # define zError z_zError # ifndef Z_SOLO # define zcalloc z_zcalloc # define zcfree z_zcfree # endif # define zlibCompileFlags z_zlibCompileFlags # define zlibVersion z_zlibVersion /* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte # define Bytef z_Bytef # define alloc_func z_alloc_func # define charf z_charf # define free_func z_free_func # ifndef Z_SOLO # define gzFile z_gzFile # endif # define gz_header z_gz_header # define gz_headerp z_gz_headerp # define in_func z_in_func # define intf z_intf # define out_func z_out_func # define uInt z_uInt # define uIntf z_uIntf # define uLong z_uLong # define uLongf z_uLongf # define voidp z_voidp # define voidpc z_voidpc # define voidpf z_voidpf /* all zlib structs in zlib.h and zconf.h */ # define gz_header_s z_gz_header_s # define internal_state z_internal_state #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif #if defined(ZLIB_CONST) && !defined(z_const) # define z_const const #else # define z_const #endif #ifdef Z_SOLO # ifdef _WIN64 typedef unsigned long long z_size_t; # else typedef unsigned long z_size_t; # endif #else # define z_longlong long long # if defined(NO_SIZE_T) typedef unsigned NO_SIZE_T z_size_t; # elif defined(STDC) # include typedef size_t z_size_t; # else typedef unsigned long z_size_t; # endif # undef z_longlong #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus about 7 kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) # include # if (UINT_MAX == 0xffffffffUL) # define Z_U4 unsigned # elif (ULONG_MAX == 0xffffffffUL) # define Z_U4 unsigned long # elif (USHRT_MAX == 0xffffffffUL) # define Z_U4 unsigned short # endif #endif #ifdef Z_U4 typedef Z_U4 z_crc_t; #else typedef unsigned long z_crc_t; #endif #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif #ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_STDARG_H #endif #ifdef STDC # ifndef Z_SOLO # include /* for off_t */ # endif #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO # include /* for va_list */ # endif #endif #ifdef _WIN32 # ifndef Z_SOLO # include /* for wchar_t */ # endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even * though the former does not conform to the LFS document), but considering * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif #ifndef Z_HAVE_UNISTD_H # ifdef __WATCOMC__ # define Z_HAVE_UNISTD_H # endif #endif #ifndef Z_HAVE_UNISTD_H # if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) # define Z_HAVE_UNISTD_H # endif #endif #ifndef Z_SOLO # if defined(Z_HAVE_UNISTD_H) # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include /* for off_t */ # endif # ifndef z_off_t # define z_off_t off_t # endif # endif #endif #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 # define Z_LFS64 #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) # define Z_LARGE64 #endif #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) # define Z_WANT64 #endif #if !defined(SEEK_SET) && !defined(Z_SOLO) # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else # if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") #pragma map(deflateInit2_,"DEIN2") #pragma map(deflateEnd,"DEEND") #pragma map(deflateBound,"DEBND") #pragma map(inflateInit_,"ININ") #pragma map(inflateInit2_,"ININ2") #pragma map(inflateEnd,"INEND") #pragma map(inflateSync,"INSY") #pragma map(inflateSetDictionary,"INSEDI") #pragma map(compressBound,"CMBND") #pragma map(inflate_table,"INTABL") #pragma map(inflate_fast,"INFA") #pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/zlib.h000066400000000000000000002750751516712004000246420ustar00rootroot00000000000000/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.3.1, January 22nd, 2024 Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.3.1" #define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 #define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough, or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip and raw deflate streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. */ typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); typedef void (*free_func)(voidpf opaque, voidpf address); struct internal_state; typedef struct z_stream_s { z_const Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total number of input bytes read so far */ Bytef *next_out; /* next output byte will go here */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total number of bytes output so far */ z_const char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text for deflate, or the decoding state for inflate */ uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ typedef struct gz_header_s { int text; /* true if compressed data believed to be text */ uLong time; /* modification time */ int xflags; /* extra flags (not used when writing a gzip file) */ int os; /* operating system */ Bytef *extra; /* pointer to extra field or Z_NULL if none */ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ uInt extra_max; /* space at extra (only when reading header) */ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ uInt name_max; /* space at name (only when reading header) */ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ uInt comm_max; /* space at comment (only when reading header) */ int hcrc; /* true if there was or will be a header crc */ int done; /* true when done reading gzip header (not used when writing a gzip file) */ } gz_header; typedef gz_header FAR *gz_headerp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. In that case, zlib is thread-safe. When zalloc and zfree are Z_NULL on entry to the initialization function, they are set to internal routines that use the standard library functions malloc() and free(). On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use by the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 #define Z_TREES 6 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field for deflate() */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion(void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. total_in, total_out, adler, and msg are initialized. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Generate more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary. Some output may be provided even if flush is zero. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. See deflatePending(), which can be used if desired to determine whether or not there is more output in that case. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. This completes the current deflate block and follows it with an empty stored block that is three bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff). If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the output buffer, but the output is not aligned to a byte boundary. All of the input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output in order for the decompressor to finish the block before the empty fixed codes block. If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to seven bits of the current block are held to be written as the next byte after the next deflate block is completed. In this case, the decompressor may not be provided enough bits at this point in order to complete decompression of the data provided so far to the compressor. It may need to wait for the next block to be emitted. This is for advanced applications that need to control the emission of deflate blocks. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six when the flush marker begins, in order to avoid repeated flush markers upon calling deflate() again when avail_out == 0. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used in the first deflate call after deflateInit if all the compression is to be done in a single step. In order to complete in one call, avail_out must be at least the value returned by deflateBound (see below). Then deflate is guaranteed to return Z_STREAM_END. If not enough output space is provided, deflate will not return Z_STREAM_END, and it must be called again as described above. deflate() sets strm->adler to the Adler-32 checksum of all input read so far (that is, total_in bytes). If a gzip stream is being generated, then strm->adler will be the CRC-32 checksum of the input read so far. (See deflateInit2 below.) deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was Z_NULL or the state was inadvertently written over by the application), or Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit(z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. In the current version of inflate, the provided input is not read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. total_in, total_out, adler, and msg are initialized. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit does not perform any decompression. Actual decompression will be done by inflate(). So next_in, and avail_in, next_out, and avail_out are unused and unchanged. The current implementation of inflateInit() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), then next_in and avail_in are updated accordingly, and processing will resume at this point for the next call of inflate(). - Generate more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. If the caller of inflate() does not provide both available input and available output space, it is possible that there will be no progress made. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. To assist in this, on return inflate() always sets strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. data_type is set as noted here every time inflate() returns for all flush options, and so can be used to determine the amount of currently consumed input in bits. The Z_TREES option behaves as Z_BLOCK does, but it also returns when the end of each deflate block header is reached, before any actual data in that block is decoded. This allows the caller to determine the length of the deflate block header for later use in random access within a deflate block. 256 is added to the value of strm->data_type when inflate() returns immediately after reaching the end of the deflate block header. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all of the uncompressed data for the operation to complete. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The use of Z_FINISH is not required to perform an inflation in one step. However it may be used to inform inflate that a faster approach can be used for the single inflate() call. Z_FINISH also informs inflate to not maintain a sliding window if the stream completes, which reduces inflate's memory footprint. If the stream does not complete, either because not all of the stream is provided or not enough output space is provided, then a sliding window will be allocated and inflate() can be called again to continue the operation as if Z_NO_FLUSH had been used. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the effects of the flush parameter in this implementation are on the return value of inflate() as noted below, when inflate() returns early when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of memory for a sliding window when Z_FINISH is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the Adler-32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed Adler-32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip header is not retained unless inflateGetHeader() is used. When processing gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output produced so far. The CRC-32 is checked against the gzip trailer, as is the uncompressed length, modulo 2^32. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value, in which case strm->msg points to a string with a more specific error), Z_STREAM_ERROR if the stream structure was inconsistent (for example next_in or next_out was Z_NULL, or the state was inadvertently written over by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress was possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is to be attempted. */ ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state was inconsistent. */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); This is another version of deflateInit with more compression options. The fields zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. For the current implementation of deflate(), a windowBits value of 8 (a window size of 256 bytes) is not supported. As a result, a request for 8 will result in 9 (a 512-byte window). In that case, providing 8 to inflateInit2() will result in an error when the zlib header with 9 is checked against the initialization of inflate(). The remedy is to not use 8 with deflateInit2() with this initialization, or at least in that case use 9 with inflateInit2(). windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute a check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to the appropriate value, if the operating system was determined at compile time. If a gzip stream is being written, strm->adler is a CRC-32 instead of an Adler-32. For raw deflate or gzip encoding, a request for a 256-byte window is rejected as invalid, since only the zlib header provides a means of transmitting the window size to the decompressor. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this function must be called immediately after deflateInit, deflateInit2 or deflateReset, and before any call of deflate. When doing raw deflate, this function must be called either before any call of deflate, or immediately after the completion of a deflate block, i.e. after all input has been consumed and all output has been delivered when using any of the flush options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size provided in deflateInit or deflateInit2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the Adler-32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler-32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the Adler-32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream or if not at a block boundary for raw deflate). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, uInt *dictLength); /* Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If deflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. Similarly, if dictLength is Z_NULL, then it is not set. deflateGetDictionary() may return a length less than the window size, even when more than the window size in input has been provided. It may return up to 258 bytes less in that case, due to how zlib's implementation of deflate manages the sliding window and lookahead for matches, where matches can be up to 258 bytes long. If the application needs the last window-size bytes of input, then that would need to be saved by the application outside of zlib. deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent. */ ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, z_streamp source); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset(z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been set unchanged. total_in, total_out, adler, and msg are initialized. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT deflateParams(z_streamp strm, int level, int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2(). This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression approach (which is a function of the level) or the strategy is changed, and if there have been any deflate() calls since the state was initialized or reset, then the input available so far is compressed with the old level and strategy using deflate(strm, Z_BLOCK). There are three approaches for the compression levels 0, 1..3, and 4..9 respectively. The new level and strategy will take effect at the next call of deflate(). If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does not have enough output space to complete, then the parameter change will not take effect. In this case, deflateParams() can be called again with the same parameters and more output space to try again. In order to assure a change in the parameters on the first try, the deflate stream should be flushed using deflate() with Z_BLOCK or other flush request until strm.avail_out is not zero, before calling deflateParams(). Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be applied to the data compressed after deflateParams(). deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if there was not enough output space to complete the compression of the available input data before a change in the strategy or approach. Note that in the case of a Z_BUF_ERROR, the parameters are not changed. A return value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be retried with more output space. */ ZEXTERN int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters. deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). If that first deflate() call is provided the sourceLen input bytes, an output buffer allocated to the size returned by deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed to return Z_STREAM_END. Note that it is possible for the compressed size to be larger than the value returned by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used. */ ZEXTERN int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits); /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not provided would be due to the available output space having being consumed. The number of bits of output not provided are between 0 and 7, where they await more bits to join them in order to fill out a full byte. If pending or bits are Z_NULL, then those values are not set. deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, int bits, int value); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to the current operating system, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be zero to request that inflate use the window size in the zlib header of the compressed stream. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an Adler-32 or a CRC-32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see below), inflate() will *not* automatically decode concatenated gzip members. inflate() will return Z_STREAM_END at the end of the gzip member. The state would need to be reset to continue decoding a subsequent gzip member. This *must* be done if there is more data after a gzip member, in order for the decompression to be compliant with the gzip standard (RFC 1952). inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit2() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the Adler-32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called at any time to set the dictionary. If the provided dictionary is smaller than the window and there is already data in the window, then the provided dictionary will amend what's there. The application must insure that the dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect Adler-32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, uInt *dictLength); /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If inflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. Similarly, if dictLength is Z_NULL, then it is not set. inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent. */ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync searches for a 00 00 FF FF pattern in the compressed data. All full flush points have this pattern, but not all occurrences of this pattern are full flush points. inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, z_streamp source); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset(z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. total_in, total_out, adler, and msg are initialized. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, int windowBits); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted the same as it is for inflateInit2. If the window size is changed, then the memory allocated for the window is freed, and the window will be reallocated by inflate() if needed. inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if the windowBits parameter is invalid. */ ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, int bits, int value); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. If bits is negative, then the input stream bit buffer is emptied. Then inflatePrime() can be called again to put bits in the buffer. This is used to clear out bits leftover after feeding inflate a block description prior to feeding inflate codes. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN long ZEXPORT inflateMark(z_streamp strm); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. If the upper value is -1 and the lower value is zero, then inflate() is currently decoding information outside of a block. If the upper value is -1 and the lower value is non-zero, then inflate is in the middle of a stored block, with the lower value equaling the number of bytes from the input remaining to copy. If the upper value is not -1, then it is the number of bits back from the current bit position in the input of the code (literal or length/distance pair) currently being processed. In that case the lower value is the number of bytes already emitted for that code. A code is being processed if inflate is waiting for more input to complete decoding of the code, or if it has completed decoding but is waiting for more output space to write the literal or match data. inflateMark() is used to mark locations in the input data for random access, which may be at bit positions, and to note those cases where the output of a code may span boundaries of random access blocks. The current location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate. inflateMark returns the value noted above, or -65536 if the provided source stream state was inconsistent. */ ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed. The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, unsigned char FAR *window); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the parameters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func)(void FAR *, z_const unsigned char FAR * FAR *); typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); ZEXTERN int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than inflate() for file i/o applications, in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. inflate() can be faster on modern CPUs when used with large buffers. inflateBack() trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the default behavior of inflate(), which expects a zlib header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero -- buf is ignored in that case -- and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags(void); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: ZLIB_DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ #ifndef Z_SOLO /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can be modified if you need special options. */ ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed data. compress() is equivalent to compress2() with a level parameter of Z_DEFAULT_COMPRESSION. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed data. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the uncompressed data. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In the case where there is not enough room, uncompress() will fill the output buffer with the uncompressed data up to that point. */ ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of source bytes consumed. */ /* gzip file access functions */ /* This library supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio, using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. */ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); Open the gzip (.gz) file at path for reading and decompressing, or compressing and writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or appending with no compression and not using the gzip format. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since reading and writing to the same gzip file is not supported. The addition of "x" when writing will create the file exclusively, which fails if the file already exists. On systems that support it, the addition of "e" when reading or writing will set the flag to close the file on an execve() call. These functions, as well as gzip, will read and decode a sequence of gzip streams in a file. The append function of gzopen() can be used to create such a file. (Also see gzflush() for another way to do this.) When appending, gzopen does not test whether the file begins with a gzip stream, nor does it look for the end of the gzip streams to begin appending. gzopen will simply append a gzip stream to the existing file. gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. When reading, this will be detected automatically by looking for the magic two- byte gzip header. gzopen returns NULL if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). errno can be checked to determine if the reason gzopen failed was that the file could not be opened. */ ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* Associate a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since gzdopen does not close fd if it fails. If you are using fileno() to get the file descriptor from a FILE *, then you will have to use dup() to avoid double-close()ing the file descriptor. Both gzclose() and fclose() will close the associated file descriptor, so they need to have different file descriptors. gzdopen returns NULL if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided), or if fd is -1. The file descriptor is not used until the next gz* read, write, seek, or close operation, so gzdopen will not detect if fd is invalid (unless fd is -1). */ ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); /* Set the internal buffer size used by this library's functions for file to size. The default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or write. Three times that size in buffer space is allocated. A larger buffer size of, for example, 64K or 128K bytes will noticeably increase the speed of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). gzbuffer() returns 0 on success, or -1 on failure, such as being called too late. */ ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); /* Dynamically update the compression level and strategy for file. See the description of deflateInit2 for the meaning of these parameters. Previously provided data is flushed before applying the parameter changes. gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not opened for writing, Z_ERRNO if there is an error writing the flushed data, or Z_MEM_ERROR if there is a memory allocation error. */ ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); /* Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file. After reaching the end of a gzip stream in the input, gzread will continue to read, looking for another gzip stream. Any number of gzip streams may be concatenated in the input file, and will all be decompressed by gzread(). If something other than a gzip stream is encountered after a gzip stream, that remaining trailing garbage is ignored (and no error is returned). gzread can be used to read a gzip file that is being concurrently written. Upon reaching the end of the input, gzread will return with the available data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then gzclearerr can be used to clear the end of file indicator in order to permit gzread to be tried again. Z_OK indicates that a gzip stream was completed on the last gzread. Z_BUF_ERROR indicates that the input file ended in the middle of a gzip stream. Note that gzread does not return -1 in the event of an incomplete gzip stream. This error is deferred until gzclose(), which will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip stream. Alternatively, gzerror can be used before gzclose to detect this case. gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. If len is too large to fit in an int, then nothing is read, -1 is returned, and the error state is set to Z_STREAM_ERROR. */ ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file); /* Read and decompress up to nitems items of size size from file into buf, otherwise operating as gzread() does. This duplicates the interface of stdio's fread(), with size_t request and return types. If the library defines size_t, then z_size_t is identical to size_t. If not, then z_size_t is an unsigned integer type that can contain a pointer. gzfread() returns the number of full items read of size size, or zero if the end of the file was reached and a full item could not be read, or if there was an error. gzerror() must be consulted if zero is returned in order to determine if there was an error. If the multiplication of size and nitems overflows, i.e. the product does not fit in a z_size_t, then nothing is read, zero is returned, and the error state is set to Z_STREAM_ERROR. In the event that the end of file is reached and only a partial item is available at the end, i.e. the remaining uncompressed data length is not a multiple of size, then the final partial item is nevertheless read into buf and the end-of-file flag is set. The length of the partial item read is not provided, but could be inferred from the result of gztell(). This behavior is the same as the behavior of fread() implementations in common libraries, but it prevents the direct use of gzfread() to read a concurrently written file, resetting and retrying on end-of-file, when size is not 1. */ ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* Compress and write the len uncompressed bytes at buf to file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, gzFile file); /* Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If the library defines size_t, then z_size_t is identical to size_t. If not, then z_size_t is an unsigned integer type that can contain a pointer. gzfwrite() returns the number of full items written of size size, or zero if there was an error. If the multiplication of size and nitems overflows, i.e. the product does not fit in a z_size_t, then nothing is written, zero is returned, and the error state is set to Z_STREAM_ERROR. */ ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); /* Convert, format, compress, and write the arguments (...) to file under control of the string format, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or a negative zlib error code in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf(), because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); /* Compress and write the given null-terminated string s to file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); /* Read and decompress bytes from file into buf, until len-1 characters are read, or until a newline character is read and transferred to buf, or an end-of-file condition is encountered. If any characters are read or if len is one, the string is terminated with a null character. If no characters are read due to an end-of-file or len is less than one, then the buffer is left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at buf are indeterminate. */ ZEXTERN int ZEXPORT gzputc(gzFile file, int c); /* Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc(gzFile file); /* Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. it does not check to see if file is NULL, nor whether the structure file points to has been clobbered or not. */ ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); /* Push c back onto the stream for file to be read as the first character on the next read. At least one character of push-back is always allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the output buffer size of pushed characters is allowed. (See gzbuffer above.) The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); /* Flush all pending output to file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush is only permitted when writing. If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such concatenated gzip streams. gzflush should be called only when strictly necessary because it will degrade compression if called too often. */ /* ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence); Set the starting position to offset relative to whence for the next gzread or gzwrite on file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind(gzFile file); /* Rewind file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). */ /* ZEXTERN z_off_t ZEXPORT gztell(gzFile file); Return the starting position for the next gzread or gzwrite on file. This position represents a number of bytes in the uncompressed data stream, and is zero when starting, even if appending or reading a gzip stream from the middle of a file using gzdopen(). gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ /* ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); Return the current compressed (actual) read or write offset of file. This offset includes the count of bytes that precede the gzip stream, for example when appending or when using gzdopen() for reading. When reading, the offset does not include as yet unused buffered input. This information can be used for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof(gzFile file); /* Return true (1) if the end-of-file indicator for file has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set only if the read tried to go past the end of the input, but came up short. Therefore, just like feof(), gzeof() may return false even if there is no more data to read, in the event that the last read request was for the exact number of bytes remaining in the input file. This will happen if the input file size is an exact multiple of the buffer size. If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file has grown since the previous end of file was detected. */ ZEXTERN int ZEXPORT gzdirect(gzFile file); /* Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream. If gzdirect() is used immediately after gzopen() or gzdopen() it will cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect(). When writing, gzdirect() returns true (1) if transparent writing was requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: gzdirect() is not needed when writing. Transparent writing must be explicitly requested, so the application already knows the answer. When linking statically, using gzdirect() will include all of the zlib code for gzip file reading and decompression, which may not be desired.) */ ZEXTERN int ZEXPORT gzclose(gzFile file); /* Flush all pending output for file, if necessary, close file and deallocate the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation. gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the last read ended in the middle of a gzip stream, or Z_OK on success. */ ZEXTERN int ZEXPORT gzclose_r(gzFile file); ZEXTERN int ZEXPORT gzclose_w(gzFile file); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to using these instead of gzclose() is that they avoid linking in zlib compression or decompression code that is not used when only reading or only writing respectively. If gzclose() is used, then both compression and decompression code will be included the application when linking to a static zlib library. */ ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* Return the error message for the last error which occurred on file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is closed, then the string previously returned by gzerror will no longer be available. gzerror() should be used to distinguish errors from end-of-file for those functions above that do not distinguish those cases in their return values. */ ZEXTERN void ZEXPORT gzclearerr(gzFile file); /* Clear the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ #endif /* !Z_SOLO */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. An Adler-32 value is in the range of a 32-bit unsigned integer. If buf is Z_NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len); /* Same as adler32(), but with a size_t length. */ /* ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note that the z_off_t type (like off_t) is a signed integer. If len2 is negative, the result has no meaning or utility. */ ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. If buf is Z_NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, z_size_t len); /* Same as crc32(), but with a size_t length. */ /* ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); /* Give the same result as crc32_combine(), using op in place of len2. op is is generated from len2 by crc32_combine_gen(). This will be faster than crc32_combine() if the generated op is used more than once. */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size); ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, const char *version, int stream_size); ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, int stream_size); ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size); #ifdef Z_PREFIX_SET # define z_deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) # define z_inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) # define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) # define z_inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ (int)sizeof(z_stream)) # define z_inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, (int)sizeof(z_stream)) #else # define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) # define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) # define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) # define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ (int)sizeof(z_stream)) # define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, (int)sizeof(z_stream)) #endif #ifndef Z_SOLO /* gzgetc() macro and its supporting function and exposed data structure. Note * that the real internal state is much larger than the exposed structure. * This abbreviated structure exposes just enough for the gzgetc() macro. The * user should not mess with these exposed elements, since their names or * behavior could change in the future, perhaps even capriciously. They can * only be used by the gzgetc() macro. You have been warned. */ struct gzFile_s { unsigned have; unsigned char *next; z_off64_t pos; }; ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #else # define gzgetc(g) \ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if * both are true, the application gets the *64 functions, and the regular * functions are changed to 64 bits) -- in case these are set on systems * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) # ifdef Z_PREFIX_SET # define z_gzopen z_gzopen64 # define z_gzseek z_gzseek64 # define z_gztell z_gztell64 # define z_gzoffset z_gzoffset64 # define z_adler32_combine z_adler32_combine64 # define z_crc32_combine z_crc32_combine64 # define z_crc32_combine_gen z_crc32_combine_gen64 # else # define gzopen gzopen64 # define gzseek gzseek64 # define gztell gztell64 # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 # define crc32_combine_gen crc32_combine_gen64 # endif # ifndef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); ZEXTERN z_off_t ZEXPORT gztell64(gzFile); ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); # endif #else ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); ZEXTERN z_off_t ZEXPORT gztell(gzFile); ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif #else /* Z_SOLO */ ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif /* !Z_SOLO */ /* undocumented functions */ ZEXTERN const char * ZEXPORT zError(int); ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); #if defined(_WIN32) && !defined(Z_SOLO) ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va); # endif #endif #ifdef __cplusplus } #endif #endif /* ZLIB_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/zutil.c000066400000000000000000000160131516712004000250250ustar00rootroot00000000000000/* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-2017 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" #ifndef Z_SOLO # include "gzguts.h" #endif z_const char * const z_errmsg[10] = { (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ (z_const char *)"stream end", /* Z_STREAM_END 1 */ (z_const char *)"", /* Z_OK 0 */ (z_const char *)"file error", /* Z_ERRNO (-1) */ (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ (z_const char *)"" }; const char * ZEXPORT zlibVersion(void) { return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags(void) { uLong flags; flags = 0; switch ((int)(sizeof(uInt))) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } switch ((int)(sizeof(uLong))) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } switch ((int)(sizeof(voidpf))) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } switch ((int)(sizeof(z_off_t))) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; default: flags += 3 << 6; } #ifdef ZLIB_DEBUG flags += 1 << 8; #endif /* #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif */ #ifdef ZLIB_WINAPI flags += 1 << 10; #endif #ifdef BUILDFIXED flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS flags += 1L << 16; #endif #ifdef NO_GZIP flags += 1L << 17; #endif #ifdef PKZIP_BUG_WORKAROUND flags += 1L << 20; #endif #ifdef FASTEST flags += 1L << 21; #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifdef NO_vsnprintf flags += 1L << 25; # ifdef HAS_vsprintf_void flags += 1L << 26; # endif # else # ifdef HAS_vsnprintf_void flags += 1L << 26; # endif # endif #else flags += 1L << 24; # ifdef NO_snprintf flags += 1L << 25; # ifdef HAS_sprintf_void flags += 1L << 26; # endif # else # ifdef HAS_snprintf_void flags += 1L << 26; # endif # endif #endif return flags; } #ifdef ZLIB_DEBUG #include # ifndef verbose # define verbose 0 # endif int ZLIB_INTERNAL z_verbose = verbose; void ZLIB_INTERNAL z_error(char *m) { fprintf(stderr, "%s\n", m); exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ const char * ZEXPORT zError(int err) { return ERR_MSG(err); } #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 /* The older Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ int errno = 0; #endif #ifndef HAVE_MEMCPY void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifndef Z_SOLO #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; (void)opaque; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; (void)opaque; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp malloc(uInt size); extern voidp calloc(uInt items, uInt size); extern void free(voidpf ptr); #endif voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; free(ptr); } #endif /* MY_ZCALLOC */ #endif /* !Z_SOLO */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/id3v2/zlib/zutil.h000066400000000000000000000150251516712004000250340ustar00rootroot00000000000000/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef ZUTIL_H #define ZUTIL_H #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL #endif #include "zlib.h" #if defined(STDC) && !defined(Z_SOLO) # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif # include # include #endif #ifndef local # define local static #endif /* since "static" is used to mean two completely different things in C, we define "local" for the non-static meaning of "static", for readability (compile with -Dlocal if your debugger can't find static symbols) */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; #if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) # include # if (ULONG_MAX == 0xffffffffffffffff) # define Z_U8 unsigned long # elif (ULLONG_MAX == 0xffffffffffffffff) # define Z_U8 unsigned long long # elif (UINT_MAX == 0xffffffffffffffff) # define Z_U8 unsigned # endif #endif extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # ifndef Z_SOLO # if defined(__TURBOC__) || defined(__BORLANDC__) # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif # endif #endif #ifdef AMIGA # define OS_CODE 1 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 2 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #ifdef __370__ # if __TARGET_LIB__ < 0x20000000 # define OS_CODE 4 # elif __TARGET_LIB__ < 0x40000000 # define OS_CODE 11 # else # define OS_CODE 8 # endif #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 5 #endif #ifdef OS2 # define OS_CODE 6 # if defined(M_I86) && !defined(Z_SOLO) # include # endif #endif #if defined(MACOS) # define OS_CODE 7 #endif #ifdef __acorn # define OS_CODE 13 #endif #if defined(WIN32) && !defined(__CYGWIN__) # define OS_CODE 10 #endif #ifdef _BEOS_ # define OS_CODE 16 #endif #ifdef __TOS_OS400__ # define OS_CODE 18 #endif #ifdef __APPLE__ # define OS_CODE 19 #endif #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 #pragma warn -8066 #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 3 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(pyr) || defined(Z_SOLO) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); #endif /* Diagnostic functions */ #ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; extern void ZLIB_INTERNAL z_error(char *m); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif #ifndef Z_SOLO voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size); void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); #endif #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} /* Reverse the bytes in a 32-bit value */ #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) #endif /* ZUTIL_H */ boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/000077500000000000000000000000001516712004000223225ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/Makefile000077500000000000000000000012201516712004000237600ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = mp4 TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = config.o dllinterface.o mp4.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/config.cpp000066400000000000000000000043121516712004000242730ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "config.h" #include "dllinterface.h" const String BoCA::ConfigureMP4::ConfigID = "MP4"; BoCA::ConfigureMP4::ConfigureMP4() { const Config *config = Config::Get(); I18n *i18n = I18n::Get(); i18n->SetContext("Taggers::MP4"); Int chapterType = config->GetIntValue(ConfigID, "ChapterType", MP4ChapterTypeQt); group_chapter = new GroupBox(i18n->TranslateString("Chapter format"), Point(7, 11), Size(236, 41)); text_chapter = new Text(i18n->AddColon(i18n->TranslateString("Chapter format")), Point(10, 15)); combo_chapter = new ComboBox(Point(17 + text_chapter->GetUnscaledTextWidth(), 12), Size(209 - text_chapter->GetUnscaledTextWidth(), 0)); combo_chapter->AddEntry(i18n->TranslateString("both")); combo_chapter->AddEntry("QuickTime"); combo_chapter->AddEntry("Nero"); switch (chapterType) { default: case MP4ChapterTypeAny: combo_chapter->SelectNthEntry(0); break; case MP4ChapterTypeQt: combo_chapter->SelectNthEntry(1); break; case MP4ChapterTypeNero: combo_chapter->SelectNthEntry(2); break; } group_chapter->Add(text_chapter); group_chapter->Add(combo_chapter); Add(group_chapter); SetSize(Size(250, 169)); } BoCA::ConfigureMP4::~ConfigureMP4() { DeleteObject(group_chapter); DeleteObject(text_chapter); DeleteObject(combo_chapter); } Int BoCA::ConfigureMP4::SaveSettings() { Config *config = Config::Get(); Int chapterType = MP4ChapterTypeAny; switch (combo_chapter->GetSelectedEntryNumber()) { case 1: chapterType = MP4ChapterTypeQt; break; // QuickTime case 2: chapterType = MP4ChapterTypeNero; break; // Nero } config->SetIntValue(ConfigID, "ChapterType", chapterType); return Success(); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/config.h000066400000000000000000000020021516712004000237320ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2018 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_MP4CONFIG #define H_MP4CONFIG #include #include using namespace smooth; using namespace smooth::GUI; using namespace BoCA; namespace BoCA { class ConfigureMP4 : public ConfigLayer { private: GroupBox *group_chapter; Text *text_chapter; ComboBox *combo_chapter; public: static const String ConfigID; ConfigureMP4(); ~ConfigureMP4(); Int SaveSettings(); }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/dllinterface.cpp000077500000000000000000000151751516712004000254760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" MP4READ ex_MP4Read = NIL; MP4MODIFY ex_MP4Modify = NIL; MP4CLOSE ex_MP4Close = NIL; MP4FREE ex_MP4Free = NIL; MP4OPTIMIZE ex_MP4Optimize = NIL; MP4TAGSALLOC ex_MP4TagsAlloc = NIL; MP4TAGSFETCH ex_MP4TagsFetch = NIL; MP4TAGSSTORE ex_MP4TagsStore = NIL; MP4TAGSFREE ex_MP4TagsFree = NIL; MP4TAGSSETNAME ex_MP4TagsSetName = NIL; MP4TAGSSETARTIST ex_MP4TagsSetArtist = NIL; MP4TAGSSETALBUM ex_MP4TagsSetAlbum = NIL; MP4TAGSSETCOMMENTS ex_MP4TagsSetComments = NIL; MP4TAGSSETGENRE ex_MP4TagsSetGenre = NIL; MP4TAGSSETGENRETYPE ex_MP4TagsSetGenreType = NIL; MP4TAGSSETRELEASEDATE ex_MP4TagsSetReleaseDate = NIL; MP4TAGSSETTRACK ex_MP4TagsSetTrack = NIL; MP4TAGSSETDISK ex_MP4TagsSetDisk = NIL; MP4TAGSSETCOMPILATION ex_MP4TagsSetCompilation = NIL; MP4TAGSSETMEDIATYPE ex_MP4TagsSetMediaType = NIL; MP4TAGSSETENCODINGTOOL ex_MP4TagsSetEncodingTool = NIL; MP4TAGSADDARTWORK ex_MP4TagsAddArtwork = NIL; MP4TAGSREMOVEARTWORK ex_MP4TagsRemoveArtwork = NIL; MP4GETCHAPTERS ex_MP4GetChapters = NIL; MP4SETCHAPTERS ex_MP4SetChapters = NIL; MP4DELETECHAPTERS ex_MP4DeleteChapters = NIL; MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc = NIL; MP4ITMFITEMFREE ex_MP4ItmfItemFree = NIL; MP4ITMFADDITEM ex_MP4ItmfAddItem = NIL; MP4ITMFREMOVEITEM ex_MP4ItmfRemoveItem = NIL; MP4ITMFGETITEMS ex_MP4ItmfGetItems = NIL; MP4ITMFGETITEMSBYCODE ex_MP4ItmfGetItemsByCode = NIL; MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning = NIL; MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree = NIL; DynamicLoader *mp4v2dll = NIL; Bool LoadMP4v2DLL() { mp4v2dll = BoCA::Utilities::LoadCodecDLL("mp4v2"); if (mp4v2dll == NIL) return False; ex_MP4Read = (MP4READ) mp4v2dll->GetFunctionAddress("MP4Read"); ex_MP4Modify = (MP4MODIFY) mp4v2dll->GetFunctionAddress("MP4Modify"); ex_MP4Close = (MP4CLOSE) mp4v2dll->GetFunctionAddress("MP4Close"); ex_MP4Free = (MP4FREE) mp4v2dll->GetFunctionAddress("MP4Free"); ex_MP4Optimize = (MP4OPTIMIZE) mp4v2dll->GetFunctionAddress("MP4Optimize"); ex_MP4TagsAlloc = (MP4TAGSALLOC) mp4v2dll->GetFunctionAddress("MP4TagsAlloc"); ex_MP4TagsFetch = (MP4TAGSFETCH) mp4v2dll->GetFunctionAddress("MP4TagsFetch"); ex_MP4TagsStore = (MP4TAGSSTORE) mp4v2dll->GetFunctionAddress("MP4TagsStore"); ex_MP4TagsFree = (MP4TAGSFREE) mp4v2dll->GetFunctionAddress("MP4TagsFree"); ex_MP4TagsSetName = (MP4TAGSSETNAME) mp4v2dll->GetFunctionAddress("MP4TagsSetName"); ex_MP4TagsSetArtist = (MP4TAGSSETARTIST) mp4v2dll->GetFunctionAddress("MP4TagsSetArtist"); ex_MP4TagsSetAlbum = (MP4TAGSSETALBUM) mp4v2dll->GetFunctionAddress("MP4TagsSetAlbum"); ex_MP4TagsSetComments = (MP4TAGSSETCOMMENTS) mp4v2dll->GetFunctionAddress("MP4TagsSetComments"); ex_MP4TagsSetGenre = (MP4TAGSSETGENRE) mp4v2dll->GetFunctionAddress("MP4TagsSetGenre"); ex_MP4TagsSetGenreType = (MP4TAGSSETGENRETYPE) mp4v2dll->GetFunctionAddress("MP4TagsSetGenreType"); ex_MP4TagsSetReleaseDate = (MP4TAGSSETRELEASEDATE) mp4v2dll->GetFunctionAddress("MP4TagsSetReleaseDate"); ex_MP4TagsSetTrack = (MP4TAGSSETTRACK) mp4v2dll->GetFunctionAddress("MP4TagsSetTrack"); ex_MP4TagsSetDisk = (MP4TAGSSETDISK) mp4v2dll->GetFunctionAddress("MP4TagsSetDisk"); ex_MP4TagsSetCompilation = (MP4TAGSSETCOMPILATION) mp4v2dll->GetFunctionAddress("MP4TagsSetCompilation"); ex_MP4TagsSetMediaType = (MP4TAGSSETMEDIATYPE) mp4v2dll->GetFunctionAddress("MP4TagsSetMediaType"); ex_MP4TagsSetEncodingTool = (MP4TAGSSETENCODINGTOOL) mp4v2dll->GetFunctionAddress("MP4TagsSetEncodingTool"); ex_MP4TagsAddArtwork = (MP4TAGSADDARTWORK) mp4v2dll->GetFunctionAddress("MP4TagsAddArtwork"); ex_MP4TagsRemoveArtwork = (MP4TAGSREMOVEARTWORK) mp4v2dll->GetFunctionAddress("MP4TagsRemoveArtwork"); ex_MP4GetChapters = (MP4GETCHAPTERS) mp4v2dll->GetFunctionAddress("MP4GetChapters"); ex_MP4SetChapters = (MP4SETCHAPTERS) mp4v2dll->GetFunctionAddress("MP4SetChapters"); ex_MP4DeleteChapters = (MP4DELETECHAPTERS) mp4v2dll->GetFunctionAddress("MP4DeleteChapters"); ex_MP4ItmfItemAlloc = (MP4ITMFITEMALLOC) mp4v2dll->GetFunctionAddress("MP4ItmfItemAlloc"); ex_MP4ItmfItemFree = (MP4ITMFITEMFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemFree"); ex_MP4ItmfAddItem = (MP4ITMFADDITEM) mp4v2dll->GetFunctionAddress("MP4ItmfAddItem"); ex_MP4ItmfRemoveItem = (MP4ITMFREMOVEITEM) mp4v2dll->GetFunctionAddress("MP4ItmfRemoveItem"); ex_MP4ItmfGetItems = (MP4ITMFGETITEMS) mp4v2dll->GetFunctionAddress("MP4ItmfGetItems"); ex_MP4ItmfGetItemsByCode = (MP4ITMFGETITEMSBYCODE) mp4v2dll->GetFunctionAddress("MP4ItmfGetItemsByCode"); ex_MP4ItmfGetItemsByMeaning = (MP4ITMFGETITEMSBYMEANING) mp4v2dll->GetFunctionAddress("MP4ItmfGetItemsByMeaning"); ex_MP4ItmfItemListFree = (MP4ITMFITEMLISTFREE) mp4v2dll->GetFunctionAddress("MP4ItmfItemListFree"); if (ex_MP4Read == NIL || ex_MP4Modify == NIL || ex_MP4Close == NIL || ex_MP4Free == NIL || ex_MP4Optimize == NIL || ex_MP4TagsAlloc == NIL || ex_MP4TagsFetch == NIL || ex_MP4TagsStore == NIL || ex_MP4TagsFree == NIL || ex_MP4TagsSetName == NIL || ex_MP4TagsSetArtist == NIL || ex_MP4TagsSetAlbum == NIL || ex_MP4TagsSetComments == NIL || ex_MP4TagsSetGenre == NIL || ex_MP4TagsSetGenreType == NIL || ex_MP4TagsSetReleaseDate == NIL || ex_MP4TagsSetTrack == NIL || ex_MP4TagsSetDisk == NIL || ex_MP4TagsSetCompilation == NIL || ex_MP4TagsSetMediaType == NIL || ex_MP4TagsSetEncodingTool == NIL || ex_MP4TagsAddArtwork == NIL || ex_MP4TagsRemoveArtwork == NIL || ex_MP4GetChapters == NIL || ex_MP4SetChapters == NIL || ex_MP4DeleteChapters == NIL || ex_MP4ItmfItemAlloc == NIL || ex_MP4ItmfItemFree == NIL || ex_MP4ItmfAddItem == NIL || ex_MP4ItmfRemoveItem == NIL || ex_MP4ItmfGetItems == NIL || ex_MP4ItmfGetItemsByCode == NIL || ex_MP4ItmfGetItemsByMeaning == NIL || ex_MP4ItmfItemListFree == NIL) { FreeMP4v2DLL(); return False; } return True; } Void FreeMP4v2DLL() { BoCA::Utilities::FreeCodecDLL(mp4v2dll); mp4v2dll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/dllinterface.h000077500000000000000000000112111516712004000251260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #ifdef callbacks # undef callbacks #endif #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *mp4v2dll; Bool LoadMP4v2DLL(); Void FreeMP4v2DLL(); typedef MP4FileHandle (*MP4READ) (const char *); typedef MP4FileHandle (*MP4MODIFY) (const char *, uint32_t); typedef void (*MP4CLOSE) (MP4FileHandle, uint32_t); typedef void (*MP4FREE) (void *); typedef bool (*MP4OPTIMIZE) (const char *, const char *); typedef const MP4Tags * (*MP4TAGSALLOC) (); typedef bool (*MP4TAGSFETCH) (const MP4Tags *, MP4FileHandle); typedef bool (*MP4TAGSSTORE) (const MP4Tags *, MP4FileHandle); typedef void (*MP4TAGSFREE) (const MP4Tags *); typedef bool (*MP4TAGSSETNAME) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETARTIST) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETALBUM) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETCOMMENTS) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETGENRE) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETGENRETYPE) (const MP4Tags *, const uint16_t *); typedef bool (*MP4TAGSSETRELEASEDATE) (const MP4Tags *, const char *); typedef bool (*MP4TAGSSETTRACK) (const MP4Tags *, const MP4TagTrack *); typedef bool (*MP4TAGSSETDISK) (const MP4Tags *, const MP4TagDisk *); typedef bool (*MP4TAGSSETCOMPILATION) (const MP4Tags *, const uint8_t *); typedef bool (*MP4TAGSSETMEDIATYPE) (const MP4Tags *, const uint8_t *); typedef bool (*MP4TAGSSETENCODINGTOOL) (const MP4Tags *, const char *); typedef bool (*MP4TAGSADDARTWORK) (const MP4Tags *, MP4TagArtwork *); typedef bool (*MP4TAGSREMOVEARTWORK) (const MP4Tags *, uint32_t); typedef MP4ChapterType (*MP4GETCHAPTERS) (MP4FileHandle, MP4Chapter_t **, uint32_t *, MP4ChapterType); typedef MP4ChapterType (*MP4SETCHAPTERS) (MP4FileHandle, MP4Chapter_t *, uint32_t, MP4ChapterType); typedef MP4ChapterType (*MP4DELETECHAPTERS) (MP4FileHandle, MP4ChapterType, MP4TrackId); typedef MP4ItmfItem * (*MP4ITMFITEMALLOC) (const char *, uint32_t); typedef void (*MP4ITMFITEMFREE) (MP4ItmfItem *); typedef bool (*MP4ITMFADDITEM) (MP4FileHandle, const MP4ItmfItem *); typedef bool (*MP4ITMFREMOVEITEM) (MP4FileHandle, const MP4ItmfItem *); typedef MP4ItmfItemList * (*MP4ITMFGETITEMS) (MP4FileHandle); typedef MP4ItmfItemList * (*MP4ITMFGETITEMSBYCODE) (MP4FileHandle, const char *); typedef MP4ItmfItemList * (*MP4ITMFGETITEMSBYMEANING) (MP4FileHandle, const char *, const char *); typedef void (*MP4ITMFITEMLISTFREE) (MP4ItmfItemList *); extern MP4READ ex_MP4Read; extern MP4MODIFY ex_MP4Modify; extern MP4CLOSE ex_MP4Close; extern MP4FREE ex_MP4Free; extern MP4OPTIMIZE ex_MP4Optimize; extern MP4TAGSALLOC ex_MP4TagsAlloc; extern MP4TAGSFETCH ex_MP4TagsFetch; extern MP4TAGSSTORE ex_MP4TagsStore; extern MP4TAGSFREE ex_MP4TagsFree; extern MP4TAGSSETNAME ex_MP4TagsSetName; extern MP4TAGSSETARTIST ex_MP4TagsSetArtist; extern MP4TAGSSETALBUM ex_MP4TagsSetAlbum; extern MP4TAGSSETCOMMENTS ex_MP4TagsSetComments; extern MP4TAGSSETGENRE ex_MP4TagsSetGenre; extern MP4TAGSSETGENRETYPE ex_MP4TagsSetGenreType; extern MP4TAGSSETRELEASEDATE ex_MP4TagsSetReleaseDate; extern MP4TAGSSETTRACK ex_MP4TagsSetTrack; extern MP4TAGSSETDISK ex_MP4TagsSetDisk; extern MP4TAGSSETCOMPILATION ex_MP4TagsSetCompilation; extern MP4TAGSSETMEDIATYPE ex_MP4TagsSetMediaType; extern MP4TAGSSETENCODINGTOOL ex_MP4TagsSetEncodingTool; extern MP4TAGSADDARTWORK ex_MP4TagsAddArtwork; extern MP4TAGSREMOVEARTWORK ex_MP4TagsRemoveArtwork; extern MP4GETCHAPTERS ex_MP4GetChapters; extern MP4SETCHAPTERS ex_MP4SetChapters; extern MP4DELETECHAPTERS ex_MP4DeleteChapters; extern MP4ITMFITEMALLOC ex_MP4ItmfItemAlloc; extern MP4ITMFITEMFREE ex_MP4ItmfItemFree; extern MP4ITMFADDITEM ex_MP4ItmfAddItem; extern MP4ITMFREMOVEITEM ex_MP4ItmfRemoveItem; extern MP4ITMFGETITEMS ex_MP4ItmfGetItems; extern MP4ITMFGETITEMSBYCODE ex_MP4ItmfGetItemsByCode; extern MP4ITMFGETITEMSBYMEANING ex_MP4ItmfGetItemsByMeaning; extern MP4ITMFITEMLISTFREE ex_MP4ItmfItemListFree; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/mp4.cpp000066400000000000000000000772711516712004000235440ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "mp4.h" #include "config.h" const String &BoCA::TaggerMP4::GetComponentSpecs() { static String componentSpecs; if (mp4v2dll != NIL) { componentSpecs = " \ \ \ \ MP4 Tagger \ 1.0 \ mp4-tag \ tagger \ \ MPEG-4 Audio Files \ m4a \ m4b \ m4r \ mp4 \ 3gp \ \ \ MP4 Metadata \ \ \ UTF-8 \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadMP4v2DLL(); } Void smooth::DetachDLL() { FreeMP4v2DLL(); } const String BoCA::TaggerMP4::ConfigID = "Tags"; const String BoCA::TaggerMP4::ItmfMeaningiTunes = "com.apple.iTunes"; const String BoCA::TaggerMP4::ItmfMeaningReplayGain = "org.hydrogenaudio.replaygain"; const String BoCA::TaggerMP4::genres[192] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alt. Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta Rap", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop", "Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout", "Downtempo", "Dub", "EBM", "Eclectic", "Electro", "Electroclash", "Emo", "Experimental", "Garage", "Global", "IDM", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield", "Lounge", "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance", "Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical", "Audiobook", "Audio Theatre", "Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient" }; BoCA::TaggerMP4::TaggerMP4() { configLayer = NIL; } BoCA::TaggerMP4::~TaggerMP4() { if (configLayer != NIL) Object::DeleteObject(configLayer); } Error BoCA::TaggerMP4::RenderStreamInfo(const String &fileName, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool preserveReplayGain = currentConfig->GetIntValue(ConfigID, "PreserveReplayGain", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToMP4 = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToMP4Metadata", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Open MP4 file for modification. */ const Info &info = track.GetInfo(); MP4FileHandle mp4File = ex_MP4Modify(fileName.ConvertTo("UTF-8"), 0); if (mp4File == NIL) return Error(); const MP4Tags *mp4Tags = ex_MP4TagsAlloc(); ex_MP4TagsFetch(mp4Tags, mp4File); String::OutputFormat outputFormat("UTF-8"); if (info.artist != NIL) ex_MP4TagsSetArtist(mp4Tags, info.artist.Trim()); if (info.title != NIL) ex_MP4TagsSetName(mp4Tags, info.title.Trim()); if (info.album != NIL) ex_MP4TagsSetAlbum(mp4Tags, info.album.Trim()); if (info.year > 0) ex_MP4TagsSetReleaseDate(mp4Tags, String::FromInt(info.year)); if (info.genre != NIL) ex_MP4TagsSetGenre(mp4Tags, info.genre.Trim()); if (info.track > 0) { MP4TagTrack mp4Track = { (uint16_t) info.track, (uint16_t) (info.numTracks > 0 ? info.numTracks : 0 ) }; ex_MP4TagsSetTrack(mp4Tags, &mp4Track); } if (info.disc > 0) { MP4TagDisk mp4Disk = { (uint16_t) info.disc, (uint16_t) (info.numDiscs > 0 ? info.numDiscs : 0) }; ex_MP4TagsSetDisk(mp4Tags, &mp4Disk); } if (info.comment != NIL && !replaceExistingComments) ex_MP4TagsSetComments(mp4Tags, info.comment); else if (defaultComment != NIL) ex_MP4TagsSetComments(mp4Tags, String(defaultComment).Trim()); /* Save encoder version. */ Application *app = Application::Get(); ex_MP4TagsSetEncodingTool(mp4Tags, app->getClientName.Call().Append(" ").Append(app->getClientVersion.Call())); /* Save album art. */ if (albumArtWriteToTags && albumArtWriteToMP4) { /* Put front and back covers first. */ Array pictures; foreach (const Picture &picInfo, track.pictures) { if (picInfo.type == 3) pictures.InsertAtPos(0, picInfo); else if (picInfo.type == 4) pictures.InsertAtPos((pictures.Length() > 0 && pictures.GetFirst().type == 3) ? 1 : 0, picInfo); else pictures.Add(picInfo); } /* Add album art to tag. */ foreach (const Picture &picInfo, pictures) { MP4TagArtwork artwork = { const_cast((const UnsignedByte *) picInfo.data), (uint32_t) picInfo.data.Size(), picInfo.mime == "image/png" ? MP4_ART_PNG : MP4_ART_JPEG }; ex_MP4TagsAddArtwork(mp4Tags, &artwork); } } /* Set media type. */ uint8_t mediaType = 1; // 1 == Music if (track.outputFile.Contains(".m4b")) mediaType = 2; // 2 == Audiobook else if (track.outputFile.Contains(".m4r")) mediaType = 14; // 14 == Ringtone ex_MP4TagsSetMediaType(mp4Tags, &mediaType); ex_MP4TagsStore(mp4Tags, mp4File); ex_MP4TagsFree(mp4Tags); /* Save other metadata atoms. */ if (info.rating >= 0) AddItmfItem(mp4File, "rate", NIL, NIL, String::FromInt(info.rating)); foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1).Trim(); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) AddItmfItem(mp4File, "aART", NIL, NIL, value); else if (key == INFO_CONTENTGROUP) AddItmfItem(mp4File, L"©grp", NIL, NIL, value); else if (key == INFO_COMPOSER) AddItmfItem(mp4File, L"©wrt", NIL, NIL, value); else if (key == INFO_MOVEMENT) AddItmfItem(mp4File, L"©mvi", NIL, NIL, value, MP4_ITMF_BT_INTEGER); else if (key == INFO_MOVEMENTTOTAL) AddItmfItem(mp4File, L"©mvc", NIL, NIL, value, MP4_ITMF_BT_INTEGER); else if (key == INFO_MOVEMENTNAME) AddItmfItem(mp4File, L"©mvn", NIL, NIL, value); else if (key == INFO_BPM) AddItmfItem(mp4File, "tmpo", NIL, NIL, value, MP4_ITMF_BT_INTEGER); else if (key == INFO_COPYRIGHT) AddItmfItem(mp4File, "cprt", NIL, NIL, value); else if (key == INFO_LYRICS) AddItmfItem(mp4File, L"©lyr", NIL, NIL, pair.Tail(pair.Length() - pair.Find(":") - 1)); else if (key == INFO_SORT_ARTIST) AddItmfItem(mp4File, "soar", NIL, NIL, value); else if (key == INFO_SORT_ALBUM) AddItmfItem(mp4File, "soal", NIL, NIL, value); else if (key == INFO_SORT_ALBUMARTIST) AddItmfItem(mp4File, "soaa", NIL, NIL, value); else if (key == INFO_SORT_COMPOSER) AddItmfItem(mp4File, "soco", NIL, NIL, value); else if (key == INFO_SORT_TITLE) AddItmfItem(mp4File, "sonm", NIL, NIL, value); } /* Save generic iTunes metadata. */ if (info.label != NIL) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "LABEL", info.label); if (info.isrc != NIL) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "ISRC", info.isrc, MP4_ITMF_BT_ISRC); foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1).Trim(); if (value == NIL) continue; if (key == INFO_SUBTITLE) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "SUBTITLE", value); else if (key == INFO_CONDUCTOR) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "CONDUCTOR", value); else if (key == INFO_REMIXER) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "REMIXER", value); else if (key == INFO_LYRICIST) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "LYRICIST", value); else if (key == INFO_PRODUCER) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "PRODUCER", value); else if (key == INFO_ENGINEER) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "ENGINEER", value); else if (key == INFO_INITIALKEY) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "initialkey", value); else if (key == INFO_MEDIATYPE) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MEDIA", value); else if (key == INFO_CATALOGNUMBER) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "CATALOGNUMBER", value); else if (key == INFO_BARCODE) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "BARCODE", value); else if (key == INFO_DISCSUBTITLE) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "DISCSUBTITLE", value); else if (key == INFO_SCRIPT) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "SCRIPT", value); else if (key == INFO_ASIN) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "ASIN", value); else if (key == INFO_MUSICBRAINZ_ARTISTID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Artist Id", value); else if (key == INFO_MUSICBRAINZ_ALBUMID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Id", value); else if (key == INFO_MUSICBRAINZ_ALBUMARTISTID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Artist Id", value); else if (key == INFO_MUSICBRAINZ_WORKID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Work Id", value); else if (key == INFO_MUSICBRAINZ_DISCID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Disc Id", value); else if (key == INFO_MUSICBRAINZ_TRACKID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Track Id", value); else if (key == INFO_MUSICBRAINZ_ORIGINALARTISTID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Original Artist Id", value); else if (key == INFO_MUSICBRAINZ_ORIGINALALBUMID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Original Album Id", value); else if (key == INFO_MUSICBRAINZ_RELEASEGROUPID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Release Group Id", value); else if (key == INFO_MUSICBRAINZ_RELEASETRACKID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Release Track Id", value); else if (key == INFO_MUSICBRAINZ_TRMID) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz TRM Id", value); else if (key == INFO_MUSICBRAINZ_RELEASETYPE) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Type", value); else if (key == INFO_MUSICBRAINZ_RELEASESTATUS) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Status", value); else if (key == INFO_RELEASECOUNTRY) AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Release Country", value); } /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "replaygain_track_gain", info.track_gain); AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "replaygain_track_peak", info.track_peak); } if (info.album_gain != NIL && info.album_peak != NIL) { AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "replaygain_album_gain", info.album_gain); AddItmfItem(mp4File, "----", ItmfMeaningiTunes, "replaygain_album_peak", info.album_peak); } } /* Save chapters. */ if (track.tracks.Length() > 0 && writeChapters) { MP4Chapter_t *chapterList = new MP4Chapter_t [track.tracks.Length()]; uint32_t chapterCount = track.tracks.Length(); for (UnsignedInt i = 0; i < chapterCount; i++) { const Track &chapterTrack = track.tracks.GetNth(i); const Info &chapterInfo = chapterTrack.GetInfo(); const Format &chapterFormat = chapterTrack.GetFormat(); const char *chapterTitle = chapterInfo.title.Trim(); memset(chapterList[i].title, 0, MP4V2_CHAPTER_TITLE_MAX + 1); if (chapterTitle != NIL) strncpy(chapterList[i].title, chapterTitle, Math::Min(strlen(chapterTitle), MP4V2_CHAPTER_TITLE_MAX)); if (chapterTrack.length >= 0) chapterList[i].duration = Math::Round(Float(chapterTrack.length) * MP4_MSECS_TIME_SCALE / chapterFormat.rate); else if (chapterTrack.approxLength >= 0) chapterList[i].duration = Math::Round(Float(chapterTrack.approxLength) * MP4_MSECS_TIME_SCALE / chapterFormat.rate); else chapterList[i].duration = MP4_INVALID_DURATION; } ex_MP4DeleteChapters(mp4File, MP4ChapterTypeAny, MP4_INVALID_TRACK_ID); ex_MP4SetChapters(mp4File, chapterList, chapterCount, (MP4ChapterType) currentConfig->GetIntValue(ConfigureMP4::ConfigID, "ChapterType", MP4ChapterTypeQt)); delete [] chapterList; } ex_MP4Close(mp4File, 0); /* Optimize MP4 structure. */ String tempName = fileName.Append(".temp"); ex_MP4Optimize(fileName.ConvertTo("UTF-8"), tempName.ConvertTo("UTF-8")); File(fileName).Delete(); File(tempName).Move(fileName); return Success(); } Bool BoCA::TaggerMP4::AddItmfItem(MP4FileHandle mp4File, const String &code, const String &meaning, const String &id, const String &value, MP4ItmfBasicType type) { /* Add iTunes metadata item. */ MP4ItmfItem *item = ex_MP4ItmfItemAlloc(code.ConvertTo("ISO-8859-1"), 1); Buffer buffer(2); item->mean = meaning; item->name = id; item->dataList.elements[0].typeCode = type; if (type == MP4_ITMF_BT_UTF8 || type == MP4_ITMF_BT_URL || type == MP4_ITMF_BT_ISRC) { item->dataList.elements[0].value = (uint8_t *) value.ConvertTo("UTF-8"); item->dataList.elements[0].valueSize = strlen((char *) item->dataList.elements[0].value); } else if (type == MP4_ITMF_BT_INTEGER) { Int number = value.ToInt(); Int size = 2; for (Int i = 0; i < size; i++) { buffer[i] = (number >> 8 * (size - i - 1)) & 0xFF; } item->dataList.elements[0].value = buffer; item->dataList.elements[0].valueSize = size; } ex_MP4ItmfAddItem(mp4File, item); item->code = NIL; item->mean = NIL; item->name = NIL; item->dataList.elements[0].typeCode = MP4_ITMF_BT_IMPLICIT; item->dataList.elements[0].value = NIL; item->dataList.elements[0].valueSize = 0; ex_MP4ItmfItemFree(item); return True; } Error BoCA::TaggerMP4::ParseStreamInfo(const String &fileName, Track &track) { const Config *currentConfig = GetConfiguration(); Info info = track.GetInfo(); MP4FileHandle mp4File = ex_MP4Read(fileName.ConvertTo("UTF-8")); if (mp4File == NIL) return Error(); const MP4Tags *mp4Tags = ex_MP4TagsAlloc(); ex_MP4TagsFetch(mp4Tags, mp4File); String::InputFormat inputFormat("UTF-8"); if (mp4Tags->name != NIL) info.title = String(mp4Tags->name).Trim(); if (mp4Tags->artist != NIL) info.artist = String(mp4Tags->artist).Trim(); if (mp4Tags->releaseDate != NIL) info.year = String(mp4Tags->releaseDate).Trim().ToInt(); if (mp4Tags->album != NIL) info.album = String(mp4Tags->album).Trim(); if (mp4Tags->comments != NIL) info.comment = String(mp4Tags->comments).Trim(); if (mp4Tags->genre != NIL) info.genre = String(mp4Tags->genre).Trim(); else if (mp4Tags->genreType != NIL) info.genre = GetID3CategoryName(*mp4Tags->genreType - 1); if (mp4Tags->track != NIL) { info.track = mp4Tags->track->index; info.numTracks = mp4Tags->track->total; } if (mp4Tags->disk != NIL) { info.disc = mp4Tags->disk->index; info.numDiscs = mp4Tags->disk->total; } if (currentConfig->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { for (UnsignedInt i = 0; i < mp4Tags->artworkCount; i++) { unsigned char *buffer = (unsigned char *) mp4Tags->artwork[i].data; uint32_t size = mp4Tags->artwork[i].size; if (size > 0) { Picture picture; if (i == 0) picture.type = 3; // Cover (front) else if (i == 1) picture.type = 4; // Cover (back) else picture.type = 0; // Other picture.data.Set(buffer, size); if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } } } } /* Set artist to album artist if artist is not filled. */ if (info.artist == NIL) info.artist = info.GetOtherInfo(INFO_ALBUMARTIST); ex_MP4TagsFree(mp4Tags); /* Parse generic iTunes metadata. */ ParseItmfItems(mp4File, info); track.SetInfo(info); /* Read chapters. */ if (currentConfig->GetIntValue(ConfigID, "ReadChapters", True)) { MP4Chapter_t *chapterList = NIL; uint32_t chapterCount = 0; ex_MP4GetChapters(mp4File, &chapterList, &chapterCount, MP4ChapterTypeAny); if (chapterList != NIL && chapterCount > 1) { MP4Duration offset = 0; for (UnsignedInt i = 0; i < chapterCount; i++) { const Format &format = track.GetFormat(); /* Fill track data. */ Track rTrack; rTrack.fileName = track.fileName; rTrack.pictures = track.pictures; rTrack.sampleOffset = Math::Round(Float(offset) / MP4_MSECS_TIME_SCALE * format.rate); if (chapterList[i].duration > 0 && i < chapterCount - 1) { rTrack.length = Math::Round(Float(chapterList[i].duration) / MP4_MSECS_TIME_SCALE * format.rate); } else { if (track.length > 0) rTrack.length = track.length - rTrack.sampleOffset; else if (track.approxLength > 0) rTrack.approxLength = track.approxLength - rTrack.sampleOffset; } if (track.length > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * rTrack.length); else if (track.approxLength > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * rTrack.length); else rTrack.fileSize = rTrack.length * format.channels * (format.bits / 8); rTrack.SetFormat(format); /* Set track title. */ Info info = track.GetInfo(); if (String(chapterList[i].title).Trim() != NIL) info.title = String(chapterList[i].title).Trim(); info.track = i + 1; rTrack.SetInfo(info); /* Add track to track list. */ track.tracks.Add(rTrack); offset += chapterList[i].duration; } } if (chapterList != NIL) ex_MP4Free(chapterList); } ex_MP4Close(mp4File, 0); return Success(); } Bool BoCA::TaggerMP4::ParseItmfItems(MP4FileHandle mp4File, Info &info) { String::InputFormat inputFormat("UTF-8"); /* Look for known atoms. */ MP4ItmfItemList *items = ex_MP4ItmfGetItems(mp4File); if (items != NIL) { /* Loop over items. */ for (UnsignedInt i = 0; i < items->size; i++) { MP4ItmfItem item = items->elements[i]; /* Read and assign value string. */ String code; code.ImportFrom("ISO-8859-1", item.code); String value = GetItmfItemValue(item); if (value == NIL) continue; else if (code == "rate") info.rating = Math::Min(100, value.ToInt()); else if (code == "aART") info.SetOtherInfo(INFO_ALBUMARTIST, value); else if (code == L"©grp") info.SetOtherInfo(INFO_CONTENTGROUP, value); else if (code == L"©wrt") info.SetOtherInfo(INFO_COMPOSER, value); if (code == L"©mvi") info.SetOtherInfo(INFO_MOVEMENT, value); else if (code == L"©mvc") info.SetOtherInfo(INFO_MOVEMENTTOTAL, value); else if (code == L"©mvn") info.SetOtherInfo(INFO_MOVEMENTNAME, value); else if (code == "tmpo") { if (value.ToInt() > 0) info.SetOtherInfo(INFO_BPM, value); } else if (code == "cprt") info.SetOtherInfo(INFO_COPYRIGHT, value); else if (code == L"©lyr") info.SetOtherInfo(INFO_LYRICS, value); else if (code == "soar") info.SetOtherInfo(INFO_SORT_ARTIST, value); else if (code == "soal") info.SetOtherInfo(INFO_SORT_ALBUM, value); else if (code == "soaa") info.SetOtherInfo(INFO_SORT_ALBUMARTIST, value); else if (code == "soco") info.SetOtherInfo(INFO_SORT_COMPOSER, value); else if (code == "sonm") info.SetOtherInfo(INFO_SORT_TITLE, value); } ex_MP4ItmfItemListFree(items); } /* Look for iTunes metadata items. */ items = ex_MP4ItmfGetItemsByMeaning(mp4File, ItmfMeaningiTunes, NIL); if (items != NIL) { /* Loop over items. */ for (UnsignedInt i = 0; i < items->size; i++) { MP4ItmfItem item = items->elements[i]; /* Read and assign value string. */ String id = String(item.name).ToUpper(); String value = GetItmfItemValue(item).Trim(); if (value == NIL) continue; if (id == "LABEL" || id == "PUBLISHER") info.label = value; else if (id == "ISRC") { if (Info::IsISRC(value)) info.isrc = value; } else if (id == "SUBTITLE") info.SetOtherInfo(INFO_SUBTITLE, value); else if (id == "CONDUCTOR") info.SetOtherInfo(INFO_CONDUCTOR, value); else if (id == "REMIXER") info.SetOtherInfo(INFO_REMIXER, value); else if (id == "LYRICIST") info.SetOtherInfo(INFO_LYRICIST, value); else if (id == "PRODUCER") info.SetOtherInfo(INFO_PRODUCER, value); else if (id == "ENGINEER") info.SetOtherInfo(INFO_ENGINEER, value); else if (id == "INITIALKEY") info.SetOtherInfo(INFO_INITIALKEY, value); else if (id == "MEDIA") info.SetOtherInfo(INFO_MEDIATYPE, value); else if (id == "CATALOGNUMBER") info.SetOtherInfo(INFO_CATALOGNUMBER, value); else if (id == "BARCODE") info.SetOtherInfo(INFO_BARCODE, value); else if (id == "DISCSUBTITLE") info.SetOtherInfo(INFO_DISCSUBTITLE, value); else if (id == "SCRIPT") info.SetOtherInfo(INFO_SCRIPT, value); else if (id == "ASIN") info.SetOtherInfo(INFO_ASIN, value); else if (id.StartsWith("MUSICBRAINZ")) { if (id == "MUSICBRAINZ ARTIST ID") info.SetOtherInfo(INFO_MUSICBRAINZ_ARTISTID, value); else if (id == "MUSICBRAINZ ALBUM ID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMID, value); else if (id == "MUSICBRAINZ ALBUM ARTIST ID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMARTISTID, value); else if (id == "MUSICBRAINZ WORK ID") info.SetOtherInfo(INFO_MUSICBRAINZ_WORKID, value); else if (id == "MUSICBRAINZ DISC ID") info.SetOtherInfo(INFO_MUSICBRAINZ_DISCID, value); else if (id == "MUSICBRAINZ TRACK ID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRACKID, value); else if (id == "MUSICBRAINZ ORIGINAL ARTIST ID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALARTISTID, value); else if (id == "MUSICBRAINZ ORIGINAL ALBUM ID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALALBUMID, value); else if (id == "MUSICBRAINZ RELEASE GROUP ID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASEGROUPID, value); else if (id == "MUSICBRAINZ RELEASE TRACK ID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETRACKID, value); else if (id == "MUSICBRAINZ TRM ID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRMID, value); else if (id == "MUSICBRAINZ ALBUM TYPE") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETYPE, value); else if (id == "MUSICBRAINZ ALBUM STATUS") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASESTATUS, value); else if (id == "MUSICBRAINZ ALBUM RELEASE COUNTRY") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); } else if (id.StartsWith("REPLAYGAIN")) { if (id == "REPLAYGAIN_TRACK_GAIN") info.track_gain = value; else if (id == "REPLAYGAIN_TRACK_PEAK") info.track_peak = value; else if (id == "REPLAYGAIN_ALBUM_GAIN") info.album_gain = value; else if (id == "REPLAYGAIN_ALBUM_PEAK") info.album_peak = value; } } ex_MP4ItmfItemListFree(items); } /* Look for Replay Gain items. */ items = ex_MP4ItmfGetItemsByMeaning(mp4File, ItmfMeaningReplayGain, NIL); if (items != NIL) { /* Loop over items. */ for (UnsignedInt i = 0; i < items->size; i++) { MP4ItmfItem item = items->elements[i]; /* Read and assign value string. */ String id = String(item.name).ToUpper(); String value = GetItmfItemValue(item); if (value == NIL) continue; if (id.StartsWith("REPLAYGAIN")) { if (id == "REPLAYGAIN_TRACK_GAIN") info.track_gain = value; else if (id == "REPLAYGAIN_TRACK_PEAK") info.track_peak = value; else if (id == "REPLAYGAIN_ALBUM_GAIN") info.album_gain = value; else if (id == "REPLAYGAIN_ALBUM_PEAK") info.album_peak = value; } } ex_MP4ItmfItemListFree(items); } return True; } String BoCA::TaggerMP4::GetItmfItemValue(MP4ItmfItem &item) { if (item.dataList.size == 0) return NIL; /* Check type code. */ if (item.dataList.elements[0].typeCode == MP4_ITMF_BT_UTF8 || item.dataList.elements[0].typeCode == MP4_ITMF_BT_URL || item.dataList.elements[0].typeCode == MP4_ITMF_BT_ISRC) { /* Read value into buffer. */ Buffer buffer(item.dataList.elements[0].valueSize + 1); memset(buffer, 0, item.dataList.elements[0].valueSize + 1); memcpy(buffer, item.dataList.elements[0].value, item.dataList.elements[0].valueSize); /* Return actual value. */ String::InputFormat inputFormat("UTF-8"); return String(buffer); } else if (item.dataList.elements[0].typeCode == MP4_ITMF_BT_INTEGER) { Int64 value = 0; for (UnsignedInt i = 0; i < item.dataList.elements[0].valueSize; i++) { value |= item.dataList.elements[0].value[i] << (8 * (item.dataList.elements[0].valueSize - i - 1)); } return String::FromInt(value); } return NIL; } Error BoCA::TaggerMP4::UpdateStreamInfo(const String &fileName, const Track &track) { MP4FileHandle mp4File = ex_MP4Modify(fileName.ConvertTo("UTF-8"), 0); if (mp4File == NIL) return Error(); const MP4Tags *mp4Tags = ex_MP4TagsAlloc(); ex_MP4TagsFetch(mp4Tags, mp4File); /* Remove metadata first. */ ex_MP4TagsSetArtist(mp4Tags, NIL); ex_MP4TagsSetName(mp4Tags, NIL); ex_MP4TagsSetAlbum(mp4Tags, NIL); ex_MP4TagsSetTrack(mp4Tags, NIL); ex_MP4TagsSetDisk(mp4Tags, NIL); ex_MP4TagsSetReleaseDate(mp4Tags, NIL); ex_MP4TagsSetGenre(mp4Tags, NIL); ex_MP4TagsSetGenreType(mp4Tags, NIL); ex_MP4TagsSetComments(mp4Tags, NIL); for (Int i = mp4Tags->artworkCount - 1; i >= 0; i--) { ex_MP4TagsRemoveArtwork(mp4Tags, i); } ex_MP4TagsStore(mp4Tags, mp4File); ex_MP4TagsFree(mp4Tags); /* Remove known atoms. */ RemoveItmfItem(mp4File, "aART"); RemoveItmfItem(mp4File, L"©grp"); RemoveItmfItem(mp4File, L"©wrt"); RemoveItmfItem(mp4File, L"©mvi"); RemoveItmfItem(mp4File, L"©mvc"); RemoveItmfItem(mp4File, L"©mvn"); RemoveItmfItem(mp4File, "tmpo"); RemoveItmfItem(mp4File, "cprt"); RemoveItmfItem(mp4File, L"©lyr"); RemoveItmfItem(mp4File, "soar"); RemoveItmfItem(mp4File, "soal"); RemoveItmfItem(mp4File, "soaa"); RemoveItmfItem(mp4File, "soco"); RemoveItmfItem(mp4File, "sonm"); /* Remove iTunes metadata items too. */ RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "LABEL"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "ISRC"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "SUBTITLE"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "CONDUCTOR"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "REMIXER"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "LYRICIST"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "PRODUCER"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "ENGINEER"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "initialkey"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MEDIA"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "CATALOGNUMBER"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "BARCODE"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "DISCSUBTITLE"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "SCRIPT"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "ASIN"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Artist Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Artist Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Work Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Disc Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Track Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Original Artist Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Original Album Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Release Group Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Release Track Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz TRM Id"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Type"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Status"); RemoveItmfItem(mp4File, "----", ItmfMeaningiTunes, "MusicBrainz Album Release Country"); ex_MP4Close(mp4File, 0); /* Now render the new metadata. */ RenderStreamInfo(fileName, track); return Success(); } Bool BoCA::TaggerMP4::RemoveItmfItem(MP4FileHandle mp4File, const String &code, const String &meaning, const String &id) { /* Look for iTunes metadata items. */ MP4ItmfItemList *items = NIL; if (code == "----") items = ex_MP4ItmfGetItemsByMeaning(mp4File, meaning, id); else items = ex_MP4ItmfGetItemsByCode(mp4File, code.ConvertTo("ISO-8859-1")); if (items == NIL) return True; /* Loop over items and remove them. */ for (UnsignedInt i = 0; i < items->size; i++) { ex_MP4ItmfRemoveItem(mp4File, &items->elements[i]); } ex_MP4ItmfItemListFree(items); return True; } const String &BoCA::TaggerMP4::GetID3CategoryName(UnsignedInt id) { static const String empty; if (id > 191) return empty; else return genres[id]; } ConfigLayer *BoCA::TaggerMP4::GetConfigurationLayer() { if (configLayer == NIL) configLayer = new ConfigureMP4(); return configLayer; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/mp4/mp4.h000066400000000000000000000033241516712004000231750ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(TaggerMP4) namespace BoCA { class TaggerMP4 : public CS::TaggerComponent { private: static const String ConfigID; static const String ItmfMeaningiTunes; static const String ItmfMeaningReplayGain; static const String genres[192]; ConfigLayer *configLayer; static Bool AddItmfItem(MP4FileHandle, const String &, const String &, const String &, const String &, MP4ItmfBasicType = MP4_ITMF_BT_UTF8); static Bool RemoveItmfItem(MP4FileHandle, const String &, const String & = NIL, const String & = NIL); static Bool ParseItmfItems(MP4FileHandle, Info &); static String GetItmfItemValue(MP4ItmfItem &); static const String &GetID3CategoryName(UnsignedInt); public: static const String &GetComponentSpecs(); TaggerMP4(); ~TaggerMP4(); Error ParseStreamInfo(const String &, Track &); Error RenderStreamInfo(const String &, const Track &); Error UpdateStreamInfo(const String &, const Track &); ConfigLayer *GetConfigurationLayer(); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerMP4) BoCA_END_COMPONENT(TaggerMP4) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/riff/000077500000000000000000000000001516712004000225505ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/riff/Makefile000077500000000000000000000011171516712004000242130ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = riff TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = riff.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/riff/riff.cpp000066400000000000000000000360331516712004000242070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "riff.h" using namespace smooth::IO; const String &BoCA::TaggerRIFF::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ RIFF Tagger \ 1.0 \ riff-tag \ tagger \ \ Microsoft Wave Files \ wav \ \ \ Sony Media Wave64 Files \ w64 \ \ \ RIFF 64 Audio Files \ rf64 \ \ \ RIFF INFO Tag \ \ \ ISO-8859-1 \ UTF-8 \ \ \ \ \ "; return componentSpecs; } const String BoCA::TaggerRIFF::ConfigID = "Tags"; BoCA::TaggerRIFF::TaggerRIFF() { } BoCA::TaggerRIFF::~TaggerRIFF() { } Error BoCA::TaggerRIFF::RenderBuffer(Buffer &buffer, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); String encodingID = currentConfig->GetStringValue(ConfigID, "RIFFINFOTagEncoding", "ISO-8859-1"); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroRIFFINFOTag", True); Bool writeMCDI = currentConfig->GetIntValue(ConfigID, "WriteMCDI", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Set output encoding. */ String::OutputFormat outputFormat(encodingID); /* Save basic information. */ const Info &info = track.GetInfo(); buffer.Resize(12); if (info.artist != NIL) RenderTagItem("IART", info.artist, buffer); if (info.title != NIL) RenderTagItem("INAM", info.title, buffer); if (info.album != NIL) RenderTagItem("IPRD", info.album, buffer); if (info.genre != NIL) RenderTagItem("IGNR", info.genre, buffer); if (info.label != NIL) RenderTagItem("IDST", info.label, buffer); if (info.track > 0) RenderTagItem("ITRK", String(prependZero && info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track)), buffer); if (info.year > 0) RenderTagItem("ICRD", String::FromInt(info.year).Append("-01-01"), buffer); if (info.rating >= 0) RenderTagItem("IRTD", String::FromInt(info.rating), buffer); if (info.comment != NIL && !replaceExistingComments) RenderTagItem("ICMT", info.comment, buffer, False); else if (defaultComment != NIL) RenderTagItem("ICMT", defaultComment, buffer); /* Save other text info. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_COMPOSER) RenderTagItem("IMUS", value, buffer); else if (key == INFO_LYRICIST) RenderTagItem("IWRI", value, buffer); else if (key == INFO_PRODUCER) RenderTagItem("IPRO", value, buffer); else if (key == INFO_ENGINEER) RenderTagItem("IENG", value, buffer); else if (key == INFO_COPYRIGHT) RenderTagItem("ICOP", value, buffer); else if (key == INFO_MEDIATYPE) RenderTagItem("ISRF", value, buffer); else if (key == INFO_RELEASECOUNTRY) RenderTagItem("ICNT", value, buffer); else if (key == INFO_WEB_ARTIST) RenderTagItem("IURL", value, buffer); } /* Save CD table of contents. */ if (writeMCDI) { if (info.mcdi.IsValid()) RenderTagItem("ITOC", info.mcdi.GetOffsetString(), buffer); else if (info.offsets != NIL) RenderTagItem("ITOC", info.offsets, buffer); } /* Save encoder version. */ Application *app = Application::Get(); RenderTagItem("ISFT", app->getClientName.Call().Append(" ").Append(app->getClientVersion.Call()), buffer); /* Render tag header. */ RenderTagHeader(buffer); return Success(); } Int BoCA::TaggerRIFF::RenderTagHeader(Buffer &buffer) { OutStream out(STREAM_BUFFER, buffer, 12); out.OutputString("LIST"); out.OutputNumber(buffer.Size() - 8, 4); out.OutputString("INFO"); return Success(); } Int BoCA::TaggerRIFF::RenderTagItem(const String &id, const String &value, Buffer &buffer, Bool trim) { String data = trim ? value.Trim() : value; Int dataSize = data != NIL ? strlen(data) + 1 : 1; Int size = dataSize + (dataSize & 1) + 8; buffer.Resize(buffer.Size() + size); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - size, size); out.OutputString(id); out.OutputNumber(dataSize, 4); out.OutputString(data); out.OutputNumber(0, 1 + (dataSize & 1)); return Success(); } Error BoCA::TaggerRIFF::ParseBuffer(const Buffer &buffer, Track &track) { InStream in(STREAM_BUFFER, buffer, buffer.Size()); Bool error = False; /* Read LIST chunk. */ if (in.InputString(4) != "LIST") error = True; /* Skip header. */ in.RelSeek(8); /* Parse individual comment items. */ Info info = track.GetInfo(); String::InputFormat inputFormat("ISO-8859-1"); while (!error) { if (in.GetPos() >= in.Size()) break; String id = in.InputString(4); Int length = in.InputNumber(4); if (length > 0) { String string = in.InputString(length); String value = string.Trim(); if (IsStringUTF8(value)) value.ImportFrom("UTF-8", value.ConvertTo("ISO-8859-1")); if (id == "IART") info.artist = value; else if (id == "INAM") info.title = value; else if (id == "IPRD") info.album = value; else if (id == "ICRD") info.year = value.Head(4).ToInt(); else if (id == "IGNR") info.genre = value; else if (id == "IRTD") info.rating = Math::Min(100, value.ToInt()); else if (id == "ICMT") { if (IsStringUTF8(string)) string.ImportFrom("UTF-8", string.ConvertTo("ISO-8859-1")); info.comment = string; } else if (id == "IDST") info.label = value; else if (id == "TORG") info.label = value; else if (id == "IPRT") info.track = value.ToInt(); else if (id == "ITRK") info.track = value.ToInt(); else if (id == "TRCK") info.track = value.ToInt(); else if (id == "IMUS") info.SetOtherInfo(INFO_COMPOSER, value); else if (id == "IWRI") info.SetOtherInfo(INFO_LYRICIST, value); else if (id == "IPRO") info.SetOtherInfo(INFO_PRODUCER, value); else if (id == "IENG") info.SetOtherInfo(INFO_ENGINEER, value); else if (id == "ICOP") info.SetOtherInfo(INFO_COPYRIGHT, value); else if (id == "ISRF") info.SetOtherInfo(INFO_MEDIATYPE, value); else if (id == "ICNT") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); else if (id == "IURL") info.SetOtherInfo(INFO_WEB_ARTIST, value); else if (id == "ITOC") info.offsets = value; /* Skip padding byte, if any. */ in.InputNumber(length & 1); } } track.SetInfo(info); if (error) return Error(); else return Success(); } Error BoCA::TaggerRIFF::ParseStreamInfo(const String &fileName, Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Read RIFF chunk. */ Bool error = False; String riff = in.InputString(4); if (riff != "RIFF" && riff != "RF64" && riff != "riff") return Error(); /* Check file format. */ if (riff == "RIFF" || riff == "RF64") { UnsignedInt32 rSize = in.InputNumber(4); in.RelSeek(4); String chunk; Int64 dSize = -1; while (!error && chunk != "LIST") { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) in.InputNumber(4); if (chunk == "LIST") { Buffer buffer(cSize + 8); in.RelSeek(-8); in.InputData(buffer, cSize + 8); if (ParseBuffer(buffer, track) != Success()) error = True; } else if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(cSize - 16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) cSize = in.Size() - in.GetPos(); if (dSize >= 0) in.RelSeek(dSize + dSize % 2); else in.RelSeek(cSize + cSize % 2); } else { /* Skip chunk. */ if (!in.RelSeek(cSize + cSize % 2)) error = True; } } } else if (riff == "riff") { static unsigned char guidRIFF[16] = { 'r', 'i', 'f', 'f', 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; static unsigned char guidLIST[16] = { 'l', 'i', 's', 't', 0x2F, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; in.RelSeek(-4); unsigned char guid[16]; in.InputData(guid, 16); if (memcmp(guid, guidRIFF, 16) != 0) error = True; in.RelSeek(24); while (!error && memcmp(guid, guidLIST, 16) != 0) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ in.InputData(guid, 16); Int64 cSize = in.InputNumber(8); if (memcmp(guid, guidLIST, 16) == 0) { Buffer buffer(cSize - 16); buffer[0] = 'L'; buffer[4] = cSize & 255; buffer[1] = 'I'; buffer[5] = (cSize >> 8) & 255; buffer[2] = 'S'; buffer[6] = (cSize >> 16) & 255; buffer[3] = 'T'; buffer[7] = (cSize >> 24) & 255; in.InputData(buffer + 8, cSize - 24); if (ParseBuffer(buffer, track) != Success()) error = True; } else { /* Skip chunk. */ if (!in.RelSeek(cSize - 24 + (cSize % 8 > 0 ? 8 - (cSize % 8) : 0))) error = True; } } } if (error) return Error(); return Success(); } Error BoCA::TaggerRIFF::UpdateStreamInfo(const String &fileName, const Track &track) { InStream in(STREAM_FILE, fileName, IS_READ); /* Read RIFF chunk. */ Bool error = False; String riff = in.InputString(4); if (riff != "RIFF" && riff != "RF64" && riff != "riff") return Error(); /* Create output file. */ OutStream out(STREAM_FILE, fileName.Append(".temp"), OS_REPLACE); if (riff == "RIFF" || riff == "RF64") { UnsignedInt32 rSize = in.InputNumber(4); UnsignedInt32 rFormat = in.InputNumber(4); out.OutputString(riff); out.OutputNumber(rSize, 4); out.OutputNumber(rFormat, 4); Int64 dSize = -1; Buffer buffer(131072); while (!error) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ String chunk = in.InputString(4); UnsignedInt64 cSize = (UnsignedInt32) in.InputNumber(4); if (chunk == "LIST") { /* Skip LIST chunk. */ if (!in.RelSeek(cSize + cSize % 2)) error = True; continue; } out.OutputString(chunk); out.OutputNumber(cSize, 4); if (chunk == "ds64") { in.RelSeek(8); dSize = in.InputNumber(8); in.RelSeek(-16); } else if (chunk == "data") { if (rSize == 0xFFFFFFFF || rSize == 0 || cSize == 0xFFFFFFFF || cSize == 0) error = True; if (dSize >= 0) cSize = dSize; } /* Write chunk data to output file. */ cSize += cSize % 2; while (!error && cSize > 0) { Int64 bytes = Math::Min(cSize, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); cSize -= bytes; } } /* Write new metadata. */ if (!error) { /* Write LIST chunk. */ buffer.Resize(0); RenderBuffer(buffer, track); out.OutputData(buffer, buffer.Size()); /* Update file size. */ UnsignedInt64 fileSize = out.GetPos() - 8; rSize = Math::Min(0xFFFFFFFF, fileSize); out.Seek(4); out.OutputNumber(rSize, 4); } } else if (riff == "riff") { static unsigned char guidRIFF[16] = { 'r', 'i', 'f', 'f', 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; static unsigned char guidLIST[16] = { 'l', 'i', 's', 't', 0x2F, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; in.RelSeek(-4); unsigned char guid[16]; in.InputData(guid, 16); if (memcmp(guid, guidRIFF, 16) != 0) error = True; out.OutputData(guidRIFF, 16); UnsignedInt64 rSize = in.InputNumber(8); in.InputData(guid, 16); out.OutputNumber(rSize, 8); out.OutputData(guid, 16); Buffer buffer(131072); while (!error) { if (in.GetPos() >= in.Size()) break; /* Read next chunk. */ in.InputData(guid, 16); Int64 cSize = in.InputNumber(8); if (memcmp(guid, guidLIST, 16) == 0) { /* Skip LIST chunk. */ if (!in.RelSeek(cSize - 24 + (cSize % 8 > 0 ? 8 - (cSize % 8) : 0))) error = True; continue; } out.OutputData(guid, 16); out.OutputNumber(cSize, 8); /* Write chunk data to output file. */ cSize += (cSize % 8 > 0 ? 8 - (cSize % 8) : 0); cSize -= 24; while (!error && cSize > 0) { Int64 bytes = Math::Min(cSize, buffer.Size()); in.InputData(buffer, bytes); out.OutputData(buffer, bytes); cSize -= bytes; } } /* Write new metadata. */ if (!error) { /* Write LIST chunk. */ buffer.Resize(0); RenderBuffer(buffer, track); Int64 size = buffer.Size() + 16; out.OutputData(guidLIST, 16); out.OutputNumber(size, 8); out.OutputData(buffer + 8, buffer.Size() - 8); if (size % 8 > 0) out.OutputNumber(0, 8 - (size % 8)); /* Update file size. */ rSize = out.GetPos(); out.Seek(16); out.OutputNumber(rSize, 8); } } /* Clean up. */ in.Close(); out.Close(); if (error) { File(fileName.Append(".temp")).Delete(); return Error(); } File(fileName).Delete(); File(fileName.Append(".temp")).Move(fileName); return Success(); } Bool BoCA::TaggerRIFF::IsStringUTF8(const String &string) { Bool result = False; Int length = string.Length(); for (Int i = 0; i < length; i++) { if ( string[i ] <= 0x7F) { continue; } result = True; if (i < length - 1 && string[i ] >= 0xC0 && string[i ] <= 0xDF && string[i + 1] >= 0x80 && string[i + 1] <= 0xBF) { i += 1; continue; } if (i < length - 2 && string[i ] >= 0xE0 && string[i ] <= 0xEF && string[i + 1] >= 0x80 && string[i + 1] <= 0xBF && string[i + 2] >= 0x80 && string[i + 2] <= 0xBF) { i += 2; continue; } if (i < length - 3 && string[i ] >= 0xF0 && string[i ] <= 0xF7 && string[i + 1] >= 0x80 && string[i + 1] <= 0xBF && string[i + 2] >= 0x80 && string[i + 2] <= 0xBF && string[i + 3] >= 0x80 && string[i + 3] <= 0xBF) { i += 3; continue; } return False; } return result; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/riff/riff.h000066400000000000000000000025261516712004000236540ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(TaggerRIFF) namespace BoCA { class TaggerRIFF : public CS::TaggerComponent { private: static const String ConfigID; static Bool IsStringUTF8(const String &); Int RenderTagHeader(Buffer &); Int RenderTagItem(const String &, const String &, Buffer &, Bool = True); public: static const String &GetComponentSpecs(); TaggerRIFF(); ~TaggerRIFF(); Error ParseBuffer(const Buffer &, Track &); Error ParseStreamInfo(const String &, Track &); Error RenderBuffer(Buffer &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerRIFF) BoCA_END_COMPONENT(TaggerRIFF) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/tocplist/000077500000000000000000000000001516712004000234635ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/tocplist/Makefile000066400000000000000000000011271516712004000251240ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = tocplist TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = tocplist.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/tocplist/tocplist.cpp000066400000000000000000000126231516712004000260340ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "tocplist.h" const String &BoCA::TaggerTOCPList::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ .TOC.plist Parser \ 1.0 \ tocplist-tag \ tagger \ \ \ "; return componentSpecs; } BoCA::TaggerTOCPList::TaggerTOCPList() { } BoCA::TaggerTOCPList::~TaggerTOCPList() { } Error BoCA::TaggerTOCPList::ParseStreamInfo(const String &fileName, Track &track) { String pListFile = fileName.Head(fileName.FindLast(Directory::GetDirectoryDelimiter()) + 1).Append(".TOC.plist"); if (!File(pListFile).Exists()) return Success(); Bool error = False; XML::Document *pList = new XML::Document(); if (pList->LoadFile(pListFile) == Success()) { XML::Node *root = pList->GetRootNode(); XML::Node *dict = root->GetNodeByName("dict"); for (Int i = 0; i < dict->GetNOfNodes(); i++) { /* Look for sessions key. */ XML::Node *node = dict->GetNthNode(i); if (node->GetName() != "key" || node->GetContent() != "Sessions") continue; /* Parse sessions and build MCDI. */ Buffer mcdi(4); Int32 address; XML::Node *array = dict->GetNthNode(++i); if (array->GetName() == "array") ReadSessions(array, mcdi, address); if (mcdi.Size() > 4) { ((UnsignedByte *) mcdi)[0] = ((mcdi.Size() + 6) >> 8) & 255; ((UnsignedByte *) mcdi)[1] = (mcdi.Size() + 6) & 255; ((UnsignedByte *) mcdi)[2] = ((UnsignedByte *) mcdi)[6]; ((UnsignedByte *) mcdi)[3] = ((UnsignedByte *) mcdi)[mcdi.Size() - 6]; /* Add lead-out entry. */ Int offset = mcdi.Size(); mcdi.Resize(offset + 8); ((UnsignedByte *) mcdi)[offset + 0] = 0; ((UnsignedByte *) mcdi)[offset + 1] = 16; ((UnsignedByte *) mcdi)[offset + 2] = 170; ((UnsignedByte *) mcdi)[offset + 3] = 0; ((UnsignedByte *) mcdi)[offset + 4] = (address >> 24) & 255; ((UnsignedByte *) mcdi)[offset + 5] = (address >> 16) & 255; ((UnsignedByte *) mcdi)[offset + 6] = (address >> 8) & 255; ((UnsignedByte *) mcdi)[offset + 7] = address & 255; /* Set MCDI in track info. */ Info info = track.GetInfo(); info.track = File(fileName).GetFileName().Head(2).ToInt(); info.mcdi.SetData(mcdi); track.SetInfo(info); } } } delete pList; if (error) return Error(); else return Success(); } Bool BoCA::TaggerTOCPList::ReadSessions(XML::Node *sessions, Buffer &mcdi, Int32 &leadOut) { for (Int i = 0; i < sessions->GetNOfNodes(); i++) { XML::Node *session = sessions->GetNthNode(i); if (session->GetName() == "dict") ReadSession(session, mcdi, leadOut); } return True; } Bool BoCA::TaggerTOCPList::ReadSession(XML::Node *session, Buffer &mcdi, Int32 &leadOut) { for (Int i = 0; i < session->GetNOfNodes(); i++) { XML::Node *node = session->GetNthNode(i); if (node->GetName() == "key" && node->GetContent() == "Leadout Block") leadOut = session->GetNthNode(++i)->GetContent().ToInt() - 150; if (node->GetName() != "key" || node->GetContent() != "Track Array") continue; XML::Node *array = session->GetNthNode(++i); if (array->GetName() == "array") ReadTracks(array, mcdi); } return True; } Bool BoCA::TaggerTOCPList::ReadTracks(XML::Node *tracks, Buffer &mcdi) { for (Int i = 0; i < tracks->GetNOfNodes(); i++) { XML::Node *track = tracks->GetNthNode(i); if (track->GetName() == "dict") ReadTrack(track, mcdi); } return True; } Bool BoCA::TaggerTOCPList::ReadTrack(XML::Node *track, Buffer &mcdi) { Bool data = False; Bool preemp = False; Int number = 0; Int32 address = 0; for (Int i = 0; i < track->GetNOfNodes(); i++) { XML::Node *node = track->GetNthNode(i); if (node->GetName() == "key") { if (node->GetContent() == "Data") data = track->GetNthNode(++i)->GetName() == "true" ? True : False; else if (node->GetContent() == "Pre-Emphasis Enabled") preemp = track->GetNthNode(++i)->GetName() == "true" ? True : False; else if (node->GetContent() == "Point") number = track->GetNthNode(++i)->GetContent().ToInt(); else if (node->GetContent() == "Start Block") address = track->GetNthNode(++i)->GetContent().ToInt() - 150; } } Int offset = mcdi.Size(); mcdi.Resize(offset + 8); ((UnsignedByte *) mcdi)[offset + 0] = 0; ((UnsignedByte *) mcdi)[offset + 1] = 16 + (data ? 4 : 0) + (preemp ? 1 : 0); ((UnsignedByte *) mcdi)[offset + 2] = number; ((UnsignedByte *) mcdi)[offset + 3] = 0; ((UnsignedByte *) mcdi)[offset + 4] = (address >> 24) & 255; ((UnsignedByte *) mcdi)[offset + 5] = (address >> 16) & 255; ((UnsignedByte *) mcdi)[offset + 6] = (address >> 8) & 255; ((UnsignedByte *) mcdi)[offset + 7] = address & 255; return True; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/tocplist/tocplist.h000066400000000000000000000023161516712004000254770ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(TaggerTOCPList) namespace BoCA { class TaggerTOCPList : public CS::TaggerComponent { private: Bool ReadSessions(XML::Node *, Buffer &, Int32 &); Bool ReadSession(XML::Node *, Buffer &, Int32 &); Bool ReadTracks(XML::Node *, Buffer &); Bool ReadTrack(XML::Node *, Buffer &); public: static const String &GetComponentSpecs(); TaggerTOCPList(); ~TaggerTOCPList(); Error ParseStreamInfo(const String &, Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerTOCPList) BoCA_END_COMPONENT(TaggerTOCPList) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/000077500000000000000000000000001516712004000231265ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/Makefile000077500000000000000000000012151516712004000245700ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = vorbis TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o vorbis.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/dllinterface.cpp000066400000000000000000000056001516712004000262670ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" using namespace BoCA; OGGSTREAMINIT ex_ogg_stream_init = NIL; OGGSTREAMPACKETIN ex_ogg_stream_packetin = NIL; OGGSTREAMPACKETOUT ex_ogg_stream_packetout = NIL; OGGSTREAMFLUSH ex_ogg_stream_flush = NIL; OGGSTREAMPAGEIN ex_ogg_stream_pagein = NIL; OGGPAGESERIALNO ex_ogg_page_serialno = NIL; OGGSTREAMCLEAR ex_ogg_stream_clear = NIL; OGGSYNCINIT ex_ogg_sync_init = NIL; OGGSYNCBUFFER ex_ogg_sync_buffer = NIL; OGGSYNCWROTE ex_ogg_sync_wrote = NIL; OGGSYNCPAGEOUT ex_ogg_sync_pageout = NIL; OGGSYNCCLEAR ex_ogg_sync_clear = NIL; DynamicLoader *oggdll = NIL; Bool LoadOggDLL() { oggdll = BoCA::Utilities::LoadCodecDLL("ogg"); if (oggdll == NIL) return False; ex_ogg_stream_init = (OGGSTREAMINIT) oggdll->GetFunctionAddress("ogg_stream_init"); ex_ogg_stream_packetin = (OGGSTREAMPACKETIN) oggdll->GetFunctionAddress("ogg_stream_packetin"); ex_ogg_stream_packetout = (OGGSTREAMPACKETOUT) oggdll->GetFunctionAddress("ogg_stream_packetout"); ex_ogg_stream_flush = (OGGSTREAMFLUSH) oggdll->GetFunctionAddress("ogg_stream_flush"); ex_ogg_stream_pagein = (OGGSTREAMPAGEIN) oggdll->GetFunctionAddress("ogg_stream_pagein"); ex_ogg_page_serialno = (OGGPAGESERIALNO) oggdll->GetFunctionAddress("ogg_page_serialno"); ex_ogg_stream_clear = (OGGSTREAMCLEAR) oggdll->GetFunctionAddress("ogg_stream_clear"); ex_ogg_sync_init = (OGGSYNCINIT) oggdll->GetFunctionAddress("ogg_sync_init"); ex_ogg_sync_buffer = (OGGSYNCBUFFER) oggdll->GetFunctionAddress("ogg_sync_buffer"); ex_ogg_sync_wrote = (OGGSYNCWROTE) oggdll->GetFunctionAddress("ogg_sync_wrote"); ex_ogg_sync_pageout = (OGGSYNCPAGEOUT) oggdll->GetFunctionAddress("ogg_sync_pageout"); ex_ogg_sync_clear = (OGGSYNCCLEAR) oggdll->GetFunctionAddress("ogg_sync_clear"); if (ex_ogg_stream_init == NIL || ex_ogg_stream_packetin == NIL || ex_ogg_stream_packetout == NIL || ex_ogg_stream_flush == NIL || ex_ogg_stream_pagein == NIL || ex_ogg_page_serialno == NIL || ex_ogg_stream_clear == NIL || ex_ogg_sync_init == NIL || ex_ogg_sync_buffer == NIL || ex_ogg_sync_wrote == NIL || ex_ogg_sync_pageout == NIL || ex_ogg_sync_clear == NIL) { FreeOggDLL(); return False; } return True; } Void FreeOggDLL() { BoCA::Utilities::FreeCodecDLL(oggdll); oggdll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/dllinterface.h000066400000000000000000000037651516712004000257460ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *oggdll; Bool LoadOggDLL(); Void FreeOggDLL(); /* Ogg API functions. */ typedef int (*OGGSTREAMINIT) (ogg_stream_state *, int); typedef int (*OGGSTREAMPACKETIN) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMPACKETOUT) (ogg_stream_state *, ogg_packet *); typedef int (*OGGSTREAMFLUSH) (ogg_stream_state *, ogg_page *); typedef int (*OGGSTREAMPAGEIN) (ogg_stream_state *, ogg_page *); typedef int (*OGGPAGESERIALNO) (ogg_page *); typedef int (*OGGSTREAMCLEAR) (ogg_stream_state *); typedef int (*OGGSYNCINIT) (ogg_sync_state *); typedef char * (*OGGSYNCBUFFER) (ogg_sync_state *, int); typedef int (*OGGSYNCWROTE) (ogg_sync_state *, int); typedef int (*OGGSYNCPAGEOUT) (ogg_sync_state *, ogg_page *); typedef int (*OGGSYNCCLEAR) (ogg_sync_state *); extern OGGSTREAMINIT ex_ogg_stream_init; extern OGGSTREAMPACKETIN ex_ogg_stream_packetin; extern OGGSTREAMPACKETOUT ex_ogg_stream_packetout; extern OGGSTREAMFLUSH ex_ogg_stream_flush; extern OGGSTREAMPAGEIN ex_ogg_stream_pagein; extern OGGPAGESERIALNO ex_ogg_page_serialno; extern OGGSTREAMCLEAR ex_ogg_stream_clear; extern OGGSYNCINIT ex_ogg_sync_init; extern OGGSYNCBUFFER ex_ogg_sync_buffer; extern OGGSYNCWROTE ex_ogg_sync_wrote; extern OGGSYNCPAGEOUT ex_ogg_sync_pageout; extern OGGSYNCCLEAR ex_ogg_sync_clear; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/vorbis.cpp000066400000000000000000001045571516712004000251520ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2026 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include "vorbis.h" using namespace smooth::IO; const String &BoCA::TaggerVorbis::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ Vorbis Comment Tagger \ 1.0 \ vorbis-tag \ tagger \ \ Vorbis Comment \ \ \ \ UTF-8 \ \ \ \ \ "; return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadOggDLL(); } Void smooth::DetachDLL() { FreeOggDLL(); } const String BoCA::TaggerVorbis::ConfigID = "Tags"; BoCA::TaggerVorbis::TaggerVorbis() { } BoCA::TaggerVorbis::~TaggerVorbis() { } Error BoCA::TaggerVorbis::RenderBuffer(Buffer &buffer, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroVorbisComment", True); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool writeMCDI = currentConfig->GetIntValue(ConfigID, "WriteMCDI", True); Bool preserveReplayGain = currentConfig->GetIntValue(ConfigID, "PreserveReplayGain", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToVorbis = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToVorbisComment", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Set output encoding. */ String::OutputFormat outputFormat("UTF-8"); /* Save basic information. */ const Info &info = track.GetInfo(); buffer.Resize(4 + (vendorString != NIL ? strlen(vendorString) : 0) + 4); Int numItems = 0; if (info.artist != NIL) { RenderTagItem("ARTIST", info.artist, buffer); numItems++; } if (info.title != NIL) { RenderTagItem("TITLE", info.title, buffer); numItems++; } if (info.album != NIL) { RenderTagItem("ALBUM", info.album, buffer); numItems++; } if (info.year > 0) { RenderTagItem("DATE", String::FromInt(info.year), buffer); numItems++; } if (info.genre != NIL) { RenderTagItem("GENRE", info.genre, buffer); numItems++; } if (info.label != NIL) { RenderTagItem("PUBLISHER", info.label, buffer); numItems++; } if (info.isrc != NIL) { RenderTagItem("ISRC", info.isrc, buffer); numItems++; } if (info.track > 0) { RenderTagItem("TRACKNUMBER", String(prependZero && info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track)), buffer); numItems++; } if (info.numTracks > 0) { RenderTagItem("TRACKTOTAL", String(prependZero && info.numTracks < 10 ? "0" : NIL).Append(String::FromInt(info.numTracks)), buffer); numItems++; } if (info.disc > 0) { RenderTagItem("DISCNUMBER", String(prependZero && info.disc < 10 ? "0" : NIL).Append(String::FromInt(info.disc)), buffer); numItems++; } if (info.numDiscs > 0) { RenderTagItem("DISCTOTAL", String(prependZero && info.numDiscs < 10 ? "0" : NIL).Append(String::FromInt(info.numDiscs)), buffer); numItems++; } if (info.rating >= 0) { RenderTagItem("RATING", String::FromInt(info.rating), buffer); numItems++; } if (info.comment != NIL && !replaceExistingComments) { RenderTagItem("COMMENT", info.comment, buffer, False); numItems++; } else if (defaultComment != NIL && numItems > 0) { RenderTagItem("COMMENT", defaultComment, buffer ); numItems++; } /* Save other text info. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) { RenderTagItem("ALBUMARTIST", value, buffer ); numItems++; } else if (key == INFO_CONTENTGROUP) { RenderTagItem("GROUPING", value, buffer ); numItems++; } else if (key == INFO_SUBTITLE) { RenderTagItem("SUBTITLE", value, buffer ); numItems++; } else if (key == INFO_BAND) { RenderTagItem("ENSEMBLE", value, buffer ); numItems++; } else if (key == INFO_PERFORMER) { RenderTagItem("PERFORMER", value, buffer ); numItems++; } else if (key == INFO_CONDUCTOR) { RenderTagItem("CONDUCTOR", value, buffer ); numItems++; } else if (key == INFO_REMIXER) { RenderTagItem("REMIXER", value, buffer ); numItems++; } else if (key == INFO_COMPOSER) { RenderTagItem("COMPOSER", value, buffer ); numItems++; } else if (key == INFO_LYRICIST) { RenderTagItem("LYRICIST", value, buffer ); numItems++; } else if (key == INFO_ARRANGER) { RenderTagItem("ARRANGER", value, buffer ); numItems++; } else if (key == INFO_PRODUCER) { RenderTagItem("PRODUCER", value, buffer ); numItems++; } else if (key == INFO_ENGINEER) { RenderTagItem("ENGINEER", value, buffer ); numItems++; } else if (key == INFO_MOVEMENT) { RenderTagItem("MOVEMENT", value, buffer ); numItems++; } else if (key == INFO_MOVEMENTTOTAL) { RenderTagItem("MOVEMENTTOTAL", value, buffer ); numItems++; } else if (key == INFO_MOVEMENTNAME) { RenderTagItem("MOVEMENTNAME", value, buffer ); numItems++; } else if (key == INFO_BPM) { RenderTagItem("BPM", value, buffer ); numItems++; } else if (key == INFO_INITIALKEY) { RenderTagItem("INITIALKEY", value, buffer ); numItems++; } else if (key == INFO_COPYRIGHT) { RenderTagItem("COPYRIGHT", value, buffer ); numItems++; } else if (key == INFO_MEDIATYPE) { RenderTagItem("MEDIA", value, buffer ); numItems++; } else if (key == INFO_CATALOGNUMBER) { RenderTagItem("CATALOGNUMBER", value, buffer ); numItems++; } else if (key == INFO_BARCODE) { RenderTagItem("BARCODE", value, buffer ); numItems++; } else if (key == INFO_RELEASECOUNTRY) { RenderTagItem("RELEASECOUNTRY", value, buffer ); numItems++; } else if (key == INFO_DISCSUBTITLE) { RenderTagItem("DISCSUBTITLE", value, buffer ); numItems++; } else if (key == INFO_LYRICS) { RenderTagItem("LYRICS", value, buffer, False); numItems++; } else if (key == INFO_SCRIPT) { RenderTagItem("SCRIPT", value, buffer); numItems++; } else if (key == INFO_SORT_ARTIST) { RenderTagItem("ARTISTSORT", value, buffer ); numItems++; } else if (key == INFO_SORT_ALBUM) { RenderTagItem("ALBUMSORT", value, buffer ); numItems++; } else if (key == INFO_SORT_ALBUMARTIST) { RenderTagItem("ALBUMARTISTSORT", value, buffer ); numItems++; } else if (key == INFO_SORT_COMPOSER) { RenderTagItem("COMPOSERSORT", value, buffer ); numItems++; } else if (key == INFO_SORT_TITLE) { RenderTagItem("TITLESORT", value, buffer ); numItems++; } else if (key == INFO_WEB_ARTIST) { RenderTagItem("WEBSITE", value, buffer ); numItems++; } else if (key == INFO_ASIN) { RenderTagItem("ASIN", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ARTISTID) { RenderTagItem("MUSICBRAINZ_ARTISTID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ALBUMID) { RenderTagItem("MUSICBRAINZ_ALBUMID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ALBUMARTISTID) { RenderTagItem("MUSICBRAINZ_ALBUMARTISTID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_WORKID) { RenderTagItem("MUSICBRAINZ_WORKID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_DISCID) { RenderTagItem("MUSICBRAINZ_DISCID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_TRACKID) { RenderTagItem("MUSICBRAINZ_TRACKID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ORIGINALARTISTID) { RenderTagItem("MUSICBRAINZ_ORIGINALARTISTID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_ORIGINALALBUMID) { RenderTagItem("MUSICBRAINZ_ORIGINALALBUMID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASEGROUPID) { RenderTagItem("MUSICBRAINZ_RELEASEGROUPID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASETRACKID) { RenderTagItem("MUSICBRAINZ_RELEASETRACKID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_TRMID) { RenderTagItem("MUSICBRAINZ_TRMID", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASETYPE) { RenderTagItem("RELEASETYPE", value, buffer ); numItems++; } else if (key == INFO_MUSICBRAINZ_RELEASESTATUS) { RenderTagItem("RELEASESTATUS", value, buffer ); numItems++; } } /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { { RenderTagItem("replaygain_track_gain", info.track_gain, buffer); numItems++; } { RenderTagItem("replaygain_track_peak", info.track_peak, buffer); numItems++; } } if (info.album_gain != NIL && info.album_peak != NIL) { { RenderTagItem("replaygain_album_gain", info.album_gain, buffer); numItems++; } { RenderTagItem("replaygain_album_peak", info.album_peak, buffer); numItems++; } } } /* Save CD table of contents. */ if (writeMCDI) { if (info.mcdi.IsValid()) { RenderTagItem("CDTOC", info.mcdi.GetOffsetString(), buffer); numItems++; } else if (info.offsets != NIL) { RenderTagItem("CDTOC", info.offsets, buffer); numItems++; } } /* Save encoder version. */ Application *app = Application::Get(); { RenderTagItem("ENCODER", app->getClientName.Call().Append(" ").Append(app->getClientVersion.Call()), buffer); numItems++; } /* Save album art. */ if (albumArtWriteToTags && albumArtWriteToVorbis) { /* This is the official way to store album art in Vorbis * comments. It is used by most newer software. */ foreach (const Picture &picInfo, track.pictures) { Buffer picBuffer; CreateMetadataBlockPicture(picBuffer, picInfo, False); RenderTagItem("METADATA_BLOCK_PICTURE", Encoding::Base64(picBuffer).Encode(), buffer); numItems++; } } /* Save chapters. */ if (track.tracks.Length() > 0 && writeChapters) { Int64 offset = 0; for (Int i = 0; i < track.tracks.Length(); i++) { const Track &chapterTrack = track.tracks.GetNth(i); const Info &chapterInfo = chapterTrack.GetInfo(); const Format &chapterFormat = chapterTrack.GetFormat(); String value = String(offset / chapterFormat.rate / 60 / 60 < 10 ? "0" : NIL).Append(String::FromInt(offset / chapterFormat.rate / 60 / 60)).Append(":") .Append(offset / chapterFormat.rate / 60 % 60 < 10 ? "0" : NIL).Append(String::FromInt(offset / chapterFormat.rate / 60 % 60)).Append(":") .Append(offset / chapterFormat.rate % 60 < 10 ? "0" : NIL).Append(String::FromInt(offset / chapterFormat.rate % 60)).Append(".") .Append(Math::Round(offset % chapterFormat.rate * 1000.0 / chapterFormat.rate) < 100 ? (Math::Round(offset % chapterFormat.rate * 1000.0 / chapterFormat.rate) < 10 ? "00" : "0") : NIL).Append(String::FromInt(Math::Round(offset % chapterFormat.rate * 1000.0 / chapterFormat.rate))); { RenderTagItem(String("CHAPTER").Append(i + 1 < 100 ? (i + 1 < 10 ? "00" : "0") : NIL).Append(String::FromInt(i + 1)), value, buffer); numItems++; } if (chapterInfo.title != NIL) { { RenderTagItem(String("CHAPTER").Append(i + 1 < 100 ? (i + 1 < 10 ? "00" : "0") : NIL).Append(String::FromInt(i + 1)).Append("NAME"), chapterInfo.title, buffer); numItems++; } } if (chapterTrack.length >= 0) offset += chapterTrack.length; else if (chapterTrack.approxLength >= 0) offset += chapterTrack.approxLength; } } /* Render tag header. */ RenderTagHeader(vendorString, numItems, buffer); return Success(); } Int BoCA::TaggerVorbis::RenderTagHeader(const String &vendorString, Int numItems, Buffer &buffer) { Int vendorStringSize = vendorString != NIL ? strlen(vendorString) : 0; OutStream out(STREAM_BUFFER, buffer, 4 + vendorStringSize + 4); out.OutputNumber(vendorStringSize, 4); out.OutputString(vendorString); out.OutputNumber(numItems, 4); return Success(); } Int BoCA::TaggerVorbis::RenderTagItem(const String &id, const String &value, Buffer &buffer, Bool trim) { String data = trim ? value.Trim() : value; Int dataSize = data != NIL ? strlen(data) : 0; Int size = id.Length() + dataSize + 5; buffer.Resize(buffer.Size() + size); OutStream out(STREAM_BUFFER, buffer + buffer.Size() - size, size); out.OutputNumber(size - 4, 4); out.OutputString(id); out.OutputNumber('=', 1); out.OutputString(data); return Success(); } Error BoCA::TaggerVorbis::ParseBuffer(const Buffer &buffer, Track &track) { const Config *currentConfig = GetConfiguration(); InStream in(STREAM_BUFFER, buffer, buffer.Size()); /* Read vendor string. */ String::InputFormat inputFormat("UTF-8"); Int vendorLength = in.InputNumber(4); if (vendorLength < 0 || vendorLength > buffer.Size() - 8) return Error(); vendorString = in.InputString(vendorLength); /* Parse individual comment items. */ Int numItems = in.InputNumber(4); Int numAlbumArt = 0; Bool haveChapters = False; Int itemsOffset = in.GetPos(); Info info = track.GetInfo(); for (Int i = 0; i < numItems; i++) { /* Read and check next comment string length. */ Int length = in.InputNumber(4); if (length < 0 || length > buffer.Size() - in.GetPos()) return Error(); /* Read and assign actual comment string. */ String comment = in.InputString(length); String id = comment.Head(comment.Find("=")).ToUpper(); String value = comment.Tail(comment.Length() - comment.Find("=") - 1).Trim(); if (value == NIL) continue; if (id == "ARTIST") info.artist = value; else if (id == "TITLE") info.title = value; else if (id == "ALBUM") info.album = value; else if (id == "DATE") info.year = value.ToInt(); else if (id == "GENRE") info.genre = value; else if (id == "COMMENT") info.comment = comment.Tail(comment.Length() - comment.Find("=") - 1); else if (id == "LABEL" || id == "PUBLISHER" || id == "ORGANIZATION") info.label = value; else if (id == "ISRC") { if (Info::IsISRC(value)) info.isrc = value; } else if (id == "TRACKNUMBER") { info.track = value.ToInt(); if (value.Contains("/")) info.numTracks = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } else if (id == "TRACKTOTAL" || id == "TOTALTRACKS") info.numTracks = value.ToInt(); else if (id == "DISCNUMBER") { info.disc = value.ToInt(); if (value.Contains("/")) info.numDiscs = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } else if (id == "DISCTOTAL" || id == "TOTALDISCS") info.numDiscs = value.ToInt(); else if (id == "RATING") info.rating = Math::Min(100, value.ToInt()); else if (id == "ALBUMARTIST") info.SetOtherInfo(INFO_ALBUMARTIST, value); else if (id == "GROUPING") info.SetOtherInfo(INFO_CONTENTGROUP, value); else if (id == "SUBTITLE") info.SetOtherInfo(INFO_SUBTITLE, value); else if (id == "BAND" || id == "ENSEMBLE" || id == "ORCHESTRA") info.SetOtherInfo(INFO_BAND, value); else if (id == "PERFORMER") info.SetOtherInfo(INFO_PERFORMER, value); else if (id == "CONDUCTOR") info.SetOtherInfo(INFO_CONDUCTOR, value); else if (id == "REMIXER") info.SetOtherInfo(INFO_REMIXER, value); else if (id == "COMPOSER") info.SetOtherInfo(INFO_COMPOSER, value); else if (id == "LYRICIST") info.SetOtherInfo(INFO_LYRICIST, value); else if (id == "ARRANGER") info.SetOtherInfo(INFO_ARRANGER, value); else if (id == "PRODUCER") info.SetOtherInfo(INFO_PRODUCER, value); else if (id == "ENGINEER") info.SetOtherInfo(INFO_ENGINEER, value); else if (id == "MOVEMENT" || id == "PART") { info.SetOtherInfo(INFO_MOVEMENT, String::FromInt(value.ToInt())); if (value.Contains("/")) info.SetOtherInfo(INFO_MOVEMENTTOTAL, String::FromInt(value.Tail(value.Length() - value.Find("/") - 1).ToInt())); } else if (id == "MOVEMENTTOTAL" || id == "TOTALMOVEMENTS" || id == "PARTTOTAL" || id == "TOTALPARTS") info.SetOtherInfo(INFO_MOVEMENTTOTAL, value); else if (id == "MOVEMENTNAME" || id == "PARTNAME") info.SetOtherInfo(INFO_MOVEMENTNAME, value); else if (id == "BPM") { if (value.ToInt() > 0) info.SetOtherInfo(INFO_BPM, value); } else if (id == "INITIALKEY") info.SetOtherInfo(INFO_INITIALKEY, value); else if (id == "COPYRIGHT") info.SetOtherInfo(INFO_COPYRIGHT, value); else if (id == "MEDIA" || id == "SOURCE" || id == "SOURCEMEDIA" || id == "SOURCE MEDIUM") info.SetOtherInfo(INFO_MEDIATYPE, value); else if (id == "LABELNO" || id == "CATALOG" || id == "CATALOGID" || id == "CATALOGUE" || id == "CATALOGNUMBER") info.SetOtherInfo(INFO_CATALOGNUMBER, value); else if (id == "BARCODE" || id == "EAN" || id == "EAN/UPC" || id == "EAN/UPN" || id == "UPC" || id == "UPN" || id == "PRODUCTNUMBER") info.SetOtherInfo(INFO_BARCODE, value); else if (id == "RELEASECOUNTRY") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); else if (id == "DISCSUBTITLE") info.SetOtherInfo(INFO_DISCSUBTITLE, value); else if (id == "LYRICS") info.SetOtherInfo(INFO_LYRICS, comment.Tail(comment.Length() - comment.Find("=") - 1)); else if (id == "SCRIPT") info.SetOtherInfo(INFO_SCRIPT, value); else if (id == "ARTISTSORT") info.SetOtherInfo(INFO_SORT_ARTIST, value); else if (id == "ALBUMSORT") info.SetOtherInfo(INFO_SORT_ALBUM, value); else if (id == "ALBUMARTISTSORT") info.SetOtherInfo(INFO_SORT_ALBUMARTIST, value); else if (id == "COMPOSERSORT") info.SetOtherInfo(INFO_SORT_COMPOSER, value); else if (id == "TITLESORT") info.SetOtherInfo(INFO_SORT_TITLE, value); else if (id == "WEBSITE") info.SetOtherInfo(INFO_WEB_ARTIST, value); else if (id == "ASIN") info.SetOtherInfo(INFO_ASIN, value); else if (id.StartsWith("MUSICBRAINZ")) { if (id == "MUSICBRAINZ_ARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ARTISTID, value); else if (id == "MUSICBRAINZ_ALBUMID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMID, value); else if (id == "MUSICBRAINZ_ALBUMARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMARTISTID, value); else if (id == "MUSICBRAINZ_WORKID") info.SetOtherInfo(INFO_MUSICBRAINZ_WORKID, value); else if (id == "MUSICBRAINZ_DISCID") info.SetOtherInfo(INFO_MUSICBRAINZ_DISCID, value); else if (id == "MUSICBRAINZ_TRACKID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRACKID, value); else if (id == "MUSICBRAINZ_ORIGINALARTISTID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALARTISTID, value); else if (id == "MUSICBRAINZ_ORIGINALALBUMID") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALALBUMID, value); else if (id == "MUSICBRAINZ_RELEASEGROUPID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASEGROUPID, value); else if (id == "MUSICBRAINZ_RELEASETRACKID") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETRACKID, value); else if (id == "MUSICBRAINZ_TRMID") info.SetOtherInfo(INFO_MUSICBRAINZ_TRMID, value); } else if (id == "RELEASETYPE") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETYPE, value); else if (id == "RELEASESTATUS") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASESTATUS, value); else if (id.StartsWith("REPLAYGAIN")) { if (id == "REPLAYGAIN_TRACK_GAIN") info.track_gain = value; else if (id == "REPLAYGAIN_TRACK_PEAK") info.track_peak = value; else if (id == "REPLAYGAIN_ALBUM_GAIN") info.album_gain = value; else if (id == "REPLAYGAIN_ALBUM_PEAK") info.album_peak = value; } else if (id == "CDTOC") { info.offsets = value; } else if (id == "METADATA_BLOCK_PICTURE") { if (currentConfig->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { /* This is the official way to store album art in Vorbis * comments. It is used by most newer software. */ Picture picture; Buffer buffer; Encoding::Base64(buffer).Decode(value); InStream picIn(STREAM_BUFFER, buffer, buffer.Size()); picture.type = picIn.InputNumberRaw(4); picture.mime = picIn.InputString(picIn.InputNumberRaw(4)); picture.description = picIn.InputString(picIn.InputNumberRaw(4)); picIn.RelSeek(16); Int dataSize = picIn.InputNumberRaw(4); picture.data.Set(buffer + picIn.GetPos(), dataSize); if (picture.mime != "-->" && picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } } } else if (id == "COVERART") { if (currentConfig->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { /* This is an unofficial way to store album art in Vorbis * comments. It is used by some existing software. */ Picture picture; Buffer buffer; Encoding::Base64(buffer).Decode(value); if (numAlbumArt == 0) picture.type = 3; // Cover (front) else if (numAlbumArt == 1) picture.type = 4; // Cover (back) else picture.type = 0; // Other picture.data = buffer; if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } numAlbumArt++; } } else if (id == "CUESHEET") { if (currentConfig->GetIntValue(ConfigID, "ReadEmbeddedCueSheets", True)) { String::OutputFormat outputFormat("UTF-8"); /* Output cuesheet to temporary file. */ String cuesheet = value.Replace("\r\n", "\n"); String cueFile = S::System::System::GetTempDirectory().Append("cuesheet_temp_").Append(String::FromInt(track.fileName.ComputeCRC32())).Append(".cue"); OutStream out(STREAM_FILE, cueFile, OS_REPLACE); /* Write UTF-8 BOM. */ if (value[0] != 0xFEFF) out.OutputNumberRaw(0xEFBBBF, 3); /* Write cuesheet line by line. */ const Array &lines = cuesheet.Explode("\n"); out.OutputLine(String("FILE \"").Append(track.fileName).Append("\" WAVE")); foreach (const String &line, lines) { if (!line.Trim().StartsWith("FILE")) out.OutputLine(line); } out.Close(); /* Get cue sheet stream info. */ AS::Registry &boca = AS::Registry::Get(); AS::DecoderComponent *decoder = (AS::DecoderComponent *) boca.CreateComponentByID("cuesheet-dec"); if (decoder != NIL) { Track cueTrack; Config *cueConfig = Config::Copy(GetConfiguration()); cueConfig->SetIntValue("Tags", "ReadChapters", False); cueConfig->SetIntValue("Tags", "ReadEmbeddedCueSheets", False); cueConfig->SetIntValue("CueSheet", "ReadInformationTags", True); cueConfig->SetIntValue("CueSheet", "PreferCueSheets", True); cueConfig->SetIntValue("CueSheet", "LookForAlternativeFiles", False); cueConfig->SetIntValue("CueSheet", "IgnoreErrors", False); decoder->SetConfiguration(cueConfig); decoder->GetStreamInfo(cueFile, cueTrack); boca.DeleteComponent(decoder); Config::Free(cueConfig); if (cueTrack.tracks.Length() > 0) track.tracks = cueTrack.tracks; } File(cueFile).Delete(); } } else if (id.StartsWith("CHAPTER")) { /* Chapters are processed further down. */ haveChapters = True; } else { /* Save any other tags as user defined text. */ info.other.Add(String(INFO_USERTEXT).Append(":").Append(id).Append(":|:").Append(value)); } } /* Set artist to album artist if artist is not filled. */ if (info.artist == NIL) info.artist = info.GetOtherInfo(INFO_ALBUMARTIST); /* Remove sub-tracks if main track has a track number. */ if (info.track > 0) track.tracks.RemoveAll(); track.SetInfo(info); /* Read chapters. */ if (haveChapters && currentConfig->GetIntValue(ConfigID, "ReadChapters", True) && (!currentConfig->GetIntValue(ConfigID, "PreferCueSheetsToChapters", True) || track.tracks.Length() == 0)) { track.tracks.RemoveAll(); in.Seek(itemsOffset); Int first = -1; for (Int i = 0; i < numItems; i++) { /* Read and check next comment string length. */ Int length = in.InputNumber(4); if (length < 0 || length > buffer.Size() - in.GetPos()) break; /* Read and assign actual comment string. */ String comment = in.InputString(length); String id = comment.Head(comment.Find("=")).ToUpper(); String value = comment.Tail(comment.Length() - comment.Find("=") - 1).Trim(); if (id.StartsWith("CHAPTER")) { const Format &format = track.GetFormat(); Int chapter = id.SubString(7, 3).ToInt(); String field = id.Tail(id.Length() - 10); if (first == -1) first = chapter; chapter = chapter - first + 1; /* Chapters must appear in order. */ if (track.tracks.Length() > chapter || track.tracks.Length() < chapter - 1) { track.tracks.RemoveAll(); break; } /* Fill track data and add to track list. */ if (track.tracks.Length() == chapter - 1) { Track nTrack; Info info = track.GetInfo(); nTrack.fileName = track.fileName; nTrack.pictures = track.pictures; info.track = chapter; nTrack.SetInfo(info); nTrack.SetFormat(format); track.tracks.Add(nTrack, chapter); } Track &rTrack = track.tracks.GetReference(chapter); /* Set track offset. */ if (field == NIL) { rTrack.sampleOffset = Math::Round(value.SubString(0, 2).ToInt() * 60 * 60 * format.rate + value.SubString(3, 2).ToInt() * 60 * format.rate + value.SubString(6, 2).ToInt() * format.rate + value.SubString(9, 3).ToInt() * format.rate / 1000.0); rTrack.length = track.length - rTrack.sampleOffset; if (track.length > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * rTrack.length); else if (track.approxLength > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * rTrack.length); else rTrack.fileSize = rTrack.length * format.channels * (format.bits / 8); } /* Set track title. */ if (field == "NAME") { Info info = rTrack.GetInfo(); info.title = value; rTrack.SetInfo(info); } /* Update previous track length. */ if (chapter > 1) { Track &pTrack = track.tracks.GetReference(chapter - 1); pTrack.length = rTrack.sampleOffset - pTrack.sampleOffset; if (track.length > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * pTrack.length); else if (track.approxLength > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * pTrack.length); else pTrack.fileSize = pTrack.length * format.channels * (format.bits / 8); } } } } return Success(); } Error BoCA::TaggerVorbis::RenderStreamInfo(const String &fileName, const Track &track) { return UpdateStreamInfo(fileName, track); } Error BoCA::TaggerVorbis::UpdateStreamInfo(const String &fileName, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); /* Open input file. */ InStream in(STREAM_FILE, fileName, IS_READ); if (in.InputString(4) != "OggS") return False; in.Seek(0); /* Create temporary file. */ OutStream out(STREAM_FILE, fileName.Append(".temp"), OS_REPLACE); if (out.GetLastError() != IO_ERROR_OK) return Error(); /* Set up Ogg state. */ ogg_sync_state oy; ogg_stream_state os_in; ogg_stream_state os_out; ex_ogg_sync_init(&oy); /* Get stream format. */ Bool initialized = False; Bool error = False; Int packetNum = 0; Bool wrotePictures = False; Bool isVorbis = False; Bool isOpus = False; Bool isSpeex = False; Bool isFLAC = False; do { Int size = Math::Min(Int64(4096), in.Size() - in.GetPos()); char *buffer = ex_ogg_sync_buffer(&oy, size); in.InputData(buffer, size); ex_ogg_sync_wrote(&oy, size); ogg_page og; while (ex_ogg_sync_pageout(&oy, &og) == 1) { if (!initialized) { ex_ogg_stream_init(&os_in, ex_ogg_page_serialno(&og)); ex_ogg_stream_init(&os_out, ex_ogg_page_serialno(&og)); initialized = True; } ex_ogg_stream_pagein(&os_in, &og); ogg_packet op; while (ex_ogg_stream_packetout(&os_in, &op) == 1) { /* Found header packet. */ if (packetNum == 0) { if (op.packet[0] == 0x01 && op.packet[1] == 'v' && op.packet[2] == 'o' && op.packet[3] == 'r' && op.packet[4] == 'b' && op.packet[5] == 'i' && op.packet[6] == 's') isVorbis = True; else if (op.packet[0] == 'O' && op.packet[1] == 'p' && op.packet[2] == 'u' && op.packet[3] == 's' && op.packet[4] == 'T' && op.packet[5] == 'a' && op.packet[6] == 'g' && op.packet[7] == 's') isOpus = True; else if (op.packet[0] == 'S' && op.packet[1] == 'p' && op.packet[2] == 'e' && op.packet[3] == 'e' && op.packet[4] == 'x') isSpeex = True; else if (op.packet[0] == 0x7F && op.packet[1] == 'F' && op.packet[2] == 'L' && op.packet[3] == 'A' && op.packet[4] == 'C') isFLAC = True; if (!isVorbis && !isOpus && !isSpeex && !isFLAC) { error = True; break; } ex_ogg_stream_packetin(&os_out, &op); } /* Found Vorbis Comment packet. */ if (packetNum == 1) { Int offset = 0; if (isVorbis) offset = 7; else if (isOpus) offset = 8; else if (isFLAC) offset = 4; Track inputTrack; Buffer comments(op.bytes - offset); memcpy(comments, op.packet + offset, op.bytes - offset); if (ParseBuffer(comments, inputTrack) != Success()) { error = True; break; } /* For FLAC, pictures are stored separately. */ Track copy = track; if (isFLAC) copy.pictures.RemoveAll(); RenderBuffer(comments, copy); /* Output updated packet. */ comments.Resize(comments.Size() + offset + (isVorbis ? 1 : 0)); memmove(comments + offset, comments, comments.Size() - offset); memcpy(comments, op.packet, offset); if (isVorbis) comments[comments.Size() - 1] = 1; else if (isFLAC) OutStream(STREAM_BUFFER, comments + 1, 3).OutputNumberRaw(comments.Size() - 4, 3); ogg_packet header_comm = { comments, comments.Size(), 0, 0, 0, 0 }; ex_ogg_stream_packetin(&os_out, &header_comm); } /* Other packet. */ if (packetNum >= 2) { /* Pass packet to output stream unless it's a FLAC picture packet. */ if (!isFLAC || op.packet[0] != 0x06) ex_ogg_stream_packetin(&os_out, &op); /* Save picture packets to FLAC if not already done. */ if (isFLAC && op.packet[0] == 0x06 && albumArtWriteToTags && !wrotePictures) { foreach (const Picture &picInfo, track.pictures) { Buffer picBuffer; CreateMetadataBlockPicture(picBuffer, picInfo, True); ogg_packet meta_pic = { picBuffer, picBuffer.Size(), 0, 0, 0, 0 }; ex_ogg_stream_packetin(&os_out, &meta_pic); WriteOggPackets(os_out, out); } wrotePictures = True; } } packetNum++; } if (error) break; WriteOggPackets(os_out, out); } if (error) break; } while (in.GetPos() < in.Size()); ex_ogg_stream_clear(&os_in); ex_ogg_stream_clear(&os_out); ex_ogg_sync_clear(&oy); in.Close(); out.Close(); if (error) { File(fileName.Append(".temp")).Delete(); return Error(); } File(fileName).Delete(); File(fileName.Append(".temp")).Move(fileName); return Success(); } Void BoCA::TaggerVorbis::CreateMetadataBlockPicture(Buffer &buffer, const Picture &picture, Bool withHeader) { buffer.Resize((picture.mime != NIL ? strlen(picture.mime) : 0) + (picture.description != NIL ? strlen(picture.description) : 0) + picture.data.Size() + 32 + (withHeader ? 4 : 0)); OutStream out(STREAM_BUFFER, buffer, buffer.Size()); if (withHeader) { out.OutputNumberRaw(0x06, 1); out.OutputNumberRaw(buffer.Size() - 4, 3); } out.OutputNumberRaw(picture.type, 4); out.OutputNumberRaw(picture.mime != NIL ? strlen(picture.mime) : 0, 4); out.OutputString(picture.mime); out.OutputNumberRaw(picture.description != NIL ? strlen(picture.description) : 0, 4); out.OutputString(picture.description); out.OutputNumberRaw(0, 4); out.OutputNumberRaw(0, 4); out.OutputNumberRaw(0, 4); out.OutputNumberRaw(0, 4); out.OutputNumberRaw(picture.data.Size(), 4); out.OutputData(picture.data, picture.data.Size()); } Void BoCA::TaggerVorbis::WriteOggPackets(ogg_stream_state &os, OutStream &out) { do { ogg_page og; if (ex_ogg_stream_flush(&os, &og) == 0) break; out.OutputData(og.header, og.header_len); out.OutputData(og.body, og.body_len); } while (True); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/vorbis/vorbis.h000066400000000000000000000030021516712004000245760ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(TaggerVorbis) namespace BoCA { class TaggerVorbis : public CS::TaggerComponent { private: static const String ConfigID; Int RenderTagHeader(const String &, Int, Buffer &); Int RenderTagItem(const String &, const String &, Buffer &, Bool = True); Void CreateMetadataBlockPicture(Buffer &, const Picture &, Bool); Void WriteOggPackets(ogg_stream_state &, IO::OutStream &); public: static const String &GetComponentSpecs(); TaggerVorbis(); ~TaggerVorbis(); Error ParseBuffer(const Buffer &, Track &); Error RenderBuffer(Buffer &, const Track &); Error RenderStreamInfo(const String &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerVorbis) BoCA_END_COMPONENT(TaggerVorbis) boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/000077500000000000000000000000001516712004000224065ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/Makefile000077500000000000000000000012171516712004000240520ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = wma TYPE = tagger VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = dllinterface.o wma.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support # Enter additional library dependencies here: LIBS = -lole32 # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/dllinterface.cpp000077500000000000000000000017601516712004000255550ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2015 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "dllinterface.h" WMCREATEEDITOR ex_WMCreateEditor = NIL; DynamicLoader *wmvcoredll = NIL; Bool LoadWMVCoreDLL() { wmvcoredll = new DynamicLoader("WMVCore"); ex_WMCreateEditor = (WMCREATEEDITOR) wmvcoredll->GetFunctionAddress("WMCreateEditor"); if (ex_WMCreateEditor == NIL) { FreeWMVCoreDLL(); return False; } return True; } Void FreeWMVCoreDLL() { Object::DeleteObject(wmvcoredll); wmvcoredll = NIL; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/dllinterface.h000077500000000000000000000015751516712004000252260ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include using namespace smooth; using namespace smooth::System; extern DynamicLoader *wmvcoredll; Bool LoadWMVCoreDLL(); Void FreeWMVCoreDLL(); typedef HRESULT (STDMETHODCALLTYPE *WMCREATEEDITOR) (IWMMetadataEditor **); extern WMCREATEEDITOR ex_WMCreateEditor; boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/wma.cpp000066400000000000000000000751601516712004000237070ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2023 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include "wma.h" const String &BoCA::TaggerWMA::GetComponentSpecs() { static String componentSpecs; if (wmvcoredll != NIL) { componentSpecs = " \ \ \ \ Windows Media Tagger \ 1.0 \ wma-tag \ tagger \ \ Windows Media Audio Files \ wma \ \ \ WMA Metadata \ \ \ \ UTF-16LE \ \ \ \ \ "; } return componentSpecs; } Void smooth::AttachDLL(Void *instance) { LoadWMVCoreDLL(); /* Register initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Connect(&BoCA::TaggerWMA::Initialize); engine->onCleanup.Connect(&BoCA::TaggerWMA::Cleanup); } } Void smooth::DetachDLL() { /* Unregister initialization and cleanup handlers. */ if (wmvcoredll != NIL) { BoCA::Engine *engine = BoCA::Engine::Get(); engine->onInitialize.Disconnect(&BoCA::TaggerWMA::Initialize); engine->onCleanup.Disconnect(&BoCA::TaggerWMA::Cleanup); } FreeWMVCoreDLL(); } Void BoCA::TaggerWMA::Initialize() { /* Init the Microsoft COM library. */ CoInitialize(NIL); } Void BoCA::TaggerWMA::Cleanup() { /* Uninit the Microsoft COM library. */ CoUninitialize(); } const String BoCA::TaggerWMA::ConfigID = "Tags"; BoCA::TaggerWMA::TaggerWMA() { } BoCA::TaggerWMA::~TaggerWMA() { } Error BoCA::TaggerWMA::RenderStreamInfo(const String &fileName, const Track &track) { /* Get configuration. */ const Config *currentConfig = GetConfiguration(); Bool prependZero = currentConfig->GetIntValue(ConfigID, "TrackPrependZeroWMAMetadata", False); Bool writeChapters = currentConfig->GetIntValue(ConfigID, "WriteChapters", True); Bool writeMCDI = currentConfig->GetIntValue(ConfigID, "WriteMCDI", True); Bool preserveReplayGain = currentConfig->GetIntValue(ConfigID, "PreserveReplayGain", True); Bool albumArtWriteToTags = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToTags", True); Bool albumArtWriteToWMA = currentConfig->GetIntValue(ConfigID, "CoverArtWriteToWMAMetadata", True); Bool replaceExistingComments = currentConfig->GetIntValue(ConfigID, "ReplaceExistingComments", False); String defaultComment = currentConfig->GetStringValue(ConfigID, "DefaultComment", NIL); /* Create metadata editor objects. */ IWMMetadataEditor *metadataEditor = NIL; IWMMetadataEditor2 *metadataEditor2 = NIL; HRESULT hr = ex_WMCreateEditor(&metadataEditor); if (FAILED(hr)) return Error(); hr = metadataEditor->QueryInterface(IID_IWMMetadataEditor2, (void **) &metadataEditor2); if (FAILED(hr)) { metadataEditor->Release(); return Error(); } /* Open file and render tags. */ hr = metadataEditor2->OpenEx(Directory::MakeExtendedPath(File(fileName)), GENERIC_READ | GENERIC_WRITE, 0); if (!FAILED(hr)) { IWMHeaderInfo3 *pHeaderInfo = NIL; metadataEditor2->QueryInterface(IID_IWMHeaderInfo3, (void **) &pHeaderInfo); /* Save basic information. */ const Info &info = track.GetInfo(); if (info.artist != NIL) RenderWMAStringItem(g_wszWMAuthor, info.artist, pHeaderInfo); if (info.title != NIL) RenderWMAStringItem(g_wszWMTitle, info.title, pHeaderInfo); if (info.album != NIL) RenderWMAStringItem(g_wszWMAlbumTitle, info.album, pHeaderInfo); if (info.year > 0) RenderWMAStringItem(g_wszWMYear, String::FromInt(info.year), pHeaderInfo); if (info.genre != NIL) RenderWMAStringItem(g_wszWMGenre, info.genre, pHeaderInfo); if (info.label != NIL) RenderWMAStringItem(g_wszWMPublisher, info.label, pHeaderInfo); if (info.isrc != NIL) RenderWMAStringItem(g_wszWMISRC, info.isrc, pHeaderInfo); if (info.track > 0) { RenderWMAStringItem(g_wszWMTrackNumber, String(prependZero && info.track < 10 ? "0" : NIL).Append(String::FromInt(info.track)), pHeaderInfo); } if (info.disc > 0) { String discString = String(prependZero && info.disc < 10 ? "0" : NIL).Append(String::FromInt(info.disc)); if (info.numDiscs > 0) discString.Append("/").Append(prependZero && info.numDiscs < 10 ? "0" : NIL).Append(String::FromInt(info.numDiscs)); RenderWMAStringItem(g_wszWMPartOfSet, discString, pHeaderInfo); } if (info.rating >= 0) { RenderWMAIntegerItem(g_wszWMSharedUserRating, Math::Min(99, info.rating), pHeaderInfo); } if (info.comment != NIL && !replaceExistingComments) RenderWMAStringItem(g_wszWMDescription, info.comment, pHeaderInfo, False); else if (defaultComment != NIL) RenderWMAStringItem(g_wszWMDescription, defaultComment, pHeaderInfo); /* Save other text info. */ foreach (const String &pair, info.other) { String key = pair.Head(pair.Find(":")); String value = pair.Tail(pair.Length() - pair.Find(":") - 1); if (value == NIL) continue; if (key == INFO_ALBUMARTIST) RenderWMAStringItem(g_wszWMAlbumArtist, value, pHeaderInfo); else if (key == INFO_CONTENTGROUP) RenderWMAStringItem(g_wszWMContentGroupDescription, value, pHeaderInfo); else if (key == INFO_SUBTITLE) RenderWMAStringItem(g_wszWMSubTitle, value, pHeaderInfo); else if (key == INFO_CONDUCTOR) RenderWMAStringItem(g_wszWMConductor, value, pHeaderInfo); else if (key == INFO_REMIXER) RenderWMAStringItem(g_wszWMModifiedBy, value, pHeaderInfo); else if (key == INFO_COMPOSER) RenderWMAStringItem(g_wszWMComposer, value, pHeaderInfo); else if (key == INFO_LYRICIST) RenderWMAStringItem(g_wszWMWriter, value, pHeaderInfo); else if (key == INFO_PRODUCER) RenderWMAStringItem(g_wszWMProducer, value, pHeaderInfo); else if (key == INFO_ORIG_ARTIST) RenderWMAStringItem(g_wszWMOriginalArtist, value, pHeaderInfo); else if (key == INFO_ORIG_ALBUM) RenderWMAStringItem(g_wszWMOriginalAlbumTitle, value, pHeaderInfo); else if (key == INFO_ORIG_LYRICIST) RenderWMAStringItem(g_wszWMOriginalLyricist, value, pHeaderInfo); else if (key == INFO_ORIG_YEAR) RenderWMAStringItem(g_wszWMOriginalReleaseYear, value, pHeaderInfo); else if (key == INFO_BPM) RenderWMAStringItem(g_wszWMBeatsPerMinute, value, pHeaderInfo); else if (key == INFO_INITIALKEY) RenderWMAStringItem(g_wszWMInitialKey, value, pHeaderInfo); else if (key == INFO_COPYRIGHT) RenderWMAStringItem(g_wszWMCopyright, value, pHeaderInfo); else if (key == INFO_MEDIATYPE) RenderWMAStringItem("WM/Media", value, pHeaderInfo); else if (key == INFO_CATALOGNUMBER) RenderWMAStringItem("WM/CatalogNo", value, pHeaderInfo); else if (key == INFO_BARCODE) RenderWMAStringItem("WM/Barcode", value, pHeaderInfo); else if (key == INFO_LYRICS) RenderWMAStringItem(g_wszWMLyrics, value, pHeaderInfo, False); else if (key == INFO_SCRIPT) RenderWMAStringItem("WM/Script", value, pHeaderInfo); else if (key == INFO_RADIOSTATION) RenderWMAStringItem(g_wszWMRadioStationName, value, pHeaderInfo); else if (key == INFO_RADIOOWNER) RenderWMAStringItem(g_wszWMRadioStationOwner, value, pHeaderInfo); else if (key == INFO_SORT_ARTIST) RenderWMAStringItem("WM/ArtistSortOrder", value, pHeaderInfo); else if (key == INFO_SORT_ALBUM) RenderWMAStringItem("WM/AlbumSortOrder", value, pHeaderInfo); else if (key == INFO_SORT_ALBUMARTIST) RenderWMAStringItem("WM/AlbumArtistSortOrder", value, pHeaderInfo); else if (key == INFO_SORT_COMPOSER) RenderWMAStringItem("WM/ComposerSortOrder", value, pHeaderInfo); else if (key == INFO_SORT_TITLE) RenderWMAStringItem("WM/TitleSortOrder", value, pHeaderInfo); else if (key == INFO_WEB_ARTIST) RenderWMAStringItem(g_wszWMAuthorURL, value, pHeaderInfo); else if (key == INFO_WEB_SOURCE) RenderWMAStringItem(g_wszWMAudioSourceURL, value, pHeaderInfo); else if (key == INFO_WEB_COPYRIGHT) RenderWMAStringItem(g_wszWMCopyrightURL, value, pHeaderInfo); else if (key == INFO_WEB_COMMERCIAL) RenderWMAStringItem(g_wszWMPromotionURL, value, pHeaderInfo); else if (key == INFO_ASIN) RenderWMAStringItem("ASIN", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_ARTISTID) RenderWMAStringItem("MusicBrainz/Artist Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_ALBUMID) RenderWMAStringItem("MusicBrainz/Album Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_ALBUMARTISTID) RenderWMAStringItem("MusicBrainz/Album Artist Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_WORKID) RenderWMAStringItem("MusicBrainz/Work Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_DISCID) RenderWMAStringItem("MusicBrainz/Disc Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_TRACKID) RenderWMAStringItem("MusicBrainz/Track Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_ORIGINALARTISTID) RenderWMAStringItem("MusicBrainz/Original Artist Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_ORIGINALALBUMID) RenderWMAStringItem("MusicBrainz/Original Album Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_RELEASEGROUPID) RenderWMAStringItem("MusicBrainz/Release Group Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_RELEASETRACKID) RenderWMAStringItem("MusicBrainz/Release Track Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_TRMID) RenderWMAStringItem("MusicBrainz/TRM Id", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_RELEASETYPE) RenderWMAStringItem("MusicBrainz/Album Type", value, pHeaderInfo); else if (key == INFO_MUSICBRAINZ_RELEASESTATUS) RenderWMAStringItem("MusicBrainz/Album Status", value, pHeaderInfo); else if (key == INFO_RELEASECOUNTRY) RenderWMAStringItem("MusicBrainz/Album Release Country", value, pHeaderInfo); } /* Save Replay Gain info. */ if (preserveReplayGain) { if (info.track_gain != NIL && info.track_peak != NIL) { RenderWMAStringItem("replaygain_track_gain", info.track_gain, pHeaderInfo); RenderWMAStringItem("replaygain_track_peak", info.track_peak, pHeaderInfo); } if (info.album_gain != NIL && info.album_peak != NIL) { RenderWMAStringItem("replaygain_album_gain", info.album_gain, pHeaderInfo); RenderWMAStringItem("replaygain_album_peak", info.album_peak, pHeaderInfo); } } /* Save CD table of contents. */ if (writeMCDI && info.mcdi.IsValid()) RenderWMABinaryItem(g_wszWMMCDI, info.mcdi.GetData(), pHeaderInfo); /* Save encoder version. */ Application *app = Application::Get(); RenderWMAStringItem(g_wszWMToolName, app->getClientName.Call(), pHeaderInfo); RenderWMAStringItem(g_wszWMToolVersion, app->getClientVersion.Call(), pHeaderInfo); /* Save album art. */ if (albumArtWriteToTags && albumArtWriteToWMA) { foreach (const Picture &picInfo, track.pictures) { WM_PICTURE picture = { 0 }; picture.bPictureType = picInfo.type; picture.pwszMIMEType = new WCHAR [picInfo.mime.Length() + 1]; picture.pwszMIMEType[0] = 0; picture.pwszDescription = new WCHAR [picInfo.description.Length() + 1]; picture.pwszDescription[0] = 0; picture.dwDataLen = picInfo.data.Size(); picture.pbData = (BYTE *) const_cast((const UnsignedByte *) picInfo.data); if (picInfo.mime != NIL) wcsncpy(picture.pwszMIMEType, picInfo.mime, picInfo.mime.Length() + 1); if (picInfo.description != NIL) wcsncpy(picture.pwszDescription, picInfo.description, picInfo.description.Length() + 1); pHeaderInfo->AddAttribute(0, g_wszWMPicture, NIL, WMT_TYPE_BINARY, 0, (BYTE *) &picture, sizeof(WM_PICTURE)); delete [] picture.pwszMIMEType; delete [] picture.pwszDescription; } } /* Save chapters. */ if (track.tracks.Length() > 0 && writeChapters) { Int64 offset = 0; for (Int i = 0; i < track.tracks.Length(); i++) { const Track &chapterTrack = track.tracks.GetNth(i); const Info &chapterInfo = chapterTrack.GetInfo(); const Format &chapterFormat = chapterTrack.GetFormat(); pHeaderInfo->AddMarker(chapterInfo.title, offset * 10000000 / chapterFormat.rate); if (chapterTrack.length >= 0) offset += chapterTrack.length; else if (chapterTrack.approxLength >= 0) offset += chapterTrack.approxLength; } } pHeaderInfo->Release(); /* Flush metadata editor. */ hr = metadataEditor2->Flush(); } metadataEditor->Release(); metadataEditor2->Release(); if (FAILED(hr)) return Error(); else return Success(); } Error BoCA::TaggerWMA::RenderWMAStringItem(const String &id, const String &value, Void *headerInfo, Bool trim) { String data = trim ? value.Trim() : value; Int dataSize = data != NIL ? wcslen(data) + 1 : 0; if (data == NIL) return Success(); HRESULT hr = ((IWMHeaderInfo3 *) headerInfo)->AddAttribute(0, id, NIL, WMT_TYPE_STRING, 0, (BYTE *) (wchar_t *) data, dataSize * 2); if (FAILED(hr)) return Error(); else return Success(); } Error BoCA::TaggerWMA::RenderWMAIntegerItem(const String &id, Int value, Void *headerInfo) { HRESULT hr = ((IWMHeaderInfo3 *) headerInfo)->AddAttribute(0, id, NIL, WMT_TYPE_DWORD, 0, (BYTE *) &value, sizeof(DWORD)); if (FAILED(hr)) return Error(); else return Success(); } Error BoCA::TaggerWMA::RenderWMABinaryItem(const String &id, const Buffer &value, Void *headerInfo) { HRESULT hr = ((IWMHeaderInfo3 *) headerInfo)->AddAttribute(0, id, NIL, WMT_TYPE_BINARY, 0, (BYTE *) (UnsignedByte *) value, value.Size()); if (FAILED(hr)) return Error(); else return Success(); } Error BoCA::TaggerWMA::ParseStreamInfo(const String &fileName, Track &track) { const Config *config = GetConfiguration(); /* Create metadata editor objects. */ IWMMetadataEditor *metadataEditor = NIL; IWMMetadataEditor2 *metadataEditor2 = NIL; HRESULT hr = ex_WMCreateEditor(&metadataEditor); if (FAILED(hr)) return Error(); hr = metadataEditor->QueryInterface(IID_IWMMetadataEditor2, (void **) &metadataEditor2); if (FAILED(hr)) { metadataEditor->Release(); return Error(); } /* Open file and parse tags. */ hr = metadataEditor2->OpenEx(Directory::MakeExtendedPath(File(fileName)), GENERIC_READ, FILE_SHARE_READ); if (!FAILED(hr)) { IWMHeaderInfo3 *pHeaderInfo = NIL; metadataEditor2->QueryInterface(IID_IWMHeaderInfo3, (void **) &pHeaderInfo); Info info = track.GetInfo(); WORD langIndex = 0; WORD numIndices = 0; pHeaderInfo->GetAttributeIndices(0, NIL, &langIndex, NIL, &numIndices); WORD *indices = new WORD [numIndices]; pHeaderInfo->GetAttributeIndices(0, NIL, &langIndex, indices, &numIndices); for (Int i = 0; i < numIndices; i++) { /* Read metadata values. */ WORD nameLen = 1024; LPWSTR name = new WCHAR [nameLen]; DWORD cbLength = 0; pHeaderInfo->GetAttributeByIndexEx(0, indices[i], name, &nameLen, NIL, NIL, NIL, &cbLength); WMT_ATTR_DATATYPE type = WMT_TYPE_DWORD; BYTE *pbValue = new BYTE [cbLength]; pHeaderInfo->GetAttributeByIndexEx(0, indices[i], name, &nameLen, &type, NIL, pbValue, &cbLength); /* Parse string values. */ String id = name; String value; if (type == WMT_TYPE_STRING) { value = String((LPWSTR) pbValue).Trim(); if (value == NIL) { delete [] pbValue; delete [] name; continue; } } /* Assign values to metadata fields. */ if (id == g_wszWMAuthor) info.artist = value; else if (id == g_wszWMTitle) info.title = value; else if (id == g_wszWMAlbumTitle) info.album = value; else if (id == g_wszWMYear) info.year = value.ToInt(); else if (id == g_wszWMGenre) info.genre = value; else if (id == g_wszWMDescription) info.comment = String((LPWSTR) pbValue); else if (id == g_wszWMPublisher) info.label = value; else if (id == g_wszWMISRC) { if (Info::IsISRC(value)) info.isrc = value; } else if (id == g_wszWMAlbumArtist) info.SetOtherInfo(INFO_ALBUMARTIST, value); else if (id == g_wszWMContentGroupDescription) info.SetOtherInfo(INFO_CONTENTGROUP, value); else if (id == g_wszWMSubTitle) info.SetOtherInfo(INFO_SUBTITLE, value); else if (id == g_wszWMConductor) info.SetOtherInfo(INFO_CONDUCTOR, value); else if (id == g_wszWMModifiedBy) info.SetOtherInfo(INFO_REMIXER, value); else if (id == g_wszWMComposer) info.SetOtherInfo(INFO_COMPOSER, value); else if (id == g_wszWMWriter) info.SetOtherInfo(INFO_LYRICIST, value); else if (id == g_wszWMProducer) info.SetOtherInfo(INFO_PRODUCER, value); else if (id == g_wszWMOriginalArtist) info.SetOtherInfo(INFO_ORIG_ARTIST, value); else if (id == g_wszWMOriginalAlbumTitle) info.SetOtherInfo(INFO_ORIG_ALBUM, value); else if (id == g_wszWMOriginalLyricist) info.SetOtherInfo(INFO_ORIG_LYRICIST, value); else if (id == g_wszWMOriginalReleaseYear) info.SetOtherInfo(INFO_ORIG_YEAR, value); else if (id == g_wszWMBeatsPerMinute) { if (value.ToInt() > 0) info.SetOtherInfo(INFO_BPM, value); } else if (id == g_wszWMInitialKey) info.SetOtherInfo(INFO_INITIALKEY, value); else if (id == g_wszWMCopyright) info.SetOtherInfo(INFO_COPYRIGHT, value); else if (id == "WM/Media") info.SetOtherInfo(INFO_MEDIATYPE, value); else if (id == "WM/CatalogNo") info.SetOtherInfo(INFO_CATALOGNUMBER, value); else if (id == "WM/Barcode") info.SetOtherInfo(INFO_BARCODE, value); else if (id == g_wszWMLyrics) info.SetOtherInfo(INFO_LYRICS, String((LPWSTR) pbValue)); else if (id == "WM/Script") info.SetOtherInfo(INFO_SCRIPT, value); else if (id == g_wszWMRadioStationName) info.SetOtherInfo(INFO_RADIOSTATION, value); else if (id == g_wszWMRadioStationOwner) info.SetOtherInfo(INFO_RADIOOWNER, value); else if (id == "WM/ArtistSortOrder") info.SetOtherInfo(INFO_SORT_ARTIST, value); else if (id == "WM/AlbumSortOrder") info.SetOtherInfo(INFO_SORT_ALBUM, value); else if (id == "WM/AlbumArtistSortOrder") info.SetOtherInfo(INFO_SORT_ALBUMARTIST, value); else if (id == "WM/ComposerSortOrder") info.SetOtherInfo(INFO_SORT_COMPOSER, value); else if (id == "WM/TitleSortOrder") info.SetOtherInfo(INFO_SORT_TITLE, value); else if (id == g_wszWMAuthorURL) info.SetOtherInfo(INFO_WEB_ARTIST, value); else if (id == g_wszWMAudioSourceURL) info.SetOtherInfo(INFO_WEB_SOURCE, value); else if (id == g_wszWMCopyrightURL) info.SetOtherInfo(INFO_WEB_COPYRIGHT, value); else if (id == g_wszWMPromotionURL) info.SetOtherInfo(INFO_WEB_COMMERCIAL, value); else if (id == g_wszWMTrack) { if (type == WMT_TYPE_DWORD) info.track = 1 + ((DWORD *) pbValue)[0]; else if (type == WMT_TYPE_STRING) info.track = 1 + value.ToInt(); } else if (id == g_wszWMTrackNumber) { if (type == WMT_TYPE_DWORD) info.track = ((DWORD *) pbValue)[0]; else if (type == WMT_TYPE_STRING) { info.track = value.ToInt(); if (value.Contains("/")) info.numTracks = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } } else if (id == g_wszWMPartOfSet) { info.disc = value.ToInt(); if (value.Contains("/")) info.numDiscs = value.Tail(value.Length() - value.Find("/") - 1).ToInt(); } else if (id == g_wszWMSharedUserRating) { info.rating = (DWORD) *pbValue; if (info.rating == 99) info.rating = 100; } else if (id == "ASIN") info.SetOtherInfo(INFO_ASIN, value); else if (id.StartsWith("MusicBrainz")) { if (id == "MusicBrainz/Artist Id") info.SetOtherInfo(INFO_MUSICBRAINZ_ARTISTID, value); else if (id == "MusicBrainz/Album Id") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMID, value); else if (id == "MusicBrainz/Album Artist Id") info.SetOtherInfo(INFO_MUSICBRAINZ_ALBUMARTISTID, value); else if (id == "MusicBrainz/Work Id") info.SetOtherInfo(INFO_MUSICBRAINZ_WORKID, value); else if (id == "MusicBrainz/Disc Id") info.SetOtherInfo(INFO_MUSICBRAINZ_DISCID, value); else if (id == "MusicBrainz/Track Id") info.SetOtherInfo(INFO_MUSICBRAINZ_TRACKID, value); else if (id == "MusicBrainz/Original Artist Id") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALARTISTID, value); else if (id == "MusicBrainz/Original Album Id") info.SetOtherInfo(INFO_MUSICBRAINZ_ORIGINALALBUMID, value); else if (id == "MusicBrainz/Release Group Id") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASEGROUPID, value); else if (id == "MusicBrainz/Release Track Id") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETRACKID, value); else if (id == "MusicBrainz/TRM Id") info.SetOtherInfo(INFO_MUSICBRAINZ_TRMID, value); else if (id == "MusicBrainz/Album Type") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASETYPE, value); else if (id == "MusicBrainz/Album Status") info.SetOtherInfo(INFO_MUSICBRAINZ_RELEASESTATUS, value); else if (id == "MusicBrainz/Album Release Country") info.SetOtherInfo(INFO_RELEASECOUNTRY, value); } else if (id.ToUpper().StartsWith("REPLAYGAIN")) { if (id.ToUpper() == "REPLAYGAIN_TRACK_GAIN") info.track_gain = value; else if (id.ToUpper() == "REPLAYGAIN_TRACK_PEAK") info.track_peak = value; else if (id.ToUpper() == "REPLAYGAIN_ALBUM_GAIN") info.album_gain = value; else if (id.ToUpper() == "REPLAYGAIN_ALBUM_PEAK") info.album_peak = value; } else if (id == g_wszWMMCDI) { /* Use a heuristic to detect if this is a valid binary MCDI * field or the commonly used track offset string. */ Bool binary = False; for (Int i = 0; unsigned(i) < cbLength; i++) { if (pbValue[i] > 0 && pbValue[i] < 0x20) { binary = True; break; } } if (binary) { Buffer data(cbLength); memcpy(data, pbValue, cbLength); /* Check validity of MCDI data and assign. */ MCDI mcdi(data); if (mcdi.IsValid()) info.mcdi.SetData(data); } else { /* Found offset string. */ for (Int i = 0; unsigned(i) < cbLength / 2; i++) { info.offsets[i] = ((short *) pbValue)[i]; if (info.offsets[i] == 0) break; } } } else if (id == g_wszWMPicture && config->GetIntValue(ConfigID, "CoverArtReadFromTags", True)) { WM_PICTURE *picData = (WM_PICTURE *) pbValue; Picture picture; picture.type = picData->bPictureType; picture.mime = picData->pwszMIMEType; picture.description = String(picData->pwszDescription).Trim(); picture.data.Set(picData->pbData, picData->dwDataLen); if (picture.data.Size() >= 16) { if (picture.data[0] == 0xFF && picture.data[1] == 0xD8) picture.mime = "image/jpeg"; else if (picture.data[0] == 0x89 && picture.data[1] == 0x50 && picture.data[2] == 0x4E && picture.data[3] == 0x47 && picture.data[4] == 0x0D && picture.data[5] == 0x0A && picture.data[6] == 0x1A && picture.data[7] == 0x0A) picture.mime = "image/png"; if (picture.data[0] != 0 && picture.data[1] != 0) track.pictures.Add(picture); } } delete [] pbValue; delete [] name; } delete [] indices; /* Set artist to album artist if artist is not filled. */ if (info.artist == NIL) info.artist = info.GetOtherInfo(INFO_ALBUMARTIST); track.SetInfo(info); /* Read chapters. */ WORD numMarkers = 0; pHeaderInfo->GetMarkerCount(&numMarkers); if (numMarkers > 0 && config->GetIntValue(ConfigID, "ReadChapters", True)) { for (Int i = 0; i < numMarkers; i++) { const Format &format = track.GetFormat(); QWORD cnsMarkerTime = 0; WORD cchMarkerNameLen = 0; pHeaderInfo->GetMarker(i, NIL, &cchMarkerNameLen, NIL); WCHAR *pwszMarkerName = new WCHAR [cchMarkerNameLen]; pHeaderInfo->GetMarker(i, pwszMarkerName, &cchMarkerNameLen, &cnsMarkerTime); /* Fill track data. */ Track rTrack; rTrack.fileName = track.fileName; rTrack.pictures = track.pictures; rTrack.sampleOffset = Math::Round(cnsMarkerTime * format.rate / 10000000.0); if (track.length >= 0) rTrack.length = track.length - rTrack.sampleOffset; else if (track.approxLength >= 0) rTrack.approxLength = track.approxLength - rTrack.sampleOffset; else rTrack.approxLength = 240 * format.rate; if (track.length > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * rTrack.length); else if (track.approxLength > 0) rTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * rTrack.approxLength); else rTrack.fileSize = rTrack.approxLength * format.channels * (format.bits / 8); rTrack.SetFormat(format); /* Set track title. */ Info info = track.GetInfo(); info.title = String(pwszMarkerName).Trim(); info.track = i + 1; rTrack.SetInfo(info); /* Update previous track length. */ if (i > 0) { Track &pTrack = track.tracks.GetNthReference(i - 1); pTrack.length = rTrack.sampleOffset - pTrack.sampleOffset; if (track.length > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.length * pTrack.length); else if (track.approxLength > 0) pTrack.fileSize = Math::Round(Float(track.fileSize) / track.approxLength * pTrack.length); else pTrack.fileSize = pTrack.length * format.channels * (format.bits / 8); } /* Add track to track list. */ track.tracks.Add(rTrack); delete [] pwszMarkerName; } } pHeaderInfo->Release(); /* Close metadata editor. */ hr = metadataEditor2->Close(); } metadataEditor->Release(); metadataEditor2->Release(); if (FAILED(hr)) return Error(); else return Success(); } Error BoCA::TaggerWMA::UpdateStreamInfo(const String &fileName, const Track &track) { /* Create metadata editor objects. */ IWMMetadataEditor *metadataEditor = NIL; IWMMetadataEditor2 *metadataEditor2 = NIL; HRESULT hr = ex_WMCreateEditor(&metadataEditor); if (FAILED(hr)) return Error(); hr = metadataEditor->QueryInterface(IID_IWMMetadataEditor2, (void **) &metadataEditor2); if (FAILED(hr)) { metadataEditor->Release(); return Error(); } /* Open file and remove tags. */ hr = metadataEditor2->OpenEx(Directory::MakeExtendedPath(File(fileName)), GENERIC_READ | GENERIC_WRITE, 0); if (!FAILED(hr)) { IWMHeaderInfo3 *pHeaderInfo = NIL; metadataEditor2->QueryInterface(IID_IWMHeaderInfo3, (void **) &pHeaderInfo); /* Remove metadata first. */ WORD langIndex = 0; WORD numIndices = 0; pHeaderInfo->GetAttributeIndices(0, NIL, &langIndex, NIL, &numIndices); WORD *indices = new WORD [numIndices]; pHeaderInfo->GetAttributeIndices(0, NIL, &langIndex, indices, &numIndices); for (Int i = numIndices - 1; i >= 0; i--) { WORD nameLen = 1024; LPWSTR name = new WCHAR [nameLen]; DWORD cbLength = 0; hr = pHeaderInfo->GetAttributeByIndexEx(0, indices[i], name, &nameLen, NIL, NIL, NIL, &cbLength); if (!FAILED(hr)) { String nameStr = name; if (nameStr == g_wszWMAuthor || nameStr == g_wszWMTitle || nameStr == g_wszWMAlbumTitle || nameStr == g_wszWMYear || nameStr == g_wszWMGenre || nameStr == g_wszWMDescription || nameStr == g_wszWMPublisher || nameStr == g_wszWMISRC || nameStr == g_wszWMAlbumArtist || nameStr == g_wszWMContentGroupDescription || nameStr == g_wszWMSubTitle || nameStr == g_wszWMConductor || nameStr == g_wszWMComposer || nameStr == g_wszWMWriter || nameStr == g_wszWMOriginalArtist || nameStr == g_wszWMOriginalAlbumTitle || nameStr == g_wszWMOriginalLyricist || nameStr == g_wszWMOriginalReleaseYear || nameStr == g_wszWMBeatsPerMinute || nameStr == g_wszWMInitialKey || nameStr == g_wszWMCopyright || nameStr == "WM/Media" || nameStr == "WM/CatalogNo" || nameStr == "WM/Barcode" || nameStr == g_wszWMLyrics || nameStr == "WM/Script" || nameStr == g_wszWMRadioStationName || nameStr == g_wszWMRadioStationOwner || nameStr == "WM/ArtistSortOrder" || nameStr == "WM/AlbumSortOrder" || nameStr == "WM/AlbumArtistSortOrder" || nameStr == "WM/ComposerSortOrder" || nameStr == "WM/TitleSortOrder" || nameStr == g_wszWMAuthorURL || nameStr == g_wszWMAudioSourceURL || nameStr == g_wszWMCopyrightURL || nameStr == g_wszWMPromotionURL || nameStr == g_wszWMSharedUserRating || nameStr == g_wszWMTrack || nameStr == g_wszWMTrackNumber || nameStr == g_wszWMPartOfSet || nameStr == g_wszWMMCDI || nameStr == g_wszWMPicture || nameStr == "ASIN" || nameStr == "MusicBrainz/Artist Id" || nameStr == "MusicBrainz/Album Id" || nameStr == "MusicBrainz/Album Artist Id" || nameStr == "MusicBrainz/Work Id" || nameStr == "MusicBrainz/Disc Id" || nameStr == "MusicBrainz/Track Id" || nameStr == "MusicBrainz/Original Artist Id" || nameStr == "MusicBrainz/Original Album Id" || nameStr == "MusicBrainz/Release Group Id" || nameStr == "MusicBrainz/Release Track Id" || nameStr == "MusicBrainz/TRM Id" || nameStr == "MusicBrainz/Album Type" || nameStr == "MusicBrainz/Album Status" || nameStr == "MusicBrainz/Album Release Country") pHeaderInfo->DeleteAttribute(0, indices[i]); } delete [] name; } delete [] indices; pHeaderInfo->Release(); /* Flush metadata editor. */ hr = metadataEditor2->Flush(); } metadataEditor2->Release(); metadataEditor->Release(); if (FAILED(hr)) return Error(); else return RenderStreamInfo(fileName, track); } boca-1.0.7+git20260412.690d4ffe+dfsg/components/tagger/wma/wma.h000066400000000000000000000026141516712004000233460ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2021 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "dllinterface.h" BoCA_BEGIN_COMPONENT(TaggerWMA) namespace BoCA { class TaggerWMA : public CS::TaggerComponent { private: static const String ConfigID; Error RenderWMAStringItem(const String &, const String &, Void *, Bool = True); Error RenderWMAIntegerItem(const String &, Int, Void *); Error RenderWMABinaryItem(const String &, const Buffer &, Void *); public: static const String &GetComponentSpecs(); static Void Initialize(); static Void Cleanup(); TaggerWMA(); ~TaggerWMA(); Error ParseStreamInfo(const String &, Track &); Error RenderStreamInfo(const String &, const Track &); Error UpdateStreamInfo(const String &, const Track &); }; }; BoCA_DEFINE_TAGGER_COMPONENT(TaggerWMA) BoCA_END_COMPONENT(TaggerWMA) boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/000077500000000000000000000000001516712004000221645ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/Makefile000066400000000000000000000012571516712004000236310ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = ../.. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options FOLDERS = md5 .PHONY: $(FOLDERS) all: $(FOLDERS) $(FOLDERS): + $(call makein,$@) clean: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##clean): $(call cleanin,$(subst ##clean,,$@)) install: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##install): $(call makein,$(subst ##install,,$@),install) uninstall: $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall) $(foreach FOLDER,$(FOLDERS),$(FOLDER)##uninstall): $(call makein,$(subst ##uninstall,,$@),uninstall) boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/md5/000077500000000000000000000000001516712004000226515ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/md5/Makefile000066400000000000000000000011171516712004000243110ustar00rootroot00000000000000########## BoCA component makefile ########## # Change these variables to fit your project: TARGET = md5 TYPE = verifier VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: OBJECTS = md5.o # Enter additional defines here: DEFINE = # Enter additional library dependencies here: LIBS = # Enter addition commands for targets all and clean here: ALLCMD1 = ALLCMD2 = CLEANCMD1 = CLEANCMD2 = INSTCMD1 = INSTCMD2 = UINSTCMD1 = UINSTCMD2 = ## Do not change anything below this line. ## include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-commands boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/md5/md5.cpp000066400000000000000000000040541516712004000240450ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2022 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "md5.h" const String &BoCA::VerifierMD5::GetComponentSpecs() { static String componentSpecs = " \ \ \ \ MD5 Checksum Verifier \ 1.0 \ md5-verify \ verifier \ \ \ "; return componentSpecs; } BoCA::VerifierMD5::VerifierMD5() { } BoCA::VerifierMD5::~VerifierMD5() { } Bool BoCA::VerifierMD5::CanVerifyTrack(const Track &track) { if (track.md5 != NIL && track.md5 != String().FillN('0', 32)) return True; else return False; } Int BoCA::VerifierMD5::ProcessData(Buffer &data) { /* Find system byte order. */ static Int systemByteOrder = CPU().GetEndianness() == EndianLittle ? BYTE_INTEL : BYTE_RAW; const Format &format = track.GetFormat(); /* Switch byte order to Intel. */ if (systemByteOrder != BYTE_INTEL) BoCA::Utilities::SwitchBufferByteOrder(data, format.bits / 8); /* Calculate MD5. */ md5.Feed(data); /* Switch back to native byte order. */ if (systemByteOrder != BYTE_INTEL) BoCA::Utilities::SwitchBufferByteOrder(data, format.bits / 8); return data.Size(); } Bool BoCA::VerifierMD5::Verify() { String checksum = md5.Finish(); errorString = String("Checksum: ").Append(checksum); if (checksum != track.md5) { errorState = True; errorString.Append("\nExpected: ").Append(track.md5); } return checksum == track.md5; } boca-1.0.7+git20260412.690d4ffe+dfsg/components/verifier/md5/md5.h000066400000000000000000000020121516712004000235020ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include BoCA_BEGIN_COMPONENT(VerifierMD5) namespace BoCA { class VerifierMD5 : public CS::VerifierComponent { private: Hash::MD5 md5; public: static const String &GetComponentSpecs(); VerifierMD5(); ~VerifierMD5(); Bool CanVerifyTrack(const Track &); Int ProcessData(Buffer &); Bool Verify(); }; }; BoCA_DEFINE_VERIFIER_COMPONENT(VerifierMD5) BoCA_END_COMPONENT(VerifierMD5) boca-1.0.7+git20260412.690d4ffe+dfsg/configure000077500000000000000000000031211516712004000200700ustar00rootroot00000000000000#!/bin/sh echo "There is no need to run configure for building the fre:ac Component Development" echo "Kit. Just make sure the following prerequisites are met before running make:" echo echo " All operating systems:" echo echo " - Get, build and install the latest version of the smooth Class Library;" echo " it can be obtained via Git using:" echo echo " git clone https://github.com/enzo1982/smooth.git" echo echo " On macOS, Linux, *BSD, Solaris, Hurd:" echo echo " - libcdio and libcdio-paranoia development packages (except OpenBSD)" echo " - libcdparanoia development package (OpenBSD only)" echo " - libexpat development package" echo " - libpulse development package (Linux only)" echo " - liburiparser development package" echo echo " - The XSPF playlist component uses a bundled version of libxspf. If you" echo " prefer linking against a library installed on your system, please build" echo " with \"make config=systemlibxspf\"." echo echo " To build using bundled version of the expat and uriparser libraries," echo " please build with \"make config=bundledlibexpat,bundledliburiparser\"." echo echo " On macOS:" echo echo " - Building the fre:ac CDK is supported on macOS 10.5.8 Leopard and later" echo " using the Xcode Command Line Tools (no Xcode project file provided)" echo echo " On Windows:" echo echo " - Please use MSYS2 (https://www.msys2.org/) or Visual Studio 2022" echo " with the msvc/BoCA.sln project file to build the fre:ac CDK" echo echo "When all prerequisites are met, simply run \"make && make install\"." echo boca-1.0.7+git20260412.690d4ffe+dfsg/doc/000077500000000000000000000000001516712004000167315ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/doc/dtds/000077500000000000000000000000001516712004000176675ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/doc/dtds/component.dtd000077500000000000000000000063611516712004000223770ustar00rootroot00000000000000 boca-1.0.7+git20260412.690d4ffe+dfsg/include/000077500000000000000000000000001516712004000176075ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/include/Makefile000066400000000000000000000010261516712004000212460ustar00rootroot00000000000000########## BoCA directory makefile ########## BOCA_PATH = .. include $(dir $(firstword $(MAKEFILE_LIST)))/$(BOCA_PATH)/Makefile-options all: clean: install: all ifneq ($(BUILD_WIN32),True) $(INSTALL) -d "$(DESTDIR)"$(includedir) cp -r "$(SRCDIR)"/boca "$(DESTDIR)"$(includedir) chmod -R a=rX,u=rwX "$(DESTDIR)"$(includedir)/boca $(INSTALL_DATA) "$(SRCDIR)"/boca.h "$(DESTDIR)"$(includedir) endif uninstall: ifneq ($(BUILD_WIN32),True) rm -f "$(DESTDIR)"$(includedir)/boca.h rm -f -r "$(DESTDIR)"$(includedir)/boca endif boca-1.0.7+git20260412.690d4ffe+dfsg/include/boca.h000077500000000000000000000425621516712004000207000ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2019 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BOCA_BOCA #define H_BOCA_BOCA #include using namespace smooth; #if defined BOCA_COMPONENT_BUILD # ifdef __WIN32__ # define BOCA_EXPORT __declspec (dllexport) # else # define BOCA_EXPORT __attribute__ ((visibility ("default"))) # endif # include "boca/component/component.h" # include "boca/component/decodercomponent.h" # include "boca/component/encodercomponent.h" # include "boca/component/deviceinfocomponent.h" # include "boca/component/dspcomponent.h" # include "boca/component/extensioncomponent.h" # include "boca/component/outputcomponent.h" # include "boca/component/playlistcomponent.h" # include "boca/component/taggercomponent.h" # include "boca/component/verifiercomponent.h" #else # ifdef __WIN32__ # define BOCA_EXPORT __declspec (dllimport) # else # define BOCA_EXPORT __attribute__ ((visibility ("default"))) # endif # include "boca/core/core.h" #endif #include "boca/application/component.h" #include "boca/application/componentspecs.h" #include "boca/application/decodercomponent.h" #include "boca/application/encodercomponent.h" #include "boca/application/deviceinfocomponent.h" #include "boca/application/dspcomponent.h" #include "boca/application/extensioncomponent.h" #include "boca/application/outputcomponent.h" #include "boca/application/playlistcomponent.h" #include "boca/application/taggercomponent.h" #include "boca/application/verifiercomponent.h" #include "boca/application/registry.h" #include "boca/common/config.h" #include "boca/common/configlayer.h" #include "boca/common/formatconverter.h" #include "boca/common/i18n.h" #include "boca/common/protocol.h" #include "boca/common/utilities.h" #include "boca/common/metadata/device.h" #include "boca/common/metadata/mcdi.h" #include "boca/common/metadata/track.h" #include "boca/common/communication/application.h" #include "boca/common/communication/engine.h" #include "boca/common/communication/joblist.h" #include "boca/common/communication/menu.h" #include "boca/common/communication/settings.h" #define BoCA_BEGIN_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT const char *BoCA_GetComponentName() { return (const char *) #componentName; } \ } #define BoCA_DEFINE_DECODER_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT bool BoCA_##componentName##_SetAudioTrackInfo(void *component, const void *track) { return ((BoCA::componentName *) component)->SetAudioTrackInfo(*((const BoCA::Track *) track)); } \ BOCA_EXPORT bool BoCA_##componentName##_CanOpenStream(void *component, const wchar_t *file) { return ((BoCA::componentName *) component)->CanOpenStream(file); } \ BOCA_EXPORT int BoCA_##componentName##_GetStreamInfo(void *component, const wchar_t *file, void *track) { return ((BoCA::componentName *) component)->GetStreamInfo(file, *((BoCA::Track *) track)); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsThreadSafe(const void *component) { return ((const BoCA::componentName *) component)->IsThreadSafe(); } \ \ BOCA_EXPORT __int64 BoCA_##componentName##_GetInBytes(const void *component) { return ((const BoCA::componentName *) component)->GetInBytes(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Activate(void *component) { return ((BoCA::componentName *) component)->Activate(); } \ BOCA_EXPORT bool BoCA_##componentName##_Deactivate(void *component) { return ((BoCA::componentName *) component)->Deactivate(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Seek(void *component, __int64 samplePosition) { return ((BoCA::componentName *) component)->Seek(samplePosition); } \ \ BOCA_EXPORT int BoCA_##componentName##_ReadData(void *component, void *buffer) { return ((BoCA::componentName *) component)->ReadData(*((Buffer *) buffer)); } \ \ BOCA_EXPORT void BoCA_##componentName##_SetDriver(void *component, void *driver) { return ((BoCA::componentName *) component)->SetDriver((IO::Driver *) driver); } \ } #define BoCA_DEFINE_ENCODER_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT bool BoCA_##componentName##_SetAudioTrackInfo(void *component, const void *track) { return ((BoCA::componentName *) component)->SetAudioTrackInfo(*((const BoCA::Track *) track)); } \ \ BOCA_EXPORT bool BoCA_##componentName##_SetOutputFormat(void *component, int n) { return ((BoCA::componentName *) component)->SetOutputFormat(n); } \ BOCA_EXPORT char *BoCA_##componentName##_GetOutputFileExtension(void *component) { return ((BoCA::componentName *) component)->GetOutputFileExtension(); } \ \ BOCA_EXPORT int BoCA_##componentName##_GetNumberOfPasses(void *component) { return ((BoCA::componentName *) component)->GetNumberOfPasses(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsThreadSafe(const void *component) { return ((const BoCA::componentName *) component)->IsThreadSafe(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsLossless(const void *component) { return ((const BoCA::componentName *) component)->IsLossless(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Activate(void *component) { return ((BoCA::componentName *) component)->Activate(); } \ BOCA_EXPORT bool BoCA_##componentName##_Deactivate(void *component) { return ((BoCA::componentName *) component)->Deactivate(); } \ \ BOCA_EXPORT int BoCA_##componentName##_WriteData(void *component, void *buffer) { return ((BoCA::componentName *) component)->WriteData(*((Buffer *) buffer)); } \ BOCA_EXPORT bool BoCA_##componentName##_NextPass(void *component) { return ((BoCA::componentName *) component)->NextPass(); } \ \ BOCA_EXPORT void BoCA_##componentName##_SetDriver(void *component, void *driver) { return ((BoCA::componentName *) component)->SetDriver((IO::Driver *) driver); } \ } #define BoCA_DEFINE_DEVICEINFO_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT int BoCA_##componentName##_GetNumberOfDevices(void *component) { return ((BoCA::componentName *) component)->GetNumberOfDevices(); } \ BOCA_EXPORT const void *BoCA_##componentName##_GetNthDeviceInfo(void *component, int n) { return &((BoCA::componentName *) component)->GetNthDeviceInfo(n); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsNthDeviceTrayOpen(void *component, int n) { return ((BoCA::componentName *) component)->IsNthDeviceTrayOpen(n); } \ \ BOCA_EXPORT bool BoCA_##componentName##_OpenNthDeviceTray(void *component, int n) { return ((BoCA::componentName *) component)->OpenNthDeviceTray(n); } \ BOCA_EXPORT bool BoCA_##componentName##_CloseNthDeviceTray(void *component, int n) { return ((BoCA::componentName *) component)->CloseNthDeviceTray(n); } \ \ BOCA_EXPORT const void *BoCA_##componentName##_GetNthDeviceTrackList(void *component, int n) { return &((BoCA::componentName *) component)->GetNthDeviceTrackList(n); } \ BOCA_EXPORT const void *BoCA_##componentName##_GetNthDeviceMCDI(void *component, int n) { return &((BoCA::componentName *) component)->GetNthDeviceMCDI(n); } \ } #define BoCA_DEFINE_DSP_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT bool BoCA_##componentName##_SetAudioTrackInfo(void *component, const void *track) { return ((BoCA::componentName *) component)->SetAudioTrackInfo(*((const BoCA::Track *) track)); } \ BOCA_EXPORT const void *BoCA_##componentName##_GetFormatInfo(void *component) { return &((BoCA::componentName *) component)->GetFormatInfo(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsThreadSafe(const void *component) { return ((const BoCA::componentName *) component)->IsThreadSafe(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Activate(void *component) { return ((BoCA::componentName *) component)->Activate(); } \ BOCA_EXPORT bool BoCA_##componentName##_Deactivate(void *component) { return ((BoCA::componentName *) component)->Deactivate(); } \ \ BOCA_EXPORT int BoCA_##componentName##_TransformData(void *component, void *buffer) { return ((BoCA::componentName *) component)->TransformData(*((Buffer *) buffer)); } \ \ BOCA_EXPORT int BoCA_##componentName##_Flush(void *component, void *buffer) { return ((BoCA::componentName *) component)->Flush(*((Buffer *) buffer)); } \ } #define BoCA_DEFINE_EXTENSION_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT void *BoCA_##componentName##_GetMainTabLayer(void *component) { return ((BoCA::componentName *) component)->getMainTabLayer.Emit(); } \ BOCA_EXPORT void *BoCA_##componentName##_GetStatusBarLayer(void *component) { return ((BoCA::componentName *) component)->getStatusBarLayer.Emit(); } \ } #define BoCA_DEFINE_OUTPUT_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT bool BoCA_##componentName##_SetAudioTrackInfo(void *component, const void *track) { return ((BoCA::componentName *) component)->SetAudioTrackInfo(*((const BoCA::Track *) track)); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsThreadSafe(const void *component) { return ((const BoCA::componentName *) component)->IsThreadSafe(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Activate(void *component) { return ((BoCA::componentName *) component)->Activate(); } \ BOCA_EXPORT bool BoCA_##componentName##_Deactivate(void *component) { return ((BoCA::componentName *) component)->Deactivate(); } \ \ BOCA_EXPORT int BoCA_##componentName##_WriteData(void *component, void *buffer) { return ((BoCA::componentName *) component)->WriteData(*((Buffer *) buffer)); } \ BOCA_EXPORT bool BoCA_##componentName##_Finish(void *component) { return ((BoCA::componentName *) component)->Finish(); } \ \ BOCA_EXPORT int BoCA_##componentName##_CanWrite(void *component) { return ((BoCA::componentName *) component)->CanWrite(); } \ \ BOCA_EXPORT int BoCA_##componentName##_SetPause(void *component, bool pause) { return ((BoCA::componentName *) component)->SetPause(pause); } \ BOCA_EXPORT bool BoCA_##componentName##_IsPlaying(void *component) { return ((BoCA::componentName *) component)->IsPlaying(); } \ } #define BoCA_DEFINE_PLAYLIST_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT void BoCA_##componentName##_SetTrackList(void *component, const void *trackList) { return ((BoCA::componentName *) component)->SetTrackList(*((const Array *) trackList)); } \ BOCA_EXPORT bool BoCA_##componentName##_CanOpenFile(void *component, const wchar_t *file) { return ((BoCA::componentName *) component)->CanOpenFile(file); } \ \ BOCA_EXPORT const void *BoCA_##componentName##_ReadPlaylist(void *component, const wchar_t *file) { return &((BoCA::componentName *) component)->ReadPlaylist(file); } \ BOCA_EXPORT int BoCA_##componentName##_WritePlaylist(void *component, const wchar_t *file) { return ((BoCA::componentName *) component)->WritePlaylist(file); } \ } #define BoCA_DEFINE_TAGGER_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT void BoCA_##componentName##_SetVendorString(void *component, const wchar_t *vendor) { return ((BoCA::componentName *) component)->SetVendorString(vendor); } \ \ BOCA_EXPORT int BoCA_##componentName##_ParseBuffer(void *component, const void *buffer, void *track) { return ((BoCA::componentName *) component)->ParseBuffer(*((const Buffer *) buffer), *((BoCA::Track *) track)); } \ BOCA_EXPORT int BoCA_##componentName##_ParseStreamInfo(void *component, const wchar_t *file, void *track) { return ((BoCA::componentName *) component)->ParseStreamInfo(file, *((BoCA::Track *) track)); } \ \ BOCA_EXPORT int BoCA_##componentName##_RenderBuffer(void *component, void *buffer, const void *track) { return ((BoCA::componentName *) component)->RenderBuffer(*((Buffer *) buffer), *((const BoCA::Track *) track)); } \ BOCA_EXPORT int BoCA_##componentName##_RenderStreamInfo(void *component, const wchar_t *file, const void *track) { return ((BoCA::componentName *) component)->RenderStreamInfo(file, *((const BoCA::Track *) track)); } \ \ BOCA_EXPORT int BoCA_##componentName##_UpdateStreamInfo(void *component, const wchar_t *file, const void *track) { return ((BoCA::componentName *) component)->UpdateStreamInfo(file, *((const BoCA::Track *) track)); } \ } #define BoCA_DEFINE_VERIFIER_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT bool BoCA_##componentName##_SetAudioTrackInfo(void *component, const void *track) { return ((BoCA::componentName *) component)->SetAudioTrackInfo(*((BoCA::Track *) track)); } \ BOCA_EXPORT bool BoCA_##componentName##_CanVerifyTrack(void *component, const void *track) { return ((BoCA::componentName *) component)->CanVerifyTrack(*((BoCA::Track *) track)); } \ \ BOCA_EXPORT bool BoCA_##componentName##_IsThreadSafe(const void *component) { return ((const BoCA::componentName *) component)->IsThreadSafe(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Activate(void *component) { return ((BoCA::componentName *) component)->Activate(); } \ BOCA_EXPORT bool BoCA_##componentName##_Deactivate(void *component) { return ((BoCA::componentName *) component)->Deactivate(); } \ \ BOCA_EXPORT int BoCA_##componentName##_ProcessData(void *component, void *buffer) { return ((BoCA::componentName *) component)->ProcessData(*((Buffer *) buffer)); } \ \ BOCA_EXPORT bool BoCA_##componentName##_Verify(void *component) { return ((BoCA::componentName *) component)->Verify(); } \ } #define BoCA_END_COMPONENT(componentName) \ extern "C" { \ BOCA_EXPORT const char *BoCA_##componentName##_GetComponentSpecs() { return BoCA::componentName::GetComponentSpecs().ConvertTo("UTF-8"); } \ \ BOCA_EXPORT void *BoCA_##componentName##_Create() { return new BoCA::componentName(); } \ BOCA_EXPORT bool BoCA_##componentName##_Delete(void *component) { delete ((BoCA::componentName *) component); return True; } \ \ BOCA_EXPORT void *BoCA_##componentName##_GetConfigurationLayer(void *component) { return ((BoCA::componentName *) component)->GetConfigurationLayer(); } \ \ BOCA_EXPORT bool BoCA_##componentName##_GetErrorState(const void *component) { return ((const BoCA::componentName *) component)->GetErrorState(); } \ BOCA_EXPORT const void *BoCA_##componentName##_GetErrorString(const void *component) { return &((const BoCA::componentName *) component)->GetErrorString(); } \ \ BOCA_EXPORT const void *BoCA_##componentName##_GetConfiguration(void *component) { return ((BoCA::componentName *) component)->GetConfiguration(); } \ BOCA_EXPORT bool BoCA_##componentName##_SetConfiguration(void *component, const void *configuration) { return ((BoCA::componentName *) component)->SetConfiguration((const BoCA::Config *) configuration); } \ } #endif boca-1.0.7+git20260412.690d4ffe+dfsg/include/boca/000077500000000000000000000000001516712004000205135ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/include/boca/application/000077500000000000000000000000001516712004000230165ustar00rootroot00000000000000boca-1.0.7+git20260412.690d4ffe+dfsg/include/boca/application/component.h000077500000000000000000000031511516712004000251740ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2017 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BOCA_AS_COMPONENT #define H_BOCA_AS_COMPONENT #include "componentspecs.h" #include "../common/config.h" #include "../common/configlayer.h" namespace BoCA { namespace AS { abstract class BOCA_DLL_EXPORT Component { protected: ComponentSpecs *specs; void *component; public: Component(ComponentSpecs *); virtual ~Component(); virtual String GetComponentSpecs(); const String &GetName() const; const String &GetVersion() const; const String &GetID() const; ComponentType GetType() const; const Array &GetInputSpecs() const; const Array &GetParameters() const; const Array &GetFormats() const; const Array &GetTagSpecs() const; virtual ConfigLayer *GetConfigurationLayer(); virtual Bool GetErrorState() const; virtual const String &GetErrorString() const; virtual const Config *GetConfiguration() const; virtual Bool SetConfiguration(const Config *); }; }; }; #endif boca-1.0.7+git20260412.690d4ffe+dfsg/include/boca/application/componentspecs.h000077500000000000000000000302121516712004000262300ustar00rootroot00000000000000 /* BoCA - BonkEnc Component Architecture * Copyright (C) 2007-2024 Robert Kausch * * 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 Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef H_BOCA_COMPONENTSPECS #define H_BOCA_COMPONENTSPECS #include "../common/config.h" using namespace smooth; using namespace smooth::System; namespace BoCA { enum ComponentType { COMPONENT_TYPE_UNKNOWN = 0, COMPONENT_TYPE_DECODER, COMPONENT_TYPE_ENCODER, COMPONENT_TYPE_TAGGER, COMPONENT_TYPE_EXTENSION, COMPONENT_TYPE_DSP, COMPONENT_TYPE_OUTPUT, COMPONENT_TYPE_DEVICEINFO, COMPONENT_TYPE_PLAYLIST, COMPONENT_TYPE_VERIFIER, NUM_COMPONENT_TYPES }; enum ComponentMode { COMPONENT_MODE_INTERNAL = 0, COMPONENT_MODE_EXTERNAL_FILE, COMPONENT_MODE_EXTERNAL_STDIO, NUM_COMPONENT_MODES }; enum TagMode { TAG_MODE_NONE = 0, TAG_MODE_PREPEND, TAG_MODE_APPEND, TAG_MODE_OTHER, NUM_TAG_MODES }; enum OptionType { OPTION_TYPE_OPTION = 0, OPTION_TYPE_MIN, OPTION_TYPE_MAX, NUM_OPTION_TYPES }; enum ParameterType { PARAMETER_TYPE_SWITCH = 0, PARAMETER_TYPE_SELECTION, PARAMETER_TYPE_RANGE, NUM_PARAMETER_TYPES }; struct ParameterRequirement { String option; String arguments; Bool useStderr; }; struct ParameterDependency { String setting; Bool state; String value; }; namespace AS { class BOCA_DLL_EXPORT InputSpec { private: Bool fp; Bool sign; String bits; String channels; String rate; public: InputSpec() : fp(False), sign(True), bits("8-32"), channels("1-255"), rate("1-768000") { } ~InputSpec() { } Bool GetFloat() const { return fp; } Void SetFloat(Bool nFp) { fp = nFp; } Bool GetSigned() const { return sign; } Void SetSigned(Bool nSign) { sign = nSign; } const String &GetBits() const { return bits; } Void SetBits(const String &nBits) { bits = nBits; } const String &GetChannels() const { return channels; } Void SetChannels(const String &nChannels) { channels = nChannels; } const String &GetRate() const { return rate; } Void SetRate(const String &nRate) { rate = nRate; } }; class BOCA_DLL_EXPORT TagFormat { private: String name; String tagger; TagMode mode; public: TagFormat() : mode(TAG_MODE_NONE) { } ~TagFormat() { } const String &GetName() const { return name; } Void SetName(const String &nName) { name = nName; } const String &GetTagger() const { return tagger; } Void SetTagger(const String &nTagger) { tagger = nTagger; } TagMode GetMode() const { return mode; } Void SetMode(TagMode nMode) { mode = nMode; } }; class BOCA_DLL_EXPORT FileFormat { private: String name; Bool lossless; Array extensions; Array tagFormats; public: FileFormat() : lossless(False) { } ~FileFormat() { } const String &GetName() const { return name; } Void SetName(const String &nName) { name = nName; } const Bool &IsLossless() const { return lossless; } Void SetLossless(Bool nLossless) { lossless = nLossless; } const Array &GetExtensions() const { return extensions; } Void AddExtension(const String &nExt) { extensions.Add(nExt); } const Array &GetCompanionExtensions() const; Void AddCompanionExtension(const String &); const Array &GetTagFormats() const { return tagFormats; } Void AddTagFormat(const TagFormat &nFormat) { tagFormats.Add(nFormat); } }; class BOCA_DLL_EXPORT TagSpec { private: String name; Bool defaultEnabled; Bool supportsFreeEncoding; Array encodings; String defaultEncoding; Bool supportsCoverArt; Bool coverArtDefault; Bool allowsPrependZero; Bool prependZeroDefault; public: TagSpec() : defaultEnabled(True), supportsFreeEncoding(True), supportsCoverArt(False), coverArtDefault(True), allowsPrependZero(False), prependZeroDefault(True) { } ~TagSpec() { } const String &GetName() const { return name; } Void SetName(const String &nName) { name = nName; } Bool IsDefault() const { return defaultEnabled; } Void SetDefault(Bool nDefault) { defaultEnabled = nDefault; } Bool IsCoverArtSupported() const { return supportsCoverArt; } Void SetCoverArtSupported(Bool nCoverArt) { supportsCoverArt = nCoverArt; } Bool IsCoverArtDefault() const { return coverArtDefault; } Void SetCoverArtDefault(Bool nCoverArt) { coverArtDefault = nCoverArt; } Bool IsPrependZeroAllowed() const { return allowsPrependZero; } Void SetPrependZeroAllowed(Bool nPrependZero) { allowsPrependZero = nPrependZero; } Bool IsPrependZeroDefault() const { return prependZeroDefault; } Void SetPrependZeroDefault(Bool nPrependZero) { prependZeroDefault = nPrependZero; } Bool IsFreeEncodingSupported() const { return supportsFreeEncoding; } Void SetFreeEncodingSupported(Bool nAnyEnc) { supportsFreeEncoding = nAnyEnc; } const Array &GetEncodings() const { return encodings; } Void AddEncoding(const String &nEnc) { encodings.Add(nEnc); } const String &GetDefaultEncoding() const { return defaultEncoding; } Void SetDefaultEncoding(const String &nDE) { defaultEncoding = nDE; } }; class BOCA_DLL_EXPORT Option { private: OptionType type; String alias; String value; public: Option() : type(OPTION_TYPE_OPTION) { } ~Option() { } OptionType GetType() const { return type; } Void SetType(OptionType nType) { type = nType; } const String &GetAlias() const { return alias; } Void SetAlias(const String &nAlias) { alias = nAlias; } const String &GetValue() const { return value; } Void SetValue(const String &nValue) { value = nValue; } }; class BOCA_DLL_EXPORT Parameter { private: ParameterType type; String name; String argument; Bool enabled; Float stepSize; String defaultValue; Array